Mudanças entre as edições de "AULA 13 - Programação 1 - Engenharia"

De MediaWiki do Campus São José
Ir para navegação Ir para pesquisar
 
(68 revisões intermediárias pelo mesmo usuário não estão sendo mostradas)
Linha 1: Linha 1:
 +
{{Date}}
 +
 
<blockquote style="background: #DCF4CC; border: 1px solid black; padding: 1em;">
 
<blockquote style="background: #DCF4CC; border: 1px solid black; padding: 1em;">
 
<center>
 
<center>
Linha 8: Linha 10:
 
*Criar tipos com 'struct' e definir/declarar  estruturas;
 
*Criar tipos com 'struct' e definir/declarar  estruturas;
 
*Inicializar estruturas na definição;
 
*Inicializar estruturas na definição;
*Acessar campos de uma estrutura e usar estruturas em sentenças/expressões;
+
*Acessar campos de uma estrutura (SEM USAR PONTEIROS) e usar estruturas em sentenças/expressões;
 
*Passar estruturas como parâmetros de funções (via cópia) e retornar estruturas em funções;
 
*Passar estruturas como parâmetros de funções (via cópia) e retornar estruturas em funções;
 
*Copiar uma variável estrutura para outra variável;
 
*Copiar uma variável estrutura para outra variável;
 
*Criar e usar estruturas como campo de outras estruturas;
 
*Criar e usar estruturas como campo de outras estruturas;
*Criar arranjos de estruturas.
+
*Criar e operar sobre arranjos de estruturas.
 
</center>
 
</center>
 
</blockquote>
 
</blockquote>
Linha 18: Linha 20:
  
 
<blockquote style="background: #DCF4CC; border: 1px solid black; padding: 1em;">
 
<blockquote style="background: #DCF4CC; border: 1px solid black; padding: 1em;">
 +
 
=Conceito e Aplicação de Estruturas=
 
=Conceito e Aplicação de Estruturas=
 +
 +
 +
<blockquote style="background: lime; border: 1px solid black; padding: 1em;">
 +
VER o Vídeo [https://drive.google.com/file/d/1uwD8-gWkZODPH0lmEiG4GTg2AJBANuGy/view?usp=sharing "O que é uma Estrutura no C"]
 
</blockquote>
 
</blockquote>
  
Linha 25: Linha 32:
 
<blockquote style="background: pink; border: 1px solid black; padding: 1em;">
 
<blockquote style="background: pink; border: 1px solid black; padding: 1em;">
 
As variáveis no C são usadas para armazenar dados que podem ser processados ao longo da execução de um programa.
 
As variáveis no C são usadas para armazenar dados que podem ser processados ao longo da execução de um programa.
O desenvolvedor deve criar variáveis a partir de um tipo que pode ser visto como a FORMA (de um bolo...) a partir da qual se cria uma variável.  
+
O desenvolvedor deve criar variáveis a partir de um TIPO que pode ser visto como a FORMA (de um bolo...) a partir da qual se cria uma variável.  
 
</blockquote>
 
</blockquote>
  
Linha 31: Linha 38:
  
 
*no tamanho da variável;
 
*no tamanho da variável;
*nas operações que podem ser realizadas sobre elas;
+
*na forma como os dados são armazenados na memória e, portanto, nas operações que podem ser realizadas sobre estes dados;
 
*e de forma geral, na organização dos dados e nos algoritmos que podem ser usados para acessar estes dados.
 
*e de forma geral, na organização dos dados e nos algoritmos que podem ser usados para acessar estes dados.
  
Linha 82: Linha 89:
 
==A necessidade de o desenvolvedor criar variáveis compostas a partir de tipos já criados==
 
==A necessidade de o desenvolvedor criar variáveis compostas a partir de tipos já criados==
  
Como visto, o arranjo  é uma forma do desenvolvedor criar variáveis para armazenar dados mais elaborados. O próprio desenvolvedor cria o arranjo, especificando o tipo do  elemento e a(s) dimensão(ões) do arranjo.
+
Como visto, o arranjo  é uma forma do desenvolvedor criar variáveis para armazenar/organizar dados de forma mais elaborado, organizando-os na forma de vetor/matriz. O próprio desenvolvedor cria o arranjo, especificando o tipo do  elemento e a(s) dimensão(ões) do arranjo. Desta forma, pode-se facilmente operar sobre uma sequência de dados.
  
Entretanto, como um desenvolvedor poderia criar uma variável que armazena dados de um livro, por exemplo, o título, o autor, o ISBN a edição etc? Neste ponto existe a necessidade de se criar uma variável constituída de partes (campos ou ''fields'') especificados pelo próoprio desenvolvedor.
+
Entretanto, como um desenvolvedor poderia criar uma variável que armazena diferentes dados (atributos) de um livro, por exemplo:
 +
*o título,  
 +
*o autor,  
 +
*o ISBN a edição etc?  
  
 +
Neste ponto existe a necessidade de se criar uma variável constituída de partes (campos ou ''fields'') especificados pelo próprio desenvolvedor. Uma variável estrutura pode ser vista como um agrupamento de variáveis (identificadas pelos campos).
  
 
[[File:PRG1-LivroEstruct-1.png|400px]]
 
[[File:PRG1-LivroEstruct-1.png|400px]]
Linha 109: Linha 120:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
 +
</blockquote>
  
 
<blockquote style="background: #DCF4CC; border: 1px solid black; padding: 1em;">
 
<blockquote style="background: #DCF4CC; border: 1px solid black; padding: 1em;">
  
= Definição/declaração de Estruturas e Acesso as campos=
+
= Definição/declaração de Estruturas e Acesso aos Campos=
 +
 
 +
 
 +
<blockquote style="background: lime; border: 1px solid black; padding: 1em;">
 +
VER o Vídeo [https://drive.google.com/file/d/1FvJqZtiwFi-JXxP5MMe89qU8kwKHFSEe/view?usp=sharing "Definindo Estruturas no C"]
 
</blockquote>
 
</blockquote>
  
No C é possível criar tipos de dados que representam uma estrutura. Veja o exemplo seguinte
+
No C é possível criar tipos de dados que representam uma estrutura. Veja o exemplo que se segue.
  
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
Linha 128: Linha 144:
 
         int  num_acessos;
 
         int  num_acessos;
 
     } Usuario; /* aqui é definida uma variável do  tipo struct TUsuario */
 
     } Usuario; /* aqui é definida uma variável do  tipo struct TUsuario */
 
    /* aqui uma tabela/vetor de estruturas */
 
    struct TUsuario TabelaUsuario[20];
 
  
 
     /* acessando os campos da estrutura Usuario */
 
     /* acessando os campos da estrutura Usuario */
Linha 136: Linha 149:
 
     scanf("%s", Usuario.senha);
 
     scanf("%s", Usuario.senha);
 
     Usuario.num_acessos = 0;
 
     Usuario.num_acessos = 0;
 
    /* acessando o campo 10 da tabela de estruturas */
 
    scanf("%s", TabelaUsuario[10].userID);
 
    scanf("%s", TabelaUsuario[10].senha);
 
  
 
     return 0;
 
     return 0;
Linha 145: Linha 154:
 
</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.
+
Na realidade nada impede que se crie um vetor de estruturas, como no exemplo abaixo:
 
 
===Exercícios===
 
  
1. Criar um tipo estrutura que permita representar um retângulo. Criar duas variáveis retângulo e mostrar como as áreas destes retângulos poderiam ser somadas.
 
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
  
 +
