Mudanças entre as edições de "PR1022804 2022 2 AULA10"

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar
(Criou página com '=Arranjos Multidimensionais (Arrays)= Os Arrays Multidimensionais, também chamados de matrizes, são estruturas de dados que possuem duas ou mais dimensões. Em resumo, temo...')
 
Linha 1: Linha 1:
=Arranjos Multidimensionais (Arrays)=
+
=Estruturas (struct) =
 
 
Os Arrays Multidimensionais, também chamados de matrizes, são estruturas de dados que possuem duas ou mais dimensões. Em resumo, temos que um Array que contém uma única dimensão (vetor) funciona internamente como um Array multidimensional. A diferença está na quantidade de índices que cada elemento da nossa estrutura terá como identificador (veremos mais tarde).
 
  
 
;Objetivos
 
;Objetivos
  
*Definindo matrizes no C.
+
*Definição de estruturas;
*Operações com matrizes e passagem de parâmetros tipo matriz.
+
*Estruturas como parâmetros;
*Matrizes com caracteres.
+
*Inicialização de estruturas;
 
+
*Cópia de estruturas;
==Como definir e operar com matrizes no C==
 
  
De forma similar ao vetor, basta definir a matriz usando colchetes para indicar a dimensão da variável.
 
  
Exemplo: Definir duas matrizes 2x3 já inicializadas e computar a soma das mesmas:
+
Na linguagem C é possível criar tipos de dados que representam uma estrutura. Veja o exemplo seguinte
  
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
 +
 +
struct TUsuario /* struct TUsuario é o nome do tipo que está sendo criado */
 +
{
 +
  char userID[20];
 +
  char senha[20];
 +
} Usuario; /* aqui é definida uma variável do  tipo struct TUsuario */
 +
 +
struct TUsuario TabelaUsuario[20];
  
 
void main()
 
void main()
 
