Você está na página 1de 22

UNIME

Estrutura de Dados Ponteiros e Alocao

Wanja Mascarenhas

Ponteiros - Definio
Ponteiros so endereos, isto , so variveis que contm um endereo de memria. Se uma varivel contm o endereo de outra, ento a primeira (o ponteiro) aponta para a segunda.

A
5

B
8

X
1022

Nome das Variveis Informao de Memria Endereos de Memria

1022

1038 1042 1061 1084 1092

X o ponteiro, aponta para o inteiro A. So ferramentas que nos possibilitam manipular endereos de memria e informaes contidas nesses endereos.
Cuidado: No so inicializados.

PONTEIROS
Definio
tipo do ponteiro *nome_variavel; (int, float, ...)

Uso
Permite a modificao dos argumentos das funes atravs da referncia ao endereo de memria; Permite o uso de rotinas de alocao dinmica; Em alguns casos aumenta a eficincia dos programas.

PONTEIROS
Operadores

Permite acessar o contedo de uma varivel, cujo endereo o valor do ponteiro.

Devolve o valor endereado pelo ponteiro. Obs: No confundir com o operador aritmtico de multiplicao de mesmo smbolo. Sendo que na declarao indica o tipo da varivel. ex.: int *p; Na manipulao retorna o contedo ex.: int n1=10, n2, *p; p = &n1; n2 = *p;

&

Fornece o endereo de determinada varivel. Atribui o endereo de uma varivel para um ponteiro. Obs: No confundir com o operador lgico de operaes de baixo nvel, de mesmo smbolo. p = &n1; // o ponteiro inicializado

PONTEIROS - Operadores
main () { int num=25; int *pont; // * (asterisco) indica o tipo da varivel pont = # //pont recebe o endereo de num

printf("\nO endereco num: %p \tconteudo num: %d",&num,num); printf("\nO conteudo pont: %p \t",pont); printf("\n\nO endereco pont: %p \tconteudo do endereco pont: %d\n\n",&pont,*pont);
O endereco num: 0022FF7C O conteudo pont: 0022FF7C O endereco pont: 0022FF78 conteudo num: 25 conteudo do endereco pont: 25

*pont=230; /* Muda o valor de num de uma maneira indireta */ printf ("\nValor final de num: %d\n\n",num); }
Valor final de num: 230

PONTEIROS - Operadores
int *p1, *p2, n=15; printf("\nO endereco de p1: %p p2: %p n: %p",&p1,&p2,&n); O endereco de p1: 0022FF74 p2: 0022FF70 n: 0022FF6C p1 =&n; p2 = p1; printf("\nO conteudo de p1: %p p2: %p",p1,p2); O conteudo de p1: 0022FF6C p2: 0022FF6C printf("\nO conteudo endereco de p1: %d p2: %d",*p1,*p2); O conteudo endereco de p1: 15 p2: 15 *p1=*p2; printf("\nO conteudo p1: %d p2: %d\n\n",*p1,*p2); O conteudo p1: 15 p2: 15 int n1,n2, *p; n1 =10; printf("\nn1: %d endereco n1: %p\n\n",n1,&n1); n1: 10 endereco n1: 0022FF74 p = &n1; printf("\nconteudo de p que eh o endereco n1: %p endereco p: %p\n",p,&p); conteudo de p que eh o endereco n1: 0022FF74 endereco p: 0022FF6C n2 = *p; printf("\nn1: %d n2: %d p: %d \n\n",n1,n2,*p); n1: 10 n2: 10 p: 10

PONTEIROS Operaes
Igualar dois ponteiros p1 = p2; // iguala os endereos *p1=*p2; // iguala os contedos Os ponteiros assim como quaisquer variveis precisam ser inicializados antes de serem utilizados. Incremento e Decremento No incremento o ponteiro passa apontar para o prximo valor do mesmo tipo para o qual o ponteiro aponta. O compilador usa o tipo do ponteiro para calcular a prxima posio de memria. p++; /* S muda a posio de memria no o contedo */ p--;

PONTEIROS Operaes
Operaes com o contedo dos ponteiros (*p)++; *(p+10);
// soma 1 ao contedo do ponteiro /*recupera o contedo do ponteiro 10 posies adiante, cuidado, no sabemos o que tem neste endereo */

Operaes relacionais com ponteiros p1 > p2 Operaes que NO podem ser feitas com ponteiros Dividir ou multiplicar ponteiros; Adicionar dois ponteiros; Adicionar ou subtrair floats ou doubles de ponteiros.

