Вы находитесь на странице: 1из 58

Linguagem C

Prof. Edmar Pereira

Ponteiros

Conceitos bsicos
Declarao de ponteiros
Inicializao de ponteiros
Ponteiros em ao
Ponteiros e tipos de dados
Ponteiros e vetores
Aritmtica dos ponteiros

Conceitos bsicos

Como se sabe tudo o que acontece


em um computador (ou quase tudo) se
passa em memria.
Quando falamos em memria falamos
em memria RAM.
na memria RAM que so
carregados os nossos programas,
jogos, processadores de texto etc.
Programao Estruturada

Conceitos bsicos

tambm na RAM que so


armazenadas as variveis que fazem
parte dos nossos programas.
De fato a memria RAM pode ser vista
como um grande vetor de bytes
consecutivos.
100

101

102

5000

Programao Estruturada

5001

5002

Conceitos bsicos

Cada um desses bytes ocupa uma


posio bem determinada em
memria, que identificada por um
nmero nico que varia entre zero e a
totalidade de bytes que ocupam a
memria RAM do computador

Programao Estruturada

Conceitos bsicos

Sempre que declaramos uma varivel


temos que indicar qual o seu tipo e qual o
seu nome.
char ch;

1000

1001

ch

1002

5000

5001

5002

A varivel ch ocupa no exemplo acima, o


byte de memria nmero 5000.
Programao Estruturada

Conceitos bsicos

Repare que quando se faz: ch = A


est se dizendo ao computador para ir posio
5000 de memria e colocar l o caractere A.
ch

A
1000

1001

1002

5000

5001

5002

Sempre que num programa se faz referncia a uma


varivel estamos, na realidade, nos referindo ao
endereo ou conjunto de endereos que essa
varivel ocupa
Programao Estruturada

Conceitos bsicos

Os ponteiros so um mecanismo
particularmente flexvel de manipulao de
dados, pois permitem manipular
diretamente dados contidos em endereos
especficos de memria.
Suponhamos ento, que tnhamos ao nosso
dispor um ponteiro denominado ptr.

Programao Estruturada

Conceitos bsicos

Como qualquer varivel, ptr ocupa uma posio de


memria
ptr

ch

A
1000

1001

1002

5000

5001

5002

Ora ptr um ponteiro, por isso dever conter o


endereo de memria de outra varivel.
Note que o endereo de uma varivel o nmero
da casa que esta ocupa em memria.

Programao Estruturada

Conceitos bsicos

Para colocar-mos ptr apontando para


a varivel ch bastar colocar o
endereo de ch em ptr.
Isso se faz utilizando o operador &
(Endereo de): ptr = &ch
ptr

ch

5000
1000

1001

1002

5000

Programao Estruturada

5001

5002

10

Declarao de ponteiros

Para declarar um ponteiro temos a seguinte forma geral:


tipo_do_ponteiro *nome_da_varivel;

o asterisco (*) que faz o compilador saber que aquela


varivel no vai guardar um valor mas sim um endereo para
aquele tipo especificado.
Exemplos de declaraes:
int *pt;
char *temp,*pt2;

Programao Estruturada

11

Inicializao de ponteiros

A inicializao de ponteiros se faz


atravs do operador Endereo de - &
Ele retorna o endereo de memria
Exemplo:
int a = 10, *p;
// p aponta para o endereo de a

p = &a;
Programao Estruturada

12

Ponteiros em ao

Seja: int a=5, b=7;


int *ptr;
ptr

1000

1001

1002

3000

3001

3002

Para colocar ptr apontando para a faz-se:


ptr = &a;
ptr

1002
1000

1001

1002

3000

Programao Estruturada

3001

3002

13

Ponteiros em ao

Aps a instruo anterior o valor de

a
ptr
*ptr

1002 /* endereo de a */
5
/* contedo que est no endereo 1002 */

Se ptr um ponteiro, ento *ptr nos permite


obter o valor que apontado por ptr, isto ,
o valor da varivel cujo endereo est
armazenado em ptr.
*ptr Deve-se ler O APONTADO POR ptr
Programao Estruturada

14

Ponteiros em ao

Dessa forma fazer:


printf (%d, a);

equivalente a
printf(%d, *ptr);

pois ptr aponta para a e *ptr


corresponde ao valor de a.

Programao Estruturada

15

Ponteiros em ao

Qual a sada da seguinte instruo?

Qual a sada depois de fazermos


ptr = &b;?