int main()
 +
{
 +
    struct TUsuario /* struct TUsuario é o nome do tipo que está sendo criado */
 +
    {
 +
        char userID[20];
 +
        char senha[20];
 +
        int  num_acessos;
 +
    } Usuario; /* aqui é definida uma variável do  tipo struct TUsuario */
  
struct tipo_retang{
+
    /* aqui uma tabela/vetor de estruturas */
  float lado1;
+
    struct TUsuario TabelaUsuario[20];
  float lado2;
 
};
 
  
main()
+
    /* acessando os campos da estrutura Usuario */
{
+
    scanf("%s", Usuario.userID);
  struct tipo_retang x,y;
+
    scanf("%s", Usuario.senha);
  float area_final;
+
    Usuario.num_acessos = 0;
  
  x.lado1=5.5;
+
    /* acessando o campo 10 da tabela de estruturas */
  x.lado2=6.7;
+
    scanf("%s", TabelaUsuario[10].userID);
 +
    scanf("%s", TabelaUsuario[10].senha);
 +
    TabelaUsuario[10].num_acessos = 0;
  
  y.lado1=2.3;
+
    return 0;
  y.lado2=7.9; /* poderia entrar com scanf: scanf("%f",&y.lado2); etc */
+
}
 +
</syntaxhighlight>
  
  area_final = x.lado1*x.lado2 + y.lado1*y.lado2;
+
<blockquote style="background: lime; border: 1px solid black; padding: 1em;">
 +
*[https://drive.google.com/file/d/1mJGY0lYUhp3Ai9JGpQ3zVhMhOHwGxT8e/view?usp=sharing Vídeo Mostrando a Execução do Programa Acima]
 +
</blockquote>
  
  printf("Área total dos dois retângulos = %f \n", area_final);  
+
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.
}
+
 
</syntaxhighlight>
+
</blockquote>
<!--
+
 
[[imagem:PRG29002-2018-2-MemoriaExercicioEstruturas.jpg|450px|center]]
+
===Exercícios===
-->
+
 
 +
1. Criar um tipo estrutura que permita representar um retângulo. Criar duas variáveis retângulo e mostrar como as áreas destes retângulos poderiam ser somadas.
 +
 
 +
<blockquote style="background: lime; border: 1px solid black; padding: 1em;">
 +
*[https://drive.google.com/file/d/1siYsqw0cBU3NWLloQHMVHPMXk65rAODS/view?usp=sharing Vídeo Explicando o Exercício]
 +
</blockquote>
  
[[imagem:Struct_figure.jpg|500px|center]]
+
{{collapse top|Solução}}
2. Criar um tipo estrutura que permita armazenar os coeficientes de uma equação do segundo grau. Implementar um código para calcular o DELTA da equação.
 
  
{{collapse top | solução Ex. 2}}
 
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
//Autor : Victor Cesconetto De Pieri
 
 
#include <stdio.h>
 
#include <stdio.h>
 
struct Equacao {
 
  float delta,a,b,c;
 
  } eq;
 
  
main()
 
{
 
  printf("Entre com o 'a' da equação\n");
 
  scanf("%f", &eq.a);
 
  printf("Entre com o 'b' da equação\n");
 
  scanf("%f", &eq.b);
 
  printf("Entre com o 'c' da equação\n");
 
  scanf("%f", &eq.c); 
 
  eq.delta = (eq.b*eq.b) - 4*eq.a*eq.c;
 
  printf("delta : %f\n", eq.delta);
 
}
 
</syntaxhighlight>
 
{{collapse bottom}} 
 
  
3. Criar um programa que define uma struct para armazenamento do nome e das notas bimestrais de um aluno. Atualizar a estrutura usando o scanf.
+
struct tipo_retang{
 +
  float lado1;
 +
  float lado2;
 +
};
 +
 
 +
main()
 +
{
 +
  struct tipo_retang x,y;
 +
  float area_final;
  
{{collapse top | solução Ex. 3}}
+
  x.lado1=5.5;
<syntaxhighlight lang=c>
+
  x.lado2=6.7;
#include <stdio.h>
 
  
#define NUM_MAX 3
+
  y.lado1=2.3;
 +
  y.lado2=7.9; /* poderia entrar com scanf: scanf("%f",&y.lado2); etc */
  
struct TAluno {
+
   area_final = x.lado1*x.lado2 + y.lado1*y.lado2;
   char nome[30];
 
  char matricula[11];
 
  float b1,b2,b3,b4;
 
} Turma[NUM_MAX];
 
  
int main()
+
   printf("Área total dos dois retângulos = %f \n", area_final);
{
 
  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);
 
  }   
 
        return 0;
 
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
{{collapse bottom}}
 
  
4. Acrescentar um código no final da função main para calcular a média da turma para cada um dos bimestres.
+
<!--
 +
[[imagem:PRG29002-2018-2-MemoriaExercicioEstruturas.jpg|450px|center]]
 +
-->
 +
 
 +
[[imagem:Struct_figure.jpg|500px|center]]
 +
{{collapse bottom}}
 +
2. Criar um tipo estrutura que permita armazenar os coeficientes de uma equação do segundo grau. Implementar um código para calcular o DELTA da equação.
  
{{collapse top | solução Ex. 4}}
+
{{collapse top | solução Ex. 2}}
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 +
//Autor : Victor Cesconetto De Pieri
 +
#include <stdio.h>
 +
 +
struct coeficientes_equacao {
 +
  float a,b,c;
 +
  } eq;
  
 +
int main()
 +
{
 +
  float delta;
  
#include <stdio.h>
+
  printf("Entre com o 'a' da equação\n");
#define NUM_MAX 3
+
  scanf("%f", &eq.a);
+
  printf("Entre com o 'b' da equação\n");
struct TAluno {
+
  scanf("%f", &eq.b);
   char nome[30];
+
  printf("Entre com o 'c' da equação\n");
   char matricula[11];
+
  scanf("%f", &eq.c); 
   float b1,b2,b3,b4;
+
  delta = (eq.b*eq.b) - 4*eq.a*eq.c;
} Turma[NUM_MAX];
+
  printf("delta : %f\n", eq.delta);
+
  return 0;
int main(){
+
}
 +
</syntaxhighlight>
 +
{{collapse bottom}} 
 +
 
 +
3. Criar um programa que define uma struct para armazenamento do nome e das notas bimestrais de um aluno. Criar uma turma de alunos como um arranjo de estruturas de tamanho 5. Atualizar a turma usando estrutura usando o scanf.
 +
 
 +
{{collapse top | solução Ex. 3}}
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 
 +
#define NUM_MAX 5
 +
 
 +
struct t_aluno {
 +
   char nome[30];
 +
   char matricula[11];
 +
   float b1,b2,b3,b4;
 +
} Turma[NUM_MAX];
 +
 
 +
int main()
 +
{
 
   int i;
 
   int i;
  float soma_b1=0,soma_b2=0,soma_b3=0,soma_b4=0
 
  float media_b1=0,media_b2=0,media_b3=0,media_b4=0;
 
 
    
 
    
  for(i=0;i<NUM_MAX;i++){
 
      printf("Entre com o nome do aluno: ");
 
      scanf("%s", Turma[i].nome);
 
      printf("Entre com a matrícula do aluno: ");
 
      scanf("%s", Turma[i].matricula);
 
      printf("Entre com a nota do bimestre 1: ");
 
      scanf("%f", &Turma[i].b1);
 
      printf("Entre com a nota do bimestre 2: ");
 
      scanf("%f", &Turma[i].b2);
 
      printf("Entre com a nota do bimestre 3: ");
 
      scanf("%f", &Turma[i].b3);
 
      printf("Entre com a nota do bimestre 4: ");
 
      scanf("%f", &Turma[i].b4);
 
  }   
 
 
 
   for(i=0;i<NUM_MAX;i++) {
 
   for(i=0;i<NUM_MAX;i++) {
      soma_b1 = (soma_b1+Turma[i].b1); /* usando media_b1 para soma acumulada */
+
  printf("Entre com o nome do aluno\n");
      soma_b2 = (soma_b2+Turma[i].b2);
+
  scanf("%s", Turma[i].nome);
      soma_b3 = (soma_b3+Turma[i].b3);
+
  printf("Entre com a matrícula do aluno\n");
      soma_b4 = (soma_b4+Turma[i].b4);
+
  scanf("%s", Turma[i].matricula);
  }
+
  printf("Entre com a nota do bimestre 1\n");
  media_b1 = (media_b1/NUM_MAX);
+
  scanf("%f", &Turma[i].b1);
  media_b2 = (media_b2/NUM_MAX);
+
  printf("Entre com a nota do bimestre 2\n");
  media_b3 = (media_b3/NUM_MAX);
+
  scanf("%f", &Turma[i].b2);
  media_b4 = (media_b4/NUM_MAX);
+
  printf("Entre com a nota do bimestre 3\n");
 
+
  scanf("%f", &Turma[i].b3);
  printf("A media do B1 => %.2f\n",media_b1);
+
  printf("Entre com a nota do bimestre 4\n");
  printf("A media do B2 => %.2f\n",media_b2);
+
  scanf("%f", &Turma[i].b4);
  printf("A media do B3 => %.2f\n",media_b3);
+
   }   
  printf("A media do B4 => %.2f\n",media_b4);
+
        return 0;
   return 0;
 
 
}
 
}
 
 
</syntaxhighlight>
 
</syntaxhighlight>
{{collapse bottom}}
+
{{collapse bottom}}  
  
5. Repensar a estrutura TAluno para que as notas bimestrais sejam representadas como um vetor de floats. Fazer um código para calcular a média anual de cada aluno. Armazenar as médias anuais da turma em um vetor de floats.
+
4. Acrescentar um código no final da função main para calcular a média da turma para cada um dos bimestres.
  
{{collapse top | solução Ex. 5}}
+
{{collapse top | solução Ex. 4}}
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 +
 +
 
#include <stdio.h>
 
#include <stdio.h>
 
 
#define NUM_MAX 3
 
#define NUM_MAX 3
 
   
 
   
Linha 309: Linha 312:
 
   char nome[30];
 
   char nome[30];
 
   char matricula[11];
 
   char matricula[11];
   float b[4];
+
   float b1,b2,b3,b4;
 
} Turma[NUM_MAX];
 
} Turma[NUM_MAX];
 
   
 
   
void print_aluno(struct TAluno aux)
+
int main(){
{
+
   int i;
   printf("Nome -> %s\n", aux.nome);
+
   float soma_b1=0,soma_b2=0,soma_b3=0,soma_b4=0
   printf("Matrícula -> %s\n", aux.matricula);
+
   float media_b1=0,media_b2=0,media_b3=0,media_b4=0;  
  printf("Bimestre 1 -> %f\n", aux.b[0]);
+
 
  printf("Bimestre 2 -> %f\n", aux.b[1]);
+
   for(i=0;i<NUM_MAX;i++){
   printf("Bimestre 3 -> %f\n", aux.b[2]);
+
       printf("Entre com o nome do aluno: ");
  printf("Bimestre 4 -> %f\n", aux.b[3]);         
+
       scanf("%s", Turma[i].nome);
}
+
       printf("Entre com a matrícula do aluno: ");
+
       scanf("%s", Turma[i].matricula);
main()
+
       printf("Entre com a nota do bimestre 1: ");
{
+
      scanf("%f", &Turma[i].b1);
  int i,j;
+
      printf("Entre com a nota do bimestre 2: ");
  float media[NUM_MAX]={0,0,0};  
+
      scanf("%f", &Turma[i].b2);
+
      printf("Entre com a nota do bimestre 3: ");
   for(i=0;i<NUM_MAX;i++) {
+
      scanf("%f", &Turma[i].b3);
       printf("Entre com o nome do aluno\n");
+
      printf("Entre com a nota do bimestre 4: ");
       scanf("%s", Turma[i].nome);
+
      scanf("%f", &Turma[i].b4);
       printf("Entre com a matrícula do aluno\n");
 
       scanf("%s", Turma[i].matricula);
 
       for(j=0;j<4;j++) {
 
          printf("Entre com a nota do bimestre %d\n", j+1);
 
          scanf("%f", &Turma[i].b[j]);
 
      }
 
 
   }     
 
   }     
+
 
  /* calculo das médias bimestrais da turma */
 
  /* separado do primeiro for para caracterizar a diferença de entrada de dados do processamento ... */
 
 
   for(i=0;i<NUM_MAX;i++) {
 
   for(i=0;i<NUM_MAX;i++) {
       for(j=0;j<4;j++)
+
       soma_b1 = (soma_b1+Turma[i].b1); /* usando media_b1 para soma acumulada */
            media[i]=media[i]+Turma[i].b[j]; /* usando media_b1 para soma acumulada */
+
       soma_b2 = (soma_b2+Turma[i].b2);
       media[i]=media[i]/4;
+
      soma_b3 = (soma_b3+Turma[i].b3);
 +
      soma_b4 = (soma_b4+Turma[i].b4);
 
   }
 
   }
 +
  media_b1 = (media_b1/NUM_MAX);
 +
  media_b2 = (media_b2/NUM_MAX);
 +
  media_b3 = (media_b3/NUM_MAX);
 +
  media_b4 = (media_b4/NUM_MAX);
 +
 +
  printf("A media do B1 => %.2f\n",media_b1);
 +
  printf("A media do B2 => %.2f\n",media_b2);
 +
  printf("A media do B3 => %.2f\n",media_b3);
 +
  printf("A media do B4 => %.2f\n",media_b4);
 +
  return 0;
 
}
 
}
 +
 
</syntaxhighlight>
 
</syntaxhighlight>
 
{{collapse bottom}}
 
{{collapse bottom}}
  
<blockquote style="background: #DCF4CC; border: 1px solid black; padding: 1em;">
+
5. Repensar a estrutura TAluno para que as notas bimestrais sejam representadas como um vetor de floats. Fazer um código para calcular a média anual de cada aluno. Armazenar as médias anuais da turma em um vetor de floats.
 
 
= Copiando Estruturas =
 
</blockquote>
 
 
 
 
 
O exemplo a seguir demonstra como se pode copiar uma variável ''struct'' para outra do mesmo tipo.
 
  
 +
{{collapse top | solução Ex. 5}}
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
 
+
struct THoras{
+
#define NUM_MAX 3
  int hora;
+
  int minuto;
+
struct TAluno {
  int segundo;
+
  char nome[30];
};
+
  char matricula[11];
 
+
  float b[4];
struct THoras Ontem = {2,10,57};
+
} Turma[NUM_MAX];
 
+
void main()
+
void print_aluno(struct TAluno aux)
 
{
 
{
    struct THoras Hoje;
+
  printf("Nome -> %s\n", aux.nome);
    Hoje = Ontem;
+
  printf("Matrícula -> %s\n", aux.matricula);
 
+
  printf("Bimestre 1 -> %f\n", aux.b[0]);
    printf("Hora hoje = %d, Minuto hoje = %d e Segundo hoje %d\n", Hoje.hora, Hoje.minuto, Hoje.segundo);
+
  printf("Bimestre 2 -> %f\n", aux.b[1]);
 +
  printf("Bimestre 3 -> %f\n", aux.b[2]);
 +
  printf("Bimestre 4 -> %f\n", aux.b[3]);        
 
}
 
}
</syntaxhighlight>
+
 
+
main()
 
+
{
</blockquote>
+
  int i,j;
 
+
  float media[NUM_MAX]={0,0,0};
=Estruturas dentro de estruturas=
+
</blockquote>
+
  for(i=0;i<NUM_MAX;i++) {
 
+
      printf("Entre com o nome do aluno\n");
Vamos  ver um exemplo com estruturas definidas dentro de estruturas:
+
      scanf("%s", Turma[i].nome);
 
+
      printf("Entre com a matrícula do aluno\n");
<syntaxhighlight lang=c>
+
      scanf("%s", Turma[i].matricula);
#include <stdio.h>
+
      for(j=0;j<4;j++) {
    
+
          printf("Entre com a nota do bimestre %d\n", j+1);
struct TEndereco{
+
          scanf("%f", &Turma[i].b[j]);
    char rua[50];
+
      }
    char numero[10];
+
  }   
};
+
 +
  /* calculo das médias bimestrais da turma */
 +
   /* separado do primeiro for para caracterizar a diferença de entrada de dados do processamento ... */
 +
  for(i=0;i<NUM_MAX;i++) {
 +
      for(j=0;j<4;j++)
 +
            media[i]=media[i]+Turma[i].b[j]; /* usando media_b1 para soma acumulada */
 +
      media[i]=media[i]/4;
 +
  }
 +
}
 +
</syntaxhighlight>
 +
{{collapse bottom}}
 +
 
 +
<blockquote style="background: #DCF4CC; border: 1px solid black; padding: 1em;">
 +
 
 +
=Iniciando estruturas na definição=
  
struct TCidadao{
+
Variáveis do tipo "estrutura" também podem ser iniciadas na declaraçao/definição. Veja o exemplo abaixo.
   char nome[50];
+
 
  char cpf[20];
+
</blockquote>
  struct TEndereco endereco;
+
 
   int num_filhos;
+
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 
 +
 
 +
struct tipo_retang{
 +
   float lado1;
 +
   float lado2;
 
};
 
};
  
void main()
+
main()
 
{
 
{
   struct TCidadao Cidadao;
+
   struct tipo_retang x = {5.5,6.7},
 +
                    y = {2.3,7.9};
 +
  float area_final;
  
   printf("Entre com o nome\n");
+
   area_final = x.lado1*x.lado2 + y.lado1*y.lado2;
  scanf ("%s",Cidadao.nome);
 
  
   printf("Entre com o cpf\n");
+
   printf("Área total dos dois retângulos = %f \n", area_final);
  scanf ("%s",Cidadao.cpf);
+
}
 +
</syntaxhighlight>
  
  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");
+
<blockquote style="background: #DCF4CC; border: 1px solid black; padding: 1em;">
  scanf ("%d",&Cidadao.num_filhos);
+
 
 
+
= Copiando Estruturas =
}
+
</blockquote>
</syntaxhighlight>
+
 
 +
 
 +
Pode-se copiar dados de uma estrutura para outra simplesmente copiando seus campos um a um. Vamos a um exemplo.A variável Ontem é copiada para variável Hoje. Elas possuem a mesma composição: horas, minutos e segundos (tipo struct THoras). Note que para realizar esta cópia não é necessário que as variáveis tenham exatamente a mesma estrutura (tipo). Basta os campos envolvidos serem de tipo compatíveis.
  
==Exercício==
 
# Faça um código adicional para imprimir o conteúdo lido na estrutura.
 
{{collapse top | solução}}
 
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
+
 
struct TEndereco{
+
struct THoras{
    char rua[50];
+
  int hora;
    char numero[10];
+
  int minuto;
};
+
  int segundo;
 
struct TCidadao{
 
  char nome[50];
 
  char cpf[20];
 
  struct TEndereco endereco;
 
  int num_filhos;
 
 
};
 
};
  
void print_cidadao(struct TCidadao aux)
+
struct THoras Ontem = {2,10,57};
 +
 
 +
void main()
 
{
 
{
  printf("Nome: %s - CPF: %s\n", aux.nome, aux.cpf);
+
    struct THoras Hoje;
  printf ("Rua %s Número %s\n", aux.endereco.rua, aux.endereco.numero);  
+
    Hoje.hora = Ontem.hora;
  printf("Numero de filhos %d\n", aux.num_filhos);
+
    Hoje.minuto = Ontem.minuto;
 +
    Hoje.segundo = Ontem.segundo;    
 +
 
 +
    printf("Hora hoje = %d, Minuto hoje = %d e Segundo hoje %d\n", Hoje.hora, Hoje.minuto, Hoje.segundo);
 
}
 
}
 +
</syntaxhighlight>
  