PONTEIROS Exerccios
1) Explique a diferena entre: p++; (*p)++; *(p++); 2) O que quer dizer *(p+10);? 3) Qual o resultado em cada printf?
y = 2; p = &y; printf ("\n\tconteudo p: %d\n",*p); x = *p; (*p)++; printf ("\n\tconteudo p: %d x: %d\n",*p,x); x--; printf ("\n\n\tx: %d conteudo p: %d\n\n",x,*p); (*p) += x; printf ("\n\n\ty = %d conteudo p: %d\n\n\n", y,*p);

Ponteiros - Exemplo
Exemplo 1: Utilizao dos operadores & e *. #include <stdio.h>; m obtm o endereo de memria main() varivel origem. { int destino, origem; int *m; destino recebe a origem = 10; informao contida no m = &origem; endereo apontado por m. destino = *m; printf(O resultado : %i,destino); }
da

Declarao de um ponteiro.

destino origem
10 10

m
1061

Nome das Variveis Informao de Memria Endereos de Memria

1038

1061

1092

Ponteiros - Exemplo
Exemplo 2: Atribuio de ponteiros
Declarao ponteiros. dos

end2 recebe a posio de memria da varivel origem que est guardada em end1.

#include <stdio.h>; Main() { float destino, origem; end1 recebe o endereo de memria da varivel origem. float *end1, *end2; origem = 5.5; end1 = &origem; destino recebe a informao end2 = end1; contida no endereo apontada por end2. destino = *end2; printf(O resultado : %f,destino); }

destino origem end1 end2


5.5 5.5 1038 1038

Nome das Variveis Informao de Memria Endereos de Memria

1022

1038

1084

1092

VETORES x PONTEIROS
Existe uma relao entre Vetores/Matrizes, pois quando um vetor ou matriz declarado apenas indicado o endereo da primeira posio. Logo as expresses abaixo so equivalentes: nome_da_varivel[ndice] e *(nome_da_varivel+ndice) LEMBRE-SE: p[t] o mesmo que *(p+t)

ALOCAO DINMICA
A alocao dinmica permite ao programador alocar memria para variveis quando o programa est sendo executado. Assim, poderemos definir, por exemplo, um vetor ou uma matriz cujo tamanho solicitado em tempo de execuo. A alocao dinmica muito utilizada em problemas de estrutura de dados, por exemplo, listas encadeadas, pilhas, filas, arvores binrias e grafos. A memria alocada deve ser obtida do heap ( a regio de memria livre do computador). Desta forma necessrio verificar se a memria livre suficiente para o armazenamento. O padro C ANSI define apenas 4 funes para o sistema de alocao dinmica, disponveis na biblioteca stdlib.h:

malloc (x) calloc realloc free (x)

ALOCAO DINMICA - malloc


Prottipo da funco: void *malloc (unsigned int num); malloc (memory allocation) . Aloca na memria um bloco de bytes consecutivos e retorna o endereo desse bloco em um ponteiro void * (genrico) para o primeiro byte alocado. O ponteiro void * pode ser atribudo a qualquer tipo de ponteiro. Se no houver memria suficiente para alocar a memria requisitada a funo malloc() retorna um ponteiro nulo. int *p; int qtde; // ser definida a quantidade de elementos a serem alocados printf(\nInforme a quantidade de elementos ); scanf(%d,&qtde); p=(int *)malloc(qtde*sizeof(int)); // o uso da funo sizeof torna o programa portvel if (!p) { // if (p==NULL) printf ("** Erro: Memoria Insuficiente **"); exit(0); }

ALOCAO DINMICA - free


