Mudanças entre as edições de "PR1022804 2020 1 AULA10"
(Criou página com ' ----- link=PR1022804_2020_1_AULA09 link=PR1022804_2020_1#Aulas link=PR1022804_2020_1_AULA11') |
|||
Linha 1: | Linha 1: | ||
+ | =Objetivos= | ||
+ | |||
+ | *Definição de estruturas; | ||
+ | *Estruturas como parâmetros; | ||
+ | *Inicialização de estruturas; | ||
+ | *Cópia de estruturas; | ||
+ | |||
+ | =Estruturas= | ||
+ | |||
+ | No C é possível criar tipos de dados que representam uma estrutura. Veja o exemplo seguinte | ||
+ | |||
+ | <syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | struct TUsuario /* struct TUsuario é o nome do tipo que está sendo criado */ | ||
+ | { | ||
+ | char userID[20]; | ||
+ | char senha[20]; | ||
+ | } Usuario; /* aqui é definida uma variável do tipo struct TUsuario */ | ||
+ | |||
+ | struct TUsuario TabelaUsuario[20]; | ||
+ | |||
+ | main() | ||
+ | { | ||
+ | scanf("%s", Usuario.userID); | ||
+ | scanf("%s", Usuario.senha); | ||
+ | scanf("%s", TabelaUsuario[10].userID); | ||
+ | scanf("%s", TabelaUsuario[10].senha); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Neste exemplo, foi definido um tipo (modelo) para o registro (''struct TUsuario'') e foi criada uma variável chamada ''Usuario'' a partir deste tipo. Na sequência foi criada mais uma variável (um vetor de estruturas) chamada ''TabelaUsuario''. Note que basta usar as palavras chave ''struct Usuario'' para criar novas variáveis. O tipo completo é definido uma única vez no início. | ||
+ | |||
+ | ;Exercícios | ||
+ | |||
+ | #Criar um programa que define uma ''struct'' para armazenamento do nome e das notas bimestrais de um aluno. Atualizar a estrutura usando o scanf. | ||
+ | #Alterar o programa para que ele calcule e imprima a média de cada aluno. | ||
+ | |||
+ | {{collapse top| Resposta}} | ||
+ | <syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | #define NUM_MAX 3 | ||
+ | |||
+ | struct TAluno { | ||
+ | char nome[30]; | ||
+ | char matricula[11]; | ||
+ | float b1,b2,b3,b4; | ||
+ | } Turma[NUM_MAX]; | ||
+ | |||
+ | void print_aluno(struct TAluno aux) | ||
+ | { | ||
+ | printf("Nome -> %s\n", aux.nome); | ||
+ | printf("Matrícula -> %s\n", aux.matricula); | ||
+ | printf("Bimestre 1 -> %f\n", aux.b1); | ||
+ | printf("Bimestre 2 -> %f\n", aux.b2); | ||
+ | printf("Bimestre 3 -> %f\n", aux.b3); | ||
+ | printf("Bimestre 4 -> %f\n", aux.b4); | ||
+ | } | ||
+ | |||
+ | main() | ||
+ | { | ||
+ | int i; | ||
+ | |||
+ | for(i=0;i<NUM_MAX;i++) { | ||
+ | printf("Entre com o nome do aluno\n"); | ||
+ | scanf("%s", Turma[i].nome); | ||
+ | printf("Entre com a matrícula do aluno\n"); | ||
+ | scanf("%s", Turma[i].matricula); | ||
+ | printf("Entre com a nota do bimestre 1\n"); | ||
+ | scanf("%f", &Turma[i].b1); | ||
+ | printf("Entre com a nota do bimestre 2\n"); | ||
+ | scanf("%f", &Turma[i].b2); | ||
+ | printf("Entre com a nota do bimestre 3\n"); | ||
+ | scanf("%f", &Turma[i].b3); | ||
+ | printf("Entre com a nota do bimestre 4\n"); | ||
+ | scanf("%f", &Turma[i].b4); | ||
+ | } | ||
+ | for(i=0;i<NUM_MAX;i++) { | ||
+ | printf("=========== Aluno %d ============\n", i); | ||
+ | print_aluno(Turma[i]); | ||
+ | } | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | ==Copiando structs== | ||
+ | |||
+ | O exemplo a seguir demonstra como se pode copiar uma variável ''struct'' para outra do mesmo tipo. | ||
+ | |||
+ | <syntaxhighlight lang=c> | ||
+ | #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); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ==Estruturas dentro de estruturas== | ||
+ | |||
+ | Vamos ver um exemplo com estruturas definidas dentro de estruturas: | ||
+ | |||
+ | <syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | struct TEndereco{ | ||
+ | char rua[50]; | ||
+ | char numero[10]; | ||
+ | }; | ||
+ | |||
+ | struct TCidadao{ | ||
+ | char nome[50]; | ||
+ | char cpf[20]; | ||
+ | struct TEndereco endereco; | ||
+ | int num_filhos; | ||
+ | }; | ||
+ | |||
+ | void main() | ||
+ | { | ||
+ | struct TCidadao Cidadao; | ||
+ | |||
+ | printf("Entre com o nome\n"); | ||
+ | scanf ("%s",Cidadao.nome); // substitua por gets() | ||
+ | |||
+ | printf("Entre com o cpf\n"); | ||
+ | scanf ("%s",Cidadao.cpf); | ||
+ | |||
+ | printf("Entre a rua\n"); | ||
+ | scanf ("%s",Cidadao.endereco.rua); // substitua por gets() | ||
+ | |||
+ | printf("Entre a numero\n"); | ||
+ | scanf ("%s",Cidadao.endereco.numero); | ||
+ | |||
+ | printf("Entre com o número de filhos\n"); | ||
+ | scanf ("%d",&Cidadao.num_filhos); | ||
+ | |||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Exercício 1: Faça um código adicional para imprimir o conteúdo lido na estrutura. | ||
+ | |||
+ | |||
+ | {{collapse top| Resposta}} | ||
+ | <syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | struct TEndereco{ | ||
+ | char rua[50]; | ||
+ | char numero[10]; | ||
+ | }; | ||
+ | |||
+ | struct TCidadao{ | ||
+ | char nome[50]; | ||
+ | char cpf[20]; | ||
+ | struct TEndereco endereco; | ||
+ | int num_filhos; | ||
+ | }; | ||
+ | |||
+ | void print_endereco(struct TEndereco aux) | ||
+ | { | ||
+ | printf ("Rua %s Número %s\n", aux.rua, aux.numero); | ||
+ | } | ||
+ | |||
+ | void print_cidadao(struct TCidadao aux) | ||
+ | { | ||
+ | printf("Nome: %s CPF: %s ", aux.nome, aux.cpf); | ||
+ | print_endereco(aux.endereco); | ||
+ | printf("Numero de filhos %d\n", aux.num_filhos); | ||
+ | } | ||
+ | |||
+ | void main() | ||
+ | { | ||
+ | struct TCidadao Cidadao; | ||
+ | |||
+ | printf("Entre com o nome\n"); | ||
+ | scanf ("%s",Cidadao.nome); | ||
+ | |||
+ | printf("Entre com o cpf\n"); | ||
+ | scanf ("%s",Cidadao.cpf); | ||
+ | |||
+ | printf("Entre a rua\n"); | ||
+ | scanf ("%s",Cidadao.endereco.rua); | ||
+ | |||
+ | printf("Entre a numero\n"); | ||
+ | scanf ("%s",Cidadao.endereco.numero); | ||
+ | |||
+ | printf("Entre com o número de filhos\n"); | ||
+ | scanf ("%d",&Cidadao.num_filhos); | ||
+ | |||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | ==Iniciando structs na definição== | ||
+ | |||
+ | Como toda variável, é possível dar valores para uma variável do tipo struct definida no programa: | ||
+ | |||
+ | <syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | struct TEndereco{ | ||
+ | char rua[50]; | ||
+ | char numero[10]; | ||
+ | }; | ||
+ | |||
+ | struct TCidadao{ | ||
+ | char nome[50]; | ||
+ | char cpf[20]; | ||
+ | struct TEndereco endereco; | ||
+ | int num_filhos; | ||
+ | }; | ||
+ | |||
+ | void main() | ||
+ | { | ||
+ | struct TCidadao Cidadao = {"Maria", | ||
+ | "42342342234", | ||
+ | {"Rua AlfaBeta","145"}, | ||
+ | 5 | ||
+ | }; | ||
+ | |||
+ | printf("Rua do cidadao = %s\n", Cidadao.endereco.rua); | ||
+ | |||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | ==Passando estruturas como parâmetro e retornando estruturas== | ||
+ | |||
+ | Se não for usado o operador "&" , um parâmetro que é estrutura será passado por cópia. Não apresentaremos agora a passagem por endereço pois necessita do conceito de ponteiro. | ||
+ | Observe o exercício abaixo. | ||
+ | |||
+ | <syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | struct TEndereco{ | ||
+ | char rua[50]; | ||
+ | char numero[10]; | ||
+ | }; | ||
+ | |||
+ | struct TCidadao{ | ||
+ | char nome[50]; | ||
+ | char cpf[20]; | ||
+ | struct TEndereco endereco; | ||
+ | int num_filhos; | ||
+ | }; | ||
+ | |||
+ | void print_struct (struct TCidadao aux) | ||
+ | { | ||
+ | printf("nome=%s cpf=%s\n", aux.nome, aux.cpf); | ||
+ | printf("endereço inicial do aux %p\n", &aux); | ||
+ | } | ||
+ | |||
+ | void main() | ||
+ | { | ||
+ | struct TCidadao Cidadao; | ||
+ | |||
+ | printf("Entre com o nome\n"); | ||
+ | scanf ("%s",Cidadao.nome); | ||
+ | |||
+ | printf("Entre com o cpf\n"); | ||
+ | scanf ("%s",Cidadao.cpf); | ||
+ | |||
+ | printf("Entre a rua\n"); | ||
+ | scanf ("%s",Cidadao.endereco.rua); | ||
+ | |||
+ | printf("Entre a numero\n"); | ||
+ | scanf ("%s",Cidadao.endereco.numero); | ||
+ | |||
+ | printf("Entre com o número de filhos\n"); | ||
+ | scanf ("%d",&Cidadao.num_filhos); | ||
+ | |||
+ | print_struct(Cidadao); | ||
+ | |||
+ | printf("endereço inicial do Cidadao %p\n", &Cidadao); | ||
+ | } | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | ;O que podemos concluir com os endereços que foram mostrados??? Vamos a mais um exemplo. | ||
+ | |||
+ | <syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | |||
+ | struct TEndereco{ | ||
+ | char rua[50]; | ||
+ | char numero[10]; | ||
+ | }; | ||
+ | |||
+ | struct TCidadao{ | ||
+ | char nome[50]; | ||
+ | char cpf[20]; | ||
+ | struct TEndereco endereco; | ||
+ | int num_filhos; | ||
+ | }; | ||
+ | |||
+ | struct TCidadao ler_struct() | ||
+ | { | ||
+ | struct TCidadao aux; | ||
+ | |||
+ | printf("Entre com o nome\n"); | ||
+ | scanf ("%s",aux.nome); | ||
+ | |||
+ | printf("Entre com o cpf\n"); | ||
+ | scanf ("%s",aux.cpf); | ||
+ | |||
+ | printf("Entre a rua\n"); | ||
+ | scanf ("%s",aux.endereco.rua); | ||
+ | |||
+ | printf("Entre a numero\n"); | ||
+ | scanf ("%s",aux.endereco.numero); | ||
+ | |||
+ | printf("Entre com o número de filhos\n"); | ||
+ | scanf ("%d",&aux.num_filhos); | ||
+ | |||
+ | return aux; | ||
+ | } | ||
+ | |||
+ | void print_struct (struct TCidadao aux) | ||
+ | { | ||
+ | printf("nome=%s cpf=%s\n", aux.nome, aux.cpf); | ||
+ | printf("endereço inicial do aux %p\n", &aux); | ||
+ | } | ||
+ | |||
+ | void main() | ||
+ | { | ||
+ | struct TCidadao Cidadao; | ||
+ | |||
+ | Cidadao = ler_struct(); | ||
+ | |||
+ | print_struct(Cidadao); | ||
+ | |||
+ | printf("endereço inicial do Cidadao %p\n", &Cidadao); | ||
+ | } | ||
+ | |||
+ | </syntaxhighlight> | ||
+ | |||
+ | ==Aplicação no Controle de Acesso== | ||
+ | |||
+ | O exemplo a seguir implementa uma parte do programa de controle de acesso usando estruturas. Neste exemplo | ||
+ | a tabela de usuários já vem inicializada nos campos ''UserID'' e ''Senha''. | ||
+ | |||
+ | <syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | #include <string.h> | ||
+ | |||
+ | /**********************************************/ | ||
+ | /*** PROGRAMA DE CONTROLE DE ACESSO **/ | ||
+ | /** Autor: TurmaENG.TELECOM - 2012.2 */ | ||
+ | /**********************************************/ | ||
+ | |||
+ | /** VARIÁVEIS GLOBAIS DESTE MÓDULO ****/ | ||
+ | |||
+ | struct TRegistroUsuario { | ||
+ | char UserId[10]; | ||
+ | char Senha[10]; | ||
+ | }; | ||
+ | |||
+ | /* Tabela de Usuários */ | ||
+ | struct TRegistroUsuario TabelaUsuarios[4] = { | ||
+ | {"joao","abcd"}, | ||
+ | {"maria","xxxx"}, | ||
+ | {"jose","yyyy"}, | ||
+ | {"lara","zzzz"}, | ||
+ | }; | ||
+ | |||
+ | |||
+ | char userID[20]; | ||
+ | |||
+ | |||
+ | /** FUNÇÔES DESTE MÓDULO ****/ | ||
+ | |||
+ | void mostrar_menu_entrada_usuario() | ||
+ | { | ||
+ | printf("*******************************\n"); | ||
+ | printf("Entre com o seu USERID para ter acesso\n"); | ||
+ | printf("*******************************\n"); | ||
+ | } | ||
+ | |||
+ | /** Função que implementa as tarefas do administrador **/ | ||
+ | |||
+ | void administrar() | ||
+ | { | ||
+ | } | ||
+ | |||
+ | /** Função que valida um usuário e abre a porta **/ | ||
+ | |||
+ | void tratar_usuario() | ||
+ | { | ||
+ | char senha[10]; | ||
+ | int userEncontrado=1; | ||
+ | int i; | ||
+ | |||
+ | |||
+ | /* | ||
+ | Loop para encontrar o usuário na tabela. | ||
+ | Ao final do loop a variavel i conterá o índice do usuário (se ele estiver | ||
+ | na tabela | ||
+ | */ | ||
+ | for (i=0;i<4 && userEncontrado; i++) { | ||
+ | if( strcmp(userID, TabelaUsuarios[i].UserId)==0) | ||
+ | userEncontrado=0; | ||
+ | } | ||
+ | |||
+ | /* se usuário encontrado abre a porta */ | ||
+ | if (userEncontrado==0) { | ||
+ | printf("Bom dia %s! Entre com a senha\n", userID); | ||
+ | scanf("%s",senha); | ||
+ | i--; /* o indice do sujeito é i-1 */ | ||
+ | if(strcmp(senha,TabelaUsuarios[i].Senha)==0) | ||
+ | printf("Abrir porta!!!\n"); | ||
+ | else | ||
+ | printf("Senha Inválida\n"); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void main() | ||
+ | { | ||
+ | for(;;) { | ||
+ | mostrar_menu_entrada_usuario(); | ||
+ | scanf("%s",userID); | ||
+ | if (strcmp(userID, "admin")==0) { | ||
+ | administrar(); | ||
+ | } else { | ||
+ | tratar_usuario(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | |||
+ | Exercício: | ||
+ | |||
+ | #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. | ||
+ | #Implementar uma funcionalidade do administrador para desbloquear o usuário bloqueado. | ||
+ | #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! | ||
+ | #Implementar na função administrar a inserção da mensagem no exercício anterior. | ||
+ | #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. | ||
+ | {{collapse top|Solução 1}} | ||
+ | <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 ****/ | ||
+ | |||
+ | struct TRegistroUsuario { | ||
+ | char UserId[10]; | ||
+ | char Senha[10]; | ||
+ | int contador; | ||
+ | }; | ||
+ | |||
+ | /* Tabela de Usuários */ | ||
+ | struct TRegistroUsuario TabelaUsuarios[4] = { | ||
+ | {"joao","abcd",0}, | ||
+ | {"maria","xxxx",0}, | ||
+ | {"jose","yyyy",0}, | ||
+ | {"lara","zzzz",0}, | ||
+ | }; | ||
+ | |||
+ | |||
+ | char userID[20]; | ||
+ | |||
+ | |||
+ | /** FUNÇÔES DESTE MÓDULO ****/ | ||
+ | |||
+ | void mostrar_menu_entrada_usuario() | ||
+ | { | ||
+ | printf("*******************************\n"); | ||
+ | printf("Entre com o seu USERID para ter acesso\n"); | ||
+ | printf("*******************************\n"); | ||
+ | } | ||
+ | |||
+ | /** Função que implementa as tarefas do administrador **/ | ||
+ | |||
+ | void administrar() | ||
+ | { | ||
+ | char aux_senha[10]; | ||
+ | int userEncontrado=1; | ||
+ | int i; | ||
+ | |||
+ | printf("Entre com a senha do admin \n"); | ||
+ | scanf ("%s", aux_senha); | ||
+ | |||
+ | if(strcmp(aux_senha,"123456")==0) { | ||
+ | /* senha valida do admin - agora entre com userid a ser desbloqueado */ | ||
+ | printf("Entre com userdID a ser desbloqueado\n"); | ||
+ | scanf("%s",userID); | ||
+ | for (i=0;i<4 && userEncontrado; i++) { | ||
+ | if( strcmp(userID, TabelaUsuarios[i].UserId)==0) | ||
+ | userEncontrado=0; | ||
+ | } | ||
+ | if (userEncontrado==0) { | ||
+ | i--; | ||
+ | TabelaUsuarios[i].contador=0; | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | |||
+ | /** Função que valida um usuário e abre a porta **/ | ||
+ | |||
+ | void tratar_usuario() | ||
+ | { | ||
+ | char senha[10]; | ||
+ | int userEncontrado=1; | ||
+ | int i; | ||
+ | |||
+ | |||
+ | /* | ||
+ | Loop para encontrar o usuário na tabela. | ||
+ | Ao final do loop a variavel i conterá o índice do usuário (se ele estiver | ||
+ | na tabela | ||
+ | */ | ||
+ | for (i=0;i<4 && userEncontrado; i++) { | ||
+ | if( strcmp(userID, TabelaUsuarios[i].UserId)==0) | ||
+ | userEncontrado=0; | ||
+ | } | ||
+ | |||
+ | /* se usuário encontrado abre a porta */ | ||
+ | if (userEncontrado==0) { | ||
+ | i--; /* o indice do sujeito é i-1 */ | ||
+ | if (TabelaUsuarios[i].contador<3){ | ||
+ | |||
+ | printf("Bom dia %s! Entre com a senha\n", userID); | ||
+ | scanf("%s",senha); | ||
+ | |||
+ | if(strcmp(senha,TabelaUsuarios[i].Senha)==0) { | ||
+ | printf("Abrir porta!!!\n"); | ||
+ | TabelaUsuarios[i].contador=0; | ||
+ | } | ||
+ | else { | ||
+ | TabelaUsuarios[i].contador++; | ||
+ | printf("Senha Inválida\n"); | ||
+ | printf("Tentativas restantes %d\n", 3-TabelaUsuarios[i].contador); | ||
+ | } | ||
+ | } else { | ||
+ | printf("Usuário bloqueado\n"); | ||
+ | } | ||
+ | } else { | ||
+ | printf("Usuário não encontrado\n"); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void main() | ||
+ | { | ||
+ | for(;;) { | ||
+ | mostrar_menu_entrada_usuario(); | ||
+ | scanf("%s",userID); | ||
+ | if (strcmp(userID, "admin")==0) { | ||
+ | administrar(); | ||
+ | } else { | ||
+ | tratar_usuario(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </syntaxhighlight>{{collapse bottom}} | ||
+ | |||
+ | {{collapse top|Solução 2}} | ||
+ | <syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | #include <string.h> | ||
+ | |||
+ | /**********************************************/ | ||
+ | /*** PROGRAMA DE CONTROLE DE ACESSO */ | ||
+ | /** Autores: Daniel Trevisan Tatsch */ | ||
+ | /** Ricardo Amorim */ | ||
+ | /**********************************************/ | ||
+ | |||
+ | /** VARIÁVEIS GLOBAIS DESTE MÓDULO ****/ | ||
+ | |||
+ | struct TRegistroUsuario { | ||
+ | char UserId[10]; | ||
+ | char Senha[10]; | ||
+ | int ativo; | ||
+ | }; | ||
+ | |||
+ | /* Tabela de Usuários */ | ||
+ | struct TRegistroUsuario TabelaUsuarios[4] = { | ||
+ | {"joao","abcd",1}, | ||
+ | {"maria","xxxx",1}, | ||
+ | {"jose","yyyy",1}, | ||
+ | {"lara","zzzz",1}, | ||
+ | }; | ||
+ | |||
+ | char userID[20]; | ||
+ | |||
+ | /** FUNÇÔES DESTE MÓDULO ****/ | ||
+ | |||
+ | void mostrar_menu_entrada_usuario() | ||
+ | { | ||
+ | printf("\n********************************************"); | ||
+ | printf("\nEntre com o seu USERID para ter acesso: "); | ||
+ | printf("\n********************************************\n"); | ||
+ | } | ||
+ | |||
+ | /** Função que implementa as tarefas do administrador **/ | ||
+ | |||
+ | void administrar() | ||
+ | { | ||
+ | int i; | ||
+ | for(i=0;i<4;i++) | ||
+ | TabelaUsuarios[i].ativo=1; | ||
+ | printf("\nTodos os usuários foram liberados!\n"); | ||
+ | } | ||
+ | |||
+ | /** Função que valida um usuário e abre a porta **/ | ||
+ | |||
+ | void tratar_usuario() | ||
+ | { | ||
+ | char senha[10]; | ||
+ | int userEncontrado=1; | ||
+ | int i, cont = 0; | ||
+ | |||
+ | /* | ||
+ | Loop para encontrar o usuário na tabela. | ||
+ | Ao final do loop a variavel i conterá o índice do usuário (se ele estiver | ||
+ | na tabela | ||
+ | */ | ||
+ | for (i=0;i<4 && userEncontrado; i++) { | ||
+ | if( strcmp(userID, TabelaUsuarios[i].UserId)==0) | ||
+ | userEncontrado=0; | ||
+ | } | ||
+ | |||
+ | if (userEncontrado==0) { // se usuário encontrado... | ||
+ | for(;;){ | ||
+ | if(TabelaUsuarios[i-1].ativo){ // se usuário ativo (1)... | ||
+ | printf("Bom dia %s! Entre com a senha\n", userID); | ||
+ | scanf("%s",senha); | ||
+ | if(strcmp(senha,TabelaUsuarios[i-1].Senha)==0){ // se senha confere (0)... | ||
+ | printf("Abrir porta!!!\n"); | ||
+ | cont=0; | ||
+ | break; | ||
+ | } else { | ||
+ | printf("Senha Inválida\n"); | ||
+ | cont++; | ||
+ | if(cont==3){ | ||
+ | printf("\nUsuário Bloqueado!\n"); | ||
+ | TabelaUsuarios[i-1].ativo = 0; | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | } else { | ||
+ | printf("\nUsuário Bloqueado!\n"); // usuario bloqueado ativo (0) | ||
+ | break; | ||
+ | } | ||
+ | } // fim do for(;;) | ||
+ | } else | ||
+ | printf("\nUsuário não encontrado!\n"); // se usuario nao encontrado. | ||
+ | } | ||
+ | |||
+ | void main() | ||
+ | { | ||
+ | for(;;) { | ||
+ | mostrar_menu_entrada_usuario(); | ||
+ | scanf("%s",userID); | ||
+ | if (strcmp(userID, "admin")==0) { | ||
+ | administrar(); | ||
+ | } else { | ||
+ | tratar_usuario(); | ||
+ | } | ||
+ | } | ||
+ | } | ||
+ | </syntaxhighlight>{{collapse bottom}} | ||
+ | |||
+ | =Exercícios com ''Structs''= | ||
+ | |||
+ | ==Desafio 1== | ||
+ | |||
+ | Implementar uma função ''converte_para_polar'' que recebe como parâmetro um número complexo na forma retangular (representado por uma ''struct''). A função deve retornar uma ''struct'' contendo o número complexo na forma polar.Usar as funções ''sqrtf'' e ''atanf'' da [[http://en.wikipedia.org/wiki/C_mathematical_functions matemáticas] biblioteca matemática]. [http://www.teacherschoice.com.au/maths_library/coordinates/polar_-_rectangular_conversion.htm Como converter]: | ||
+ | :<math> mod = \sqrt{x^2+y^2} </math> | ||
+ | :<math> \phi = \arctan \frac{y}{x} </math> ou <math> \phi = \tan^{-1} \frac{y}{x} </math> | ||
+ | |||
+ | '''NOTE''' que as funções atanf e similares retornam em RADIANOS. | ||
+ | |||
+ | {{collapse top|Solução}} | ||
+ | <syntaxhighlight lang=c> | ||
+ | #include <stdio.h> | ||
+ | #include <math.h> | ||
+ | |||
+ | struct tipo_ret { | ||
+ | float x; | ||
+ | float y; | ||
+ | }; | ||
+ | |||
+ | struct tipo_polar { | ||
+ | float mod; | ||
+ | float ang; | ||
+ | }; | ||
+ | |||
+ | |||
+ | /* Função para converter complexo retangular em polar */ | ||
+ | |||
+ | struct tipo_polar converter_ret_pol(struct tipo_ret num_ret) | ||
+ | { | ||
+ | struct tipo_polar num_polar; | ||
+ | float aux; | ||
+ | |||
+ | aux = num_ret.x*num_ret.x + num_ret.y*num_ret.y; | ||
+ | |||
+ | /* falta a lógica para detectar o quadrante */ | ||
+ | num_polar.mod = sqrtf(aux); | ||
+ | num_polar.ang = atanf(num_ret.y/num_ret.x); | ||
+ | return num_polar; | ||
+ | } | ||
+ | |||
+ | /* Função para imprimir complexo retangular */ | ||
+ | void imprimir_complexo_ret(struct tipo_ret num_ret) | ||
+ | { | ||
+ | printf("Coordenada x = %f", num_ret.x); | ||
+ | printf("Coordenada y = %f\n", num_ret.y); | ||
+ | } | ||
+ | |||
+ | /* Função para imprimir complexo retangular */ | ||
+ | void imprimir_complexto_pol(struct tipo_ret num_ret) | ||
+ | { | ||
+ | printf("Coordenada x = %f", num_ret.x); | ||
+ | printf("Coordenada y = %f\n", num_ret.y); | ||
+ | } | ||
+ | |||
+ | main() | ||
+ | { | ||
+ | struct tipo_ret num1; | ||
+ | struct tipo_polar num2; | ||
+ | |||
+ | num1.x = 5; | ||
+ | num1.y = 10; | ||
+ | num2 = converter_ret_pol (num1); | ||
+ | } | ||
+ | </syntaxhighlight> | ||
+ | {{collapse bottom}} | ||
+ | |||
+ | ==Desafio 2 == | ||
+ | |||
+ | Implementar uma função que some dois números complexos no formato ''retangular'' e retorne a soma como um complexo ''retangular''. | ||
+ | |||
+ | ==Desafio 3== | ||
+ | |||
+ | Implementar uma função que some dois números complexos no formato ''polar'' e retorna a soma no formato ''polar''. | ||
+ | |||
+ | |||
+ | |||
+ | |||
+ | =Referências= | ||
+ | |||
+ | [1] https://pt.wikibooks.org/wiki/Programar_em_C/Estruturas | ||
+ | |||
+ | |||
+ | |||
Edição das 15h26min de 17 de março de 2020
Objetivos
- Definição de estruturas;
- Estruturas como parâmetros;
- Inicialização de estruturas;
- Cópia de estruturas;
Estruturas
No C é possível criar tipos de dados que representam uma estrutura. Veja o exemplo seguinte
#include <stdio.h>
struct TUsuario /* struct TUsuario é o nome do tipo que está sendo criado */
{
char userID[20];
char senha[20];
} Usuario; /* aqui é definida uma variável do tipo struct TUsuario */
struct TUsuario TabelaUsuario[20];
main()
{
scanf("%s", Usuario.userID);
scanf("%s", Usuario.senha);
scanf("%s", TabelaUsuario[10].userID);
scanf("%s", TabelaUsuario[10].senha);
}
Neste exemplo, foi definido um tipo (modelo) para o registro (struct TUsuario) e foi criada uma variável chamada Usuario a partir deste tipo. Na sequência foi criada mais uma variável (um vetor de estruturas) chamada TabelaUsuario. Note que basta usar as palavras chave struct Usuario para criar novas variáveis. O tipo completo é definido uma única vez no início.
- Exercícios
- Criar um programa que define uma struct para armazenamento do nome e das notas bimestrais de um aluno. Atualizar a estrutura usando o scanf.
- Alterar o programa para que ele calcule e imprima a média de cada aluno.
Resposta |
---|
#include <stdio.h>
#define NUM_MAX 3
struct TAluno {
char nome[30];
char matricula[11];
float b1,b2,b3,b4;
} Turma[NUM_MAX];
void print_aluno(struct TAluno aux)
{
printf("Nome -> %s\n", aux.nome);
printf("Matrícula -> %s\n", aux.matricula);
printf("Bimestre 1 -> %f\n", aux.b1);
printf("Bimestre 2 -> %f\n", aux.b2);
printf("Bimestre 3 -> %f\n", aux.b3);
printf("Bimestre 4 -> %f\n", aux.b4);
}
main()
{
int i;
for(i=0;i<NUM_MAX;i++) {
printf("Entre com o nome do aluno\n");
scanf("%s", Turma[i].nome);
printf("Entre com a matrícula do aluno\n");
scanf("%s", Turma[i].matricula);
printf("Entre com a nota do bimestre 1\n");
scanf("%f", &Turma[i].b1);
printf("Entre com a nota do bimestre 2\n");
scanf("%f", &Turma[i].b2);
printf("Entre com a nota do bimestre 3\n");
scanf("%f", &Turma[i].b3);
printf("Entre com a nota do bimestre 4\n");
scanf("%f", &Turma[i].b4);
}
for(i=0;i<NUM_MAX;i++) {
printf("=========== Aluno %d ============\n", i);
print_aluno(Turma[i]);
}
}
|
Copiando structs
O exemplo a seguir demonstra como se pode copiar uma variável struct para outra do mesmo tipo.
#include <stdio.h>
struct THoras{
int hora;
int minuto;
int segundo;
};
struct THoras Ontem = {2,10,57};
void main()
{
struct THoras Hoje;
Hoje = Ontem;
printf("Hora hoje = %d, Minuto hoje = %d e Segundo hoje %d\n", Hoje.hora, Hoje.minuto, Hoje.segundo);
}
Estruturas dentro de estruturas
Vamos ver um exemplo com estruturas definidas dentro de estruturas:
#include <stdio.h>
struct TEndereco{
char rua[50];
char numero[10];
};
struct TCidadao{
char nome[50];
char cpf[20];
struct TEndereco endereco;
int num_filhos;
};
void main()
{
struct TCidadao Cidadao;
printf("Entre com o nome\n");
scanf ("%s",Cidadao.nome); // substitua por gets()
printf("Entre com o cpf\n");
scanf ("%s",Cidadao.cpf);
printf("Entre a rua\n");
scanf ("%s",Cidadao.endereco.rua); // substitua por gets()
printf("Entre a numero\n");
scanf ("%s",Cidadao.endereco.numero);
printf("Entre com o número de filhos\n");
scanf ("%d",&Cidadao.num_filhos);
}
Exercício 1: Faça um código adicional para imprimir o conteúdo lido na estrutura.
Resposta |
---|
#include <stdio.h>
struct TEndereco{
char rua[50];
char numero[10];
};
struct TCidadao{
char nome[50];
char cpf[20];
struct TEndereco endereco;
int num_filhos;
};
void print_endereco(struct TEndereco aux)
{
printf ("Rua %s Número %s\n", aux.rua, aux.numero);
}
void print_cidadao(struct TCidadao aux)
{
printf("Nome: %s CPF: %s ", aux.nome, aux.cpf);
print_endereco(aux.endereco);
printf("Numero de filhos %d\n", aux.num_filhos);
}
void main()
{
struct TCidadao Cidadao;
printf("Entre com o nome\n");
scanf ("%s",Cidadao.nome);
printf("Entre com o cpf\n");
scanf ("%s",Cidadao.cpf);
printf("Entre a rua\n");
scanf ("%s",Cidadao.endereco.rua);
printf("Entre a numero\n");
scanf ("%s",Cidadao.endereco.numero);
printf("Entre com o número de filhos\n");
scanf ("%d",&Cidadao.num_filhos);
}
|
Iniciando structs na definição
Como toda variável, é possível dar valores para uma variável do tipo struct definida no programa:
#include <stdio.h>
struct TEndereco{
char rua[50];
char numero[10];
};
struct TCidadao{
char nome[50];
char cpf[20];
struct TEndereco endereco;
int num_filhos;
};
void main()
{
struct TCidadao Cidadao = {"Maria",
"42342342234",
{"Rua AlfaBeta","145"},
5
};
printf("Rua do cidadao = %s\n", Cidadao.endereco.rua);
}
Passando estruturas como parâmetro e retornando estruturas
Se não for usado o operador "&" , um parâmetro que é estrutura será passado por cópia. Não apresentaremos agora a passagem por endereço pois necessita do conceito de ponteiro. Observe o exercício abaixo.
#include <stdio.h>
struct TEndereco{
char rua[50];
char numero[10];
};
struct TCidadao{
char nome[50];
char cpf[20];
struct TEndereco endereco;
int num_filhos;
};
void print_struct (struct TCidadao aux)
{
printf("nome=%s cpf=%s\n", aux.nome, aux.cpf);
printf("endereço inicial do aux %p\n", &aux);
}
void main()
{
struct TCidadao Cidadao;
printf("Entre com o nome\n");
scanf ("%s",Cidadao.nome);
printf("Entre com o cpf\n");
scanf ("%s",Cidadao.cpf);
printf("Entre a rua\n");
scanf ("%s",Cidadao.endereco.rua);
printf("Entre a numero\n");
scanf ("%s",Cidadao.endereco.numero);
printf("Entre com o número de filhos\n");
scanf ("%d",&Cidadao.num_filhos);
print_struct(Cidadao);
printf("endereço inicial do Cidadao %p\n", &Cidadao);
}
- O que podemos concluir com os endereços que foram mostrados??? Vamos a mais um exemplo.
#include <stdio.h>
struct TEndereco{
char rua[50];
char numero[10];
};
struct TCidadao{
char nome[50];
char cpf[20];
struct TEndereco endereco;
int num_filhos;
};
struct TCidadao ler_struct()
{
struct TCidadao aux;
printf("Entre com o nome\n");
scanf ("%s",aux.nome);
printf("Entre com o cpf\n");
scanf ("%s",aux.cpf);
printf("Entre a rua\n");
scanf ("%s",aux.endereco.rua);
printf("Entre a numero\n");
scanf ("%s",aux.endereco.numero);
printf("Entre com o número de filhos\n");
scanf ("%d",&aux.num_filhos);
return aux;
}
void print_struct (struct TCidadao aux)
{
printf("nome=%s cpf=%s\n", aux.nome, aux.cpf);
printf("endereço inicial do aux %p\n", &aux);
}
void main()
{
struct TCidadao Cidadao;
Cidadao = ler_struct();
print_struct(Cidadao);
printf("endereço inicial do Cidadao %p\n", &Cidadao);
}
Aplicação no Controle de Acesso
O exemplo a seguir implementa uma parte do programa de controle de acesso usando estruturas. Neste exemplo a tabela de usuários já vem inicializada nos campos UserID e Senha.
#include <stdio.h>
#include <string.h>
/**********************************************/
/*** PROGRAMA DE CONTROLE DE ACESSO **/
/** Autor: TurmaENG.TELECOM - 2012.2 */
/**********************************************/
/** VARIÁVEIS GLOBAIS DESTE MÓDULO ****/
struct TRegistroUsuario {
char UserId[10];
char Senha[10];
};
/* Tabela de Usuários */
struct TRegistroUsuario TabelaUsuarios[4] = {
{"joao","abcd"},
{"maria","xxxx"},
{"jose","yyyy"},
{"lara","zzzz"},
};
char userID[20];
/** FUNÇÔES DESTE MÓDULO ****/
void mostrar_menu_entrada_usuario()
{
printf("*******************************\n");
printf("Entre com o seu USERID para ter acesso\n");
printf("*******************************\n");
}
/** Função que implementa as tarefas do administrador **/
void administrar()
{
}
/** Função que valida um usuário e abre a porta **/
void tratar_usuario()
{
char senha[10];
int userEncontrado=1;
int i;
/*
Loop para encontrar o usuário na tabela.
Ao final do loop a variavel i conterá o índice do usuário (se ele estiver
na tabela
*/
for (i=0;i<4 && userEncontrado; i++) {
if( strcmp(userID, TabelaUsuarios[i].UserId)==0)
userEncontrado=0;
}
/* se usuário encontrado abre a porta */
if (userEncontrado==0) {
printf("Bom dia %s! Entre com a senha\n", userID);
scanf("%s",senha);
i--; /* o indice do sujeito é i-1 */
if(strcmp(senha,TabelaUsuarios[i].Senha)==0)
printf("Abrir porta!!!\n");
else
printf("Senha Inválida\n");
}
}
void main()
{
for(;;) {
mostrar_menu_entrada_usuario();
scanf("%s",userID);
if (strcmp(userID, "admin")==0) {
administrar();
} else {
tratar_usuario();
}
}
}
Exercício:
- 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.
- Implementar uma funcionalidade do administrador para desbloquear o usuário bloqueado.
- 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!
- Implementar na função administrar a inserção da mensagem no exercício anterior.
- 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.
Solução 1 | ||||
---|---|---|---|---|
#include <stdio.h>
#include <string.h>
/**********************************************/
/*** PROGRAMA DE CONTROLE DE ACESSO **/
/** Autor: Turma ENG.TELECOM - 2013.1 */
/**********************************************/
/** VARIÁVEIS GLOBAIS DESTE MÓDULO ****/
struct TRegistroUsuario {
char UserId[10];
char Senha[10];
int contador;
};
/* Tabela de Usuários */
struct TRegistroUsuario TabelaUsuarios[4] = {
{"joao","abcd",0},
{"maria","xxxx",0},
{"jose","yyyy",0},
{"lara","zzzz",0},
};
char userID[20];
/** FUNÇÔES DESTE MÓDULO ****/
void mostrar_menu_entrada_usuario()
{
printf("*******************************\n");
printf("Entre com o seu USERID para ter acesso\n");
printf("*******************************\n");
}
/** Função que implementa as tarefas do administrador **/
void administrar()
{
char aux_senha[10];
int userEncontrado=1;
int i;
printf("Entre com a senha do admin \n");
scanf ("%s", aux_senha);
if(strcmp(aux_senha,"123456")==0) {
/* senha valida do admin - agora entre com userid a ser desbloqueado */
printf("Entre com userdID a ser desbloqueado\n");
scanf("%s",userID);
for (i=0;i<4 && userEncontrado; i++) {
if( strcmp(userID, TabelaUsuarios[i].UserId)==0)
userEncontrado=0;
}
if (userEncontrado==0) {
i--;
TabelaUsuarios[i].contador=0;
}
}
}
/** Função que valida um usuário e abre a porta **/
void tratar_usuario()
{
char senha[10];
int userEncontrado=1;
int i;
/*
Loop para encontrar o usuário na tabela.
Ao final do loop a variavel i conterá o índice do usuário (se ele estiver
na tabela
*/
for (i=0;i<4 && userEncontrado; i++) {
if( strcmp(userID, TabelaUsuarios[i].UserId)==0)
userEncontrado=0;
}
/* se usuário encontrado abre a porta */
if (userEncontrado==0) {
i--; /* o indice do sujeito é i-1 */
if (TabelaUsuarios[i].contador<3){
printf("Bom dia %s! Entre com a senha\n", userID);
scanf("%s",senha);
if(strcmp(senha,TabelaUsuarios[i].Senha)==0) {
printf("Abrir porta!!!\n");
TabelaUsuarios[i].contador=0;
}
else {
TabelaUsuarios[i].contador++;
printf("Senha Inválida\n");
printf("Tentativas restantes %d\n", 3-TabelaUsuarios[i].contador);
}
} else {
printf("Usuário bloqueado\n");
}
} else {
printf("Usuário não encontrado\n");
}
}
void main()
{
for(;;) {
mostrar_menu_entrada_usuario();
scanf("%s",userID);
if (strcmp(userID, "admin")==0) {
administrar();
} else {
tratar_usuario();
}
}
}
|