You are on page 1of 9

Ponteiros - Introduo

Ponteiros so um dos recursos mais poderosos da linguagem C e de outras. Qualquer programa de utilidade prtica escrito em C dificilmente dispensar o uso de ponteiros. A tentativa de evit-los implicar quase sempre cdigos maiores e de execuo mais lenta. Para quem est comeando, pode parecer (e algumas vezes ) um tanto difcil. Mas no h outro caminho seno enfrentar a realidade. So muitas as aplicaes de ponteiros. A seguir, relao das mais comuns. Acessar endereos de memria que o programa aloca em tempo de execuo. Acessar variveis que no so visveis em uma funo. Manipulao de arrays. Manipulao de strings.

Definio e Declarao
Os ponteiros so variveis que contm endereos de memria com valores. Normalmente, uma varivel faz uma referncia direta a um valor especfico. Um ponteiro, por outro lado, contm um endereo de uma varivel que contm um valor especfico. Sob esse ponto de vista, um nome de varivel faz uma referncia direta a um valor, e um ponteiro faz referncia indireta a um valor. Diz-se que fazer referncia a um valor por meio de um ponteiro fazer uma referncia indireta. Os ponteiros, como quaisquer outras variveis, devem ser declarados antes de serem usados. Conforme qualquer varivel em C, o ponteiro deve ser declarado antes de ser usado. Basta inserir o operador indireto (*) aps o tipo da varivel

int *ptr;
Essa declarao define a varivel ptr como um ponteiro para uma varivel do tipo int (nmero inteiro). A declarao de ponteiro no tem o mesmo significado da declarao de uma varivel. Ela indica apenas o tipo de objeto de dados apontado e, desde que contm endereo de

memria, o tamanho em bytes que ocupa no tem relao com o tamanho do objeto apontado. O tamanho do ponteiro fixo e depende apenas do modelo de memria do sistema (2 bytes ou 4 bytes, normalmente). Para declarar mais de um ponteiro por linha, usa-se um operador indireto (*) para cada

char *ch1, *ch2; (so ponteiros para o tipo char).


Se um operador for omitido (exemplo: char *ch1, ch2;), a varivel correspondente no ser ponteiro e, certamente, provocar erro de execuo se usada como tal. O ponteiro pode ser declarado para qualquer tipo legal de varivel em C (char, int, float, double, etc), alm de void, que seria um genrico, podendo apontar para qualquer tipo de dado.

Inicializando um Ponteiro
A simples declarao de um ponteiro no o faz til. necessria a indicao da varivel para a qual ele aponta.

int var; int *ptr; var = 10; ptr = &var;

Na sequncia acima, so declarados uma varivel tipo int (var) e um ponteiro para o mesmo tipo (ptr). A terceira linha atribui o valor 10 a var e a ltima linha inicializa o ponteiro ptr.
Observa-se o uso do operador de endereamento (&) para inicializao do ponteiro. Isso significa, no cdigo ptr = &var;, que ptr passa a conter o endereo de var, no o seu valor. Supondo que o sistema endereado por 2 bytes, a Figura acima d uma idia grfica dessa associao: o contedo de ptr 4052, que o endereo do primeiro byte da varivel var (ptr ocupa 2 bytes por causa do endereamento do sistema e var tambm ocupa 2 bytes, mas por ser do tipo int). O valor 4052 para a posio de memria de var apenas ilustrativo. Na prtica, depender do local de memria onde o programa foi carregado. Com ptr apontando para var, possvel realizar operaes com esta ltima de forma indireta, a partir de ptr. Exemplos a seguir.

Acrescentando a linha

int newVar = *ptr;

ao cdigo anterior, o valor de newVar 10, que o valor de var lido indiretamente atravs de ptr.

E a linha

*ptr = 20;

modifica o valor de var para 20, ou seja, altera de forma indireta atravs de ptr.

importante lembrar que um ponteiro declarado e no inicializado poder ter contedo nulo ou aleatrio, a depender da alocao sistema. Nessa condio, se o contedo apontado for modificado, algumas posies de memria tero seus valores indevidamente alterados e as conseqncias sero imprevisveis.

Exerccio / meu primeiro ponteiro #include <stdio.h> int main () { int a; // a um inteiro int *aPtr; // aPtr um ponteiro para um inteiro a = 7; aPtr = &a; // aPtr define o endereo de a printf(O endereo de a %p \n O valor de aPtr e %p\n\n,&a, aPtr); printf(O valor de a %d \n O valor de *aPtr e %d\n\n,a, *aPtr); }

Ponteiro para Estruturas


