Post on 25-May-2015
description
Linguagem C
Escola Secundária da BatalhaEscola Secundária da Batalha
Estruturas em CEstruturas em C
Miguela FernandesMiguela Fernandes
Linguagem C
EstruturasEstruturas
• Struct são colecções de dados heterogêneos agrupados em uma mesma estrutura de dados
• Ex: armazenas as coordenadas (x,y) de um ponto:
(x, y)
Linguagem C
Tipos Complexos
•Tipos básicos: char, int, float, etc.Variáveis guardam um só valor.
•Matrizes: v.g. char matriz[20]Variáveis guardam colecções de objectos do mesmo tipo.
Como guardar colecções de tipos diversos?
Linguagem C
Solução: EstruturasSolução: Estruturas
• Declaração:
struct { int x; int y;} p1, p2;
• a estrutura contém dois inteiros, x e y• p1 e p2 são duas variáveis tipo struct
contendo duas coordenadas cada.
(x, y)
Linguagem C
EstruturasEstruturas
Exemplo: struct {
char nome[NOME_MAX + 1]; int numero;double media; } aluno1, aluno2;
• Informação diversa sobre uma única entidade (um aluno).
• Podem conter matrizes (e vice-versa).• Podem conter outras estruturas.
Linguagem C
DeclaraçãoDeclaração
• Formato da declaração:struct nome_da_estrutura {
tipo_1 dado_1;tipo_2 dado_2;...tipo_n dado_n;
} lista_de_variaveis;
• A estrutura pode agrupar um número arbitrário de dados de tipos diferentes
• Pode nomear-se a estrutura para referenciá-la
Linguagem C
Definição de TiposDefinição de Tipos
struct {
int x;
int y;
} p1;
struct {
int x;
int y;
} p2;
struct ponto { int x;int y;
};struct ponto p1, p2;
Repetição
• struct ponto define um novo tipo de dado
• Pode definir-se novas variáveis do tipo ponto
Linguagem C
Definição de TiposDefinição de Tipos (declaração de variáveis)(declaração de variáveis)
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];
Novo tipo:
struct Aluno
Definição de variáveis:
struct Aluno aluno1, aluno2,*p, lista[10];
Linguagem C
InicializaçãoInicialização
struct Aluno { char nome[NOME_MAX + 1]; int numero; double media;};
struct Aluno aluno = {"Zacarias", 666, 20.0}; aluno
nome:numero:media:
Linguagem C
Acesso aos dadosAcesso aos dados
struct-var.campo
Exemplo:aluno1.nome = “Pedro”;/*atribuição
*/
aluno2.nome = “João;
if ((aluno1.nome == aluno2.nome) && (aluno1.media >= aluno2.media))
...
Linguagem C
Inicialização de estruturasInicialização de estruturas
struct Aluno { char nome[NOME_MAX + 1]; int numero; double media;};
struct Aluno aluno = {"Zacarias", 666,
20.0};
Equivalente a:
struct Aluno aluno;
strcpy(aluno.nome,"Zacarias");
aluno.numero = 666;
aluno.media = 20.0; aluno
nome:numero:media:
Z a c a r i as666
20.0
Linguagem C
Atribuição de EstruturasAtribuição de Estruturas
Revisão:• Inicialização de uma estrutura:
struct ponto p1 = { 220, 110 };
• Atribuição entre estruturas do mesmo tipo:struct ponto p1 = { 220, 110 };
struct ponto p2;
p2 = p1; /* p2.x = p1.x e p2.y = p1.y */
• Os campos correspondentes das estruturas são automaticamente copiados do destino para a origem
p1x:y:
220
110
p2x:y:
p2 = p1
p2x:y:
220
110
Linguagem C
Atribuição de EstruturasAtribuição de Estruturas
• Atenção para estruturas que contenham ponteiros:struct aluno {
char *nome;int idade;
} a1, a2;
a1.nome = “Afonso”;a1.idade = 32;a2 = a1;
• Agora a1 e a2 apontam para a mesma string nome: a1.nome == a2.nome == “Afonso”
Linguagem C
Composição de EstruturasComposição de Estruturas
struct retangulo { struct ponto inicio; struct ponto fim;};struct retangulo r = { { 10, 20 },
{ 30 , 40 } };
• Acesso aos dados:r.inicio.x += 10;r.inicio.y -= 10;
iniciox:y:
10
20
fimx:y:
30
40
r
Linguagem C
Estruturas como parâmetrosEstruturas como parâmetros
struct ponto cria_ponto (int x, int y) {
struct ponto tmp;
tmp.x = x;
tmp.y = y;
return tmp;
}
main () {
struct ponto p = cria_ponto(10, 20);
}
px:y:
10
20
px:y:
Linguagem C
OperaçõesOperações
Operações entre membros das estruturas devem ser feitas membro a membro:
/* retorna uma cópia de p1 = p1 + p2 */
struct soma_pts (struct ponto p1, struct ponto p2)
{
p1.x += p2.x; (relembro que p1.x = p1.x +p2.x)
p1.y += p2.y;
return p1; /* retorna uma copia de p1 */
}
Linguagem C
Arrays de EstruturasArrays 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 ...};
nome:idade:
Figo
32
PT
nome:idade:
Carlos
24
nome:idade:
Rui Costa
27
nome:idade:
...
...
Linguagem C
Ponteiros para EstruturasPonteiros para Estruturas
Estruturas grandes são passadas como parâmetro De forma mais eficiente através de ponteiros
struct ponto *pp;struct ponto p1 = { 10, 20 };pp = &p1;printf(“Ponto P1: (%d %d)\n”, (*pp).x, (*pp).y};
• Aceder com o operador “->”:printf(“Ponto P1: (%d %d)\n”, pp->x, pp->y};
(*pp).x == pp->x
p1x:y:
1002
10
20
pp
1002
Linguagem C
Espaço Alocado para uma EstruturaEspaço Alocado para uma Estrutura
struct aluno {
char *nome; /* ponteiro 4 bytes */
short idade; /* 2 bytes */
char matricula[8]; /* array 8 bytes */
};
struct aluno al;
al.nome = “Xexeo”;
al.idade = 30;
strcpy(al.matricula, “00/0001”);
struct aluno al
* “Xexeo”
30
“00/0000”
Linguagem C
Função Função sizeof(tipo)sizeof(tipo)
• A função sizeof(tipo) retorna o tamanho em bytes ocupado na memória pelo tipo de dado passado como parâmetro
Ex:sizeof(int) => 4 bytes
sizeof(char) => 1 byte
sizeof(struct ponto) => 8 bytes
sizeof(struct ponto *) => 4 bytes
Linguagem C
Espaço EfectivoEspaço Efectivo
/* teste com Symantec C, PowerPC 603 - Macintosh */
struct aluno {
char *nome; /* 4 bytes */
short idade; /* 2 bytes */
char matricula[3]; /* 3 bytes */
};/* sizeof(aluno) = 12 bytes */
Linguagem C
Espaço EfectivoEspaço Efectivo
/* teste com Symantec C, PowerPC 603 - Macintosh */
struct aluno1 {
char *nome; /* 4 bytes */
short idade; /* 2 bytes */
char matricula[5]; /* 5 bytes */
};
/* sizeof(aluno1) = 12 bytes */
Linguagem C
Espaço EfectivoEspaço Efectivo
/* teste com Symantec C, PowerPC 603 - Macintosh */
struct aluno2 {
char *nome; /* 4 bytes */
short idade; /* 2 bytes */
char matricula[7]; /* 7 bytes */
};
/* sizeof(aluno2) = 16 bytes */
• no PowerMac uma estrutura é um múltipo do tamanho da palavra, 32 bits
Linguagem C
Alocação Dinâmica de MemóriaAlocação Dinâmica de Memória
• incluir a biblioteca standard do C: stdlib.h (malloc() e free())
• possibilidade de libertar memória à medida que deixa de ser precisa
• as funções calloc e malloc permitem alocar blocos de memória em tempo de execução
void * malloc( );
/* retorna um ponteiro void para n bytes de memória não
iniciados. Se não há memória disponível malloc retorna NULL
*/
número de bytes alocadossize_t n
Linguagem C
Alocação Dinâmica de MemóriaAlocação Dinâmica de Memória
• A função malloc() (memory allocation)• 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
• A sua utilização é representada no exemplo seguinte:
int *pi;
pi= (int *) malloc (sizeof(int));
/* aloca espaço para um inteiro */
Linguagem C
mallocmalloc() – exemplo() – exemplo
float *v; int n; printf("Quantos valores? "); scanf("%d", n); v = (float *) malloc(n * sizeof(float) );
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.
Linguagem C
mallocmalloc()()
• 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.
Linguagem C
Libertar memória dinâmicaLibertar memória dinâmica
• A memória é libertada utilizando a função free()
int *pi;
pi= (int *) malloc (sizeof(int));
• Para libertar a memória:
free(pi);
Linguagem C
Ajuste da memória dinâmicaAjuste da memória dinâmica
• É 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.
Linguagem C
Ajuste da memória dinâmicaAjuste da memória dinâmica
int *a;
a = (int *) malloc( 10 * sizeof(int) );
(...)
a = (int *) realloc( a, 23 * sizeof(int) );
(...)
free(a);
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.
Linguagem C
Alocação dinâmica de memóriaAlocação dinâmica de memória
void * calloc(size_t n, size_t size);
/*
calloc retorna um ponteiro para um array com n
elementos de tamanho size cada um ou NULL se não
houver memória disponível. Os elementos são
iniciados em zero
*/
• o ponteiro retornado por malloc e calloc deve ser convertido para o tipo de ponteiro que invoca a função:
Linguagem C
Alocação dinâmica de memóriaAlocação dinâmica de memória
int *ai = (int *) calloc (n, sizeof(int));
/* aloca espaço para um array de n inteiros */
• toda memória não mais utilizada deve ser liberada através da função free():
free(ai); /* libera todo o array */free(pi); /* libera o inteiro alocado */
Linguagem C
ExercíciosExercícios
• 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.
• 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.
• 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.
Linguagem C
Resolução Nº 1Resolução Nº 11- 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 ("A aloca‡Æo nÆo correu bem!!");exit(1);
} //p=dados; podia iniciar um outro ponteirofor (i=0;i<5;++i){
printf("O dados sÆo %d ", *(dados+i)); //mostra o que existe nesse espa‡o de mem¢ria
printf(". E est no endere‡o %d\n", dados);//endere‡o de mem¢riadados++;//printf("O dados sÆo %d\n", *(p+i));//p++;
}getch();
}
Linguagem C
Resolução Nº 2Resolução Nº 2Leia 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.
#include <stdio.h>#include <stdlib.h>void main(){ int *v, *min, *max; int i, soma = 0; float media; /* v passa a apontar para um bloco de memória com capacidade para 10 inteiros */
v = (int *) malloc(10 * sizeof(int)); for(i = 0; i < 10; i++) { printf("Insira um número: "); scanf("%d", v+i); } /* min e max passam a apontar para o primeiro valor do vector */ min = v; max = v;
for(i = 0; i < 10; i++) { if ( *(v+i) > *max ) max = v+i; else if ( *(v+i) < *min ) min = v+i; } printf("O menor número inserido: %d\n", *min); printf("O maior número inserido: %d\n", *max);}
Linguagem C
Resolução Nº 3Resolução Nº 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.
#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("Insira um número (zero para acabar): "); scanf("%d", &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("Insira um número (zero para acabar): "); scanf("%d", &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("O valor %d está acima da média.\n", *(v+i));}
Linguagem C
BibliografiaBibliografia
• Damas, L. M. D. (2004). Linguagem C. Lisboa: FCA.