Você está na página 1de 9

01/11/2011

Um ponteiro uma varivel que contm um endereo de memria. Um ponteiro armazena um endereo de memria.

Ponteiros em C Prof. Me. Ricardo Becker

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;

int *a; float *v; char *c;

Operador: &
devolve um endereo de memria; o endereo a posio interna ao computador da varivel.

No confunda com &&!

01/11/2011

int x, *px; px = &x; /* a varivel px aponta para x */

Declarao Int x, *px;


MEMRIA

coloca em px o endereo de memria que contm a varivel x.;

Varivel x

Endereo 0434FF3 1124AZ9 8271YW1

Atribuio px = &x;
MEMRIA Varivel x Endereo 0434FF3 1124AZ9 8271YW1 O endereo de px 1124AZ9

Operador: * devolve o valor da varivel localizada no endereo correspondente;


No confunda com * da multiplicao!

10

int x=10, y, *px; px = &x; /* a varivel px aponta para x */ y = *px; /* y recebe o valor de px */

Declarao int x=10, y, *px;

MEMRIA Varivel x = 10 y Endereo 0434FF3 1124AZ9 8271YW1

11

12

01/11/2011

Atribuio px=&x; y = *px;


MEMRIA

#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

char tmp, ch = 'a'; char *pc; pc = &ch; tmp = *pc;

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...

Qual o valor de tmp?

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

main(){ int x=10, y; int *p = &x; y = *p; } /* inicializao */

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.

Assim como no faz sentido deixarmos de inicializar uma varivel comum:


int p; printf("%d",p);

Tambm no faz sentido utilizar um ponteiro sem inicializ-lo:


int *p; printf("%d", *p);

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.

Se voc quiser acessar o contedo do ponteiro em 3 posies adiante:


*(px+3);

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

Inicalizao int vec[5]


MEMRIA 0 1 2

Inicalizao int vec[5]


vec MEMRIA 0 1 2 Tendo alocado na memria o espao para o vetor, ele toma o nome da varivel (que um ponteiro) e aponta para o primeiro elemento da matriz 3 4

O compilador aloca 20 (5X4) bytes em um espao livre de memria

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; } }

Podemos reescrev-lo de uma maneira muito mais eficiente usando ponteiros


main(){
float M[10][10]; float *p; int count; p = M; for (count=0;count<100;count++){ *p=0.0; p++; } Enquanto que nesse programa o } nico clculo que deve ser feito o de um incremento de ponteiro.
41 42

O programa tem que calcular o deslocamento para dar ao ponteiro.

01/11/2011

Sejam:
float M[2][3]; float *p = M;

Sejam:
float M[2][3]; float *p = M;

Como acessar o valor do elemento M[i][j] utilizando o ponteiro p?

Como acessar o valor do elemento M[i][j] utilizando o ponteiro p?


Resposta: *(p+i+3*j);

43

44

Um ponteiro uma varivel, mas o nome de um vetor no uma varivel. Exemplo:


int vetor[10]; int *ponteiro = vetor; ponteiro = vetor+2; /* OK */

Operaes abaixo so invlidas:


vetor = vetor + 2; vetor++; vetor = ponteiro;

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]);

p[2] equivalente a *(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;

Exemplo: int (*pmatriz)[10];


Nesse caso, pmatriz um ponteiro para um vetor que armazena 10 inteiros.

49

50

Observao: **nome_da_varivel o contedo final da varivel apontada e *nome_da_varivel o contedo do ponteiro intermedirio.

#include <stdio.h> main(){ int x,*p,**pp; x=10; p=&x; pp=&p; printf("%d",**pp); }

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

Você também pode gostar