Ponteiros para estruturas so escritos de forma similar aos anteriores. A principal diferena o uso do operador -> para acesso aos membros. Seja exemplo a seguir.

#include <stdio.h> struct telelista{ char nome[15]; char ddd[2]; char num[10]; }; struct telelista *ptr; main() { struct telelista pedro={"Pedro", "99", "123-456"}; ptr = &pedro; printf( "%s", ptr->nome ); }
No programa acima, aps a declarao da estrutura, definido um ponteiro dela (ptr) de forma similar aos ponteiros de outros tipos. A linha ptr = &pedro; inicializa o ponteiro e, como argumento de printf, usado o operador de ponteiro para estrutura

ptr->nome

Essa declarao tem o mesmo efeito da sem ponteiro pedro.nome.

Estruturas Auto-Referenciadas
Contm um membro que aponta para uma estrutura do mesmo tipo

struct node { int data; struct node *nextPrt; }

Alocao Dinmica da Memria


Varivel Dinmica: uma varivel criada (e destruda) explicitamente durante a execuo do programa Objetivo: utilizar a memria sob demanda. Uma varivel dinmica no declarada, pois ela no existe antes da execuo do programa. A referncia a ela feita por meio de uma varivel ponteiro que contm o valor do endereo da varivel dinmica. Quando um ponteiro contm o endereo de uma varivel, dizemos que o ponteiro est apontando para essa varivel. Ao declarar uma varivel ponteiro, deve-se declarar o tipo de valor para o qual ela aponta. Funo Malloc reserva espao de memria. Utiliza como argumento o nmero de bytes a serrem alocados e retorna um ponteiro do tipo void* (ponteiro para void) para a memria alocada.

Pont = (struct Treg *) malloc (sizeof(struct


varivel A funo free libera a memria alocada.

TReg));

Funo Sizeof quantidade de bytes necessrios para armazenar o tipo de dados ou

Exerccios _______________________________________________________________
1) Observe o programa abaixo e identifique a sada do printf. Desenhe um esquema de memria contendo x, p1 e p2 (estime os endereos atribudos a cada varivel).

# include <stdio.h> int main () { int x, *p1, *p2; p1 = &x; p2 = p1; printf ("%d", p2); }
2) Execute o programa abaixo passo a passo no compilador e registre em papel os endereos alocados para cada varivel (inclusive os ponteiros). Observe o que acontece no decorrer do programa e no final. Tente entender o que o programa faz e explique porque acontece o erro de execuo ao final.

# include <stdio.h> int main () { int x, *p, *q, i, k=0; q = p = &x; for (i=1; i <= 3; i++) { scanf ("%d", p); p++; } p--; while (p >= q) { k = k + *p; p--; } printf ("%d", k); }
Inverta a ordem de declarao das variveis e observe o que acontece. 3) Observe os programas abaixo e identifique o erro cometido em cada um no uso de ponteiros.

int main () { int x, *p; x = 10; *p = x; }


________________________________________________

int main () { int x, *p; x = 10; p = x; printf (%d, *p); }


________________________________________________

int main () { char s[80], y[80]; char *p1, *p2; p1 = s; p2 = y; if (p1 < p2) .... }
________________________________________________

int main () { int primeiro[10], segundo[10]; int *p, t; p = primeiro; for (t = 0; t < 20; ++t) *p++ = t; }
________________________________________________

int main () /* deve ler vrias strings, (at fim) e mostrar cada string com 1 letra por linha */ { char *p1, s[80]; p1 = s; gets (s); while (strcmp (s, fim) != 0) { while (*p1 != NULL) printf (%c\n, *p1++); gets (s); } }

4) Para o cdigo abaixo:

#include<stdio.h> #include <alloc.h> int main () { int y, x, k, *p,*q; p = &x; q = (int *)malloc(6 * sizeof(int)); for(y = 0; y< 3; y=y+1) { p--; scanf(%d, p); p++; scanf(%d, p); *q = k; *(q+1) = x; q = q + 2; } }

a) Desenhe o esquema de memria mostrando a localizao das variveis do programa, at a linha 5 (inclusive). Mostre o contedo de p e q. Considere 100 como o endereo de incio de atribuio das variveis e 200 para a rea de alocao de memria, o tamanho de inteiro como 4 bytes e o tamanho de um ponteiro como 4 bytes. b) Desenhe o esquema de memria mostrando a localizao e contedo das variveis do programa ao final da execuo, se forem digitados: 50, 30, 20, 10, 40, 80. c) Indique o valor dos itens abaixo aps a execuo da linha 13. pela primeira vez: I. q[0] II. &q