Prottipo da funco: void free (void *p); Libera a memria alocada dinamicamente. As variveis alocadas estaticamente dentro de uma funo desaparecem quando a execuo da funo termina. J as variveis alocadas dinamicamente continuam a existir mesmo depois que a execuo da funo termina. Se for necessrio liberar a memria ocupada por essas variveis, preciso recorrer funo free. Passamos para free() o ponteiro que aponta para o incio da memria alocada.
int *p; int qtde; printf(\nInforme a quantidade de elementos ); scanf(%d,&qtde); p=(int *)malloc(qtde*sizeof(int)); if (!p) { // if (p==NULL) printf ("** Erro: Memoria Insuficiente **"); exit(0); }

free(p);

ALOCAO ESTTICA VETOR


necessrio saber de antemo a dimenso mxima do vetor; Varivel que representa o vetor (nome) armazena o endereo ocupado pelo primeiro elemento do vetor; Se o vetor for declarado dentro do corpo de uma funo no pode ser usado fora do corpo da funo #define N 10 int v[N];

ALOCAO DINMICA VETOR


A dimenso do vetor pode ser definida em tempo de execuo; Varivel do tipo ponteiro recebe o valor do endereo do primeiro elemento do vetor; A rea de memria ocupada pelo vetor permanece vlida at que seja explicitamente liberada (atravs da funo free). O vetor alocado dentro do corpo de uma funo pode ser usado fora do corpo da funo, enquanto estiver alocado. int* v, qtde; v = (int*) malloc(qtde * sizeof(int));

ALOCAO
Com a alocao dinmica de vetores podemos referenciar o nome do vetor como um ponteiro constante. Com isso possvel indexar o nome de um vetor, e como consequncia podemos tambm indexar um ponteiro qualquer.

alocar_vetor.cpp alocar_vetor.exe

alocar_vetor.cpp

#include <stdio.h> #include <stdlib.h> float *Alocar_vetor_real (int n); float *Liberar_vetor_real (int n, float *v);

// Funo Alocao // Funo libera rea alocada

main () // Incio do Programa { float *p,*aux; int tam,i,; printf("\nInforme o tamanho do vetor: "); scanf("%d",&tam); p = Alocar_vetor_real (tam); aux=p; // guarda o endereo inicial de p for (i=0;i<tam;i++) { //carrega dados no vetor printf("\nInforme o elemento %d do vetor: ",i+1); //scanf("%f",&p[i]); // leitura com notao de vetor scanf("%f",p); p++; } // leitura com notao de ponteiro p=aux; //recupera o endereo inicial de p for (i=0;i<tam;i++) { //exibe dados do vetor //printf("\nElemento %d eh: %f ",i+1,p[i]); //impresso com notao de vetor printf("\nElemento %d eh: %.2f ",i+1,*p); p++; } //impresso com notao de ponteiro p = Liberar_vetor_real (tam, p); printf("\n\n"); system("pause"); } //fim do programa

alocar_vetor.cpp
float *Alocar_vetor_real (int n) // Funo Alocao { float *v; /* ponteiro para o vetor */ if (n < 1) { /* verifica parametros recebidos */ printf ("** Erro: Parametro invalido **\n"); return (NULL); v = (float *) malloc (n*sizeof(float)); /* aloca o vetor */ if (v == NULL) { printf ("** Erro: Memoria Insuficiente **"); return (NULL); return (v); } /* retorna o ponteiro para o vetor */

} }

float *Liberar_vetor_real (int n, float *v) // Funo libera rea alocada { if (v == NULL) return (NULL); free(v); /* libera o vetor */ return (NULL); }/* retorna o ponteiro */

Ponteiros e Vetores
Inicialmente temos que esclarecer que o nome de um vetor um ponteiro. Dessa forma podemos trabalhar com vetores de duas formas. veja os cdigos a seguir. main () main () { float vet[10]; int i; for (i=0;i<10;i++) { vet[i]=0.0; printf("\n %f",vet[i]); } getchar(); }
{ float vet[10], *p; int i; p=vet; for (i=0;i<10;i++) { *p=0.0; p++; } for (i=0;i<10;i++) { printf("\n %f",vet[i]); p++; } getchar(); }

No 1a cdigo, cada vez que se faz vet[i] o programa tem que calcular o deslocamento para dar ao ponteiro. Ou seja, o programa tem que calcular 10 deslocamentos. No segundo o nico clculo que deve ser feito o de um incremento de ponteiro, que muito mais rpido que calcular 10 deslocamentos completos.

Exerccios
1.

Crie um programa para preencher os elementos de vetor com um certo valor. Para varrer o vetor, no utilize ndices, use apenas aritmtica de ponteiros. Faa isto para os vetores de inteiros e de reais. Escreva um programa que solicita ao usurio um vetor de notas e imprima: mdia aritmtica das notas, a maior e a menor nota e a quantidade de notas acima da mdia aritmtica calculada. Faa um programa para alocar espao para colocar o nome de uma pessoa (50 caracteres). Se conseguir alocar leia esta string e mostre-a ao contrrio.

2.

3.

Você também pode gostar