{
 
{
   int mA[2][3]={ 11,12,13,
+
   scanf("%s", Usuario.userID);
                21,22,23},
+
   scanf("%s", Usuario.senha);
      mB[2][3]={1,2,3,
+
   scanf("%s", TabelaUsuario[10].userID);
                1,2,3},
+
  scanf("%s", TabelaUsuario[10].senha);
      mC[2][3];
 
   int i,j;
 
 
 
   for(i=0;i<2;i++){
 
    for(j=0;j<3;j++) {
 
        mC[i][j] = mA[i][j] + mB[i][j];
 
    }
 
  }
 
 
 
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
 +
Neste exemplo, foi definido um tipo (modelo) para o registro (''struct TUsuario'') e foi criada uma variável chamada ''Usuario''  a partir deste tipo. Na sequência foi criada mais uma variável (um vetor de estruturas) chamada ''TabelaUsuario''. Note que basta usar as palavras chave ''struct Usuario'' para criar novas variáveis. O tipo completo é definido uma única vez no início.
  
 
;Exercícios
 
;Exercícios
  
#Modificar este exercício para que a função receba um parâmetro adicional do tipo inteiro. A função deve retornar a média de todos os valores da matriz soma que estão acima do valor passado como parâmetro.
+
#Criar um programa que define uma ''struct'' para armazenamento do nome e das notas bimestrais de um aluno. Atualizar a estrutura usando o scanf.
#implementar um programa para calcular a média de todos elementos da matriz C do exemplo acima.<syntaxhighlight lang=c>
+
#Alterar o programa para que ele calcule e imprima a média de cada aluno.
 +
 
 +
{{collapse top| Resposta}}
 +
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
  
void main()
+
#define NUM_MAX 3
 +
 
 +
struct TAluno {
 +
  char nome[30];
 +
  char matricula[11];
 +
  float b1,b2,b3,b4;
 +
} Turma[NUM_MAX];
 +
 
 +
void print_aluno(struct TAluno aux)
 
{
 
{
   int mA[2][3]={ 11,12,13,
+
   printf("Nome -> %s\n", aux.nome);
                21,22,23},
+
   printf("Matrícula -> %s\n", aux.matricula);
      mB[2][3]={1,2,3,
+
   printf("Bimestre 1 -> %f\n", aux.b1);
                1,2,3},
+
   printf("Bimestre 2 -> %f\n", aux.b2);
      mC[2][3];
+
  printf("Bimestre 3 -> %f\n", aux.b3);
   int i,j, soma_ac=0;
+
   printf("Bimestre 4 -> %f\n", aux.b4);        
   float media;
 
 
 
   for(i=0;i<2;i++){
 
    for(j=0;j<3;j++) {
 
        mC[i][j] = mA[i][j] + mB[i][j];
 
        soma_ac = soma_ac + mC[i][j];
 
    }
 
   }
 
  media = soma_ac/6.0;
 
 
}
 
}
</syntaxhighlight>
 
#Implementar um programa para ler uma matriz quadrada NxN pelo teclado e armazená-la em uma matriz matA. Defina matA com um tamanho máximo ''matA''[N_MAX][N_MAX].<syntaxhighlight lang=c>
 
#include <stdio.h>
 
  
#define N_MAX 50
 
 
 
void main()
 
void main()
 
{
 
{
  int mA[N_MAX][N_MAX];
+
   int i;
   int i,j,dimN;
 
 
 
  /*  Entrada da dimensão  */
 
  printf("Entre com a dimensao\n");
 
  scanf ("%d",&dimN);
 
 
    
 
    
  /*      Entrada de dados  */ 
+
   for(i=0;i<NUM_MAX;i++) {
   for (i=0;i<dimN;i++) {
+
  printf("Entre com o nome do aluno\n");
    for (j=0;j<dimN;j++) {
+
  scanf("%s", Turma[i].nome);
      printf("Entre com mA[%d][%d]\n",i,j);
+
  printf("Entre com a matrícula do aluno\n");
      scanf("%d",&mA[i][j]);
+
  scanf("%s", Turma[i].matricula);
    }
+
  printf("Entre com a nota do bimestre 1\n");
 +
  scanf("%f", &Turma[i].b1);
 +
  printf("Entre com a nota do bimestre 2\n");
 +
  scanf("%f", &Turma[i].b2);
 +
  printf("Entre com a nota do bimestre 3\n");
 +
  scanf("%f", &Turma[i].b3);
 +
  printf("Entre com a nota do bimestre 4\n");
 +
  scanf("%f", &Turma[i].b4);
 
   }
 
   }
 
+
   for(i=0;i<NUM_MAX;i++) {
  /* impressao dos dados lidos */
+
     printf("=========== Aluno %d ============\n", i); 
   for (i=0;i<dimN;i++) {
+
  print_aluno(Turma[i]);  
     for (j=0;j<dimN;j++) {
+
   }    
      printf("=>  mA[%d][%d] => %d\n",i,j,mA[i][j]);
 
    }
 
   }
 
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
{{collapse bottom}}
  
==Passando matrizes como parâmetro==
+
==Copiando estruturas==
 
 
Como matrizes também são vetores, a mesma característica da passagem de parâmetros é considerada. Observe os exemplos a seguir:
 
  
;Exemplo 1
+
O exemplo a seguir demonstra como se pode copiar uma variável ''struct'' para outra do mesmo tipo.
  
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
 +
 
 +
struct THoras{
 +
  int hora;
 +
  int minuto;
 +
  int segundo;
 +
};
 +
 +
struct THoras Ontem = {2,10,57};
  
void somar_mat(int aA[][3],int aB[][3], int cC[][3])
+
void main()
 
{
 
{
  int i,j;
+
    struct THoras Hoje;
 +
    Hoje = Ontem;
  
  for(i=0;i<2;i++){
+
    printf("Hora hoje = %d, Minuto hoje = %d e Segundo hoje %d\n", Hoje.hora, Hoje.minuto, Hoje.segundo);
    for(j=0;j<3;j++) {
 
        cC[i][j] = aA[i][j] + aB[i][j];
 
    }
 
  }
 
 
}
 
}
 +
</syntaxhighlight>
 +
 +
==Estruturas dentro de estruturas==
 +
 +
Vamos  ver um exemplo com estruturas definidas dentro de estruturas:
 +
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 
 +
struct TEndereco{
 +
    char rua[50];
 +
    char numero[10];
 +
};
 +
 +
struct TCidadao{
 +
  char nome[50];
 +
  char cpf[20];
 +
  struct TEndereco endereco;
 +
  int num_filhos;
 +
};
  
 
void main()
 
void main()
 
{
 
{
   int mA[2][3]={ 11,12,13,
+
   struct TCidadao Cidadao;
                21,22,23},
+
 
      mB[2][3]={1,2,3,
+
  printf("Entre com o nome\n");
                1,2,3},
+
  scanf ("%s",Cidadao.nome); // substitua por gets()
      mC[2][3];
+
 
 +
  printf("Entre com o cpf\n");
 +
  scanf ("%s",Cidadao.cpf);
 +
 
 +
  printf("Entre a rua\n");
 +
  scanf ("%s",Cidadao.endereco.rua); // substitua por gets()
 +
 
 +
  printf("Entre a numero\n"); 
 +
  scanf ("%s",Cidadao.endereco.numero);
  
somar_mat(mA,mB,mC);
+
  printf("Entre com o número de filhos\n");
 +
  scanf ("%d",&Cidadao.num_filhos);
 
    
 
    
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
  
'''OBSERVE''' que matrizes são sempre passadas como referência.
+
Exercício 1: Faça um código adicional para imprimir o conteúdo lido na estrutura.
  
;Exemplo 2
 
  
 +
{{collapse top| Resposta}}
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
 +
 +
struct TEndereco{
 +
    char rua[50];
 +
    char numero[10];
 +
};
 +
 +
struct TCidadao{
 +
  char nome[50];
 +
  char cpf[20];
 +
  struct TEndereco endereco;
 +
  int num_filhos;
 +
};
  
void somar_mat(int m1[][3],int m2[][3], int m3[][3]);
+
void print_endereco(struct TEndereco aux)
void imprimir_mat(int mat[][3]);
+
{
 +
  printf ("Rua %s Número %s\n", aux.rua, aux.numero);  
 +
}
  
void main()
+
void print_cidadao(struct TCidadao aux)
 
{
 
{
   int mA[2][3]={ 11,12,13,
+
   printf("Nome: %s CPF: %s ", aux.nome, aux.cpf);
                21,22,23},
+
  print_endereco(aux.endereco);
      mB[2][3]={1,2,3,
+
  printf("Numero de filhos %d\n", aux.num_filhos);
                1,2,3},
 
      mC[2][3]={4,5,6,
 
                7,8,9 },
 
      mR[2][3];
 
  int i,j;
 
somar_mat(mA,mB,mR); // somar matrix A com B
 
imprimir_mat(mR);
 
somar_mat(mB,mC,mR);
 
imprimir_mat(mR);
 
somar_mat(mA,mC,mR);
 
imprimir_mat(mR);
 
 
}
 
}
  
void somar_mat(int m1[][3],int m2[][3], int m3[][3])
+
void main()
 
{
 
{
   int i,j;
+
   struct TCidadao Cidadao;
 
+
   for(i=0;i<2;i++){
+
  printf("Entre com o nome\n");
    for(j=0;j<3;j++) {
+
  scanf ("%s",Cidadao.nome);
        m3[i][j] = m1[i][j] + m2[i][j];
+
    }
+
   printf("Entre com o cpf\n");
  }
+
  scanf ("%s",Cidadao.cpf);
 +
 +
  printf("Entre a rua\n");
 +
  scanf ("%s",Cidadao.endereco.rua);
 +
 +
  printf("Entre a numero\n");  
 +
  scanf ("%s",Cidadao.endereco.numero);
 +
 +
  printf("Entre com o número de filhos\n");
 +
  scanf ("%d",&Cidadao.num_filhos);
 +
 
}
 
}
 +
</syntaxhighlight>
 +
{{collapse bottom}}
  
void imprimir_mat(int mat[][3]){
+
==Iniciando estruturas na definição==
  int i,j;
 
  for(i=0;i<2;i++){
 
    for(j=0;j<3;j++) {
 
        printf("%d\t",mat[i][j]);
 
    }
 
    printf("\n");
 
  }
 
  printf("\n");
 
}
 
  
 +
Como toda variável, é possível dar valores para uma variável do tipo struct definida no programa:
  
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 +
struct TEndereco{
 +
    char rua[50];
 +
    char numero[10];
 +
};
 +
 +
struct TCidadao{
 +
  char nome[50];
 +
  char cpf[20];
 +
  struct TEndereco endereco;
 +
  int num_filhos;
 +
};
 +
 +
void main()
 +
{
 +
  struct TCidadao Cidadao = {"Maria",
 +
                            "42342342234",
 +
                            {"Rua AlfaBeta","145"},
 +
                            5
 +
                            };
 +
 +
  printf("Rua do cidadao = %s\n", Cidadao.endereco.rua);
 +
 +
}
 
</syntaxhighlight>
 
</syntaxhighlight>
  
===Exercícios 1===
+
==Passando estruturas como parâmetro e retornando estruturas==
  
1. Fazer uma função que recebe duas matrizes 2x3 como parâmetros e retorna a média entre todos elementos da matriz soma destas matrizes.
+
Se não for usado o operador "&" , um parâmetro que é estrutura será passado por cópia. Não apresentaremos agora a passagem por endereço pois necessita do conceito de ponteiro.
 +
Observe o exercício abaixo.
  
{{collapse top|Resposta}}
 
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
 +
 
 +
struct TEndereco{
 +
    char rua[50];
 +
    char numero[10];
 +
};
  
 +
struct TCidadao{
 +
  char nome[50];
 +
  char cpf[20];
 +
  struct TEndereco endereco;
 +
  int num_filhos;
 +
};
  
float media_soma_mat(int aA[][3],int aB[][3])
+
void print_struct (struct TCidadao aux)
 
{
 
{
   int i,j;
+
   printf("nome=%s cpf=%s\n", aux.nome, aux.cpf);
  int soma_ac=0;
+
   printf("endereço inicial do aux %p\n", &aux);
  /*int cC[2][3];*/
 
 
 
  for(i=0;i<2;i++){
 
    for(j=0;j<3;j++) {
 
        /*cC[i][j] = aA[i][j] + aB[i][j];*/
 
        soma_ac = soma_ac +aA[i][j] + aB[i][j];
 
    }
 
  }
 
   return (soma_ac/6.0);
 
 
}
 
}
  
 
void main()
 
void main()
 
{
 
{
   int mA[2][3]={
+
   struct TCidadao Cidadao;
                11,12,13,
+
 
                21,22,23},
+
  printf("Entre com o nome\n");
      mB[2][3]={
+
  scanf ("%s",Cidadao.nome);
                1,2,3,
+
 
                1,2,3};
+
  printf("Entre com o cpf\n");
   float media;
+
  scanf ("%s",Cidadao.cpf);
 +
 
 +
  printf("Entre a rua\n");
 +
  scanf ("%s",Cidadao.endereco.rua);
 +
 
 +
  printf("Entre a numero\n");  
 +
   scanf ("%s",Cidadao.endereco.numero);
  
   media =  media_soma_mat(mA,mB);
+
   printf("Entre com o número de filhos\n");
 +
  scanf ("%d",&Cidadao.num_filhos);
 
    
 
    
 +
  print_struct(Cidadao);
 +
 +
  printf("endereço inicial do Cidadao %p\n", &Cidadao);
 
}
 
}
</syntaxhighlight>
 
{{collapse bottom}}
 
  
2. Implementar uma programa para calcular o determinante de uma matriz 3x3 (de reais) a ser fornecida pelo teclado.<br>
+
</syntaxhighlight>  
3. Implementar um programa para ler duas matrizes (''matA'' e ''matB'') e multiplicá-las, colocando o resultado em uma matriz matC.<br>
+
 
4. Vamos implementar um jogo similar a batalha naval da seguinte forma.<br>
+
;O que podemos concluir com os endereços que foram mostrados??? Vamos a mais um exemplo.
:4.1. Crie uma matriz de inteiros global chamada ZonaDeGuerra com 10x10 posições (iniciada com 0). Construa  uma função para gerar randomicamente a posição de 1 porta-aviões (colocando 1 na sua posição), 5 fragatas (número 2) e 5 submarinos (número 3). Assuma que a cada casa onde o inimigo alvejar  será somado 10 ao número da casa.<br>
+
 
:4.2. Crie um contador global de tiros iniciado com 0.<br>
 
:4.3. Crie uma função de tiro. Esta função deve ler a posição de tiro, verificar se a casa ainda não foi alvejada. Se alvejada pergunta novamente a posição. Se a posição for válida e tiver um navio então o usuário ganha pontos da seguinte forma: 10 para o porta aviões, 5 para o submarino e 3 para fragata. A função deve retornar 0 se o jogo continua, 1 se o usuário atingiu todos os navios ou 2 se o usuário teve um número máximo de tiros ultrapassado (assumir  30 tiros).<br>
 
:4.4. Ao final do jogo é mostrado o nome do jogador, o número de tiros dados e a pontuação obtida.<br>
 
{{collapse top|Resposta}}
 
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
/*
+
#include <stdio.h>
  Batalha Naval
+
 
  Versão Turma PRG2014-1-IFSC
+
struct TEndereco{
*/
+
    char rua[50];
 +
    char numero[10];
 +
};
  
#include <stdio.h>
+
struct TCidadao{
#include <stdlib.h>
+
  char nome[50];
#include <time.h>
+
  char cpf[20];
 +
  struct TEndereco endereco;
 +
  int num_filhos;
 +
};
  
/**********************************/
+
struct TCidadao ler_struct()
/***** DEFINIÇÕES DESTE MÓDULO  ****/
+
{
/**********************************/
+
  struct TCidadao aux;
  
#define TAM_MAT 10
+
  printf("Entre com o nome\n");
#define MAX_TIROS 30
+
  scanf ("%s",aux.nome);
#define MAX_NOME 30
 
  
/**********************************/
+
  printf("Entre com o cpf\n");
/***** VARIÁVEIS GLOBAIS **********/
+
  scanf ("%s",aux.cpf);
/**********************************/
 
  
int ZonaDeGuerra[TAM_MAT][TAM_MAT];/* Matriz do espaço de batalha */
+
  printf("Entre a rua\n");
int ContadorTiros=0;
+
  scanf ("%s",aux.endereco.rua);
int PontuacaoFinal;      /* acumula a pontuação do jogador */
 
char nome[MAX_NOME];
 
int x_sorteado;
 
int y_sorteado;
 
  
 +
  printf("Entre a numero\n"); 
 +
  scanf ("%s",aux.endereco.numero);
  
/***********************************/
+
  printf("Entre com o número de filhos\n");
/****  FUNÇÕES DESTE MÓDULO ********/
+
  scanf ("%d",&aux.num_filhos);
/***********************************/
 
  
/***** FUNÇÕES DE INICIALIZAÇÃO ****/
+
  return aux;
 +
}
  
void ZerarMatriz()
+
void print_struct (struct TCidadao aux)
 
{
 
{
   int i,j;
+
   printf("nome=%s cpf=%s\n", aux.nome, aux.cpf);
    
+
   printf("endereço inicial do aux %p\n", &aux);
  for (i=0;i<TAM_MAT;i++)
 
  for(j=0;j<TAM_MAT;j++)
 
  ZonaDeGuerra[i][j]=0;
 
 
}
 
}
  
void SortearCasa()
+
void main()
 
{
 
{
  do {
+
  struct TCidadao Cidadao;
  /* generate secret number: */
+
 
  x_sorteado = rand() % TAM_MAT;
+
  Cidadao = ler_struct();
  y_sorteado = rand() % TAM_MAT;
+
 
  } while (ZonaDeGuerra[x_sorteado][y_sorteado]!=0);
+
  print_struct(Cidadao);
 
+
 
 +
  printf("endereço inicial do Cidadao %p\n", &Cidadao);
 
}
 
}
  
PosicionarFragatas()
+
</syntaxhighlight>
{  
+
 
 +
==Aplicação no Controle de Acesso==
 +
 
 +
O exemplo a seguir implementa uma parte do programa de controle de acesso usando estruturas. Neste exemplo
 +
a tabela de usuários já vem inicializada nos campos ''UserID'' e ''Senha''.
 +
 
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
#include <string.h>
 +
 +
/**********************************************/
 +
/*** PROGRAMA DE CONTROLE DE ACESSO  **/
 +
/** Autor: TurmaENG.TELECOM - 2012.2 */
 +
/**********************************************/
 +
 +
/** VARIÁVEIS GLOBAIS DESTE MÓDULO ****/
 +
 
 +
struct TRegistroUsuario {
 +
char UserId[10];
 +
char Senha[10];
 +
};
 +
 
 +
/* Tabela de Usuários */
 +
struct TRegistroUsuario TabelaUsuarios[4] = {
 +
        {"joao","abcd"},
 +
        {"maria","xxxx"},
 +
        {"jose","yyyy"},
 +
        {"lara","zzzz"},
 +
};
 +
 
 +
 +
char userID[20];
 +
 +
 +
/** FUNÇÔES DESTE MÓDULO ****/
 +
 +
void mostrar_menu_entrada_usuario()
 +
{
 +
  printf("*******************************\n");
 +
  printf("Entre com o seu USERID para ter acesso\n");
 +
  printf("*******************************\n");
 +
}
 +
 +
/** Função que implementa as tarefas do administrador **/
 +
 +
void  administrar()
 +
{
 +
}
 +
 +
/** Função que valida um usuário e abre a porta **/
 +
 +
void tratar_usuario()
 +
{
 +
  char senha[10];
 +
  int userEncontrado=1;
 
   int i;
 
   int i;
   for(i=0;i<5;i++){
+
  SortearCasa();
+
    ZonaDeGuerra[x_sorteado][y_sorteado]=2;
+
/*
 +
    Loop para encontrar o usuário na tabela.
 +
    Ao final do loop a variavel i conterá o índice do usuário (se ele estiver
 +
    na tabela
 +
  */
 +
   for (i=0;i<4 && userEncontrado; i++) {
 +
      if( strcmp(userID, TabelaUsuarios[i].UserId)==0)
 +
            userEncontrado=0;
 
   }
 
   }
}
+
 
+
  /* se usuário encontrado abre a porta */
PosicionarSubmarinos()
+
  if (userEncontrado==0) {
{
+
printf("Bom dia %s! Entre com a senha\n", userID);
  int i;
+
  scanf("%s",senha);
  for(i=0;i<5;i++){
+
i--; /* o indice do sujeito é i-1 */
  SortearCasa();
+
if(strcmp(senha,TabelaUsuarios[i].Senha)==0)  
    ZonaDeGuerra[x_sorteado][y_sorteado]=3;
+
      printf("Abrir porta!!!\n");
 +
else
 +
printf("Senha Inválida\n");
 
   }
 
   }
 
}
 
}
 
+
void PosicionarPortaAvioes()
+
void main()
 
{
 
{
  SortearCasa();
+
  for(;;) {
ZonaDeGuerra[x_sorteado][y_sorteado]=1;
+
    mostrar_menu_entrada_usuario();
 +
    scanf("%s",userID);
 +
    if (strcmp(userID, "admin")==0) {
 +
          administrar();
 +
    } else {
 +
        tratar_usuario();
 +
    }
 +
 
}
 
}
 +
</syntaxhighlight>
 +
 +
=Desafios com ''Structs''=
 +
 +
==Desafio 1==
 +
 +
Implementar uma função ''converte_para_polar'' que recebe como parâmetro um número complexo na forma retangular (representado por uma ''struct''). A função deve retornar uma ''struct'' contendo o número complexo na forma polar.Usar as funções ''sqrtf'' e  ''atanf''  da [[http://en.wikipedia.org/wiki/C_mathematical_functions matemáticas] biblioteca matemática]. [http://www.teacherschoice.com.au/maths_library/coordinates/polar_-_rectangular_conversion.htm Como converter]:
 +
:<math> mod = \sqrt{x^2+y^2} </math>
 +
:<math> \phi = \arctan \frac{y}{x} </math>  ou  <math> \phi = \tan^{-1} \frac{y}{x} </math>
 +
 +
'''NOTE''' que as funções atanf e similares retornam em RADIANOS.
 +
 +
{{collapse top|Solução}}
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
#include <math.h>
  
void PosicionarNavios()
+
struct tipo_ret {
{
+
float x;
/* initialize random seed: */
+
float y;
srand ( time(NULL) );
+
};
 
PosicionarPortaAvioes();
 
PosicionarFragatas();
 
PosicionarSubmarinos();  
 
}
 
  
/*** FUNÇÕES DE IMPRESSÃO NA TELA **/
+
struct tipo_polar {
 +
float mod;
 +
float ang;
 +
};
  
void ImprimeLinha(int linha)
 
{
 
  int j;
 
 
 
  printf("    ");   
 
  for(j=0;j<TAM_MAT;j++) {
 
    printf("| %d ",ZonaDeGuerra[linha][j]);
 
  }
 
  printf("|\n");
 
  printf("    +---+---+---+---+---+---+---+---+---+---+\n");
 
}
 
  
 +
/* Função para converter complexo retangular em polar */
  
void ImprimeMatriz()
+
struct tipo_polar converter_ret_pol(struct tipo_ret num_ret)
 
{
 
{
   int i;
+
   struct tipo_polar num_polar;
 +
  float aux;
 +
 
 +
  aux = num_ret.x*num_ret.x + num_ret.y*num_ret.y;
 
    
 
    
   printf("    +---+---+---+---+---+---+---+---+---+---+\n");
+
   /* falta a lógica para detectar o quadrante */
   for(i=0;i<TAM_MAT;i++)
+
  num_polar.mod = sqrtf(aux);
  ImprimeLinha(i);
+
   num_polar.ang = atanf(num_ret.y/num_ret.x);
}
+
  return num_polar;
 
 
int Tiro()
 
{
 
 
}
 
}
  
main()
+
/* Função para imprimir complexo retangular */
 +
void imprimir_complexo_ret(struct tipo_ret num_ret)
 
{
 
{
   ZerarMatriz();
+
   printf("Coordenada x = %f", num_ret.x);
  PosicionarNavios();
+
   printf("Coordenada y = %f\n", num_ret.y);
  ImprimeMatriz();
 
  do {
 
    situacao = Tiro();
 
   while (situacao!=0);
 
 
}
 
}
</syntaxhighlight>
 
  
<!--
+
/* Função para imprimir complexo retangular */
int Tiro()
+
void imprimir_complexto_pol(struct tipo_ret num_ret)
 
{
 
{
   for (;;)  {
+
   printf("Coordenada x = %f", num_ret.x);
  printf("Entre com a linha: ");
+
  printf("Coordenada y = %f\n", num_ret.y);
  scanf ("%d", &linha);
 
  printf("Entre com a coluna: ");
 
  scanf ("%d", &coluna);
 
     
 
 
}
 
}
  
 
main()
 
main()
 
{
 
{
   int situacao;
+
   struct tipo_ret num1;
    
+
   struct tipo_polar num2;
  ZerarMatriz();
 
  PosicionarNavios();
 
  ImprimeMatriz();
 
  do {
 
    situacao = Tiro();
 
  while (situacao!=0);
 
 
 
  switch (situacao) {
 
  case 1: printf("%s: Você acertou todos os navios\n", nome);
 
          printf("Sua pontuação é %d\n", pontuacao_final);
 
          break;
 
    case 2: printf("%s: Você atingiu o limite máximo de tiros\n", nome);
 
          break;
 
  default: printf("Algum problema ocorreu...\n");
 
          break;
 
  }
 
 
    
 
    
 +
  num1.x = 5;
 +
  num1.y = 10;
 +
  num2 = converter_ret_pol (num1); 
 
}
 
}
-->
+
</syntaxhighlight>
 
{{collapse bottom}}
 
{{collapse bottom}}
  
==Matrizes de caracteres e vetores de strings==
+
==Desafio 2 ==
 
 
Um vetor de strings pode ser construído usando matrizes de ''char''. Cada string será armazenada em uma linha do vetor.
 
 
 
;Exemplo
 
  
<syntaxhighlight lang=c>
+
Implementar uma função que some dois números complexos no formato ''retangular'' e retorne a soma como um complexo ''retangular''.
#include <stdio.h>
 
  
main()
+
==Desafio 3==
{
 
  char TabelaUsuarios[4][10] = {
 
        "joao",
 
        "maria",
 
        "jose",
 
        "lara",
 
                                };
 
  int i;
 
  
  for (i=0;i<4;i++)
+
Implementar uma função que some dois números complexos no formato ''polar'' e retorna a soma no formato ''polar''.
      printf("%s\n",&TabelaUsuarios[i][0]);
 
}
 
</syntaxhighlight>
 
  
Note a forma como é realizada a inicialização da matriz.
 
  
===Exercícios 2===
+
=Exercícios=
  
1. Implementar um programa para "abrir uma porta" para um usuário que se encontra na tabela acima.
+
1. Implementar um contador de acesso que permita bloquear o usuário após 3 tentativas seguidas. Note que caso o usuário acerte a senha, este contador deverá ser zerado.
{{collapse top|Reposta}}
+
{{collapse top|Solução 1}}
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
 
+
#include <string.h>
char tabelaUsuarios[4][10] = {
+
         "joao",
+
/**********************************************/
         "maria",
+
/*** PROGRAMA DE CONTROLE DE ACESSO  **/
         "josefina",
+
/** Autor: Turma ENG.TELECOM - 2013.1 */
         "lara",
+
/**********************************************/
 +
 +
/** VARIÁVEIS GLOBAIS DESTE MÓDULO ****/
 +
 +
struct TRegistroUsuario {
 +
char UserId[10];
 +
char Senha[10];
 +
int contador;
 +
};
 +
 +
/* Tabela de Usuários */
 +
struct TRegistroUsuario TabelaUsuarios[4] = {
 +
         {"joao","abcd",0},
 +
         {"maria","xxxx",0},
 +
         {"jose","yyyy",0},
 +
         {"lara","zzzz",0},
 
};
 
};
 +
 +
 +
char userID[20];
 +
 +
 +
/** FUNÇÔES DESTE MÓDULO ****/
 +
 +
void mostrar_menu_entrada_usuario()
 +
{
 +
  printf("*******************************\n");
 +
  printf("Entre com o seu USERID para ter acesso\n");
 +
  printf("*******************************\n");
 +
}
  
int str_cmp(char str1[],char str2[])
+
/** Função que implementa as tarefas do administrador **/
 +
 +
void  administrar()
 
{
 
{
   int i=0;
+
  char aux_senha[10];
+
  int userEncontrado=1;
  while(str1[i]!=0 && str2[i]!=0) {
+
   int i;
    if (str1[i]!=str2[i])
+
   
        break;  
+
  printf("Entre com a senha do admin \n");
    i++;
+
  scanf ("%s", aux_senha);
 +
 
 +
  if(strcmp(aux_senha,"123456")==0) {
 +
      /* senha valida do admin - agora entre com userid a ser desbloqueado */
 +
      printf("Entre com userdID a ser desbloqueado\n");
 +
      scanf("%s",userID);
 +
      for (i=0;i<4 && userEncontrado; i++) {
 +
        if( strcmp(userID, TabelaUsuarios[i].UserId)==0)
 +
            userEncontrado=0;
 +
      }
 +
      if (userEncontrado==0) {
 +
        i--;
 +
        TabelaUsuarios[i].contador=0;
 +
      }         
 
   }
 
   }
  if(str1[i]==0 && str2[i]==0)
 
    return 0; // Perceba que retorna "0" quando as strings forem iguais
 
  else
 
    return 1; // e "1" quando forem diferentes (tomem cuidado com o entendimento)
 
 
 
 
}
 
}
       
+
main()
+
/** Função que valida um usuário e abre a porta **/
 +
 +
void tratar_usuario()
 
{
 
{
 
+
  char senha[10];
 +
  int userEncontrado=1;
 
   int i;
 
   int i;
  char nome[10];
 
 
   
 
   
   printf("Entre com seu USERID\n");
+
  scanf("%s", nome);
+
/*
  for (i=0;i<4;i++) {
+
    Loop para encontrar o usuário na tabela.
      if (str_cmp(nome,&tabelaUsuarios[i][0])==0) {
+
    Ao final do loop a variavel i conterá o índice do usuário (se ele estiver
      break;
+
    na tabela
      }
+
   */
 +
  for (i=0;i<4 && userEncontrado; i++) {
 +
      if( strcmp(userID, TabelaUsuarios[i].UserId)==0)
 +
            userEncontrado=0;
 +
  }
 +
 +
  /* se usuário encontrado abre a porta */
 +
  if (userEncontrado==0) {
 +
  i--; /* o indice do sujeito é i-1 */
 +
    if (TabelaUsuarios[i].contador<3){
 +
   
 +
  printf("Bom dia %s! Entre com a senha\n", userID);
 +
    scanf("%s",senha);
 +
 
 +
  if(strcmp(senha,TabelaUsuarios[i].Senha)==0) {
 +
      printf("Abrir porta!!!\n");
 +
      TabelaUsuarios[i].contador=0;
 +
  }
 +
  else {
 +
  TabelaUsuarios[i].contador++;
 +
  printf("Senha Inválida\n");
 +
  printf("Tentativas restantes %d\n", 3-TabelaUsuarios[i].contador);
 +
}
 +
    } else {
 +
      printf("Usuário bloqueado\n");
 +
    }
 +
  } else {
 +
    printf("Usuário não encontrado\n");
 
   }
 
   }
  if (i==4)
+
}
    printf("Usuário não existente!\n");  
+
  else
+
void main()
      printf("abrir a porta\n");   
+
{
 +
for(;;) {
 +
    mostrar_menu_entrada_usuario();
 +
    scanf("%s",userID);
 +
    if (strcmp(userID, "admin")==0) {
 +
          administrar();
 +
    } else {
 +
        tratar_usuario();
 +
    }
 +
}    
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 
{{collapse bottom}}
 
{{collapse bottom}}
2. Implementar uma tabela adicional com senhas dos usuários. O acesso deve ser concedido somente se o usuário for validado e a senha. Defina as tabelas como variáveis globais.<br>
+
2. Implementar uma funcionalidade do administrador para desbloquear o usuário bloqueado.
3. Implementar uma modificação do exercício anterior que permite ao programa ficar em loop até que se entre com userID igual a "fim".<br>
 
4. No exercício anterior, acrescente uma tabela de contadores que permite armazenar o número de tentativas seguidas de um usuário, no caso de erro de senha. Se o número de tentativas for maior que 3 a porta não deverá mais ser aberta para o usuário (usuário bloqueado).<br>
 
5. No exercício anterior, acrecente a figura do administrador (armazenado separadamente como user "admin" e senha "12345". Ao logar o administrador será questionado por um usuário a ser desbloqueado. O administrador entra com o usuário a ser desbloquado e o sistema volta a perguntar por um userID.<br>
 
  
{{collapse top|Exercício MEGASENA}}
+
{{collapse top|Solução 2}}
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
#include <stdlib.h>
+
#include <string.h>
#include <time.h>
+
 
+
/**********************************************/
#define NUM_JOGOS 8
+
/*** PROGRAMA DE CONTROLE DE ACESSO          */
#define NUMS_MEGA 6
+
/** Autores: Daniel Trevisan Tatsch          */
 
+
/**          Ricardo Amorim                  */
int matriz_jogos[NUM_JOGOS][NUMS_MEGA];
+
/**********************************************/
 
+
int gerar_num_al()
+
/** VARIÁVEIS GLOBAIS DESTE MÓDULO ****/
 +
 +
struct TRegistroUsuario {
 +
    char UserId[10];
 +
    char Senha[10];
 +
    int ativo;
 +
};
 +
 +
/* Tabela de Usuários */
 +
struct TRegistroUsuario TabelaUsuarios[4] = {
 +
        {"joao","abcd",1},
 +
        {"maria","xxxx",1},
 +
        {"jose","yyyy",1},
 +
        {"lara","zzzz",1},
 +
};
 +
 +
char userID[20];
 +
 +
/** FUNÇÔES DESTE MÓDULO ****/
 +
 +
void mostrar_menu_entrada_usuario()
 
{
 
{
   return (rand()%60 + 1);
+
   printf("\n********************************************");
 +
  printf("\nEntre com o seu USERID para ter acesso: ");
 +
  printf("\n********************************************\n");
 
}
 
}
 
+
int testar_num(int numero, int vetor[NUMS_MEGA], int limite)
+
/** Função que implementa as tarefas do administrador **/
{
+
  int i=0;
+
void administrar()
  for (i=0;i<limite;i++) {
 
    if (vetor[i]==numero)
 
        return 1;
 
  }
 
  return 0;
 
}
 
 
 
void ordenar_vetor(int vetor[NUMS_MEGA])
 
 
{
 
{
 
+
    int i;
 +
    for(i=0;i<4;i++)
 +
TabelaUsuarios[i].ativo=1;
 +
    printf("\nTodos os usuários foram liberados!\n");
 
}
 
}
 
+
void imprimir_matriz()
+
/** Função que valida um usuário e abre a porta **/
 +
 +
void tratar_usuario()
 
{
 
{
   int i,j;
+
  char senha[10];
    
+
  int userEncontrado=1;
   for(i=0;i<NUM_JOGOS;i++) {
+
   int i, cont = 0;
      for(j=0;j<NUMS_MEGA;j++)
+
        printf("%d ", matriz_jogos[i][j]);
+
/*
      printf("\n");
+
    Loop para encontrar o usuário na tabela.
 +
    Ao final do loop a variavel i conterá o índice do usuário (se ele estiver
 +
    na tabela
 +
   */
 +
   for (i=0;i<4 && userEncontrado; i++) {
 +
      if( strcmp(userID, TabelaUsuarios[i].UserId)==0)
 +
            userEncontrado=0;  
 
   }
 
   }
 
    
 
    
 +
  if (userEncontrado==0) {  // se usuário encontrado...
 +
      for(;;){
 +
      if(TabelaUsuarios[i-1].ativo){ // se usuário ativo (1)...
 +
printf("Bom dia %s! Entre com a senha\n", userID);
 +
scanf("%s",senha);
 +
if(strcmp(senha,TabelaUsuarios[i-1].Senha)==0){ // se senha confere (0)...
 +
    printf("Abrir porta!!!\n");
 +
    cont=0;
 +
    break;
 +
} else {
 +
    printf("Senha Inválida\n");
 +
    cont++;
 +
    if(cont==3){
 +
      printf("\nUsuário Bloqueado!\n");   
 +
      TabelaUsuarios[i-1].ativo = 0;
 +
      break;
 +
    }
 +
}
 +
      } else {
 +
printf("\nUsuário Bloqueado!\n");  // usuario bloqueado ativo (0)   
 +
break;
 +
      }
 +
} // fim do for(;;)
 +
  } else
 +
        printf("\nUsuário não encontrado!\n"); // se usuario nao encontrado. 
 
}
 
}
 
+
int gerar_jogo(int num_jogo)
+
void main()
 
{
 
{
  int i, num_al;
+
for(;;) {
 
+
    mostrar_menu_entrada_usuario();
  matriz_jogos[num_jogo][0] = gerar_num_al();
+
    scanf("%s",userID);
  for(i=1;i<6;i++) {  
+
    if (strcmp(userID, "admin")==0) {
  do {
+
          administrar();
    num_al = gerar_num_al();
+
    } else {
  } while(testar_num(num_al, matriz_jogos[num_jogo],i));
+
        tratar_usuario();
  matriz_jogos[num_jogo][i]=num_al;
+
    }
  }
+
}    
}
 
 
 
main()
 
{
 
  int i;
 
 
  srand ( time(NULL) );
 
       
 
  for (i=0;i<NUM_JOGOS;i++)
 
      gerar_jogo(i);
 
   imprimir_matriz();
 
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 
{{collapse bottom}}
 
{{collapse bottom}}
 +
3. No programa de controle de senha inserir um campo na estrutura do usuário de forma a acomodar uma mensagem de boas vindas particularizada para cada usuário. A mensagem "DEFAULT" é Bom dia! <br>
 +
4. Implementar na função administrar a inserção da mensagem no exercício anterior.<br>
 +
5. Na solução acima criar uma função que procura usuário na tabela (já que este código é utilizado em mais do que um luga). A função deve receber o UserID a ser procurado e deve retornar um inteiro correspondente ao índice do usuário encontrado ou -1 se não for encontrado.<br>
 +
 +
=Referências=
 +
 +
[1] https://pt.wikibooks.org/wiki/Programar_em_C/Estruturas
 +
  
  
Linha 546: Linha 766:
 
[[Imagem:icone_voltar.png|link=PR1022804_2022_2_AULA09]]
 
[[Imagem:icone_voltar.png|link=PR1022804_2022_2_AULA09]]
 
[[Imagem:icone_menu.png|link=PR1022804_2022_2#Aulas]]
 
[[Imagem:icone_menu.png|link=PR1022804_2022_2#Aulas]]
[[Imagem:icone_prox.png|link=PR1022804_2022_2_AULA11]]
+
[[Imagem:icone_prox.png|link=PR1022804_2022_2_AULA10]]

Edição das 14h34min de 27 de outubro de 2022

Estruturas (struct)

Objetivos
  • Definição de estruturas;
  • Estruturas como parâmetros;
  • Inicialização de estruturas;
  • Cópia de estruturas;


Na linguagem C é possível criar tipos de dados que representam uma estrutura. Veja o exemplo seguinte

#include <stdio.h>

struct TUsuario /* struct TUsuario é o nome do tipo que está sendo criado */
{ 
  char userID[20];
  char senha[20];
} Usuario; /* aqui é definida uma variável do  tipo struct TUsuario */

struct TUsuario TabelaUsuario[20];

void main()
{
  scanf("%s", Usuario.userID);
  scanf("%s", Usuario.senha);
  scanf("%s", TabelaUsuario[10].userID);
  scanf("%s", TabelaUsuario[10].senha);
}

Neste exemplo, foi definido um tipo (modelo) para o registro (struct TUsuario) e foi criada uma variável chamada Usuario a partir deste tipo. Na sequência foi criada mais uma variável (um vetor de estruturas) chamada TabelaUsuario. Note que basta usar as palavras chave struct Usuario para criar novas variáveis. O tipo completo é definido uma única vez no início.

Exercícios
  1. Criar um programa que define uma struct para armazenamento do nome e das notas bimestrais de um aluno. Atualizar a estrutura usando o scanf.
  2. Alterar o programa para que ele calcule e imprima a média de cada aluno.
Resposta
#include <stdio.h>

#define NUM_MAX 3

struct TAluno {
  char nome[30];
  char matricula[11];
  float b1,b2,b3,b4;
} Turma[NUM_MAX];

void print_aluno(struct TAluno aux)
{
  printf("Nome -> %s\n", aux.nome);
  printf("Matrícula -> %s\n", aux.matricula);
  printf("Bimestre 1 -> %f\n", aux.b1);
  printf("Bimestre 2 -> %f\n", aux.b2);
  printf("Bimestre 3 -> %f\n", aux.b3);
  printf("Bimestre 4 -> %f\n", aux.b4);          
}

void main()
{
  int i;
  
  for(i=0;i<NUM_MAX;i++) {
  	printf("Entre com o nome do aluno\n");
  	scanf("%s", Turma[i].nome);
  	printf("Entre com a matrícula do aluno\n");
  	scanf("%s", Turma[i].matricula);
  	printf("Entre com a nota do bimestre 1\n");
  	scanf("%f", &Turma[i].b1);
  	printf("Entre com a nota do bimestre 2\n");
  	scanf("%f", &Turma[i].b2);
  	printf("Entre com a nota do bimestre 3\n");
  	scanf("%f", &Turma[i].b3);
  	printf("Entre com a nota do bimestre 4\n");
  	scanf("%f", &Turma[i].b4);
  }
  for(i=0;i<NUM_MAX;i++) {
    printf("=========== Aluno %d ============\n", i);  
  	print_aluno(Turma[i]); 
  }      
}

Copiando estruturas

O exemplo a seguir demonstra como se pode copiar uma variável struct para outra do mesmo tipo.

#include <stdio.h>
  
struct THoras{
   int hora;
   int minuto;
   int segundo;
};

struct THoras Ontem = {2,10,57};

void main()
{
     struct THoras Hoje;
     Hoje = Ontem;

     printf("Hora hoje = %d, Minuto hoje = %d e Segundo hoje %d\n", Hoje.hora, Hoje.minuto, Hoje.segundo);
}

Estruturas dentro de estruturas

Vamos ver um exemplo com estruturas definidas dentro de estruturas:

#include <stdio.h>
  
struct TEndereco{
     char rua[50];
     char numero[10];
};

struct TCidadao{
  char nome[50];
  char cpf[20];
  struct TEndereco endereco;
  int num_filhos;
};

void main()
{
  struct TCidadao Cidadao;

  printf("Entre com o nome\n");
  scanf ("%s",Cidadao.nome); // substitua por gets()

  printf("Entre com o cpf\n");
  scanf ("%s",Cidadao.cpf);

  printf("Entre a rua\n");
  scanf ("%s",Cidadao.endereco.rua); // substitua por gets()

  printf("Entre a numero\n");   
  scanf ("%s",Cidadao.endereco.numero);

  printf("Entre com o número de filhos\n");
  scanf ("%d",&Cidadao.num_filhos);
  
}

Exercício 1: Faça um código adicional para imprimir o conteúdo lido na estrutura.


Resposta
#include <stdio.h>
 
struct TEndereco{
     char rua[50];
     char numero[10];
};
 
struct TCidadao{
  char nome[50];
  char cpf[20];
  struct TEndereco endereco;
  int num_filhos;
};

void print_endereco(struct TEndereco aux)
{
  printf ("Rua %s Número %s\n", aux.rua, aux.numero); 
}

void print_cidadao(struct TCidadao aux)
{
  printf("Nome: %s CPF: %s ", aux.nome, aux.cpf);
  print_endereco(aux.endereco);
  printf("Numero de filhos %d\n", aux.num_filhos);
}

void main()
{
  struct TCidadao Cidadao;
 
  printf("Entre com o nome\n");
  scanf ("%s",Cidadao.nome);
 
  printf("Entre com o cpf\n");
  scanf ("%s",Cidadao.cpf);
 
  printf("Entre a rua\n");
  scanf ("%s",Cidadao.endereco.rua);
 
  printf("Entre a numero\n");   
  scanf ("%s",Cidadao.endereco.numero);
 
  printf("Entre com o número de filhos\n");
  scanf ("%d",&Cidadao.num_filhos);
 
}

Iniciando estruturas na definição

Como toda variável, é possível dar valores para uma variável do tipo struct definida no programa:

#include <stdio.h>
 
struct TEndereco{
     char rua[50];
     char numero[10];
};
 
struct TCidadao{
  char nome[50];
  char cpf[20];
  struct TEndereco endereco;
  int num_filhos;
};
 
void main()
{
  struct TCidadao Cidadao = {"Maria",
                             "42342342234",
                             {"Rua AlfaBeta","145"},
                             5
                            };
 
  printf("Rua do cidadao = %s\n", Cidadao.endereco.rua);
 
}

Passando estruturas como parâmetro e retornando estruturas

Se não for usado o operador "&" , um parâmetro que é estrutura será passado por cópia. Não apresentaremos agora a passagem por endereço pois necessita do conceito de ponteiro. Observe o exercício abaixo.

#include <stdio.h>
  
struct TEndereco{
     char rua[50];
     char numero[10];
};

struct TCidadao{
  char nome[50];
  char cpf[20];
  struct TEndereco endereco;
  int num_filhos;
};

void print_struct (struct TCidadao aux)
{
  printf("nome=%s cpf=%s\n", aux.nome, aux.cpf);
  printf("endereço inicial do aux %p\n", &aux);
}

void main()
{
  struct TCidadao Cidadao;

  printf("Entre com o nome\n");
  scanf ("%s",Cidadao.nome);

  printf("Entre com o cpf\n");
  scanf ("%s",Cidadao.cpf);

  printf("Entre a rua\n");
  scanf ("%s",Cidadao.endereco.rua);

  printf("Entre a numero\n");   
  scanf ("%s",Cidadao.endereco.numero);

  printf("Entre com o número de filhos\n");
  scanf ("%d",&Cidadao.num_filhos);
  
  print_struct(Cidadao);

  printf("endereço inicial do Cidadao %p\n", &Cidadao);
}
O que podemos concluir com os endereços que foram mostrados??? Vamos a mais um exemplo.
#include <stdio.h>
  
struct TEndereco{
     char rua[50];
     char numero[10];
};

struct TCidadao{
  char nome[50];
  char cpf[20];
  struct TEndereco endereco;
  int num_filhos;
};

struct TCidadao ler_struct()
{
  struct TCidadao aux;

  printf("Entre com o nome\n");
  scanf ("%s",aux.nome);

  printf("Entre com o cpf\n");
  scanf ("%s",aux.cpf);

  printf("Entre a rua\n");
  scanf ("%s",aux.endereco.rua);

  printf("Entre a numero\n");   
  scanf ("%s",aux.endereco.numero);

  printf("Entre com o número de filhos\n");
  scanf ("%d",&aux.num_filhos);

  return aux;
}

void print_struct (struct TCidadao aux)
{
  printf("nome=%s cpf=%s\n", aux.nome, aux.cpf);
  printf("endereço inicial do aux %p\n", &aux);
}

void main()
{
  struct TCidadao Cidadao;

  Cidadao = ler_struct();

  print_struct(Cidadao);

  printf("endereço inicial do Cidadao %p\n", &Cidadao);
}

Aplicação no Controle de Acesso

O exemplo a seguir implementa uma parte do programa de controle de acesso usando estruturas. Neste exemplo a tabela de usuários já vem inicializada nos campos UserID e Senha.

#include <stdio.h>
#include <string.h>
 
/**********************************************/
/*** PROGRAMA DE CONTROLE DE ACESSO  **/
/** Autor: TurmaENG.TELECOM - 2012.2 */
/**********************************************/
 
/** VARIÁVEIS GLOBAIS DESTE MÓDULO ****/

struct TRegistroUsuario {
	char UserId[10];
	char Senha[10];
};

/* Tabela de Usuários */
struct TRegistroUsuario TabelaUsuarios[4] = {
         {"joao","abcd"},
         {"maria","xxxx"},
         {"jose","yyyy"},
         {"lara","zzzz"},
};

 
char userID[20];
 
 
/** FUNÇÔES DESTE MÓDULO ****/
 
void mostrar_menu_entrada_usuario()
{
  printf("*******************************\n");
  printf("Entre com o seu USERID para ter acesso\n"); 
  printf("*******************************\n");
}
 
/** Função que implementa as tarefas do administrador **/
 
void  administrar()
{
}
 
/** Função que valida um usuário e abre a porta **/
 
void tratar_usuario()
{
  char senha[10];
  int userEncontrado=1;
  int i;
 
 
 /* 
     Loop para encontrar o usuário na tabela. 
     Ao final do loop a variavel i conterá o índice do usuário (se ele estiver
     na tabela
  */
  for (i=0;i<4 && userEncontrado; i++) {
       if( strcmp(userID, TabelaUsuarios[i].UserId)==0)
             userEncontrado=0;
  }
 
  /* se usuário encontrado abre a porta */
  if (userEncontrado==0) {
	printf("Bom dia %s! Entre com a senha\n", userID);
  	scanf("%s",senha);
	i--; /* o indice do sujeito é i-1 */
	if(strcmp(senha,TabelaUsuarios[i].Senha)==0) 
	       printf("Abrir porta!!!\n");
	else
		printf("Senha Inválida\n");
  }
}
 
void main()
{
 for(;;) {
     mostrar_menu_entrada_usuario();
     scanf("%s",userID);
     if (strcmp(userID, "admin")==0) {
          administrar();
     } else {
         tratar_usuario();
     }
 }   
}

Desafios com Structs

Desafio 1

Implementar uma função converte_para_polar que recebe como parâmetro um número complexo na forma retangular (representado por uma struct). A função deve retornar uma struct contendo o número complexo na forma polar.Usar as funções sqrtf e atanf da [matemáticas biblioteca matemática]. Como converter:

ou

NOTE que as funções atanf e similares retornam em RADIANOS.

Solução
#include <stdio.h>
#include <math.h>

struct tipo_ret {
 	float x;
 	float y;
};

struct tipo_polar {
 	float mod;
 	float ang;
};


/* Função para converter complexo retangular em polar */

struct tipo_polar converter_ret_pol(struct tipo_ret num_ret)
{
  struct tipo_polar num_polar;
  float aux;
  
  aux = num_ret.x*num_ret.x + num_ret.y*num_ret.y;
  
  /* falta a lógica para detectar o quadrante */
  num_polar.mod = sqrtf(aux);
  num_polar.ang = atanf(num_ret.y/num_ret.x);
  return num_polar; 
}

/* Função para imprimir complexo retangular */
void imprimir_complexo_ret(struct tipo_ret num_ret)
{
  printf("Coordenada x = %f", num_ret.x);
  printf("Coordenada y = %f\n", num_ret.y);
}

/* Função para imprimir complexo retangular */
void imprimir_complexto_pol(struct tipo_ret num_ret)
{
  printf("Coordenada x = %f", num_ret.x);
  printf("Coordenada y = %f\n", num_ret.y);
}

main()
{
  struct tipo_ret num1;
  struct tipo_polar num2;
  
  num1.x = 5;
  num1.y = 10;
  num2 = converter_ret_pol (num1);  
}

Desafio 2

Implementar uma função que some dois números complexos no formato retangular e retorne a soma como um complexo retangular.

Desafio 3

Implementar uma função que some dois números complexos no formato polar e retorna a soma no formato polar.


Exercícios

1. Implementar um contador de acesso que permita bloquear o usuário após 3 tentativas seguidas. Note que caso o usuário acerte a senha, este contador deverá ser zerado.

Solução 1
#include <stdio.h>
#include <string.h>
 
/**********************************************/
/*** PROGRAMA DE CONTROLE DE ACESSO  **/
/** Autor: Turma ENG.TELECOM - 2013.1 */
/**********************************************/
 
/** VARIÁVEIS GLOBAIS DESTE MÓDULO ****/
 
struct TRegistroUsuario {
	char UserId[10];
	char Senha[10];
	int contador;
};
 
/* Tabela de Usuários */
struct TRegistroUsuario TabelaUsuarios[4] = {
         {"joao","abcd",0},
         {"maria","xxxx",0},
         {"jose","yyyy",0},
         {"lara","zzzz",0},
};
 
 
char userID[20];
 
 
/** FUNÇÔES DESTE MÓDULO ****/
 
void mostrar_menu_entrada_usuario()
{
  printf("*******************************\n");
  printf("Entre com o seu USERID para ter acesso\n"); 
  printf("*******************************\n");
}

/** Função que implementa as tarefas do administrador **/
 
void  administrar()
{
  char aux_senha[10];
  int userEncontrado=1;
  int i;
    
  printf("Entre com a senha do admin \n");
  scanf ("%s", aux_senha);
  
  if(strcmp(aux_senha,"123456")==0) {
      /* senha valida do admin - agora entre com userid a ser desbloqueado */
      printf("Entre com userdID a ser desbloqueado\n");
      scanf("%s",userID);
      for (i=0;i<4 && userEncontrado; i++) {
         if( strcmp(userID, TabelaUsuarios[i].UserId)==0)
             userEncontrado=0;
      } 
      if (userEncontrado==0) {
         i--;
         TabelaUsuarios[i].contador=0;
      }           
  }
}
 
/** Função que valida um usuário e abre a porta **/
 
void tratar_usuario()
{
  char senha[10];
  int userEncontrado=1;
  int i;
 
 
 /* 
     Loop para encontrar o usuário na tabela. 
     Ao final do loop a variavel i conterá o índice do usuário (se ele estiver
     na tabela
  */
  for (i=0;i<4 && userEncontrado; i++) {
       if( strcmp(userID, TabelaUsuarios[i].UserId)==0)
             userEncontrado=0;
  }
 
  /* se usuário encontrado abre a porta */
  if (userEncontrado==0) {
  	 i--; /* o indice do sujeito é i-1 */
    if (TabelaUsuarios[i].contador<3){
    
	   printf("Bom dia %s! Entre com a senha\n", userID);
  	   scanf("%s",senha);

	   if(strcmp(senha,TabelaUsuarios[i].Senha)==0) {
	       printf("Abrir porta!!!\n");
	       TabelaUsuarios[i].contador=0;
	   }
	   else {
		   TabelaUsuarios[i].contador++;
		   printf("Senha Inválida\n");
		   printf("Tentativas restantes %d\n", 3-TabelaUsuarios[i].contador);
		}
    } else {
      printf("Usuário bloqueado\n");
    }
  } else {
    printf("Usuário não encontrado\n");
  }
}
 
void main()
{
 for(;;) {
     mostrar_menu_entrada_usuario();
     scanf("%s",userID);
     if (strcmp(userID, "admin")==0) {
          administrar();
     } else {
         tratar_usuario();
     }
 }   
}

2. Implementar uma funcionalidade do administrador para desbloquear o usuário bloqueado.

Solução 2
#include <stdio.h>
#include <string.h>
 
/**********************************************/
/*** PROGRAMA DE CONTROLE DE ACESSO           */
/** Autores: Daniel Trevisan Tatsch           */
/**          Ricardo Amorim                   */
/**********************************************/
 
/** VARIÁVEIS GLOBAIS DESTE MÓDULO ****/
 
struct TRegistroUsuario {
    char UserId[10];
    char Senha[10];
    int ativo;
};
 
/* Tabela de Usuários */
struct TRegistroUsuario TabelaUsuarios[4] = {
         {"joao","abcd",1},
         {"maria","xxxx",1},
         {"jose","yyyy",1},
         {"lara","zzzz",1},
};
 
char userID[20];
 
/** FUNÇÔES DESTE MÓDULO ****/
 
void mostrar_menu_entrada_usuario()
{
  printf("\n********************************************");
  printf("\nEntre com o seu USERID para ter acesso: "); 
  printf("\n********************************************\n");
}
 
/** Função que implementa as tarefas do administrador **/
 
void administrar()
{
    int i;
    for(i=0;i<4;i++)
	TabelaUsuarios[i].ativo=1;
    printf("\nTodos os usuários foram liberados!\n"); 
}
 
/** Função que valida um usuário e abre a porta **/
 
void tratar_usuario()
{
  char senha[10];
  int userEncontrado=1;
  int i, cont = 0;
 
 /* 
     Loop para encontrar o usuário na tabela. 
     Ao final do loop a variavel i conterá o índice do usuário (se ele estiver
     na tabela
  */
  for (i=0;i<4 && userEncontrado; i++) {
       if( strcmp(userID, TabelaUsuarios[i].UserId)==0)
             userEncontrado=0;    
  }
  
  if (userEncontrado==0) {  // se usuário encontrado...
      for(;;){
	      if(TabelaUsuarios[i-1].ativo){ // se usuário ativo (1)...
		 printf("Bom dia %s! Entre com a senha\n", userID);
		 scanf("%s",senha);
		 if(strcmp(senha,TabelaUsuarios[i-1].Senha)==0){ // se senha confere (0)...
		    printf("Abrir porta!!!\n");
		    cont=0;
		    break;
		 } else {
		    printf("Senha Inválida\n");
		    cont++;
		    if(cont==3){
		       printf("\nUsuário Bloqueado!\n");    
		       TabelaUsuarios[i-1].ativo = 0;
		       break;
		    }
		 }
	      } else {
		 printf("\nUsuário Bloqueado!\n");  // usuario bloqueado ativo (0)    
		 break;
	      }
	} // fim do for(;;)
  } else
        printf("\nUsuário não encontrado!\n"); // se usuario nao encontrado.   
}
 
void main()
{
 for(;;) {
     mostrar_menu_entrada_usuario();
     scanf("%s",userID);
     if (strcmp(userID, "admin")==0) {
          administrar();
     } else {
         tratar_usuario();
     }
 }   
}

3. No programa de controle de senha inserir um campo na estrutura do usuário de forma a acomodar uma mensagem de boas vindas particularizada para cada usuário. A mensagem "DEFAULT" é Bom dia!
4. Implementar na função administrar a inserção da mensagem no exercício anterior.
5. Na solução acima criar uma função que procura usuário na tabela (já que este código é utilizado em mais do que um luga). A função deve receber o UserID a ser procurado e deve retornar um inteiro correspondente ao índice do usuário encontrado ou -1 se não for encontrado.

Referências

[1] https://pt.wikibooks.org/wiki/Programar_em_C/Estruturas




Icone voltar.png Icone menu.png Icone prox.png