240 likes | 332 Views
Linguagem de programação I A. Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação. Versão: 180614_01. Estrutura de Dados Compostos (Structs) e Unions. Definição. Uma estrutura ( struct ) ou registro em C é uma coleção de um ou mais valores, agrupados sob um único nome.
E N D
Linguagem de programação I A Carlos Oberdan Rolim Ciência da Computação Sistemas de Informação Versão: 180614_01
Estrutura de Dados Compostos (Structs) e Unions
Definição • Uma estrutura (struct) ou registro em C é uma coleção de um ou mais valores, agrupados sob um único nome. • Estruturas constituem um recurso importante para organizar os dados utilizados por um programa graças à possibilidade de tratar um grupo de valores como uma única variável
Estruturas anônimas • O exemplo abaixo cria uma estrutura chamada de estrutura anônima. Esse tipo de estrutura não pode ser referenciada em outras partes do programa. struct { int dia; int mes ; int ano;} hoje; • Serve somente para declaração de variáveis do tipo da estrutura • Não será possível declarar outras variáveis do mesmo tipo da variável hoje • Para resolver isso deve-se declarar estruturas usando rótulos
Exemplo de criação de estrutura rotulada struct ponto { int x; int y;};struct funcionario { int registro; char nome[30]; char depto[5]; float salario;}; • As variáveis variáveis que fazem parte de uma estrutura são denominadas membros e são identificadas por nomes O rótulo dessas estruturas são ponto e funcionario e usa-se eles para declaração de variáveis
Exemplo de uso • As declarações de ponto e funcionario, definem os respectivos tipos de dados, que podem ser utilizados em declarações de variáveis. Exemplos:struct ponto p1, p2, p3; struct funcionario Joao; • Na primeira declaração, estão sendo declaradas as variáveis p1, p2 e p3 do tipo ponto. Na segunda declaração, é declarada a variável Joao do tipo funcionário.
Exemplo de uso • Para uma variável do tipo ponto, dizemos que x e y são seus campos ou membros. Os campos de uma variável podem ser acessados individualmente como variáveis usando-se o nome da variável seguido de "." e o nome do campo. Exemplos:p1.x = 10;p1.y = 20;p2.x = p1.x + 5;p2.y = p2.y + 5; • Além disso, é possível atribuir a uma estrutura o valor de outra estrutura do mesmo tipo. Exemplos:funcionario f = Joao;p3 = p2;
Estruturas complexas • Os campos de uma estrutura podem ser de qualquer tipo: tipos simples (int, char, float, etc), vetores, ou até mesmo estruturas. Exemplo: struct retangulo { struct ponto pa; struct ponto pb;}
Declaração com valores iniciais • Ao declararmos uma estrutura, podemos também definir o seu valor inicial, de forma análoga a aquela utilizada para vetores. Exemplos: struct ponto origem = {0,0};...struct ponto trapezio[] = { { 5,5}, {5, 10}, {10,5}, {10,13} };...
Exemplo de programa usando estruturas #include <conio.h>#include <stdio.h> // uma estrutura Pessoastruct Pessoa{ char *nome; int idade;}; int main() { // declara uma variável do tipo structstruct Pessoa cliente; cliente.nome = "Osmar J. Silva“; cliente.idade = 36; // obtém os dados printf("O nome do cliente e: %s\n", cliente.nome); printf("A idade do cliente e: %d\n", cliente.idade); return 0; }
Estruturas rotuladas e nomeadas • É possível criar um tipo baseado em uma estrutura • Para isso utiliza-se typedef na declaração struct tipo_data{ int dia, mes, ano; }; typedef struct tipo_data DATA; • Para criar uma estrutura rotulada e nomeada pode-se usar typedef struct tipo_data{ int dia, mes, ano; } DATA; ATENÇÃO: DATA é o nome to tipo Agora pode ser declarada uma variável dessa forma DATA d; Não existe mais a necessidade de structtipo_data d; Forma mais comum de declarar
Funções e structs • Passagem de uma struct como parâmetro para função struct data{int dia;int mês; int ano;}; void imprime(struct data d) { printf(“%d - %d - %d d->dia, d->mes, d->ano); } Intmain(){ struct data d; d->dia =10; d->mês = 12; d->ano = 1500; imprime(d);.... }
Funções e structs • Retorno de uma struct a partir de uma função struct tamanho{int t;}; struct tamanho define(int valor){ struct tamanho a; a.t = valor; return a; } Intmain(){ struct tamanho a; a = define( 10 ); a recebe a struct resultante da função printf(“%d”, a->t); vai imprimir 10 ....
Funções e structs – Uso de ponteiros struct data{ int dia; int mês; int ano;}; • Definindo uma variável do tipo datastruct data dt; • Definindo um ponteiro para dtstruct data *pdt=&dt; • Fazendo referência a um elemento da estruturadt.dia ou (*pdt).dia ou pdt->diadt.mes ou (*pdt).mes ou pdt->mêsdt.ano ou (*pdt).ano ou pdt->ano
Funções e structs – Passagem por referencia • Uma estrutura pode ser passada como parâmetro por referência numa função. Quando se usa uma referência (ponteiro), o acesso aos campos da mesma é feito através do operador “->” (seta) ao invés de “.” (ponto). Exemplo:void moveP(struct ponto* p, int dx, int dy){ p -> x += dx; p -> y += dy;}... Observe o uso de -> ao invés de .
Alocação dinâmica de estruturas • A alocação dinâmica de uma struct é feita exatamente igual ao demais tipos • Única diferença é usar o sizeof adequando-o para o tipo struct • E fazer o casting para um ponteiro para o tipo struct • Exemplo no próximo slide
#include <stdio.h> typedef struct tipo_data{ int dia, mes, ano; } DATA; int main (void) { DATA *d; d = (DATA *) malloc (sizeof (DATA)); d->dia = 31; d->mes = 12; d->ano = 2008; /* ou scanf("%d%d%d", &d->dia, &d->mes, &d->ano); */ printf("Data: %d / %d / %d \n", d->dia, d->mes, d->ano); free(d); return 0; }
Union • Uma union determina uma única localização de memória onde podem estar armazenadas várias variáveis diferentes. A declaração de uma união é semelhante à declaração de uma estrutura:unionnome_do_tipo_da_union{ tipo_1 nome_1; tipo_2 nome_2; ...tipo_nnome_n; } variáveis_union;
Union • Exemplo union angulo { float graus; float radianos; }; As variaveis graus e radianos que, apesar de terem nomes diferentes, ocupam o mesmo local da memória. Isto quer dizer que só gastamos o espaço equivalente a um único float.
#include <stdio.h>#define GRAUS 'G'#define RAD 'R'union angulo { int graus; float radianos; };void main(){union angulo ang; char op; printf("\nNumeros em graus ou radianos? "); scanf("%c",&op); if (op == GRAUS) { ang.graus = 180;printf("\nAngulo: %d\n",ang.graus); }else if (op == RAD) {ang.radianos = 3.1415; printf("\nAngulo: %f\n",ang.radianos); }else printf("\nEntrada invalida!!\n");} Exemplo de uso de union
#include <stdio.h> union numero { char Ch; int I; float F; };main (void) { union numero N; N.graus = 123; printf ("%f",N.F); return 0; } CUIDADO!!!!! O programa acima é muito perigoso pois você está lendo uma região da memória, que foi "gravada" como um inteiro, como se fosse um ponto flutuante. Tome cuidado! O resultado pode não fazer sentido.
Enumerações • Numa enumeração podemos dizer ao compilador quais os valores que uma determinada variável pode assumir. Sua forma geral é: enumnome_do_tipo_da_enumeração {lista_de_valores} lista_de_variáveis; • Vamos considerar o seguinte exemplo: enumdias_da_semana {segunda, terca, quarta, quinta, sexta,sabado, domingo}; O programador diz ao compilador que qualquer variável do tipodias_da_semana só pode ter os valores enumerados
#include <stdio.h> enum dias_da_semana {segunda, terca, quarta, quinta, sexta, sabado, domingo}; main (void) { enum dias_da_semana d1,d2; d1=segunda; d2=sexta; if (d1==d2) { printf ("O dia e o mesmo."); } else { printf ("São dias diferentes."); } return 0; } O compilador pega a lista de valores e associa, a cada um, um número inteiro. Então, ao primeiro da lista, é associado o número zero, o segundo ao número 1 e assim por diante. As variáveis declaradas são então variáveis int.
Enumerações • Pode-se criar um enum com valores incrementados com valores iniciais diferentes de zero • Exemplo: enum { ARGENTINA = 3, ITALIA, BRASIL }; Aqui Italia = 4 e Brasil = 5