int main(void){
 
  
  struct TCidadao Cidadao;
+
Entretanto, é possível
+
copiar inteiramente uma estrutura, sem precisar citar seus atributos. Veja o exemplo abaixo:
  printf("Entre com o nome\n");
+
 
  scanf ("%s",Cidadao.nome);
+
<syntaxhighlight lang=c>
  getchar();
+
#include <stdio.h>
+
    
  printf("Entre com o cpf\n");
+
struct THoras{
  scanf ("%s",Cidadao.cpf);
+
  int hora;
   getchar();
+
  int minuto;
+
  int segundo;
  printf("Entre a rua\n");
+
};
  scanf ("%s",Cidadao.endereco.rua);
+
 
  getchar();
+
struct THoras Ontem = {2,10,57};
 
  printf("Entre a numero\n"); 
 
  scanf ("%s",Cidadao.endereco.numero);
 
  getchar();
 
 
  printf("Entre com o número de filhos\n");
 
  scanf ("%d",&Cidadao.num_filhos);
 
  
  print_cidadao(Cidadao);
+
void main()
  return 0;
+
{
 +
    struct THoras Hoje;
 +
    Hoje = Ontem;
 +
 
 +
    printf("Hora hoje = %d, Minuto hoje = %d e Segundo hoje %d\n", Hoje.hora, Hoje.minuto, Hoje.segundo);
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
{{collapse bottom}}
 
  
<blockquote style="background: #DCF4CC; border: 1px solid black; padding: 1em;">
+
=Estruturas dentro de estruturas=
=Iniciando Estruturas na Criação=
 
 
</blockquote>
 
</blockquote>
  
Como toda variável, é possível dar valores para uma variável do tipo struct definida no programa:
+
Vamos  ver um exemplo com estruturas definidas dentro de estruturas:
  
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
+
 
 
struct TEndereco{
 
struct TEndereco{
 
     char rua[50];
 
     char rua[50];
 
     char numero[10];
 
     char numero[10];
 
};
 
};
+
 
 
struct TCidadao{
 
struct TCidadao{
 
   char nome[50];
 
   char nome[50];
Linha 496: Linha 511:
 
   int num_filhos;
 
   int num_filhos;
 
};
 
};
+
 
 
void main()
 
void main()
 
{
 
{
   struct TCidadao Cidadao = {"Maria",
+
   struct TCidadao Cidadao;
                            "42342342234",
 
                            {"Rua AlfaBeta","145"},
 
                            5;
 
                            };
 
 
  printf("Rua do cidadao = %s\n", Cidadao.endereco.rua);
 
 
}
 
</syntaxhighlight>
 
  
<blockquote style="background: #DCF4CC; border: 1px solid black; padding: 1em;">
+
  printf("Entre com o nome\n");
=Passando estruturas como parâmetro e retornando estruturas=
+
  scanf ("%s",Cidadao.nome);
</blockquote>
+
 
 +
  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);
  
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 conceita de ponteiro.
+
  printf("Entre com o número de filhos\n");
Observe o exercício abaixo.
+
  scanf ("%d",&Cidadao.num_filhos);
 +
 
 +
}
 +
</syntaxhighlight>
  
 +
==Exercício==
 +
# Faça um código adicional para imprimir o conteúdo lido na estrutura.
 +
{{collapse top | solução}}
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
 
+
 
struct TEndereco{
 
struct TEndereco{
 
     char rua[50];
 
     char rua[50];
 
     char numero[10];
 
     char numero[10];
 
};
 
};
 
+
 
struct TCidadao{
 
struct TCidadao{
 
   char nome[50];
 
   char nome[50];
Linha 532: Linha 552:
 
};
 
};
  
void print_struct (struct TCidadao aux)
+
void print_cidadao(struct TCidadao aux)
 
{
 
{
   printf("nome=%s cpf=%s\n", aux.nome, aux.cpf);
+
   printf("Nome: %s - CPF: %s\n", aux.nome, aux.cpf);
   printf("endereço inicial do aux %p\n", &aux);
+
   printf ("Rua %s Número %s\n", aux.endereco.rua, aux.endereco.numero);
 +
  printf("Numero de filhos %d\n", aux.num_filhos);
 
}
 
}
  
void main()
+
int main(void){
{
+
 
 
   struct TCidadao Cidadao;
 
   struct TCidadao Cidadao;
 
+
 
   printf("Entre com o nome\n");
 
   printf("Entre com o nome\n");
 
   scanf ("%s",Cidadao.nome);
 
   scanf ("%s",Cidadao.nome);
 
+
  getchar();
 +
 
   printf("Entre com o cpf\n");
 
   printf("Entre com o cpf\n");
 
   scanf ("%s",Cidadao.cpf);
 
   scanf ("%s",Cidadao.cpf);
 
+
  getchar();
 +
 
   printf("Entre a rua\n");
 
   printf("Entre a rua\n");
 
   scanf ("%s",Cidadao.endereco.rua);
 
   scanf ("%s",Cidadao.endereco.rua);
 
+
  getchar();
 +
 
   printf("Entre a numero\n");   
 
   printf("Entre a numero\n");   
 
   scanf ("%s",Cidadao.endereco.numero);
 
   scanf ("%s",Cidadao.endereco.numero);
 
+
  getchar();
 +
 
   printf("Entre com o número de filhos\n");
 
   printf("Entre com o número de filhos\n");
 
   scanf ("%d",&Cidadao.num_filhos);
 
   scanf ("%d",&Cidadao.num_filhos);
 
 
  print_struct(Cidadao);
 
  
   printf("endereço inicial do Cidadao %p\n", &Cidadao);
+
   print_cidadao(Cidadao);
 +
  return 0;
 
}
 
}
 +
</syntaxhighlight>
 +
{{collapse bottom}}
 +
 +
===Iniciando Estruturas cujos campos são estruturas===
  
</syntaxhighlight>
 
  
O que podemos concluir com os endereços que foram mostrados??? Vamos a mais um exemplo.
+
Como todas variáveis no C, é possível iniciar um variável estrutura na sua definição. Vejamos o exemplo a seguir, onde uma
 +
variável chamada '''Cidadao''' tem todos os seus campos iniciados na sua definição. Note que inclusive um campo que também  é estrutura está sendo iniciado.
  
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
 
+
 
struct TEndereco{
 
struct TEndereco{
 
     char rua[50];
 
     char rua[50];
 
     char numero[10];
 
     char numero[10];
 
};
 
};
 
+
 
struct TCidadao{
 
struct TCidadao{
 
   char nome[50];
 
   char nome[50];
Linha 580: Linha 608:
 
   int num_filhos;
 
   int num_filhos;
 
};
 
};
 
+
struct TCidadao ler_struct()
+
void main()
 
{
 
{
   struct TCidadao aux;
+
   struct TCidadao Cidadao = {"Maria",
 
+
                            "42342342234",
  printf("Entre com o nome\n");
+
                            {"Rua AlfaBeta","145"},
   scanf ("%s",aux.nome);
+
                            5;
 +
                            };
 +
 +
   printf("Rua do cidadao = %s\n", Cidadao.endereco.rua);
 +
 +
}
 +
</syntaxhighlight>
  
  printf("Entre com o cpf\n");
+
<blockquote style="background: #DCF4CC; border: 1px solid black; padding: 1em;">
  scanf ("%s",aux.cpf);
 
  
  printf("Entre a rua\n");
+
=Passando estruturas como parâmetro e retornando estruturas=
  scanf ("%s",aux.endereco.rua);
+
</blockquote>
  
  printf("Entre a numero\n")
+
Estruturas podem ser passadas como parâmetros de funções e podem ser retornadas com o comando ''return''. Na realidade, a criação de um tipo estrutura é normalmente
  scanf ("%s",aux.endereco.numero);
+
acompanhado de um conjunto de funções que permitem realizar OPERAÇÕES sobre as mesmas (ver a noção de tipo abstrato de dados). Por exemplo, uma estrutura que representa um número complexo pode ser acompanhada de um conjunto de funções que operam sobre estes números.
  
  printf("Entre com o número de filhos\n");
 
  scanf ("%d",&aux.num_filhos);
 
  
  return aux;
+
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 conceita de ponteiro.
}
+
Observe o exercício abaixo.
  
void print_struct (struct TCidadao aux)
+
<syntaxhighlight lang=c  line>
{
+
#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("nome=%s cpf=%s\n", aux.nome, aux.cpf);
 
   printf("endereço inicial do aux %p\n", &aux);
 
   printf("endereço inicial do aux %p\n", &aux);
Linha 613: Linha 659:
 
   struct TCidadao Cidadao;
 
   struct TCidadao Cidadao;
  
   Cidadao = ler_struct();
+
   printf("Entre com o nome\n");
 +
  scanf ("%s",Cidadao.nome);
  
   print_struct(Cidadao);
+
   printf("Entre com o cpf\n");
 +
  scanf ("%s",Cidadao.cpf);
  
   printf("endereço inicial do Cidadao %p\n", &Cidadao);
+
   printf("Entre a rua\n");
}
+
  scanf ("%s",Cidadao.endereco.rua);
  
</syntaxhighlight>
+
  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);
  
<blockquote style="background: #DCF4CC; border: 1px solid black; padding: 1em;">
+
  printf("endereço inicial do Cidadao %p\n", &Cidadao);
=Usando typedef com Estruturas=
+
}
</blockquote>
+
 
 +
</syntaxhighlight>  
  
A palavra reservada 'typedef' pode ser usada para redefinir o nome de um tipo. No exemplo abaixo o tipo ''float'' também poderá ser representado por ''FLOAT''
+
O que podemos concluir com os endereços que foram mostrados??? Vamos a mais um exemplo que MOSTRA como uma estrutura pode ser retornada por uma função. NOTE que é retornada a cópia da estrutura.
  
<syntaxhighlight lang=c>
+
<syntaxhighlight lang=c line>
 
#include <stdio.h>
 
#include <stdio.h>
 +
 
 +
struct TEndereco{
 +
    char rua[50];
 +
    char numero[10];
 +
};
  
typedef float FLOAT;
+
struct TCidadao{
 +
  char nome[50];
 +
  char cpf[20];
 +
  struct TEndereco endereco;
 +
  int num_filhos;
 +
};
  
FLOAT x;
+
struct TCidadao ler_struct()
 +
{
 +
  struct TCidadao aux;
  
int main()
+
  printf("Entre com o nome\n");
{
+
  scanf ("%s",aux.nome);
    x = 0.5;
 
    return 0;
 
}
 
</syntaxhighlight>
 
  
O typedef pode ser usado para abreviar e apoiar na construção de estruturas:
+
  printf("Entre com o cpf\n");
 +
  scanf ("%s",aux.cpf);
  
<syntaxhighlight lang=c>
+
  printf("Entre a rua\n");
#include <stdio.h>
+
  scanf ("%s",aux.endereco.rua);
  
typedef struct {
+
  printf("Entre a numero\n");  
                float lado1;
+
  scanf ("%s",aux.endereco.numero);
                float lado2;
 
              } tipo_retang;
 
  
int main()
+
  printf("Entre com o número de filhos\n");
{
+
  scanf ("%d",&aux.num_filhos);
    tipo_retang retang1;
 
  
    retang1.lado1 = 2.5;
+
  return aux;
    retang1.lado2 = 4.5;
 
    return 0;
 
 
}
 
}
</syntaxhighlight>
 
  
No exemplo acima a struct foi usada no typedef sem um nome específico (na realidade, este nome é opcional). O nome tipo_retang veio após a declaração da estrutura. Este identificador pode agora ser usado sem ''struct''. Note no exemplo abaixo como retang1 r retang2 foram definidas. São declarações equivalentes.
+
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);
 +
}
  
<syntaxhighlight lang=c>
+
void main()
#include <stdio.h>
+
{
 +
  struct TCidadao Cidadao;
  
typedef struct tretang {
+
  Cidadao = ler_struct();
                float lado1;
 
                float lado2;
 
              } tipo_retang;
 
  
int main()
+
  print_struct(Cidadao);
{
 
    tipo_retang retang1;
 
    struct tretang retang2;
 
  
    retang1.lado1 = 2.5;
+
  printf("endereço inicial do Cidadao %p\n", &Cidadao);
    retang1.lado2 = 4.5;
+
}
  
    retang2.lado1 = 3.5;
 
    retang2.lado2 = 5.5;
 
    return 0;
 
}
 
 
</syntaxhighlight>
 
</syntaxhighlight>
 +
  
 
<blockquote style="background: #DCF4CC; border: 1px solid black; padding: 1em;">
 
<blockquote style="background: #DCF4CC; border: 1px solid black; padding: 1em;">
=Fazendo Busca em Arranjo Unidimensional de Estruturas=
+
 
 +
=Usando typedef com Estruturas=
 
</blockquote>
 
</blockquote>
 +
 +
A palavra RESERVADA ''typedef'' pode ser usada para redefinir o nome de um tipo. No exemplo abaixo o tipo ''float'' também poderá ser representado por ''MEU_FLOAT''
  
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
#include <string.h>
 
  
#define TAM_ID 10
+
typedef float MEU_FLOAT;
#define TAM_NOME 30
 
#define TAM_USERS 5
 
  
typedef struct {
+
MEU_FLOAT x;
                char userID[TAM_ID];
 
                char nome[30];
 
                int cont;
 
              } tipo_usuario;
 
  
/* Variável Global - Tabela de Usuários do Sistema */
+
int main()
tipo_usuario usuarios[TAM_USERS] = {
+
{
         {"joaos","joao da silva", 0},
+
    x = 0.5;
         {"marias","maria da silva", 0},
+
    return 0;
         {"joses","jose da silva",0},
+
}
         {"laras","lara da silva",0},
+
</syntaxhighlight>
         {"eraldo","eraldo e silva",0},
+
 
         };
+
O ''typedef'' pode ser usado para abreviar e apoiar a construção de estruturas:
 +
 
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 
 +
typedef struct {
 +
                float lado1;
 +
                float lado2;
 +
              } tipo_retang;
 +
 
 +
int main()
 +
{
 +
    tipo_retang retang1;
 +
 
 +
    retang1.lado1 = 2.5;
 +
    retang1.lado2 = 4.5;
 +
    return 0;
 +
}
 +
</syntaxhighlight>
 +
 
 +
No exemplo acima a ''struct'' foi usada no ''typedef'' sem um nome específico (na realidade, este nome é opcional). O nome  tipo_retang veio após a declaração da estrutura. Este identificador pode agora ser usado sem ''struct''. Note no exemplo abaixo como retang1 r retang2 foram definidas. São declarações equivalentes.
 +
 
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 
 +
typedef struct tretang {
 +
                float lado1;
 +
                float lado2;
 +
              } tipo_retang;
 +
 
 +
int main()
 +
{
 +
    tipo_retang retang1;
 +
    struct tretang retang2;
 +
 
 +
    retang1.lado1 = 2.5;
 +
    retang1.lado2 = 4.5;
 +
 
 +
    retang2.lado1 = 3.5;
 +
    retang2.lado2 = 5.5;
 +
    return 0;
 +
}
 +
