Escolar Documentos
Profissional Documentos
Cultura Documentos
Um ponteiro uma varivel que contm um endereo de memria. Um ponteiro armazena um endereo de memria.
Esse endereo normalmente a posio de uma outra varivel na memria. O endereo apontado contm um valor especfico.
1 2
Ponteiros fornecem os meios pelos quais as funes podem modificar seus argumentos; Usados em alocaes dinmicas; Usados para aumentar a eficincia dos cdigos.
Devemos declarar um ponteiro de forma correta: uma declarao de ponteiro consiste no tipo bsico, um * e o nome da varivel. Sintaxe: tipo *nome;
Operador: &
devolve um endereo de memria; o endereo a posio interna ao computador da varivel.
01/11/2011
Varivel x
Atribuio px = &x;
MEMRIA Varivel x Endereo 0434FF3 1124AZ9 8271YW1 O endereo de px 1124AZ9
10
int x=10, y, *px; px = &x; /* a varivel px aponta para x */ y = *px; /* y recebe o valor de px */
11
12
01/11/2011
#include <stdio.h>
main( ) { int x=10,y; int *px; Varivel x = 10 y = 10 Endereo 0434FF3 1124AZ9 8271YW1 } px = &x; y = *px; printf("x=%d printf("x=%d y=%d\ y=%d\n",x,y); n",x,y); /* atribuio */ /* declarao */
13
14
As variveis ponteiros sempre devem apontar para o tipo de dado correto. correto. Quando um ponteiro declarado como do tipo int o ponteiro assume que qualquer endereo que ele contenha aponta para uma varivel inteira. A linguagem C no avisa isso ao programador!!! Vejo o prximo exemplo...
15
16
#include <stdio.h>
main(){ float x=10, y=20; int *p; p = &x; y = *p; } Cuidado: alguns compiladores no acusam esse tipo de erro!!!
Como em qualquer varivel, um ponteiro pode ser usado ao lado direito de um comando de atribuio para passar seu valor para um outro ponteiro. Exemplo:
char a,*p1,*p2; p1 = &a; p2 = p1;
17
18
01/11/2011
#include <stdio.h>
#include <stdio.h>
main(){ int x=11; int *p1, *p2; p1 = &x; printf("p1 apos atribuicao: %d\ %d\n",*p1); printf("endereco de p1: %p\ %p\n",p1); printf("p2 antes da atribuicao: %d\ %d\n",*p2); printf("endereco de p2: %p\ %p\n\n",p2); p2 = p1; /* atribuio de ponteiro */ printf("p2 apos atribuicao: %d\ %d\n",*p2); printf("endereco de p2: %p\ %p\n",p2); }
19 20
Conveno
Um ponteiro que atualmente no aponta para um local de memria vlido recebe o valor nulo; nulo; Qualquer ponteiro que nulo, nulo implica que ele no aponta para nada e no deve ser usado.
21
22
Temos que tomar um cuidado adicional com ponteiros: ele pode ter sido inicializado, mas inicializado com o valor NULL, NULL logo no podemos fazer:
int *p = NULL; printf("%d", *p);
Observem que quando declaramos um ponteiro, no estamos reservando espao para armazenar um dado, estamos apenas reservando espao da memria para armazenar um endereo. Exemplo: int *p = NULL; O ponteiro p no apontar para nenhum endereo de memria.
23 24
muito comum o uso de ifs ifs ifs para verificar se um ponteiro possui o valor NULL ou no, para s ento ser utilizado ou no. O valor especial NULL (precisamos do stdlib.h) stdlib.h significa que no temos nenhum endereo de memria.
01/11/2011
#include <stdio.h> #include <stdlib.h> main(){ char ch = 'w'; char *p = NULL; if ( p == NULL) { p = &ch; printf("O valor de p eh:%c\ eh:%c\n",*p); } }
Cada vez que um ponteiro incrementado, ele aponta para a posio da memria do prximo elemento do seu tipo base. Exemplo:
double x=1.7; double *px = &x; px++;
25
26
Atribuio px = &x;
MEMRIA Varivel x = 1.7 Endereo 1000 1008 1016 double = 8 bytes
Incremento px++;
MEMRIA Varivel x = 1.7 Endereo 1000 1008 1016 double = 8 bytes O ponteiro aponta para o prximo endereo de memria
27 28
Analogamente, um ponteiro pode ser decrementado, decrementado ou seja, ele aponta para a posio do elemento anterior.
double *px; px-px--; --;
Ateno: Estamos falando de operaes com ponteiros e no de operaes com o contedo das variveis para as quais eles apontam. Os operadores ++ e -- tm maior precedncia que o operador * e so avaliados da direita para a esquerda.
De maneira mais geral, toda aritmtica de ponteiros feita relativamente ao tipo base do ponteiro, para que ele sempre aponte para o elemento do tipo base apropriado.
29
30
01/11/2011
Exemplo:
(*px)++;
Outras operaes aritmticas teis so a soma e subtrao de inteiros com ponteiros. Exemplo:
Vamos incrementar um ponteiro px em 3 posies de memria:
px = px+3; px += 3;
A operao acima incrementa o contedo (valor) da varivel apontada pelo ponteiro px (aponta para o mesmo endereo). Exemplo:
*px-*px--; --; /* igual a *(px-*(px--) --) */ Desce uma posio de memria.
31
32
Ateno: O operador unrio * tem maior precedncia sobre os operadores aritmticos. Exemplo:
y = *px + 3; pega o contedo do endereo que px aponta e soma 3 ao seu contedo. y = *(px + 3); o ponteiro px ser incrementado em 3 posies de memria e o contedo ser atribudo a y.
Operao
y = *px + 3;
Memria Contedo 1.7 px 3.1 9.3 5.4 O valor de y 4.7 Endereo 1000 1008 1016 1024
33
34
Operao
y = *(px + 3);
Memria Contedo 1.7 px 3.1 9.3 5.4 O valor de y 5.4 Endereo 1000 1008 1016 1024
Consideremos um vetor tipo nome[n]; Na verdade, o nome da varivel que voc declarou na verdade um ponteiro constante para o tipo da varivel do vetor.
35
36
01/11/2011
3 4
37
38
Notao: Acesso de um valor de um vetor: nome[ndice]; A notao acima absolutamente equivalente a se fazer: *(nome+ndice);
39
Exemplo:
int vec[10], y; int *p;
p = vec; &vec[0]*/ vec[0]*/ vec; /* igual a p = &vec y = *p; /* igual a y = vec[0]*/ vec[0]*/
40
Considere o seguinte programa para zerar uma matriz (por varredura seqencial)
main () { float M[10][10]; int i,j; for (i=0;i<10;i++) { for (j=0;j<10;j++) M[i][j]=0.0; } }
01/11/2011
Sejam:
float M[2][3]; float *p = M;
Sejam:
float M[2][3]; float *p = M;
43
44
As operaes acima so invlidas pois vetor no uma varivel. Lembre-se de que o nome de um vetor um ponteiro constate.
45 46
Sabemos agora que, na verdade, o nome de um vetor um ponteiro constante. Sabemos tambm que podemos indexar o nome de um vetor, logo podemos tambm indexar um ponteiro qualquer.
} #include <stdio.h> main () { int M[10]={1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; int *p; p = M; printf("O terceiro elemento do vetor eh: %d",p[2]);
47
48
01/11/2011
Podemos construir vetores de ponteiros como declaramos vetores de qualquer outro tipo.
Exemplo: int *pmatriz[10];
Nesse caso, pmatriz um vetor que armazena 10 ponteiros para inteiros.
Um ponteiro para um ponteiro como se voc anotasse em um papel o nmero da ficha que tem o endereo da casa do seu amigo. Sintaxe:
tipo **nome_da_varivel; int **M; char **nomes;
49
50
Observao: **nome_da_varivel o contedo final da varivel apontada e *nome_da_varivel o contedo do ponteiro intermedirio.
51
52
No C podemos declarar ponteiros para ponteiros para ponteiros, ou ento, ponteiros para ponteiros para ponteiros para ponteiros e assim por diante...
53