Estruturas

2.293 visualizações

Publicada em

Matéria relacionada com Estruturas em C.
Disciplina: programação.

Publicada em: Educação, Tecnologia, Negócios
0 comentários
1 gostou
Estatísticas
Notas
  • Seja o primeiro a comentar

Sem downloads
Visualizações
Visualizações totais
2.293
No SlideShare
0
A partir de incorporações
0
Número de incorporações
14
Ações
Compartilhamentos
0
Downloads
141
Comentários
0
Gostaram
1
Incorporações 0
Nenhuma incorporação

Nenhuma nota no slide

Estruturas

  1. 1. Escola Secundária da Batalha Estruturas em C Miguela Fernandes
  2. 2. Estruturas <ul><li>Struct são colecções de dados heterogêneos agrupados em uma mesma estrutura de dados </li></ul><ul><li>Ex: </li></ul><ul><ul><li>armazenas as coordenadas (x,y) de um ponto: </li></ul></ul>
  3. 3. <ul><li>Tipos Complexos </li></ul><ul><ul><li>Tipos básicos : char , int , float , etc. </li></ul></ul><ul><ul><ul><li>Variáveis guardam um só valor. </li></ul></ul></ul><ul><ul><li>Matrizes : v.g. char matriz[20] </li></ul></ul><ul><ul><ul><li>Variáveis guardam colecções de objectos do mesmo tipo. </li></ul></ul></ul><ul><li>  </li></ul><ul><li>          Como guardar colecções de tipos diversos? </li></ul>
  4. 4. Solução: Estruturas <ul><li>Declaração: </li></ul><ul><li>struct { </li></ul><ul><li> int x; </li></ul><ul><li> int y; </li></ul><ul><li>} p1, p2; </li></ul><ul><li>a estrutura contém dois inteiros, x e y </li></ul><ul><li>p1 e p2 são duas variáveis tipo struct contendo duas coordenadas cada. </li></ul>
  5. 5. Estruturas <ul><li>Exemplo: </li></ul><ul><li>struct { </li></ul><ul><ul><li>char nome[NOME_MAX + 1]; </li></ul></ul><ul><ul><li>int numero; </li></ul></ul><ul><ul><li>double media; </li></ul></ul><ul><ul><li>} aluno1, aluno2; </li></ul></ul><ul><li>Informação diversa sobre uma única entidade (um aluno). </li></ul><ul><li>Podem conter matrizes (e vice-versa). </li></ul><ul><li>Podem conter outras estruturas. </li></ul>
  6. 6. Declaração <ul><li>Formato da declaração: </li></ul><ul><li>struct nome_da_estrutura { </li></ul><ul><li>tipo_1 dado_1; </li></ul><ul><li>tipo_2 dado_2; </li></ul><ul><li>... </li></ul><ul><li>tipo_n dado_n; </li></ul><ul><li>} lista_de_variaveis; </li></ul><ul><li>A estrutura pode agrupar um número arbitrário de dados de tipos diferentes </li></ul><ul><li>Pode nomear-se a estrutura para referenciá-la </li></ul>
  7. 7. Definição de Tipos <ul><li>struct { </li></ul><ul><li> int x; </li></ul><ul><li> int y; </li></ul><ul><li>} p1; </li></ul><ul><li>struct { </li></ul><ul><li> int x; </li></ul><ul><li> int y; </li></ul><ul><li>} p2; </li></ul>struct ponto { int x; int y; }; struct ponto p1, p2; Repetição <ul><li>struct ponto define um novo tipo de dado </li></ul><ul><li>Pode definir-se novas variáveis do tipo ponto </li></ul>
  8. 8. Definição de Tipos (declaração de variáveis)  Novo tipo: struct Aluno  Definição de variáveis: struct Aluno aluno1 , aluno2,*p, lista[10] ; struct Aluno { char nome [NOME_MAX + 1]; int numero ; double media ; }; Equivalente a: struct { char nome [NOME_MAX + 1]; int numero ; double media ; }aluno1,aluno2,*p, lista[10];
  9. 9. Inicialização <ul><li>struct Aluno { </li></ul><ul><li>char nome[NOME_MAX + 1]; </li></ul><ul><li>int numero; </li></ul><ul><li>double media;}; </li></ul><ul><li>struct Aluno aluno = {&quot;Zacarias&quot;, 666, 20.0}; </li></ul>aluno nome: numero: media:
  10. 10. Acesso aos dados struct-var.campo Exemplo : aluno1.nome = “Pedro”;/*atribuição */ aluno2.nome = “João; if ((aluno1.nome == aluno2.nome) && (aluno1.media >= aluno2.media)) ...
  11. 11. Inicialização de estruturas struct Aluno { char nome[NOME_MAX + 1]; int numero; double media;}; struct Aluno aluno = {&quot;Zacarias&quot;, 666, 20.0}; Equivalente a: struct Aluno aluno; strcpy(aluno.nome,&quot;Zacarias&quot;); aluno.numero = 666; aluno.media = 20.0; aluno nome: numero: media: Z a c a r i as 666 20.0
  12. 12. Atribuição de Estruturas <ul><li>Revisão : </li></ul><ul><li>Inicialização de uma estrutura: </li></ul><ul><li>struct ponto p1 = { 220, 110 }; </li></ul><ul><li>Atribuição entre estruturas do mesmo tipo : </li></ul><ul><li>struct ponto p1 = { 220, 110 }; </li></ul><ul><li>struct ponto p2; </li></ul><ul><li>p2 = p1; /* p2.x = p1.x e p2.y = p1.y */ </li></ul><ul><li>Os campos correspondentes das estruturas são automaticamente copiados do destino para a origem </li></ul>p2 = p1 p1 x: y: 220 110 p2 x: y: p2 x: y: 220 110
  13. 13. Atribuição de Estruturas <ul><li>Atenção para estruturas que contenham ponteiros : </li></ul><ul><li>struct aluno { </li></ul><ul><li>char *nome; </li></ul><ul><li>int idade; </li></ul><ul><li>} a1, a2; </li></ul><ul><li>a1.nome = “Afonso”; </li></ul><ul><li>a1.idade = 32; </li></ul><ul><li>a2 = a1; </li></ul><ul><li>Agora a1 e a2 apontam para a mesma string nome: </li></ul><ul><li>a1.nome == a2.nome == “Afonso” </li></ul>
  14. 14. Composição de Estruturas <ul><li>struct retangulo { </li></ul><ul><li> struct ponto inicio; </li></ul><ul><li> struct ponto fim; </li></ul><ul><li>}; </li></ul><ul><li>struct retangulo r = { { 10, 20 }, </li></ul><ul><li>{ 30 , 40 } </li></ul><ul><li>}; </li></ul><ul><li>Acesso aos dados: </li></ul><ul><li>r.inicio.x += 10; </li></ul><ul><li>r.inicio.y -= 10; </li></ul>r inicio x: y: 10 20 fim x: y: 30 40
  15. 15. Estruturas como parâmetros <ul><li>struct ponto cria_ponto ( int x, int y) { </li></ul><ul><li>struct ponto tmp; </li></ul><ul><li>tmp.x = x; </li></ul><ul><li>tmp.y = y; </li></ul><ul><li>return tmp; </li></ul><ul><li>} </li></ul><ul><li>main () { </li></ul><ul><li>struct ponto p = cria_ponto(10, 20); </li></ul><ul><li>} </li></ul>p x: y: 10 20 p x: y:
  16. 16. Operações <ul><li>Operações entre membros das estruturas devem ser feitas membro a membro: </li></ul><ul><li>/* retorna uma cópia de p1 = p1 + p2 */ </li></ul><ul><li>struct soma_pts ( struct ponto p1, struct ponto p2) </li></ul><ul><li>{ </li></ul><ul><li> p1.x += p2.x; (relembro que p1.x = p1.x +p2.x) </li></ul><ul><li> p1.y += p2.y; </li></ul><ul><li> return p1; /* retorna uma copia de p1 */ </li></ul><ul><li>} </li></ul>
  17. 17. Arrays de Estruturas struct ponto arp[10]; /* cria um array de 10 pontos */ arp[1].x = 5; /*atribui 5 a coordenada x do 2º ponto */ struct jogador { char *nome; int idade; }; struct jogador PT[4] = {“Figo”,32, “ Carlos”, 24, “ Rui Costa”,27 ...}; PT nome: idade: Figo 32 nome: idade: Carlos 24 nome: idade: Rui Costa 27 nome: idade: ... ...
  18. 18. Ponteiros para Estruturas <ul><li>Estruturas grandes são passadas como parâmetro </li></ul><ul><li>De forma mais eficiente através de ponteiros </li></ul><ul><li>struct ponto *pp; </li></ul><ul><li>struct ponto p1 = { 10, 20 }; </li></ul><ul><li>pp = &p1; </li></ul><ul><li>printf(“Ponto P1: (%d %d) ”, (*pp).x, (*pp).y}; </li></ul><ul><li>Aceder com o operador “->”: </li></ul><ul><li>printf(“Ponto P1: (%d %d) ”, pp->x, pp->y}; </li></ul><ul><li>(*pp).x == pp->x </li></ul>pp 1002 p1 x: y: 1002 10 20
  19. 19. Espaço Alocado para uma Estrutura <ul><li>struct aluno { </li></ul><ul><li>char *nome; /* ponteiro 4 bytes */ </li></ul><ul><li>short idade; /* 2 bytes */ </li></ul><ul><li>char matricula[8]; /* array 8 bytes */ </li></ul><ul><li>}; </li></ul><ul><li>struct aluno al; </li></ul><ul><li>al.nome = “Xexeo”; </li></ul><ul><li>al.idade = 30; </li></ul><ul><li>strcpy(al.matricula, “00/0001”); </li></ul>
  20. 20. Função sizeof(tipo) <ul><li>A função sizeof(tipo) retorna o tamanho em bytes ocupado na memória pelo tipo de dado passado como parâmetro </li></ul><ul><li>Ex: </li></ul><ul><li>sizeof(int) => 4 bytes </li></ul><ul><li>sizeof(char) => 1 byte </li></ul><ul><li>sizeof(struct ponto) => 8 bytes </li></ul><ul><li>sizeof(struct ponto *) => 4 bytes </li></ul>
  21. 21. Espaço Efectivo <ul><li>/* teste com Symantec C, PowerPC 603 - Macintosh */ </li></ul><ul><li>struct aluno { </li></ul><ul><li> char *nome; /* 4 bytes */ </li></ul><ul><li> short idade; /* 2 bytes */ </li></ul><ul><li> char matricula[3]; /* 3 bytes */ </li></ul><ul><li>}; /* sizeof(aluno) = 12 bytes */ </li></ul>
  22. 22. Espaço Efectivo <ul><li>/* teste com Symantec C, PowerPC 603 - Macintosh */ </li></ul><ul><li>struct aluno1 { </li></ul><ul><li>char *nome; /* 4 bytes */ </li></ul><ul><li>short idade; /* 2 bytes */ </li></ul><ul><li>char matricula[5]; /* 5 bytes */ </li></ul><ul><li>}; </li></ul><ul><li>/* sizeof(aluno1) = 12 bytes */ </li></ul>
  23. 23. Espaço Efectivo <ul><li>/* teste com Symantec C, PowerPC 603 - Macintosh */ </li></ul><ul><li>struct aluno2 { </li></ul><ul><li>char *nome; /* 4 bytes */ </li></ul><ul><li>short idade; /* 2 bytes */ </li></ul><ul><li>char matricula[7]; /* 7 bytes */ </li></ul><ul><li>}; </li></ul><ul><li>/* sizeof(aluno2) = 16 bytes */ </li></ul><ul><li>no PowerMac uma estrutura é um múltipo do tamanho da palavra, 32 bits </li></ul>
  24. 24. Alocação Dinâmica de Memória <ul><li>incluir a biblioteca standard do C: stdlib.h (malloc() e free()) </li></ul><ul><li>possibilidade de libertar memória à medida que deixa de ser precisa </li></ul><ul><li>as funções calloc e malloc permitem alocar blocos de memória em tempo de execução </li></ul><ul><li>void * malloc( ); </li></ul><ul><li>/* </li></ul><ul><li>retorna um ponteiro void para n bytes de memória não iniciados. Se não há memória disponível malloc retorna NULL </li></ul><ul><li>*/ </li></ul>número de bytes alocados size_t n
  25. 25. Alocação Dinâmica de Memória <ul><li>A função malloc () ( memory allocation ) </li></ul><ul><li>reserva uma porção de memória, retornando um apontador genérico (tipo void *) para o ínicio da porção reservada, ou o valor NULL no caso da reserva ser impossível </li></ul><ul><li>A sua utilização é representada no exemplo seguinte: </li></ul><ul><li>int *pi; </li></ul><ul><li>pi= ( int *) malloc (sizeof( int )); </li></ul><ul><li>/* aloca espaço para um inteiro */ </li></ul>
  26. 26. malloc () – exemplo <ul><li>float *v; </li></ul><ul><li>int n; </li></ul><ul><li>printf(&quot;Quantos valores? &quot;); </li></ul><ul><li>scanf(&quot;%d&quot;, n); </li></ul><ul><li>v = (float *) malloc(n * sizeof(float) ); </li></ul><ul><li>Neste exemplo, é reservada uma porção de memória capaz de guardar n números reais ( float ), ficando o apontador v a apontar para o endereço inicial dessa porção de memória. O cast da função malloc() - (float *) - assegura que o apontador retornado é para o tipo especificado na declaração do apontador. Certos compiladores requerem obrigatóriamente o cast . </li></ul>
  27. 27. malloc () <ul><li>Conselho: não altere o valor do apontador que recebeu o retorno da função malloc(). Desta forma poderá sempre saber onde começa o bloco de memória dinâmica reservado. Utilize apontadores auxiliares para realizar operações (leitura, escrita) dentro do bloco de memória. </li></ul>
  28. 28. Libertar memória dinâmica <ul><li>A memória é libertada utilizando a função free() </li></ul><ul><li>int *pi; </li></ul><ul><li>pi= ( int *) malloc (sizeof( int )); </li></ul><ul><li>Para libertar a memória: </li></ul><ul><li>free(pi); </li></ul>
  29. 29. Ajuste da memória dinâmica <ul><li>É possível alterar o tamanho do bloco de memória reservado, utilizando a função realloc() . Esta função salvaguarda os valores anteriormente em memória, até ao limite do novo tamanho (especialmente importante quando se reduz o tamanho do bloco de memória). O seguinte exemplo ilustra a forma de utilização desta função. </li></ul>
  30. 30. Ajuste da memória dinâmica <ul><li>int *a; </li></ul><ul><li>a = (int *) malloc( 10 * sizeof(int) ); </li></ul><ul><li>(...) </li></ul><ul><li>a = (int *) realloc( a, 23 * sizeof(int) ); </li></ul><ul><li>(...) </li></ul><ul><li>free(a); </li></ul><ul><li>A chamada da função realloc() recebe como argumentos um apontador para o bloco de memória previamente reservado, com uma função malloc(), de forma a saber qual a porção de memória a ser redimensionada e o novo tamanho absoluto para o bloco de memória. </li></ul>
  31. 31. Alocação dinâmica de memória <ul><li>void * calloc(size_t n, size_t size); </li></ul><ul><li>/* </li></ul><ul><li>calloc retorna um ponteiro para um array com n </li></ul><ul><li> elementos de tamanho size cada um ou NULL se não </li></ul><ul><li> houver memória disponível. Os elementos são </li></ul><ul><li> iniciados em zero </li></ul><ul><li>*/ </li></ul><ul><li>o ponteiro retornado por malloc e calloc deve ser convertido para o tipo de ponteiro que invoca a função: </li></ul>
  32. 32. Alocação dinâmica de memória <ul><li>int *ai = ( int *) calloc (n, sizeof( int )); </li></ul><ul><li>/* aloca espaço para um array de n inteiros */ </li></ul><ul><li>toda memória não mais utilizada deve ser liberada através da função free() : </li></ul><ul><li>free(ai); /* libera todo o array */ </li></ul><ul><li>free(pi); /* libera o inteiro alocado */ </li></ul>
  33. 33. Exercícios <ul><li>1- Pretende-se que faça a alocação de espaço em memória para 10 inteiros. Deverá imprimir os seus respectivos endereço de memórias e o seu conteúdo. </li></ul><ul><li>2- Leia uma sequência de 10 números to teclado usando apontadores em lugar de índices. Usando a mesma técnica (apontadores) determine o maior e o menor valor. Reserve memória dinâmica em vez de declarar o vector de uma forma estática. </li></ul><ul><li>3- Ler uma sequência de números do teclado (sequência terminada em zero ).Escreva no ecrã os números que estão acima da média. Utilize um vector dinâmico para armazenar os números. </li></ul>
  34. 34. Resolução Nº 1 1- Pretende-se que faça a alocação de espaço em memória para 10 inteiros. Deverá imprimir os seus respectivos endereço de memórias e o seu conteúdo. #include <stdio.h> #include <conio.h> #include <stdlib.h> #include <alloc.h> int *dados,i; //int *p; void main() { clrscr(); dados=(int *)malloc(5*sizeof(int)); if (dados==NULL) { printf (&quot;A aloca‡Æo nÆo correu bem!!&quot;); exit(1); } //p=dados; podia iniciar um outro ponteiro for (i=0;i<5;++i) { printf(&quot;O dados sÆo %d &quot;, *(dados+i)); //mostra o que existe nesse espa‡o de mem¢ria printf(&quot;. E est  no endere‡o %d &quot;, dados);//endere‡o de mem¢ria dados++; //printf(&quot;O dados sÆo %d &quot;, *(p+i)); //p++; } getch(); }
  35. 35. Resolução Nº 2 <ul><li>Leia uma sequência de 10 números to teclado usando apontadores em lugar de índices. Usando a mesma técnica (apontadores) determine o maior e o menor valor. Reserve memória dinâmica em vez de declarar o vector de uma forma estática. </li></ul><ul><li>#include <stdio.h> </li></ul><ul><li>#include <stdlib.h> </li></ul><ul><li>void main() </li></ul><ul><li>{ int *v, *min, *max; int i, soma = 0; float media; </li></ul><ul><li>/* v passa a apontar para um bloco de memória com capacidade para 10 inteiros */ </li></ul><ul><li>v = (int *) malloc(10 * sizeof(int)); </li></ul><ul><li>for(i = 0; i < 10; i++) </li></ul><ul><li>{ printf(&quot;Insira um número: &quot;); </li></ul><ul><li>scanf(&quot;%d&quot;, v+i); </li></ul><ul><li>} /* min e max passam a apontar para o primeiro valor do vector */ </li></ul><ul><li>min = v; </li></ul><ul><li>max = v; </li></ul><ul><li>for(i = 0; i < 10; i++) </li></ul><ul><li>{ if ( *(v+i) > *max ) </li></ul><ul><li>max = v+i; </li></ul><ul><li>else if ( *(v+i) < *min ) </li></ul><ul><li>min = v+i; </li></ul><ul><li>} </li></ul><ul><li>printf(&quot;O menor número inserido: %d &quot;, *min); </li></ul><ul><li>printf(&quot;O maior número inserido: %d &quot;, *max); </li></ul><ul><li>} </li></ul>
  36. 36. Resolução Nº 3 <ul><li>Ler uma sequência de números do teclado (sequência terminada em zero ).Escreva no ecrã os números que estão acima da média. Utilize um vector dinâmico para armazenar os números. </li></ul>#include <stdio.h> #include <stdlib.h> void main() { int *v; int soma, i, num, c; float media; /* Esta operação é necessária para utilizar posteriormente a função realloc() */ v = (int *) malloc( sizeof(int) ); /* São inicializadas as variáveis soma e contador de números inseridos */ soma = 0; i = 0; /* O primeiro número é inserido antes do ciclo while para verificar se é zero (para a acabar) */ printf(&quot;Insira um número (zero para acabar): &quot;); scanf(&quot;%d&quot;, &num); while( num ) /* O ciclo é executado enquanto num não é zero */ { i++; v = (int *) realloc(v, i*sizeof(int)); *(v+i-1) = num; /* O vector começa na posição zero pelo que i anda avançado um valor */ soma += num; /* É efectuado o somatório dos números inseridos */ /* É inserido um novo número para verificar no início do próximo ciclo */ printf(&quot;Insira um número (zero para acabar): &quot;); scanf(&quot;%d&quot;, &num); } /* O cast (float) força as operações a serem realizadas no domínio dos float */ /* que de outra forma seria nos int (soma e i são ambos inteiros) */ media = (float) soma / i; for(c = 0; c < i; c++) if ( *(v+c) > media ) printf(&quot;O valor %d está acima da média. &quot;, *(v+i)); }
  37. 37. Bibliografia <ul><li>Damas, L. M. D. (2004). Linguagem C . Lisboa: FCA. </li></ul>

×