Programação de Computadores I – Ponteiros Profa. Mercedes Gonzales Márquez Ponteiros - Manipulação Declaração: <tipo> *<identificador> int *p; float *q; O operador unário & captura o endereço de um objeto. p = &x; O operador unário * é um operador de indireção: quando aplicado a um apontador, acessa o conteúdo do objeto apontado. x = *p; Ponteiros - Manipulação int vet[4]; vet aponta para vet[0] (vet[0]==*vet) e - vet+1 aponta para vet[1] e *(vet+1) refere-se ao conteúdo de vet[1] – vet+i aponta para vet[i] e *(vet+i) refere-se ao conteúdo de vet[i] Ponteiros - Manipulação int vet[4]; int *pa; pa = &vet[0]; pa vet Se pa aponta para vet[0], então: - pa+1 aponta para vet[1] e pa+i aponta para vet[i]. Ponteiros - Manipulação Exemplo int x=3, y=5, *p=&x, *q=&y, *r; double z; Expressão p==&x **&p r=&z 7**p/*q+7 *(&y)*=*p Valor 1 3 erro 11 15 Ponteiros Exemplo O que será impresso pelo programa abaixo considerando que os valores lidos nas variáveis x e y sejam 2 e 5,respectivamente? Ponteiros Exemplo O que será impresso pelo programa abaixo considerando que os valores lidos nas variáveis x e y sejam 2 e 5,respectivamente? Ponteiros Exemplo O que faz o trecho de programa abaixo? Ponteiros para registros Ao criarmos uma variável de um tipo struct, esta e armazenada na memoria como qualquer outra variável, e portanto possui um endereço. Exemplo #include <stdio.h> typedef struct { double x; double y; } Coordenada; int main(){ Coordenada c1, c2, *c3; c3 = &c1; Ponteiros para registros Para acessarmos os campos de uma variavel struct via um ponteiro, podemos utilizar o operador * juntamente com o operador . como de costume: Coordenada c1, *c3; c3 = &c1; (*c3).x = 1.5; (*c3).y = 1.5; Em C também podemos usar o operador -> para acessar campos de uma estrutura via um ponteiro. Podemos obter o mesmo resultado do exemplo anterior: Coordenada c1, *c3; c3 = &c1; c3->x = 1.5; c3->y = 1.5; Ponteiros para registros Resumindo: Para acessar campos de estruturas via ponteiros use um dos dois: ponteiroEstrutura->campo (*ponteiroEstrutura).campo Exercício 1: Vamos criar as seguinte funcões: void leCoordenada3D(Coordenada3d *f);: lê dados de uma ponto no espaço tridimensional com coordenadas (x,y,z) passada como ponteiro. (Por quê como ponteiro?) void imprimeCoordenada3D(Coordenada3d f); Imprime coordenadas de um ponto. O programa principal que requeira a leitura de 5 pontos no espaço tridimensional. Alocação dinámica função malloc – Parâmetro: tamanho desejado, em bytes – Resultado: apontador para espaço na memória Programa int *p; p = (int*)malloc(4); *p = 5; printf("%d", *p); Alocação dinámica função free: – Parâmetro: endereço já alocado – Resultado: libera a área alocada Programa int *p; p = (int*)malloc(4); *p = 5; free(p); Alocação dinámica função sizeof: sizeof(variavel) – Retorna quantidade de memória ocupada pela variável sizeof(tipo) – Retorna quantidade de memória ocupada por uma variável com este tipo. VETOR DINÂMICO • Calcular tamanho do vetor com sizeof • Reservar memória com malloc • Acessar elementos com [ ] ou ponteiros • Liberar memória do vetor com free Alocação dinámica Exemplo: int *v; int tamanho; scanf(“%d”, &tamanho); v = (int*)malloc(sizeof(int)*tamanho); v[1] = v[2] + v[3]; *(v+1) = *(v+2) + *(v+3); free(v); Exercício 2. O exercício 1 pedia para ingressar 5 pontos do espaço tridimensional, agora considere um vetor de pontos de tamanho dinâmico. Exercícios Exercício 3. O que será impresso pelo programa abaixo: #include <stdio.h> Typedef struct{ int x; int y; } T; void f1(T *a){ f2(&(a->x)); f2(&(a->y)); } void f2(int *b){ *b = 2*(*b); Exercícios int main(){ T a, b, *c, *d; c = &a; a.x = 2; a.y = 4; b.x = 2; b.y = 2; d = c; f1(d); b = *d; printf("x: %d --- y: %d\n",b.x,b.y); } Exercícios int main(){ T a, b, *c, *d; c = &a; a.x = 2; a.y = 4; b.x = 2; b.y = 2; d = c; f1(d); b = *d; printf("x: %d --- y: %d\n",b.x,b.y); }