Diferenças
Aqui você vê as diferenças entre duas revisões dessa página.
Ambos lados da revisão anterior Revisão anterior Próxima revisão | Revisão anterior | ||
c:estruturas [2023/08/15 14:28] – maziero | c:estruturas [2024/09/19 20:34] (atual) – maziero | ||
---|---|---|---|
Linha 1: | Linha 1: | ||
+ | ====== Estruturas ====== | ||
+ | |||
+ | As estruturas (// | ||
+ | |||
+ | Estruturas são geralmente utilizadas para agrupar variáveis correlatas, ou seja, que fazem parte de um mesmo conceito lógico. Por exemplo: Uma estrutura pode representar um paciente em uma aplicação médica e conter todos os dados relativos a ele. | ||
+ | |||
+ | Uma estrutura é definida através da palavra reservada '' | ||
+ | |||
+ | <code c> | ||
+ | struct <nome da estrutura> | ||
+ | { | ||
+ | type variable ; | ||
+ | type variable ; | ||
+ | ... | ||
+ | } ; | ||
+ | </ | ||
+ | |||
+ | <note important> | ||
+ | Uma estrutura define um novo **tipo de dado**, mas não cria/aloca variáveis desse tipo. Variáveis desse tipo devem ser declaradas posteriormente. | ||
+ | </ | ||
+ | |||
+ | A declaração e manipulação de variáveis desse novo tipo é simples: | ||
+ | |||
+ | <code c struct1.c> | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | struct paciente_t | ||
+ | { | ||
+ | char nome[100] ; | ||
+ | short idade ; | ||
+ | short quarto ; | ||
+ | } ; | ||
+ | |||
+ | int main () | ||
+ | { | ||
+ | // declaração/ | ||
+ | struct paciente_t pac1, pac2 ; | ||
+ | |||
+ | // atribuição de valor aos campos | ||
+ | pac1.idade = 53 ; | ||
+ | pac1.quarto = 417 ; | ||
+ | |||
+ | // uso como parâmetro | ||
+ | strcpy (pac1.nome, "Homer Simpson" | ||
+ | |||
+ | // atribuição de structs (o conteúdo é copiado) | ||
+ | pac2 = pac1 ; | ||
+ | |||
+ | // uso dos valores dos campos | ||
+ | printf (" | ||
+ | pac1.nome, pac1.idade, pac1.quarto) ; | ||
+ | printf (" | ||
+ | pac2.nome, pac2.idade, pac2.quarto) ; | ||
+ | |||
+ | return (0) ; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== Atribuição de structs ===== | ||
+ | |||
+ | Valores de tipo '' | ||
+ | |||
+ | As seguintes operações com estruturas são perfeitamente válidas (e muito úteis): | ||
+ | |||
+ | <code c struct2.c> | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | struct paciente_t | ||
+ | { | ||
+ | char nome[100] ; | ||
+ | short idade ; | ||
+ | short quarto ; | ||
+ | } ; | ||
+ | |||
+ | // imprime na tela os dados do paciente | ||
+ | void imprime_paciente (struct paciente_t p) | ||
+ | { | ||
+ | printf (" | ||
+ | } | ||
+ | |||
+ | // devolve um paciente " | ||
+ | struct paciente_t paciente_nulo () | ||
+ | { | ||
+ | struct paciente_t p = {" | ||
+ | return (p) ; | ||
+ | } | ||
+ | |||
+ | int main () | ||
+ | { | ||
+ | // declaração de variável com valor inicial | ||
+ | struct paciente_t pac1 = { "Home Simpson", | ||
+ | |||
+ | // cópia de struct | ||
+ | struct paciente_t pac2 = pac1 ; | ||
+ | |||
+ | // struct como parâmetro de função (passagem por cópia) | ||
+ | imprime_paciente (pac2) ; | ||
+ | |||
+ | // struct como retorno de função | ||
+ | pac2 = paciente_nulo () ; | ||
+ | imprime_paciente (pac2) ; | ||
+ | |||
+ | return (0) ; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | |||
+ | ===== Structs e vetores ===== | ||
+ | |||
+ | O uso de vetores de //structs// permite criar estruturas de dados sofisticadas, | ||
+ | |||
+ | <code c> | ||
+ | #define VECSIZE 1000 | ||
+ | |||
+ | struct paciente_t | ||
+ | { | ||
+ | char nome[100] ; | ||
+ | short idade ; | ||
+ | short quarto ; | ||
+ | } ; | ||
+ | |||
+ | // declaração/ | ||
+ | struct paciente_t paciente[VECSIZE] ; // vetor com VECSIZE pacientes | ||
+ | |||
+ | // inicializa vetor | ||
+ | for (i = 0; i < VECSIZE; i++) | ||
+ | { | ||
+ | strcpy (paciente[i].nome, | ||
+ | paciente[i].idade | ||
+ | paciente[i].quarto = 0 ; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | ===== Structs e ponteiros ===== | ||
+ | |||
+ | Uma variável de tipo //struct// é alocada na memória da mesma forma que as demais variáveis, então é possível obter o endereço da variável usando o operador ''&'' | ||
+ | |||
+ | <code c struct-ptr.c> | ||
+ | #include < | ||
+ | #include < | ||
+ | |||
+ | struct paciente_t | ||
+ | { | ||
+ | char nome[100] ; | ||
+ | short idade ; | ||
+ | short quarto ; | ||
+ | } ; | ||
+ | |||
+ | int main () | ||
+ | { | ||
+ | // declaração/ | ||
+ | struct paciente_t pac, *ptr ; | ||
+ | |||
+ | // atribuição de valor aos campos | ||
+ | pac.idade = 53 ; | ||
+ | pac.quarto = 417 ; | ||
+ | strcpy (pac.nome, "Homer Simpson" | ||
+ | |||
+ | // atribuição do ponteiro | ||
+ | ptr = &pac ; | ||
+ | |||
+ | // acesso pela variável struct | ||
+ | printf (" | ||
+ | pac.nome, pac.idade, pac.quarto) ; | ||
+ | |||
+ | // acesso pelo ponteiro | ||
+ | printf (" | ||
+ | (*ptr).nome, | ||
+ | |||
+ | return (0) ; | ||
+ | } | ||
+ | </ | ||
+ | |||
+ | <note tip> | ||
+ | A especificação de C garante que os campos internos de um //struct// são alocados na ordem em que foram definidos, e na área alocada não há outras informações além dos próprios campos. Assim, o endereço de uma variável de tipo //struct// coincide com o endereço de seu primeiro campo. | ||
+ | </ | ||
+ | |||
+ | O acesso ao campo interno do //struct// feito através do desreferenciamento do ponteiro também pode ser feito através do operador // | ||
+ | |||
+ | <code c> | ||
+ | (*ptr).idade = 45 ; | ||
+ | ptr-> | ||
+ | </ | ||
+ | |||
+ | O uso conjunto de //structs// e ponteiros permite construir estruturas de dados complexas, como filas, pilhas, árvores e grafos. Por exemplo, podemos definir um elemento de uma fila de inteiros da seguinte forma: | ||
+ | |||
+ | <code c> | ||
+ | struct filaInt_t | ||
+ | { | ||
+ | int valor ; | ||
+ | struct filaInt_t *prox ; | ||
+ | } ; | ||
+ | |||
+ | // ponteiro para o início de uma fila | ||
+ | struct filaInt_t *fila1 ; | ||
+ | </ | ||
+ | |||
+ | O ponteiro '' | ||
+ | |||
+ | {{ fila.png | ||
+ | |||
+ | O código que constrói essa estrutura é o seguinte (simplificado, | ||
+ | |||
+ | <code c> | ||
+ | fila1 = malloc (sizeof (struct filaInt_t)) ; | ||
+ | |||
+ | fila1-> | ||
+ | fila1-> | ||
+ | |||
+ | fila1-> | ||
+ | fila1-> | ||
+ | |||
+ | fila1-> | ||
+ | fila1-> | ||
+ | </ | ||
+ | |||
+ | ===== Exercícios ===== | ||
+ | |||
+ | - Escrever um programa em C para gerenciar uma relação de alunos, implementada como um vetor de //structs// de tipo '' | ||
+ | - ler os dados de um aluno (nome, idade, GRR, curso), devolvendo os campos lidos como um //struct//; | ||
+ | - imprimir os dados de um aluno a partir de seu //struct//; | ||
+ | - imprimir a relação de alunos; | ||
+ | - imprimir os nomes dos alunos com idade acima de 22 anos; | ||
+ | - ordenar a relação de alunos por idade; | ||
+ | - ordenar a relação de alunos por nome. | ||
+ | - escreva um programa em C para manipular datas e horários: | ||
+ | - //structs// do tipo '' | ||
+ | - //structs// do tipo '' | ||
+ | - //structs// do tipo '' | ||
+ | - a função '' | ||
+ | - a função '' | ||
+ | - a função '' | ||
+ | - as funções '' | ||
+ | - a função '' | ||
+ | - a função '' | ||
+ | - a função '' | ||
+ | - a função '' | ||
+ | - a função '' | ||