printf (%d %d %d, a, b, *ptr);

printf (%d %d %d, a, b, *ptr);

E se executssemos a instruo:
*ptr = 20; /* colocar 20 no apontado por ptr */
Qual seria a sada de:

printf (%d %d %d, a, b, *ptr);


Programao Estruturada

16

Ponteiros em ao

Repare que no esquema anterior (em que ptr =


&b) existe o seguinte conjunto de valores
associados s expresses:
Expresso

Valor

&a

1002

20

&b

3001

ptr

3001

&ptr

1000

*ptr

20
Programao Estruturada

17

Ponteiros em ao

Note que no faz sentido falar em *a ou *b,


pois tais variveis no foram declaradas
como ponteiros.
Se tivssemos declarado outro ponteiro
denominado p2, para coloc-lo apontando
para b, poderamos fazer:

p2 = &b; ou
p2 = ptr; /* SEM ENDEREO!!! pois ptr j contm o
endereo de b */
Programao Estruturada

18

Auto avaliao

O que faz o programa seguinte?

#include <stdio.h>
int main ()
{
int num,valor;
int *p;
num=55;
p=&num;
valor=*p;
printf ("\n\n%d\n",valor);
printf ("Endereco para onde o ponteiro aponta: %p\n",p);
printf ("Valor da variavel apontada: %d\n",*p);
return(0);
}

Programao Estruturada

19

Auto avaliao

O que faz o programa seguinte?

#include <stdio.h>
int main ()
{
int num,*p;
num=55;
p=&num;
printf ("\nValor inicial: %d\n",num);
*p=100;
printf ("\nValor final: %d\n",num);
return(0);
}

Programao Estruturada

20

Ponteiros e tipos de dados


Por que razo os ponteiros
tm que possuir um
determinado tipo e no so
simplesmente ponteiros
genricos?

Programao Estruturada

21

Ponteiros e tipos de dados

Os tipos de dados em C (char, int,


float e double) ocupam diferentes
nmeros de bytes em memria,
podendo, inclusive, o mesmo tipo
ocupar um nmero diferente de bytes
em diferentes arquiteturas, como o
caso do inteiro (dois ou quatro bytes).
Programao Estruturada

22

Ponteiros e tipos de dados

Considere as seguintes declaraes


de variveis:

char a = Z;
int n = 1234;
float pi = 3.1415;

12

34

1002

1003

1000

1001

pi

1004

1005

1006

3.

141

1007

1008

1009

Programao Estruturada

1010

...

23

Ponteiros e tipos de dados


Qual o endereo de uma
varivel com mais de um
byte de comprimento?
O endereo de uma
varivel sempre o menor
dos endereos que ela
ocupa em memria

Programao Estruturada

24

Ponteiros e tipos de dados

Qual o nmero de bytes que ir ser


considerado por cada um dos
ponteiros declarados abaixo?

char *ptr_a = &a;


int *ptr_n = &n;
float *ptr_pi = &pi;

Programao Estruturada

25

Ponteiros e tipos de dados


Um ponteiro para o tipo xyz
enderea sempre o nmero de
bytes que esse tipo ocupa em
memria, isto , enderea
sempre sizeof(xyz) bytes.

Programao Estruturada

26

Ponteiros e tipos de dados

O endereamento de um ponteiro
sempre realizado pelo operador *
(asterisco).

*ptr_a considera sizeof(char) bytes a partir do


endereo contido em ptr_a.

*ptr_n considera sizeof(int) bytes a partir do


endereo contido em ptr_n.

*ptr_pi considera sizeof(float) bytes a partir do


endereo contido em ptr_pi.
Programao Estruturada

27

Ponteiros e tipos de dados


a

12

34

1002

1003

1000

sizeof(float)

sizeof(int)

sizeof(char)

1001

pi

1004

1005

1006

3.

141

1007

1008

1009

1010

ptr_a

ptr_n

ptr_pi

1000

1002

1006

Programao Estruturada

...

28

Auto avaliao

Qual das instrues abaixo correta


para declarar um ponteiro para
inteiro?
a)
b)

c)
d)
e)

*int pti;
*pti;
&i;
int_pti pti;
int *pti;
Programao Estruturada

29

Auto avaliao
Seja a seguinte seqncia de instrues em um programa C:
int *pti;
int i = 10;
pti = &i;
Qual afirmativa falsa?

a)

b)
c)
d)
e)

pti armazena o endereo de i