</syntaxhighlight>
 +
 
 +
<blockquote style="background: #DCF4CC; border: 1px solid black; padding: 1em;">
 +
 
 +
=Fazendo Busca em Arranjo Unidimensional de Estruturas=
 +
</blockquote>
 +
 
 +
 
 +
[[File:PRG1-BuscaEstrutura.png|550px]]
 +
 
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
#include <string.h>
 +
 
 +
#define TAM_ID 10
 +
#define TAM_NOME 30
 +
#define TAM_USERS 5
 +
 
 +
typedef struct {
 +
                char userID[TAM_ID];
 +
                char nome[30];
 +
                int cont;
 +
              } tipo_usuario;
 +
 
 +
/* Variável Global - Tabela de Usuários do Sistema */
 +
tipo_usuario usuarios[TAM_USERS] = {
 +
         {"joaos","joao da silva", 0},
 +
         {"marias","maria da silva", 0},
 +
         {"joses","jose da silva",0},
 +
         {"laras","lara da silva",0},
 +
         {"eraldo","eraldo e silva",0},
 +
         };
 +
 
 +
/* Função que busca um usuário na tabela:
 +
* ENTRADA: string correspondente ao userID
 +
* SAIDA (retorno): retorna -1 se usuário não existe ou retorna o índice
 +
* do usuário na tabela
 +
*/
 +
int buscar_indice_usuario(char userID[])
 +
{
 +
    int i, flag = 1;
 +
 
 +
    for (i = 0; i < TAM_USERS && flag; i++){
 +
        if (strcmp(userID,usuarios[i].userID)==0)
 +
            flag = 0; /* encerra a busca - usuário encontrado */
 +
    }
 +
    if (flag)
 +
        return -1;
 +
    else
 +
        return i-1;
 +
}
 +
 
 +
int main()
 +
{
 +
    int i;
 +
    i = buscar_indice_usuario("marias");
 +
    if (i>-1)
 +
        printf("Nome completo = %s \n", usuarios[i].nome);
 +
    return 0;
 +
}
 +
</syntaxhighlight>
 +
 
 +
<blockquote style="background: #DCF4CC; border: 1px solid black; padding: 1em;">
 +
 
 +
=Aplicação de estruturas - Representação de números complexos =
 +
</blockquote>
 +
 
 +
Um número complexo possui dois componentes reais que podem ser representados por duas variáveis float ou double. Observe que a declaração separada destes componentes prejudica a legibilidade do código e a construção de algoritmos eficientes para o tratamento destes números.
 +
Na sequência apresentamos exercícios que representam números complexos em estruturas. 
 +
 
 +
<ol>
 +
<li>
 +
Implementar uma estrutura que permita representar um número complexo no formato retangular. Em adição, implemente uma função que permita somar
 +
dois números complexos retornando um número complexo com o valor da soma.
 +
 
 +
{{collapse top | Solução Ex. 1}}
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
 
 +
struct tcomplexo {
 +
  float x;  /* parte real */
 +
  float y;  /* parte imaginária */
 +
};
  
/* Função que busca um usuário na tabela:
+
struct tcomplexo add_complex(struct tcomplexo num_A, struct tcomplexo num_B)
* ENTRADA: string correspondente ao userID
 
* SAIDA (retorno): retorna -1 se usuário não existe ou retorna o índice
 
* do usuário na tabela
 
*/
 
int buscar_indice_usuario(char userID[])
 
 
{
 
{
    int i, flag = 1;
+
  struct tcomplexo temp;
  
    for (i = 0; i < TAM_USERS && flag; i++){
+
  temp.x = num_A.x + num_B.x;
        if (strcmp(userID,usuarios[i].userID)==0)
+
  temp.y = num_A.y + num_B.y;
            flag = 0; /* encerra a busca - usuário encontrado */
+
  return temp;
    }
 
    if (flag)
 
        return -1;
 
    else
 
        return i-1;
 
 
}
 
}
  
int main()
+
int main(void)
 
{
 
{
    int i;
+
  struct tcomplexo num_1, num_2, num_3;
    i = buscar_indice_usuario("marias");
 
    if (i>-1)
 
        printf("Nome completo = %s \n", usuarios[i].nome);
 
    return 0;
 
}
 
</syntaxhighlight>
 
  
<blockquote style="background: #DCF4CC; border: 1px solid black; padding: 1em;">
+
  num_1.x = 1.5;
 
+
  num_1.y = 2.5;
=Aplicação de estruturas - Representação de números complexos =
+
  num_2.x = 3.5;
</blockquote>
+
  num_2.y = 1.5; 
 +
  num_3 = add_complex(num_1, num_2);
 +
  /* implementar aqui m printf para mostrar o valor de num_3...*/
  
Um número complexo possui dois componentes reais que podem ser representados por duas variáveis float ou double. Observe que a declaração separada destes componentes prejudica a legibilidade do código e a construção de algoritmos eficientes para o tratamento destes números.
+
  return 0;
Na sequência apresentamos exercícios que representam números complexos em estruturas. 
+
}
 +
</syntaxhighlight>
 +
{{collapse bottom}}
  
<ol>
+
</li>
 +
<li> Implementar uma função que retorna o quadrante de um número complexo. O quadrante será um número inteiro 1, 2, 3 ou 4. Caso o número seja (0,0) retornar 0. Caso esteja sobre o eixo x retornar 5 e caso esteja sobre o eixo y retornar 6.
 +
</li>
 
<li>
 
<li>
Implementar uma estrutura que permita representar um número complexo no formato retangular. Em adição, implemente uma função que permita somar
+
Implementar uma função que retorne o módulo de um número complexo.
dois números complexos retornando um número complexo com o valor da soma.
+
*'''Observação''': Quando utilizar a biblioteca matemática [[<math.h>]] deve-se compilar o código com a opção -lm. Por exemplo: ''gcc -o arquivo arquivo.c -lm''
  
{{collapse top | Solução Ex. 1}}
+
{{collapse top | Solução Ex. 2}}
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
 
+
#include <math.h>
 +
 
struct tcomplexo {
 
struct tcomplexo {
   float x; /* parte real */
+
   float x;
   float y; /* parte imaginária */
+
   float y;
 
};
 
};
  
struct tcomplexo add_complex(struct tcomplexo num_A, struct tcomplexo num_B)
+
float calc_mod_complex(struct tcomplexo num_A)
 
{
 
{
   struct tcomplexo temp;
+
   float temp;
  
   temp.x = num_A.x + num_B.x;
+
   temp = sqrtf(num_A.x*num_A.x + num_A.y * num_A.y);
  temp.y = num_A.y + num_B.y;
 
 
   return temp;
 
   return temp;
 
}
 
}
  
int main(void)
+
main()
 