*pti igual a 10
ao se executar *pti = 20; i passar a ter o valor 20
ao se alterar o valor de i, *pti ser modificado
pti igual a 10

Programao Estruturada

30

Ponteiros e vetores

Os ponteiros so normalmente
utilizados no tratamento e na
manipulao de vetores e strings.
O nome de um vetor corresponde ao
endereo do seu primeiro elemento,
isto , se v for um vetor ento
v == &v[0].
Programao Estruturada

31

Ponteiros e vetores
Embora o nome de um vetor seja um
ponteiro para o primeiro elemento do
vetor, esse ponteiro no pode ser
alterado durante a execuo do
programa a que pertence. Se tal fosse
possvel, estaramos nos arriscando a
perder o vetor previamente declarado.

Programao Estruturada

32

Ponteiros e vetores

Exemplo:

int v[3] = { 10, 20, 30 };


int *ptr;

Existem duas formas de colocar ptr


apontando para o primeiro elemento
de v:

ptr = &v[0];
ptr = v;
Programao Estruturada

33

Ponteiros e vetores

O que faz os trechos de cdigo abaixo?

int v[3] = { 10, 20, 30 };


int *ptr;
ptr = v;
printf(%d %d\n, v[0], *ptr);
ptr = &v[2];
printf(%d %d\n, v[2], *ptr);
Programao Estruturada

34

Ponteiros e vetores
NO ESQUEA: Os elementos de
um vetor ocupam posies
consecutivas de memria, sendo o
nome do vetor igual ao endereo do
primeiro elemento, isto , o menor
endereo do vetor.

Programao Estruturada

35

Aritmtica de ponteiros

Operaes possveis:

incremento
decremento
diferena
comparao

Programao Estruturada

36

Aritmtica de ponteiros

Incremento

Um ponteiro pode ser incrementado como


qualquer varivel.
Um ponteiro para o tipo xyz avana sempre
sizeof(xyz) bytes por unidade de incremento.
Na operao de incremento, podem-se utilizar
os operadores normais:

ptr++;
ptr = ptr + 2;
ptr += 4; /* Se ptr apontar para um float avana 4 * 4 = 16 bytes */
Programao Estruturada

37

Aritmtica de ponteiros

Exemplo: int 2 bytes; ender 1211048978


float 4 bytes; ender 000000 1211048970

...
5.
6.
7.
8.

int x = 5, *px = &x;


float y = 5.0, *py = &y;
printf(%d %1d\n, x, (long) px);
printf(%d %1d\n, x + 1, (long) (px+1));

9.
10.
11.

printf(%f %1d\n, y, (long) py);


printf(%f %1d\n, y + 1, (long) (py + 1));

...
Programao Estruturada

38

Aritmtica de ponteiros

Decremento

O decremento de ponteiros funciona da


mesma forma que o incremento.
Um ponteiro para o tipo xyz recua
sempre sizeof(xyz) bytes por unidade de
decremento.
ptr = ptr -10 /* decrementa de 10 * sizeof(tipo) de ptr */

Programao Estruturada

39

Aritmtica de ponteiros

Exerccio

Escreva um programa que mostre uma string na tela pela


ordem em que est escrita e pela ordem contrria.
...
char s[100];
char *ptr = s;
printf("Digite uma palavra: "); gets(s);
if (*ptr == '\0') return 0;
while (*ptr != '\0')
putchar(*ptr++);
ptr--;

while (ptr >= s)


putchar(*ptr--);
Programao Estruturada

40

Aritmtica de ponteiros

Diferena

A operao de diferena entre dois ponteiros


permite saber quantos elementos existem entre
um endereo e o outro.
Por exemplo , o comprimento de uma string
pode ser obtido atravs da diferena entre o
endereo de caractere \0 e o endereo do
caractere inicial.
A diferena entre dois ponteiros s pode ser
realizada entre ponteiros do mesmo tipo.
ptr1 ptr2
Programao Estruturada

41

Aritmtica de ponteiros

Exerccio

Escreva um programa que mostre na tela o comprimento


de uma string digitada.
...
char c[40], *ptc = c;
printf("Digite uma palavra: ");
gets(c);
if (*ptc == '\0')
return 0;
while(*ptc != '\0')
ptc++;
printf("%s tem %d caracteres\n", c, (int) (ptc - c));
Programao Estruturada

42

Passando variveis para


funes por referncia

O ponteiro utilizado para passar


variveis por referncia.
So variveis que podem ter seu
contedo alterado por funes e
mantm este valor aps o trmino da
funo.

Programao Estruturada

43

Passando variveis para


funes por referncia

Complete o programa a seguir para


apresentar a seguinte sada:

Programao Estruturada

44

Passando variveis para


funes por referncia
#include <stdio.h>
void soma(int, int, int*);
int main(void) {
int iValorA, iValorB, iResultado;
printf(Entre com os valores: );
scanf(%d %d ,&iValorA, &iValorB);
printf(Endereo de iResultado = %d , &iResultado);
soma(iValorA, iValorB, &iResultado);
printf(Soma : %d ,iResultado);
return 0;
}

Programao Estruturada

45

Aritmtica com ponteiros

Com uma varivel do tipo ponteiro,


possvel realizar, operaes de soma
e subtrao.
Ser somada ou diminuda no ponteiro
a quantidade de endereos de
memria relativos ao tipo do ponteiro.

Programao Estruturada

46

Aritmtica com ponteiros

Complete o programa a seguir para


apresentar a seguinte sada:

Programao Estruturada

47

Aritmtica com ponteiros


#include <stdio.h>
int main(void) {
int iValor, *piValor;
char cValor, *pcValor;
printf("Endereco de piValor = %d\n", piValor);
printf("Endereco de pcValor = %d\n", pcValor);

printf("Endereco de piValor = %d\n", piValor);


printf("Endereco de pcValor = %d\n", pcValor);
system("pause");
return 0;
}

Programao Estruturada

48

Vetores e matrizes como


ponteiros

Vetores so ponteiros com alocao


esttica de memria.
O acesso aos ndices do vetor pode ser
realizado atravs de aritmtica de ponteiros.
Existem duas formas para se obter o
endereo (ponteiro) do incio do vetor ou
matriz:

&t[0]
t
Programao Estruturada

49

Vetores e matrizes como


ponteiros

Vetor como ponteiro em C

Programao Estruturada

50

Vetores e matrizes como


ponteiros

Complete o programa a seguir para


apresentar a seguinte sada:

Programao Estruturada

51

Vetores e matrizes como


ponteiros
#include <stdio.h>
#include <string.h>
int main(void) {
char t [5];
strcpy(t,"abcde");
system("pause");
return 0;

Programao Estruturada

52

Vetores e matrizes como


ponteiros
#include <stdio.h>
#include <string.h>
int main(void)
{
char t [5];
strcpy(t,abcde);
printf("\n%d %c", t, *t);
printf("\n%d %c", t+1, *(t+1));
printf("\n%d %c", t+ , *(t+ ));
printf("\n%d %c", t+ , *(t+ ));
printf("\n%d %c", t+4, *(t+4));
return 0;
}

Programao Estruturada

53

Alocao de memria

A alocao esttica ocorre em tempo de


compilao, ou seja, no momento em que se define
uma varivel ou estrutura necessrio que se
definam seu tipo e tamanho.
A alocao dinmica ocorre em tempo de
execuo, ou seja, as variveis e estruturas so
declaradas sem a necessidade de se definir seu
tamanho, pois nenhuma memria ser reservada
ao colocar o programa em execuo.

Programao Estruturada

54

Funes para alocao de


memria

Funo malloc: permite que seja feita a alocao


de uma nova rea de memria para uma estrutura.
void * malloc(int qty_bytes_alloc);

Funo calloc:tem a mesma funcionalidade de


malloc, exceto que devem ser fornecidos o
tamanho da rea e a quantidade de elementos.
void * calloc(int qty, int size);
Programao Estruturada

55

Funes para alocao de


memria

Funo realloc: permite que uma rea previamente


alocada seja aumentada ou diminuda
void * realloc(void * pointer, int new_size);

Funo free: libera uma rea alocada previamente


com a funo malloc, calloc ou realloc.

free( void * pointer);


Programao Estruturada

56

Uso das funes para


alocao de memria

Declarao de vetor como ponteiro


aVetor[10];
int *aVetor;
aVetor = (int *) malloc(10 * sizeof(int *));

Programao Estruturada

57

Uso das funes para


alocao de memria

Declarao de matriz como ponteiro


aMatriz[2][3];
int **aMatriz;
aMatriz = (int **) malloc(2 * sizeof(int *)); /* 2 linhas */
for( i=0; i<2 ; i++ ) {
aMatriz[i] = (int *) malloc(3 * sizeof(int)); /* 3 colunas */
}

Programao Estruturada

58