{
 
{
   struct tcomplexo num_1, num_2, num_3;
+
   struct tcomplexo num_1;
 +
  float result_mod;
  
 
   num_1.x = 1.5;
 
   num_1.x = 1.5;
   num_1.y = 2.5;
+
   num_1.y = 2.5;  
  num_2.x = 3.5;
+
   
  num_2.y = 1.5;  
+
   result_mod = calc_mod_complex(num_1);
   num_3 = add_complex(num_1, num_2);
 
  /* implementar aqui m printf para mostrar o valor de num_3...*/
 
 
 
  return 0;
 
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 
{{collapse bottom}}
 
{{collapse bottom}}
  
</li>
 
<li> Implementar uma função que retorna o quadrante de um número complexo. O quadrante será um número inteiro 1, 2, 3 ou 4. Caso o número seja (0,0) retornar 0. Caso esteja sobre o eixo x retornar 5 e caso esteja sobre o eixo y retornar 6.
 
 
</li>
 
</li>
 
<li>
 
<li>
Implementar uma função que retorne o módulo de um número complexo.
+
Implementar um programa que cria duas  matrizes 2X2 de números complexos no formato retangular. Adicionalmente, implementar uma função para somar estas matrizes. Reusar a função de soma de número já implementada.
*'''Observação''': Quando utilizar a biblioteca matemática [[<math.h>]] deve-se compilar o código com a opção -lm. Por exemplo: ''gcc -o arquivo arquivo.c -lm''
 
  
{{collapse top | Solução Ex. 2}}
+
{{collapse top | Solução Ex. 3}}
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
 
#include <math.h>
 
#include <math.h>
+
 
 +
#define NUM_LIN 2
 +
#define NUM_LIN 2
 +
#define NUM_COL 2
 +
 
 
struct tcomplexo {
 
struct tcomplexo {
 
   float x;
 
   float x;
Linha 807: Linha 968:
 
};
 
};
  
float calc_mod_complex(struct tcomplexo num_A)
+
struct tcomplexo add_complex(struct tcomplexo num_A, struct tcomplexo num_B)
 
{
 
{
   float temp;
+
   struct tcomplexo temp;
 
+
   temp = sqrtf(num_A.x*num_A.x + num_A.y * num_A.y);
+
   temp.x = num_A.x + num_B.x;
 +
  temp.y = num_A.y + num_B.y;
 
   return temp;
 
   return temp;
 
}
 
}
  
main()
+
void add_mat_complex(struct tcomplexo mat_A[NUM_LIN][NUM_COL],struct tcomplexo mat_B[NUM_LIN][NUM_COL], struct tcomplexo mat_C[NUM_LIN][NUM_COL])
 
{
 
{
   struct tcomplexo num_1;
+
  int i,j;
  float result_mod;
+
 
 +
  for (i=0;i<NUM_LIN;i++)
 +
    for (j=0;j<NUM_COL;j++)
 +
        mat_C[i][j]=add_complex(mat_A[i][j], mat_B[i][j]);
 +
}
 +
 
 +
int main(void)
 +
{
 +
   struct tcomplexo mat1[NUM_LIN][NUM_COL]={
 +
                              {{.x=2.5,.y=2.7,}, {.x=1.5,.y=2.3,}},
 +
                              {{.x=1.9,.y=2.6,}, {.x=3.5,.y=7.3,}}
 +
                            },
 +
                  mat2[NUM_LIN][NUM_COL]={
 +
                              {{.x=4.5,.y=2.8,}, {.x=1.6,.y=8.3,}},
 +
                              {{.x=0.9,.y=2.9,}, {.x=7.5,.y=4.3,}}
 +
                            },   
 +
                  mat3[NUM_LIN][NUM_COL];
  
   num_1.x = 1.5;
+
   add_mat_complex(mat1,mat2,mat3);
   num_1.y = 2.5;
+
   /* fazer função para imprimir matriz complexa... */
 
  result_mod = calc_mod_complex(num_1); 
 
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
Linha 830: Linha 1 006:
 
</li>
 
</li>
 
<li>
 
<li>
Implementar um programa que cria duas  matrizes 2X2 de números complexos no formato retangular. Adicionalmente, implementar uma função para somar estas matrizes. Reusar a função de soma de número já implementada.
+
Implementar uma função converte_para_polar que recebe como parâmetro um número complexo na forma retangular (uma struct). A função deve retornar uma struct contendo o número complexo na forma polar.Usar as funções sqrt[http://www.elook.org/programming/c/sqrt.html] e  atan [http://www.elook.org/programming/c/atan.html] da 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>
  
{{collapse top | Solução Ex. 3}}
+
{{collapse top | Solução 4}}
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
#include <stdio.h>
 
 
#include <math.h>
 
#include <math.h>
  
#define NUM_LIN 2
+
struct TComplexoRet {
#define NUM_LIN 2
+
  float x,y;
#define NUM_COL 2
+
};
  
struct tcomplexo {
+
struct TComplexoPolar {
   float x;
+
   float mod,ang;
  float y;
 
 
};
 
};
  
struct tcomplexo add_complex(struct tcomplexo num_A, struct tcomplexo num_B)
+
struct TComplexoPolar convert_polar(struct TComplexoRet a)
 
{
 
{
   struct tcomplexo temp;
+
   struct TComplexoPolar aux;
+
 
   temp.x = num_A.x + num_B.x;
+
   aux.mod = sqrtf(powf(a.x,2)+powf(a.y,2));
   temp.y = num_A.y + num_B.y;
+
   aux.ang = atan(a.y/a.x);
   return temp;
+
   return aux;
 
}
 
}
  
void add_mat_complex(struct tcomplexo mat_A[NUM_LIN][NUM_COL],struct tcomplexo mat_B[NUM_LIN][NUM_COL], struct tcomplexo mat_C[NUM_LIN][NUM_COL])
+
main()
 
{
 
{
  int i,j;
+
struct TComplexoRet w;
 
+
struct TComplexoPolar y;
  for (i=0;i<NUM_LIN;i++)
+
    for (j=0;j<NUM_COL;j++)
+
w.x = 11.5;
        mat_C[i][j]=add_complex(mat_A[i][j], mat_B[i][j]);
+
w.y = 4.6;
 +
y = convert_polar(w);  
 
}
 
}
 +
</syntaxhighlight>
 +
{{collapse bottom}}
  
int main(void)
+
</li>
{
+
<li>
  struct tcomplexo mat1[NUM_LIN][NUM_COL]={
+
Implementar uma função que retorne a multiplicação de dois números complexos fornecidos como parâmetro.
                              {{.x=2.5,.y=2.7,}, {.x=1.5,.y=2.3,}},
+
 
                              {{.x=1.9,.y=2.6,}, {.x=3.5,.y=7.3,}}
+
{{collapse top | Solução 5}}
                            },
+
<syntaxhighlight lang=c>
                  mat2[NUM_LIN][NUM_COL]={
+
//Autor : Victor Cesconetto De Pieri
                              {{.x=4.5,.y=2.8,}, {.x=1.6,.y=8.3,}},
 
                              {{.x=0.9,.y=2.9,}, {.x=7.5,.y=4.3,}}
 
                            },   
 
                  mat3[NUM_LIN][NUM_COL];
 
  
  add_mat_complex(mat1,mat2,mat3);
+
#include <stdio.h>
  /* fazer função para imprimir matriz complexa... */
+
#include <math.h>
}
 
</syntaxhighlight>
 
{{collapse bottom}}
 
  
</li>
+
struct tcomplexo {
<li>
+
  float x;
Implementar uma função converte_para_polar que recebe como parâmetro um número complexo na forma retangular (uma struct). A função deve retornar uma struct contendo o número complexo na forma polar.Usar as funções sqrt[http://www.elook.org/programming/c/sqrt.html] e  atan [http://www.elook.org/programming/c/atan.html] da biblioteca matemática. [http://www.teacherschoice.com.au/maths_library/coordinates/polar_-_rectangular_conversion.htm Como converter]:
+
  float y;
:<math> mod = \sqrt{x^2+y^2}
+
};
</math>
 
:<math> \phi = \arctan \frac{y}{x} </math>  ou  <math> \phi = \tan^{-1} \frac{y}{x} </math>
 
  
{{collapse top | Solução 4}}
+
float calc_num_imag(struct tcomplexo num_A, struct tcomplexo num_B) {
<syntaxhighlight lang=c>
+
 
#include <math.h>
+
  float temp_imag = num_A.x * num_B.y + num_A.y * num_B.x;
 +
 
 +
  return temp_imag;
 +
}
  
struct TComplexoRet {
+
float calc_num_real(struct tcomplexo num_A, struct tcomplexo num_B) {
  float x,y;
 
};
 
  
struct TComplexoPolar {
+
   float temp_real = num_A.x * num_B.x + num_A.y * num_B.y * (-1);
   float mod,ang;
 
};
 
  
struct TComplexoPolar convert_polar(struct TComplexoRet a)
+
   return temp_real;
{
 
  struct TComplexoPolar aux;
 
 
 
  aux.mod = sqrtf(powf(a.x,2)+powf(a.y,2));
 
  aux.ang = atan(a.y/a.x); 
 
   return aux;
 
 
}
 
}
  
main()
+
int main() {
{
+
  struct tcomplexo num_1;
struct TComplexoRet w;
+
  struct tcomplexo num_2;
struct TComplexoPolar y;
+
  float real, imag;
+
  num_1.x = 2.5;
w.x = 11.5;
+
  num_1.y = 1;
w.y = 4.6;
+
  num_2.x = 2.5;
y = convert_polar(w);  
+
  num_2.y = 1;
 +
  real = calc_num_real(num_1, num_2);
 +
  imag = calc_num_imag(num_1, num_2);
 +
 
 +
  printf("Resultado : %f + %fi\n", real, imag);
 +
 
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 
{{collapse bottom}}
 
{{collapse bottom}}
 
 
</li>
 
</li>
<li>
+
</ol>
Implementar uma função que retorne a multiplicação de dois números complexos fornecidos como parâmetro.
 
  
{{collapse top | Solução 5}}
+
<blockquote style="background: #DCF4CC; border: 1px solid black; padding: 1em;">
<syntaxhighlight lang=c>
+
=Aplicação no Controle de Acesso=
//Autor : Victor Cesconetto De Pieri
+
</blockquote>
 +
 
 +
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''. A função strcmp da BIBLIOTECA DO C para comparação de strings. Ela retorna 0 caso as strings a serem comparadas sejam iguais. Note que deve ser incluído string.h
  
 +
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
#include <math.h>
+
#include <string.h>
 +
 +
/**********************************************/
 +
/***PROGRAMA DE CONTROLE DE ACESSO**/
 +
/**********************************************/
 +
 +
/** VARIÁVEIS GLOBAIS DESTE MÓDULO ****/
  
struct tcomplexo {
+
struct TRegistroUsuario {
   float x;
+
   char UserId[10];
   float y;
+
   char Senha[10];
 
};
 
};
  
float calc_num_imag(struct tcomplexo num_A, struct tcomplexo num_B) {
+
/* Tabela de Usuários */
 
+
struct TRegistroUsuario TabelaUsuarios[4] = {
   float temp_imag = num_A.x * num_B.y + num_A.y * num_B.x;
+
  {"joao","abcd"},
 +
  {"maria","xxxx"},
 +
  {"jose","yyyy"},
 +
   {"lara","zzzz"},
 +
};
  
   return temp_imag;
+
 +
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");
 
}
 
}
 
+
float calc_num_real(struct tcomplexo num_A, struct tcomplexo num_B) {
+
/** Função que implementa as tarefas do administrador **/
 
+
  float temp_real = num_A.x * num_B.x + num_A.y * num_B.y * (-1);
+
void  administrar()
 
+
{
  return temp_real;
 
 
}
 
}
 
+
int main() {
+
/** Função que valida um usuário e abre a porta **/
   struct tcomplexo num_1;
+
   struct tcomplexo num_2;
+
void tratar_usuario()
   float real, imag;
+
{
   num_1.x = 2.5;
+
   char senha[10];
  num_1.y = 1;
+
   int userEncontrado=1;
   num_2.x = 2.5;
+
   int i;
   num_2.y = 1;
+
  real = calc_num_real(num_1, num_2);
+
  imag = calc_num_imag(num_1, num_2);
+
/*
 
+
    Loop para encontrar o usuário na tabela.
  printf("Resultado : %f + %fi\n", real, imag);
+
    Ao final do loop a variavel i conterá o índice do usuário (menos 1)(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");
 +
  }
 
}
 
}
</syntaxhighlight>
+
{{collapse bottom}}
+
void main()
</li>
+
{
</ol>
+
  for(;;) {
 
+
    mostrar_menu_entrada_usuario();
 +
    scanf("%s",userID);
 +
    if (strcmp(userID, "admin")==0) {
 +
        administrar();
 +
    } else {
 +
        tratar_usuario();
 +
    }
 +
}  
 +
}
 +
</syntaxhighlight>
 +
 
 
<blockquote style="background: #DCF4CC; border: 1px solid black; padding: 1em;">
 
<blockquote style="background: #DCF4CC; border: 1px solid black; padding: 1em;">
=Aplicação no Controle de Acesso=
+
==Exercícios:==
 
</blockquote>
 
</blockquote>
  
O exemplo a seguir implementa uma parte do programa de controle de acesso usando estruturas. Neste exemplo
+
<ol>
a tabela de usuários já vem inicializada nos campos ''UserID'' e ''Senha''. A função strcmp da BIBLIOTECA DO C para comparação de strings. Ela retorna 0 caso as strings a serem comparadas sejam iguais. Note que deve ser incluído string.h
+
<li>
 
+
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 | Solução - Exercício 01}}
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
 
#include <string.h>
 
#include <string.h>
+
 
/**********************************************/
+
struct TRegistroUsuario {
/***PROGRAMA DE CONTROLE DE ACESSO**/
 
/**********************************************/
 
 
/** VARIÁVEIS GLOBAIS DESTE MÓDULO ****/
 
 
 
struct TRegistroUsuario {
 
 
   char UserId[10];
 
   char UserId[10];
 
   char Senha[10];
 
   char Senha[10];
 +
  int contador;
 
};
 
};
 
+
/* Tabela de Usuários */
 
 
struct TRegistroUsuario TabelaUsuarios[4] = {
 
struct TRegistroUsuario TabelaUsuarios[4] = {
   {"joao","abcd"},
+
   {"joao","abcd",0},
   {"maria","xxxx"},
+
   {"maria","xxxx",0},
   {"jose","yyyy"},
+
   {"jose","yyyy",0},
   {"lara","zzzz"},
+
   {"lara","zzzz",0},
 
};
 
};
 
 
   
 
   
char userID[20];
+
void tratar_usuario(char userid[20])
 +
{
 +
  char senha[10];
 +
  int userEncontrado=1;
 +
  int i;
 
   
 
   
 
   
 
   
/** FUNÇÔES DESTE MÓDULO ****/
+
  for (i=0;i<4 && userEncontrado; i++) {
 +
    if( strcmp(userid, TabelaUsuarios[i].UserId)==0)
 +
        userEncontrado=0;
 +
  }
 
   
 
   
void mostrar_menu_entrada_usuario()
+
 
{
+
  if (userEncontrado==0) {//se o usuario for encontrado começa-se o tratamento da senha
  printf("*******************************\n");
+
    i--;
  printf("Entre com o seu USERID para ter acesso\n");  
+
    if (TabelaUsuarios[i].contador<3){  
  printf("*******************************\n");
+
        printf("Bom dia %s! Entre com a senha\n", userid);
}
+
        scanf("%s",senha);
+
        if(strcmp(senha,TabelaUsuarios[i].Senha)==0) {
/** Função que implementa as tarefas do administrador **/
+
        printf("Abrir porta!!!\n");
+
        TabelaUsuarios[i].contador=0;
void  administrar()
+
        } else {
{
+
          TabelaUsuarios[i].contador++;
 +
          printf("Senha invalida\n");
 +
          printf("Tentativas restantes %d\n", 3-TabelaUsuarios[i].contador);
 +
          if (TabelaUsuarios[i].contador==3)
 +
              printf("%s seu userId foi bloqueado!!!!\n", TabelaUsuarios[i].UserId);
 +
        }
 +
    } else {
 +
        printf("Usuário bloqueado\n");
 +
    }
 +
  } else {
 +
    printf("Usuário não encontrado\n");
 +
  }
 
}
 
}
 
   
 
   
/** Função que valida um usuário e abre a porta **/
+
int main(){
+
   char userID[20];
void tratar_usuario()
+
   for(;;) {
{
+
    printf("Entre com o seu USERID para ter acesso\n");
   char senha[10];
+
    scanf("%s",userID);
   int userEncontrado=1;
+
   
  int i;
+
    tratar_usuario(userID);
 +
    }
 +
}
 +
</syntaxhighlight>
 +
{{collapse bottom}}
 +
-->
 +
</li>
 +
<li>
 +
Implementar uma funcionalidade do administrador para desbloquear o usuário bloqueado.</li>
 +
<!--
 +
{{collapse top | Solução - Exercício 02}}
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
#include <string.h>
 
   
 
   
 +
/**********************************************/
 +
/*** PROGRAMA DE CONTROLE DE ACESSO  **/
 +
/** Autor: Turma ENG.TELECOM - 2013.1 */
 +
/**********************************************/
 
   
 
   
/*  
+
/** VARIÁVEIS GLOBAIS DESTE MÓDULO ****/
    Loop para encontrar o usuário na tabela.
 
    Ao final do loop a variavel i conterá o índice do usuário (menos 1)(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 */
+
struct TRegistroUsuario {
   if (userEncontrado==0) {
+
   char UserId[10];
    printf("Bom dia %s! Entre com a senha\n", userID);
+
  char Senha[10];
    scanf("%s",senha);
+
   int contador;
    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()
+
/* Tabela de Usuários */
{
+
struct TRegistroUsuario TabelaUsuarios[4] = {
   for(;;) {
+
   {"joao","abcd",0},
    mostrar_menu_entrada_usuario();
+
  {"maria","xxxx",0},
    scanf("%s",userID);
+
  {"jose","yyyy",0},
    if (strcmp(userID, "admin")==0) {
+
   {"lara","zzzz",0},
        administrar();
+
};
    } else {
 
        tratar_usuario();
 
    }
 
}    
 
}
 
</syntaxhighlight>
 
 
 
==Exercícios:==
 
 
 
*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 | Solução - Exercício 01}}
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <string.h>
 
 
    
 
    
struct TRegistroUsuario {
+
char userID[20];
  char UserId[10];
+
  char Senha[10];
+
/** FUNÇÔES DESTE MÓDULO ****/
  int contador;
 
};
 
 
   
 
   
struct TRegistroUsuario TabelaUsuarios[4] = {
+
void mostrar_menu_entrada_usuario()
   {"joao","abcd",0},
+
{
   {"maria","xxxx",0},
+
   printf("*******************************\n");
   {"jose","yyyy",0},
+
   printf("Entre com o seu USERID para ter acesso\n");
  {"lara","zzzz",0},
+
   printf("*******************************\n");
};
+
}
 +
 +
/** Função que implementa as tarefas do administrador **/
 
   
 
   
void tratar_usuario(char userid[20])
+
void administrar()
 
{
 
{
   char senha[10];
+
   char aux_senha[10];
 
   int userEncontrado=1;
 
   int userEncontrado=1;
 
   int i;
 
   int i;
+
   
+
  printf("MODO ADMIN!!!! \n");
   for (i=0;i<4 && userEncontrado; i++) {
+
  printf("Entre com a senha do admin \n");
    if( strcmp(userid, TabelaUsuarios[i].UserId)==0)
+
  scanf ("%s", aux_senha);
         userEncontrado=0;
+
    
 +
  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;
 +
        printf("ATENÇÃO: o usuário %s foi desbloqueado!\n", TabelaUsuarios[i].UserId);
 +
    }         
 
   }
 
   }
 +
}
 +
 +
/** Função que valida um usuário e abre a porta **/
 
   
 
   
    
+
void tratar_usuario()
   if (userEncontrado==0) {//se o usuario for encontrado começa-se o tratamento da senha
+
{
     i--;  
+
   char senha[10];
     if (TabelaUsuarios[i].contador<3){   
+
   int userEncontrado=1;
         printf("Bom dia %s! Entre com a senha\n", userid);
+
  int i;
         scanf("%s",senha);
+
 +
/*
 +
    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) {
 
         if(strcmp(senha,TabelaUsuarios[i].Senha)==0) {
 
        printf("Abrir porta!!!\n");
 
        printf("Abrir porta!!!\n");
Linha 1 109: Linha 1 359:
 
         } else {
 
         } else {
 
           TabelaUsuarios[i].contador++;
 
           TabelaUsuarios[i].contador++;
           printf("Senha invalida\n");
+
           printf("Senha Inválida\n");
 
           printf("Tentativas restantes %d\n", 3-TabelaUsuarios[i].contador);
 
           printf("Tentativas restantes %d\n", 3-TabelaUsuarios[i].contador);
 
           if (TabelaUsuarios[i].contador==3)
 
           if (TabelaUsuarios[i].contador==3)
               printf("%s seu userId foi bloqueado!!!!\n", TabelaUsuarios[i].UserId);
+
               printf("ATENÇÃO usuário %s - fale com o ADMINISTRADOR DO SISTEMA - SEU LOGIN FOI BLOQUEADO!\n", TabelaUsuarios[i].UserId);
 
         }
 
         }
 
     } else {
 
     } else {
Linha 1 122: Linha 1 372:
 
}
 
}
 
   
 
   
int main(){
+
void main()
  char userID[20];
+
{
 
   for(;;) {
 
   for(;;) {
     printf("Entre com o seu USERID para ter acesso\n");  
+
     mostrar_menu_entrada_usuario();
 
     scanf("%s",userID);
 
     scanf("%s",userID);
      
+
     if (strcmp(userID, "admin")==0) {
     tratar_usuario(userID);
+
        administrar();
    }
+
     } else {
}
+
        tratar_usuario();
 +
    }
 +
  }
 +
}  
 
</syntaxhighlight>
 
</syntaxhighlight>
 
{{collapse bottom}}
 
{{collapse bottom}}
 
+
-->
*Implementar uma funcionalidade do administrador para desbloquear o usuário bloqueado.
+
</li>
{{collapse top | Solução - Exercício 02}}
+
<li>
 +
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!
 +
<!--
 +
{{collapse top | Solucão - Exercício 03}}
 
<syntaxhighlight lang=c>
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <stdio.h>
 
#include <string.h>
 
#include <string.h>
+
 
/**********************************************/
+
struct TRegistroUsuario {
/*** PROGRAMA DE CONTROLE DE ACESSO  **/
+
   char UserId[10];
/** Autor: Turma ENG.TELECOM - 2013.1 */
 
/**********************************************/
 
 
/** VARIÁVEIS GLOBAIS DESTE MÓDULO ****/
 
 
struct TRegistroUsuario {
 
   char UserId[10];
 
 
   char Senha[10];
 
   char Senha[10];
 
   int contador;
 
   int contador;
 +
  char mensagem[20];
 
};
 
};
 
   
 
   
/* Tabela de Usuários */
+
 
 
struct TRegistroUsuario TabelaUsuarios[4] = {
 
struct TRegistroUsuario TabelaUsuarios[4] = {
   {"joao","abcd",0},
+
   {"joao","abcd",0,"Bom dia João"},
   {"maria","xxxx",0},
+
   {"maria","xxxx",0,"Bom dia Maria"},
   {"jose","yyyy",0},
+
   {"jose","yyyy",0,"Bom dia José"},
   {"lara","zzzz",0},
+
   {"lara","zzzz",0,"Bom dia Lara"},
 
};
 
};
 
 
char userID[20];
 
 
   
 
   
/** FUNÇÔES DESTE MÓDULO ****/
 
 
   
 
   
void mostrar_menu_entrada_usuario()
+
void tratar_usuario(char userid[20])
 
{
 
{
   printf("*******************************\n");
+
   char senha[10];
   printf("Entre com o seu USERID para ter acesso\n");  
+
   int userEncontrado=1;
   printf("*******************************\n");
+
   int i;
}
+
 
   
 
   
/** Função que implementa as tarefas do administrador **/
+
  for (i=0;i<4 && userEncontrado; i++) {
 +
    if( strcmp(userid, TabelaUsuarios[i].UserId)==0)
 +
        userEncontrado=0;
 +
  }
 
   
 
   
void  administrar()
 
{
 
  char aux_senha[10];
 
  int userEncontrado=1;
 
  int i;
 
   
 
  printf("MODO ADMIN!!!! \n");
 
  printf("Entre com a senha do admin \n");
 
  scanf ("%s", aux_senha);
 
 
    
 
    
   if(strcmp(aux_senha,"123456")==0) {
+
   if (userEncontrado==0) {//se o usuario for encontrado começa-se o tratamento da senha
     /* senha valida do admin - agora entre com userid a ser desbloqueado */
+
     i--;
     printf("Entre com userdID a ser desbloqueado\n");
+
     if (TabelaUsuarios[i].contador<3){ 
    scanf("%s",userID);
+
        printf("%s! Entre com a senha\n",TabelaUsuarios[i].mensagem);
    for (i=0;i<4 && userEncontrado; i++) {
+
        scanf("%s",senha);
         if( strcmp(userID, TabelaUsuarios[i].UserId)==0)
+
         if(strcmp(senha,TabelaUsuarios[i].Senha)==0) {
          userEncontrado=0;
+
        printf("Abrir porta!!!\n");
    }  
+
        TabelaUsuarios[i].contador=0;
    if (userEncontrado==0) {
+
        } else {
        i--;
+
          TabelaUsuarios[i].contador++;
        TabelaUsuarios[i].contador=0;
+
          printf("Senha invalida\n");
        printf("ATENÇÃO: o usuário %s foi desbloqueado!\n", TabelaUsuarios[i].UserId);
+
          printf("Tentativas restantes %d\n", 3-TabelaUsuarios[i].contador);
     }          
+
          if (TabelaUsuarios[i].contador==3)
 +
              printf("%s seu userId foi bloqueado!!!!\n", TabelaUsuarios[i].UserId);
 +
        }
 +
    } else {
 +
        printf("Usuário bloqueado\n");
 +
     }
 +
  } else {
 +
    printf("Usuário não encontrado\n");
 
   }
 
   }
 
}
 
}
 
   
 
   
/** Função que valida um usuário e abre a porta **/
+
int main(){
 +
  char userID[20];
 +
  for(;;) {
 +
    printf("Entre com o seu USERID para ter acesso\n");
 +
    scanf("%s",userID);
 +
   
 +
    tratar_usuario(userID);
 +
    }
 +
  }
 +
}
 +
</syntaxhighlight>
 +
{{collapse bottom}}
 +
-->
 +
</li>
 +
<li>
 +
mplementar na função administrar a inserção da mensagem no exercício anterior.
 +
<!--
 +
{{collapse top | Solução - Exercício 04}}
 +
<syntaxhighlight lang=c>
 +
#include <stdio.h>
 +
#include <string.h>
 
   
 
   
void tratar_usuario()
+
struct TRegistroUsuario {
{
+
  char UserId[10];
 +
  char Senha[10];
 +
  int contador;
 +
  char mensagem[20];
 +
};
 +
 +
 +
struct TRegistroUsuario TabelaUsuarios[4] = {
 +
  {"joao","abcd",0,"Bom dia João"},
 +
  {"maria","xxxx",0,"Bom dia Maria"},
 +
  {"jose","yyyy",0,"Bom dia José"},
 +
  {"lara","zzzz",0,"Bom dia Lara"},
 +
};
 +
 +
void tratar_usuario(char userid[20])
 +
{
 
   char senha[10];
 
   char senha[10];
 
   int userEncontrado=1;
 
   int userEncontrado=1;
 
   int i;
 
   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++) {
 
   for (i=0;i<4 && userEncontrado; i++) {
     if( strcmp(userID, TabelaUsuarios[i].UserId)==0)
+
     if( strcmp(userid, TabelaUsuarios[i].UserId)==0)
 
         userEncontrado=0;
 
         userEncontrado=0;
 
   }
 
   }
 
   
 
   
  /* se usuário encontrado abre a porta */
+
   if (userEncontrado==0) {
+
   if (userEncontrado==0) {//se o usuario for encontrado começa-se o tratamento da senha
     i--; /* o indice do sujeito é i-1 */
+
     i--;  
 
     if (TabelaUsuarios[i].contador<3){   
 
     if (TabelaUsuarios[i].contador<3){   
         printf("Bom dia %s! Entre com a senha\n", userID);
+
         printf("%s! Entre com a senha\n",TabelaUsuarios[i].mensagem);
 
         scanf("%s",senha);
 
         scanf("%s",senha);
 
         if(strcmp(senha,TabelaUsuarios[i].Senha)==0) {
 
         if(strcmp(senha,TabelaUsuarios[i].Senha)==0) {
Linha 1 229: Linha 1 508:
 
         } else {
 
         } else {
 
           TabelaUsuarios[i].contador++;
 
           TabelaUsuarios[i].contador++;
           printf("Senha Inválida\n");
+
           printf("Senha invalida\n");
 
           printf("Tentativas restantes %d\n", 3-TabelaUsuarios[i].contador);
 
           printf("Tentativas restantes %d\n", 3-TabelaUsuarios[i].contador);
 
           if (TabelaUsuarios[i].contador==3)
 
           if (TabelaUsuarios[i].contador==3)
               printf("ATENÇÃO usuário %s - fale com o ADMINISTRADOR DO SISTEMA - SEU LOGIN FOI BLOQUEADO!\n", TabelaUsuarios[i].UserId);
+
               printf("%s seu userId foi bloqueado!!!!\n", TabelaUsuarios[i].UserId);
 
         }
 
         }
 
     } else {
 
     } else {
Linha 1 241: Linha 1 520:
 
   }
 
   }
 
}
 
}
 +
 +
void  administrar()
 +
{
 +
  char aux_senha[10];
 +
  char userID[20];
 +
  char novamensagem[20];
 +
  int userEncontrado=1;
 +
  int i;
 +
  int select;
 
   
 
   
void main()
+
   printf("MODO ADMIN!!!! \n");
{
+
  printf("Entre com a senha do admin \n");
   for(;;) {
+
  scanf ("%s", aux_senha);
    mostrar_menu_entrada_usuario();
 
    scanf("%s",userID);
 
    if (strcmp(userID, "admin")==0) {
 
        administrar();
 
    } else {
 
        tratar_usuario();
 
    }
 
  }
 
 
</syntaxhighlight>
 
{{collapse bottom}}
 
*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!
 
{{collapse top | Solucão - Exercício 03}}
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <string.h>
 
 
 
struct TRegistroUsuario {
 
  char UserId[10];
 
  char Senha[10];
 
  int contador;
 
  char mensagem[20];
 
};
 
 
   
 
   
 
+
   if(strcmp(aux_senha,"123456")==0) {
struct TRegistroUsuario TabelaUsuarios[4] = {
+
    /* senha valida do admin - agora entre com userid a ser desbloqueado */
   {"joao","abcd",0,"Bom dia João"},
+
    printf("Voce deseja desbloquear usuario - 1\nVoce deseja mudar a mensagem de boas vindas - 2\n");
  {"maria","xxxx",0,"Bom dia Maria"},
+
    scanf("%d",&select);
  {"jose","yyyy",0,"Bom dia José"},
+
    if(select==1){
  {"lara","zzzz",0,"Bom dia Lara"},
+
      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)
void tratar_usuario(char userid[20])
+
            userEncontrado=0;
{
+
        }
  char senha[10];
+
        if (userEncontrado==0) {
  int userEncontrado=1;
+
            i--;
  int i;
+
            TabelaUsuarios[i].contador=0;
+
            printf("ATENÇÃO: o usuário %s foi desbloqueado!\n", TabelaUsuarios[i].UserId);
+
        }     
  for (i=0;i<4 && userEncontrado; i++) {
+
    }else{
    if( strcmp(userid, TabelaUsuarios[i].UserId)==0)
+
      printf("Entre com userdID a ser trocado a mensagem\n");
         userEncontrado=0;
+
      scanf("%s",userID);
 +
      for (i=0;i<4 && userEncontrado; i++) {
 +
          if( strcmp(userID, TabelaUsuarios[i].UserId)==0)
 +
            userEncontrado=0;
 +
        }
 +
         if (userEncontrado==0) {
 +
            i--;
 +
            printf("Digite uma nova mensagem de boas vindas para %s :\n",TabelaUsuarios[i].UserId);
 +
            scanf("%s",novamensagem);
 +
            printf("%s\n",novamensagem);
 +
            strcpy(TabelaUsuarios[i].mensagem,novamensagem);
 +
            printf("%s\n",TabelaUsuarios[i].mensagem);
 +
            printf("Mensagem atualizada com sucesso\n");
 +
        }
 +
    }
 +
       
 
   }
 
   }
+
}
 
+
 
  if (userEncontrado==0) {//se o usuario for encontrado começa-se o tratamento da senha
+
int main()
    i--;
+
{
    if (TabelaUsuarios[i].contador<3){ 
 
        printf("%s! Entre com a senha\n",TabelaUsuarios[i].mensagem);
 
        scanf("%s",senha);
 
        if(strcmp(senha,TabelaUsuarios[i].Senha)==0) {
 
        printf("Abrir porta!!!\n");
 
        TabelaUsuarios[i].contador=0;
 
        } else {
 
          TabelaUsuarios[i].contador++;
 
          printf("Senha invalida\n");
 
          printf("Tentativas restantes %d\n", 3-TabelaUsuarios[i].contador);
 
          if (TabelaUsuarios[i].contador==3)
 
              printf("%s seu userId foi bloqueado!!!!\n", TabelaUsuarios[i].UserId);
 
        }
 
    } else {
 
        printf("Usuário bloqueado\n");
 
    }
 
  } else {
 
    printf("Usuário não encontrado\n");
 
  }
 
}
 
 
int main(){
 
 
   char userID[20];
 
   char userID[20];
 
   for(;;) {
 
   for(;;) {
 
     printf("Entre com o seu USERID para ter acesso\n");  
 
     printf("Entre com o seu USERID para ter acesso\n");  
 
     scanf("%s",userID);
 
     scanf("%s",userID);
   
+
     if (strcmp(userID, "admin")==0) {
    tratar_usuario(userID);
 
    }
 
  }
 
}
 
</syntaxhighlight>
 
{{collapse bottom}}
 
*Implementar na função administrar a inserção da mensagem no exercício anterior.
 
{{collapse top | Solução - Exercício 04}}
 
<syntaxhighlight lang=c>
 
#include <stdio.h>
 
#include <string.h>
 
 
struct TRegistroUsuario {
 
  char UserId[10];
 
  char Senha[10];
 
  int contador;
 
  char mensagem[20];
 
};
 
 
 
struct TRegistroUsuario TabelaUsuarios[4] = {
 
  {"joao","abcd",0,"Bom dia João"},
 
  {"maria","xxxx",0,"Bom dia Maria"},
 
  {"jose","yyyy",0,"Bom dia José"},
 
  {"lara","zzzz",0,"Bom dia Lara"},
 
};
 
 
void tratar_usuario(char userid[20])
 
{
 
  char senha[10];
 
  int userEncontrado=1;
 
  int i;
 
 
 
  for (i=0;i<4 && userEncontrado; i++) {
 
    if( strcmp(userid, TabelaUsuarios[i].UserId)==0)
 
        userEncontrado=0;
 
  }
 
 
 
  if (userEncontrado==0) {//se o usuario for encontrado começa-se o tratamento da senha
 
    i--;
 
    if (TabelaUsuarios[i].contador<3){ 
 
        printf("%s! Entre com a senha\n",TabelaUsuarios[i].mensagem);
 
        scanf("%s",senha);
 
        if(strcmp(senha,TabelaUsuarios[i].Senha)==0) {
 
        printf("Abrir porta!!!\n");
 
        TabelaUsuarios[i].contador=0;
 
        } else {
 
          TabelaUsuarios[i].contador++;
 
          printf("Senha invalida\n");
 
          printf("Tentativas restantes %d\n", 3-TabelaUsuarios[i].contador);
 
          if (TabelaUsuarios[i].contador==3)
 
              printf("%s seu userId foi bloqueado!!!!\n", TabelaUsuarios[i].UserId);
 
        }
 
    } else {
 
        printf("Usuário bloqueado\n");
 
    }
 
  } else {
 
    printf("Usuário não encontrado\n");
 
  }
 
}
 
 
 
void  administrar()
 
{
 
  char aux_senha[10];
 
  char userID[20];
 
  char novamensagem[20];
 
  int userEncontrado=1;
 
  int i;
 
  int select;
 
 
  printf("MODO ADMIN!!!! \n");
 
  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("Voce deseja desbloquear usuario - 1\nVoce deseja mudar a mensagem de boas vindas - 2\n");
 
    scanf("%d",&select);
 
    if(select==1){
 
      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;
 
            printf("ATENÇÃO: o usuário %s foi desbloqueado!\n", TabelaUsuarios[i].UserId);
 
        }     
 
    }else{
 
      printf("Entre com userdID a ser trocado a mensagem\n");
 
      scanf("%s",userID);
 
      for (i=0;i<4 && userEncontrado; i++) {
 
          if( strcmp(userID, TabelaUsuarios[i].UserId)==0)
 
            userEncontrado=0;
 
        }
 
        if (userEncontrado==0) {
 
            i--;
 
            printf("Digite uma nova mensagem de boas vindas para %s :\n",TabelaUsuarios[i].UserId);
 
            scanf("%s",novamensagem);
 
            printf("%s\n",novamensagem);
 
            strcpy(TabelaUsuarios[i].mensagem,novamensagem);
 
            printf("%s\n",TabelaUsuarios[i].mensagem);
 
            printf("Mensagem atualizada com sucesso\n");
 
        }
 
    }
 
       
 
  }
 
}
 
 
 
int main()
 
{
 
  char userID[20];
 
  for(;;) {
 
    printf("Entre com o seu USERID para ter acesso\n");
 
    scanf("%s",userID);
 
     if (strcmp(userID, "admin")==0) {
 
 
         administrar();
 
         administrar();
 
     } else {
 
     } else {
Linha 1 448: Linha 1 586:
 
</syntaxhighlight>
 
</syntaxhighlight>
 
{{collapse bottom}}
 
{{collapse bottom}}
<!--
 
#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.
 
 
-->
 
-->
 +
</li>
 +
<li>
 +
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 lugar). 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. Use esta função para no desbloqueio do usuário.
 +
</li>
 +
</ol>
  
 
=Referências=
 
=Referências=

Edição atual tal como às 09h08min de 18 de fevereiro de 2022

22 abril 2024

Objetivos

Ao final desta Unidade o aluno deverá ser capaz de:

  • Conceituar estruturas e campos de estruturas em C, através de exemplos de utilização;
  • Criar tipos com 'struct' e definir/declarar estruturas;
  • Inicializar estruturas na definição;
  • Acessar campos de uma estrutura (SEM USAR PONTEIROS) e usar estruturas em sentenças/expressões;
  • Passar estruturas como parâmetros de funções (via cópia) e retornar estruturas em funções;
  • Copiar uma variável estrutura para outra variável;
  • Criar e usar estruturas como campo de outras estruturas;
  • Criar e operar sobre arranjos de estruturas.


Conceito e Aplicação de Estruturas

VER o Vídeo "O que é uma Estrutura no C"

Revendo variáveis criadas a partir de tipos primitivos e variáveis arranjos

As variáveis no C são usadas para armazenar dados que podem ser processados ao longo da execução de um programa. O desenvolvedor deve criar variáveis a partir de um TIPO que pode ser visto como a FORMA (de um bolo...) a partir da qual se cria uma variável.

Escolher o tipo da variável é importante pois impacta:

  • no tamanho da variável;
  • na forma como os dados são armazenados na memória e, portanto, nas operações que podem ser realizadas sobre estes dados;
  • e de forma geral, na organização dos dados e nos algoritmos que podem ser usados para acessar estes dados.


PRG1-GalaxiaEvariavel-1.png PRG1-GalaxiaEvariavel-2.png


Exemplo 1: Se o desenvolvedor precisa armazenar o valor de uma tecla pressionada, possivelmente optará por armazená-la em uma variável tipo char:

int main()
{
  char tecla;

  scanf("%c", &tecla);
  :
}

Exemplo 2: Se o desenvolvedor precisa armazenar a quantidade total de livros em estoque de uma biblioteca possivelmente optará por uma variável do tipo inteira:

int main()
{
  int quantidade_livros;

  scanf("%d", &quantidade_livros);
  :
}

Exemplo 3: Se o desenvolvedor precisa armazenar um identificador de usuário talvez opte por armazená-lo como uma string e neste caso precisará de uma variável vetor de char (arranjo unidimensional).

int main()
{
  char user_id[10];

  :
  scanf("%s", user_id);
  :
}


NOTE que tipos como char, int, float e double são considerados tipos primitivos, no sentido que o compilador C já sabe o que é e como deve operar sobre variáveis criadas a partir destes tipos. Já uma variável arranjo é formada a partir de elementos de um determinado tipo.

A necessidade de o desenvolvedor criar variáveis compostas a partir de tipos já criados

Como visto, o arranjo é uma forma do desenvolvedor criar variáveis para armazenar/organizar dados de forma mais elaborado, organizando-os na forma de vetor/matriz. O próprio desenvolvedor cria o arranjo, especificando o tipo do elemento e a(s) dimensão(ões) do arranjo. Desta forma, pode-se facilmente operar sobre uma sequência de dados.

Entretanto, como um desenvolvedor poderia criar uma variável que armazena diferentes dados (atributos) de um livro, por exemplo:

  • o título,
  • o autor,
  • o ISBN a edição etc?

Neste ponto existe a necessidade de se criar uma variável constituída de partes (campos ou fields) especificados pelo próprio desenvolvedor. Uma variável estrutura pode ser vista como um agrupamento de variáveis (identificadas pelos campos).

PRG1-LivroEstruct-1.png PRG1-LivroEstruct-2.png PRG1-LivroEstruct-3.png

No caso do livro poderia ser criado um tipo struct tipo_livro da forma:

struct tipo_livro {
   char titulo[30];
   char autor[50];
   char isbn[13];
   int  ano;
};


e na sequência uma variável de nome livro da forma:

struct tipo_livro livro;

Definição/declaração de Estruturas e Acesso aos Campos

VER o Vídeo "Definindo Estruturas no C"

No C é possível criar tipos de dados que representam uma estrutura. Veja o exemplo que se segue.

#include <stdio.h>

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

    /* acessando os campos da estrutura Usuario */
    scanf("%s", Usuario.userID);
    scanf("%s", Usuario.senha);
    Usuario.num_acessos = 0;

    return 0;
}

Na realidade nada impede que se crie um vetor de estruturas, como no exemplo abaixo:

#include <stdio.h>

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

    /* aqui uma tabela/vetor de estruturas */
    struct TUsuario TabelaUsuario[20];

    /* acessando os campos da estrutura Usuario */
    scanf("%s", Usuario.userID);
    scanf("%s", Usuario.senha);
    Usuario.num_acessos = 0;

    /* acessando o campo 10 da tabela de estruturas */
    scanf("%s", TabelaUsuario[10].userID);
    scanf("%s", TabelaUsuario[10].senha);
    TabelaUsuario[10].num_acessos = 0;

    return 0;
}

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 tipo estrutura que permita representar um retângulo. Criar duas variáveis retângulo e mostrar como as áreas destes retângulos poderiam ser somadas.

Solução
#include <stdio.h>


struct tipo_retang{
  float lado1;
  float lado2;
};

main()
{
  struct tipo_retang x,y;
  float area_final;

  x.lado1=5.5;
  x.lado2=6.7;

  y.lado1=2.3;
  y.lado2=7.9; /* poderia entrar com scanf: scanf("%f",&y.lado2); etc */

  area_final = x.lado1*x.lado2 + y.lado1*y.lado2;

  printf("Área total dos dois retângulos = %f \n", area_final);  
}


Struct figure.jpg

2. Criar um tipo estrutura que permita armazenar os coeficientes de uma equação do segundo grau. Implementar um código para calcular o DELTA da equação.

solução Ex. 2
//Autor : Victor Cesconetto De Pieri
#include <stdio.h>
 
struct coeficientes_equacao {
  float a,b,c;
  } eq;

int main()
{
  float delta;

  printf("Entre com o 'a' da equação\n");
  scanf("%f", &eq.a);
  printf("Entre com o 'b' da equação\n");
  scanf("%f", &eq.b);
  printf("Entre com o 'c' da equação\n");
  scanf("%f", &eq.c);  
  delta = (eq.b*eq.b) - 4*eq.a*eq.c;
  printf("delta : %f\n", eq.delta);
  return 0;
}

3. Criar um programa que define uma struct para armazenamento do nome e das notas bimestrais de um aluno. Criar uma turma de alunos como um arranjo de estruturas de tamanho 5. Atualizar a turma usando estrutura usando o scanf.

solução Ex. 3
#include <stdio.h>

#define NUM_MAX 5

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

int 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);
  }    
        return 0;
}

4. Acrescentar um código no final da função main para calcular a média da turma para cada um dos bimestres.

solução Ex. 4
#include <stdio.h>
#define NUM_MAX 3
 
struct TAluno {
  char nome[30];
  char matricula[11];
  float b1,b2,b3,b4;
} Turma[NUM_MAX];
 
int main(){
  int i;
  float soma_b1=0,soma_b2=0,soma_b3=0,soma_b4=0
  float media_b1=0,media_b2=0,media_b3=0,media_b4=0; 
  
  for(i=0;i<NUM_MAX;i++){
      printf("Entre com o nome do aluno: ");
      scanf("%s", Turma[i].nome);
      printf("Entre com a matrícula do aluno: ");
      scanf("%s", Turma[i].matricula);
      printf("Entre com a nota do bimestre 1: ");
      scanf("%f", &Turma[i].b1);
      printf("Entre com a nota do bimestre 2: ");
      scanf("%f", &Turma[i].b2);
      printf("Entre com a nota do bimestre 3: ");
      scanf("%f", &Turma[i].b3);
      printf("Entre com a nota do bimestre 4: ");
      scanf("%f", &Turma[i].b4);
  }    

  for(i=0;i<NUM_MAX;i++) {
      soma_b1 = (soma_b1+Turma[i].b1); /* usando media_b1 para soma acumulada */
      soma_b2 = (soma_b2+Turma[i].b2);
      soma_b3 = (soma_b3+Turma[i].b3);
      soma_b4 = (soma_b4+Turma[i].b4);
  }
  media_b1 = (media_b1/NUM_MAX);
  media_b2 = (media_b2/NUM_MAX);
  media_b3 = (media_b3/NUM_MAX);
  media_b4 = (media_b4/NUM_MAX);

  printf("A media do B1 => %.2f\n",media_b1);
  printf("A media do B2 => %.2f\n",media_b2);
  printf("A media do B3 => %.2f\n",media_b3);
  printf("A media do B4 => %.2f\n",media_b4);
  return 0;
}

5. Repensar a estrutura TAluno para que as notas bimestrais sejam representadas como um vetor de floats. Fazer um código para calcular a média anual de cada aluno. Armazenar as médias anuais da turma em um vetor de floats.

solução Ex. 5
#include <stdio.h>
 
#define NUM_MAX 3
 
struct TAluno {
  char nome[30];
  char matricula[11];
  float b[4];
} 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.b[0]);
  printf("Bimestre 2 -> %f\n", aux.b[1]);
  printf("Bimestre 3 -> %f\n", aux.b[2]);
  printf("Bimestre 4 -> %f\n", aux.b[3]);          
}
 
main()
{
  int i,j;
  float media[NUM_MAX]={0,0,0}; 
 
  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);
      for(j=0;j<4;j++) {
          printf("Entre com a nota do bimestre %d\n", j+1);
          scanf("%f", &Turma[i].b[j]);
      }
  }    
 
  /* calculo das médias bimestrais da turma */
  /* separado do primeiro for para caracterizar a diferença de entrada de dados do processamento ... */
  for(i=0;i<NUM_MAX;i++) {
      for(j=0;j<4;j++)
            media[i]=media[i]+Turma[i].b[j]; /* usando media_b1 para soma acumulada */
      media[i]=media[i]/4;
  }
}

Iniciando estruturas na definição

Variáveis do tipo "estrutura" também podem ser iniciadas na declaraçao/definição. Veja o exemplo abaixo.

#include <stdio.h>


struct tipo_retang{
  float lado1;
  float lado2;
};

main()
{
  struct tipo_retang x = {5.5,6.7},
                     y = {2.3,7.9};
  float area_final;

  area_final = x.lado1*x.lado2 + y.lado1*y.lado2;

  printf("Área total dos dois retângulos = %f \n", area_final);  
}


Copiando Estruturas


Pode-se copiar dados de uma estrutura para outra simplesmente copiando seus campos um a um. Vamos a um exemplo.A variável Ontem é copiada para variável Hoje. Elas possuem a mesma composição: horas, minutos e segundos (tipo struct THoras). Note que para realizar esta cópia não é necessário que as variáveis tenham exatamente a mesma estrutura (tipo). Basta os campos envolvidos serem de tipo compatíveis.

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

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

void main()
{
     struct THoras Hoje;
     Hoje.hora = Ontem.hora;
     Hoje.minuto = Ontem.minuto;
     Hoje.segundo = Ontem.segundo;     

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


Entretanto, é possível copiar inteiramente uma estrutura, sem precisar citar seus atributos. Veja o exemplo abaixo:

#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);

  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);
  
}

Exercício

  1. Faça um código adicional para imprimir o conteúdo lido na estrutura.
solução
#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_cidadao(struct TCidadao aux)
{
  printf("Nome: %s - CPF: %s\n", aux.nome, aux.cpf);
  printf ("Rua %s Número %s\n", aux.endereco.rua, aux.endereco.numero); 
  printf("Numero de filhos %d\n", aux.num_filhos);
}

int main(void){

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

  print_cidadao(Cidadao);
  return 0;
}

Iniciando Estruturas cujos campos são estruturas

Como todas variáveis no C, é possível iniciar um variável estrutura na sua definição. Vejamos o exemplo a seguir, onde uma variável chamada Cidadao tem todos os seus campos iniciados na sua definição. Note que inclusive um campo que também é estrutura está sendo iniciado.

#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

Estruturas podem ser passadas como parâmetros de funções e podem ser retornadas com o comando return. Na realidade, a criação de um tipo estrutura é normalmente acompanhado de um conjunto de funções que permitem realizar OPERAÇÕES sobre as mesmas (ver a noção de tipo abstrato de dados). Por exemplo, uma estrutura que representa um número complexo pode ser acompanhada de um conjunto de funções que operam sobre estes números.


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 conceita de ponteiro. Observe o exercício abaixo.

 1#include <stdio.h>
 2  
 3struct TEndereco{
 4     char rua[50];
 5     char numero[10];
 6};
 7
 8struct TCidadao{
 9  char nome[50];
10  char cpf[20];
11  struct TEndereco endereco;
12  int num_filhos;
13};
14
15void print_struct (struct TCidadao aux)
16{
17  printf("nome=%s cpf=%s\n", aux.nome, aux.cpf);
18  printf("endereço inicial do aux %p\n", &aux);
19}
20
21void main()
22{
23  struct TCidadao Cidadao;
24
25  printf("Entre com o nome\n");
26  scanf ("%s",Cidadao.nome);
27
28  printf("Entre com o cpf\n");
29  scanf ("%s",Cidadao.cpf);
30
31  printf("Entre a rua\n");
32  scanf ("%s",Cidadao.endereco.rua);
33
34  printf("Entre a numero\n");   
35  scanf ("%s",Cidadao.endereco.numero);
36
37  printf("Entre com o número de filhos\n");
38  scanf ("%d",&Cidadao.num_filhos);
39  
40  print_struct(Cidadao);
41
42  printf("endereço inicial do Cidadao %p\n", &Cidadao);
43}
O que podemos concluir com os endereços que foram mostrados??? Vamos a mais um exemplo que MOSTRA como uma estrutura pode ser retornada por uma função. NOTE que é retornada a cópia da estrutura.
 1#include <stdio.h>
 2  
 3struct TEndereco{
 4     char rua[50];
 5     char numero[10];
 6};
 7
 8struct TCidadao{
 9  char nome[50];
10  char cpf[20];
11  struct TEndereco endereco;
12  int num_filhos;
13};
14
15struct TCidadao ler_struct()
16{
17  struct TCidadao aux;
18
19  printf("Entre com o nome\n");
20  scanf ("%s",aux.nome);
21
22  printf("Entre com o cpf\n");
23  scanf ("%s",aux.cpf);
24
25  printf("Entre a rua\n");
26  scanf ("%s",aux.endereco.rua);
27
28  printf("Entre a numero\n");   
29  scanf ("%s",aux.endereco.numero);
30
31  printf("Entre com o número de filhos\n");
32  scanf ("%d",&aux.num_filhos);
33
34  return aux;
35}
36
37void print_struct (struct TCidadao aux)
38{
39  printf("nome=%s cpf=%s\n", aux.nome, aux.cpf);
40  printf("endereço inicial do aux %p\n", &aux);
41}
42
43void main()
44{
45  struct TCidadao Cidadao;
46
47  Cidadao = ler_struct();
48
49  print_struct(Cidadao);
50
51  printf("endereço inicial do Cidadao %p\n", &Cidadao);
52}


Usando typedef com Estruturas

A palavra RESERVADA typedef pode ser usada para redefinir o nome de um tipo. No exemplo abaixo o tipo float também poderá ser representado por MEU_FLOAT

#include <stdio.h>

typedef float MEU_FLOAT;

MEU_FLOAT x;

int main()
{
    x = 0.5;
    return 0;
}

O typedef pode ser usado para abreviar e apoiar a construção de estruturas:

#include <stdio.h>

typedef struct {
                float lado1;
                float lado2;
               } tipo_retang;

int main()
{
    tipo_retang retang1;

    retang1.lado1 = 2.5;
    retang1.lado2 = 4.5;
    return 0;
}

No exemplo acima a struct foi usada no typedef sem um nome específico (na realidade, este nome é opcional). O nome tipo_retang veio após a declaração da estrutura. Este identificador pode agora ser usado sem struct. Note no exemplo abaixo como retang1 r retang2 foram definidas. São declarações equivalentes.

#include <stdio.h>

typedef struct tretang {
                float lado1;
                float lado2;
               } tipo_retang;

int main()
{
    tipo_retang retang1;
    struct tretang retang2;

    retang1.lado1 = 2.5;
    retang1.lado2 = 4.5;

    retang2.lado1 = 3.5;
    retang2.lado2 = 5.5;
    return 0;
}

Fazendo Busca em Arranjo Unidimensional de Estruturas


PRG1-BuscaEstrutura.png

#include <stdio.h>
#include <string.h>

#define TAM_ID 10
#define TAM_NOME 30
#define TAM_USERS 5

typedef struct {
                char userID[TAM_ID];
                char nome[30];
                int cont;
               } tipo_usuario;

/* Variável Global - Tabela de Usuários do Sistema */
tipo_usuario usuarios[TAM_USERS] = {
        {"joaos","joao da silva", 0},
        {"marias","maria da silva", 0},
        {"joses","jose da silva",0},
        {"laras","lara da silva",0},
        {"eraldo","eraldo e silva",0},
        };

/* Função que busca um usuário na tabela:
 * ENTRADA: string correspondente ao userID
 * SAIDA (retorno): retorna -1 se usuário não existe ou retorna o índice
 * do usuário na tabela
*/
int buscar_indice_usuario(char userID[])
{
    int i, flag = 1;

    for (i = 0; i < TAM_USERS && flag; i++){
        if (strcmp(userID,usuarios[i].userID)==0)
            flag = 0; /* encerra a busca - usuário encontrado */
    }
    if (flag)
        return -1;
    else
        return i-1;
}

int main()
{
    int i;
    i = buscar_indice_usuario("marias");
    if (i>-1)
        printf("Nome completo = %s \n", usuarios[i].nome);
    return 0;
}

Aplicação de estruturas - Representação de números complexos

Um número complexo possui dois componentes reais que podem ser representados por duas variáveis float ou double. Observe que a declaração separada destes componentes prejudica a legibilidade do código e a construção de algoritmos eficientes para o tratamento destes números. Na sequência apresentamos exercícios que representam números complexos em estruturas.

  1. Implementar uma estrutura que permita representar um número complexo no formato retangular. Em adição, implemente uma função que permita somar dois números complexos retornando um número complexo com o valor da soma.
    Solução Ex. 1
    #include <stdio.h>
    
    struct tcomplexo {
      float x;  /* parte real */
      float y;  /* parte imaginária */
    };
    
    struct tcomplexo add_complex(struct tcomplexo num_A, struct tcomplexo num_B)
    {
      struct tcomplexo temp;
    
      temp.x = num_A.x + num_B.x;
      temp.y = num_A.y + num_B.y;
      return temp;
    }
    
    int main(void)
    {
      struct tcomplexo num_1, num_2, num_3;
    
      num_1.x = 1.5;
      num_1.y = 2.5;
      num_2.x = 3.5;
      num_2.y = 1.5;  
      num_3 = add_complex(num_1, num_2);
      /* implementar aqui m printf para mostrar o valor de num_3...*/
    
      return 0;
    }
    
  2. Implementar uma função que retorna o quadrante de um número complexo. O quadrante será um número inteiro 1, 2, 3 ou 4. Caso o número seja (0,0) retornar 0. Caso esteja sobre o eixo x retornar 5 e caso esteja sobre o eixo y retornar 6.
  3. Implementar uma função que retorne o módulo de um número complexo.
    • Observação: Quando utilizar a biblioteca matemática [[<math.h>]] deve-se compilar o código com a opção -lm. Por exemplo: gcc -o arquivo arquivo.c -lm
    Solução Ex. 2
    #include <stdio.h>
    #include <math.h>
     
    struct tcomplexo {
      float x;
      float y;
    };
    
    float calc_mod_complex(struct tcomplexo num_A)
    {
      float temp;
    
      temp = sqrtf(num_A.x*num_A.x + num_A.y * num_A.y);
      return temp;
    }
    
    main()
    {
      struct tcomplexo num_1;
      float result_mod;
    
      num_1.x = 1.5;
      num_1.y = 2.5; 
     
      result_mod = calc_mod_complex(num_1);  
    }
    
  4. Implementar um programa que cria duas matrizes 2X2 de números complexos no formato retangular. Adicionalmente, implementar uma função para somar estas matrizes. Reusar a função de soma de número já implementada.
    Solução Ex. 3
    #include <stdio.h>
    #include <math.h>
    
    #define NUM_LIN 2
    #define NUM_LIN 2
    #define NUM_COL 2
    
    struct tcomplexo {
      float x;
      float y;
    };
    
    struct tcomplexo add_complex(struct tcomplexo num_A, struct tcomplexo num_B)
    {
      struct tcomplexo temp;
     
      temp.x = num_A.x + num_B.x;
      temp.y = num_A.y + num_B.y;
      return temp;
    }
    
    void add_mat_complex(struct tcomplexo mat_A[NUM_LIN][NUM_COL],struct tcomplexo mat_B[NUM_LIN][NUM_COL], struct tcomplexo mat_C[NUM_LIN][NUM_COL])
    {
      int i,j;
      
      for (i=0;i<NUM_LIN;i++)
         for (j=0;j<NUM_COL;j++)
             mat_C[i][j]=add_complex(mat_A[i][j], mat_B[i][j]);
    }
    
    int main(void)
    {
      struct tcomplexo mat1[NUM_LIN][NUM_COL]={
                                  {{.x=2.5,.y=2.7,}, {.x=1.5,.y=2.3,}},
                                  {{.x=1.9,.y=2.6,}, {.x=3.5,.y=7.3,}}
                                },
                       mat2[NUM_LIN][NUM_COL]={
                                  {{.x=4.5,.y=2.8,}, {.x=1.6,.y=8.3,}},
                                  {{.x=0.9,.y=2.9,}, {.x=7.5,.y=4.3,}}
                                },    
                       mat3[NUM_LIN][NUM_COL];
    
      add_mat_complex(mat1,mat2,mat3);
      /* fazer função para imprimir matriz complexa... */
    }
    
  5. Implementar uma função converte_para_polar que recebe como parâmetro um número complexo na forma retangular (uma struct). A função deve retornar uma struct contendo o número complexo na forma polar.Usar as funções sqrt[1] e atan [2] da biblioteca matemática. Como converter:
    ou
    Solução 4
    #include <math.h>
    
    struct TComplexoRet {
      float x,y;
    };
    
    struct TComplexoPolar {
      float mod,ang;
    };
    
    struct TComplexoPolar convert_polar(struct TComplexoRet a)
    {
      struct TComplexoPolar aux;
      
      aux.mod = sqrtf(powf(a.x,2)+powf(a.y,2));
      aux.ang = atan(a.y/a.x);  
      return aux;
    }
    
    main()
    {
     struct TComplexoRet w;
     struct TComplexoPolar y;
     
     w.x = 11.5;
     w.y = 4.6;
     y = convert_polar(w); 
    }
    
  6. Implementar uma função que retorne a multiplicação de dois números complexos fornecidos como parâmetro.
    Solução 5
    //Autor : Victor Cesconetto De Pieri
    
    #include <stdio.h>
    #include <math.h>
    
    struct tcomplexo {
      float x;
      float y;
    };
    
    float calc_num_imag(struct tcomplexo num_A, struct tcomplexo num_B) {
    
      float temp_imag = num_A.x * num_B.y + num_A.y * num_B.x;
    
      return temp_imag;
    }
    
    float calc_num_real(struct tcomplexo num_A, struct tcomplexo num_B) {
    
      float temp_real = num_A.x * num_B.x + num_A.y * num_B.y * (-1);
    
      return temp_real;
    }
    
    int main() {
      struct tcomplexo num_1;
      struct tcomplexo num_2;
      float real, imag;
      num_1.x = 2.5;
      num_1.y = 1;
      num_2.x = 2.5;
      num_2.y = 1;
      real = calc_num_real(num_1, num_2);
      imag = calc_num_imag(num_1, num_2);
    
      printf("Resultado : %f + %fi\n", real, imag);
    
    }
    

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. A função strcmp da BIBLIOTECA DO C para comparação de strings. Ela retorna 0 caso as strings a serem comparadas sejam iguais. Note que deve ser incluído string.h

#include <stdio.h>
#include <string.h>
 
/**********************************************/
/***PROGRAMA DE CONTROLE DE ACESSO**/
/**********************************************/
 
/** 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 (menos 1)(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();
     }
 }   
}

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.
  2. Implementar uma funcionalidade do administrador para desbloquear o usuário bloqueado.
  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. mplementar 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 lugar). 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. Use esta função para no desbloqueio do usuário.

Referências

https://www.geeksforgeeks.org/memory-layout-of-c-program/

https://docs.cs50.net/2017/fall/notes/5/lecture5.html#data-structures

http://www.mathwarehouse.com/programming/passing-by-value-vs-by-reference-visual-explanation.php