Professional Documents
Culture Documents
s e Programao
4 Ponteiros
Ponteiro uma varivel que contm o endereo de memria de outra varivel. Da o seu nome, pois ele aponta para outra varivel. possvel ter um apontador para qualquer tipo de varivel
Ministrio da Educao Universidade Federal de Santa Maria Centro de Tecnologia Curso de Engenharia Eltrica Disciplina ELC 1022 Algoritmos e Programao
A seguir, a varivel y fica com o valor da posio de memria cujo endereo se encontra em ip. No exemplo ip aponta para a posio de memria 100 - que o endereo de x. Assim y fica com o valor de x, que 1.
ip=&x; x 1 100 y=*ip; x x=ip; x 1 100 100 100 *ip=3; x 3 100 y y y y 2 200 1 200 2 200 2 200 ip ip ip ip 100 1000 100 1000 100 1000 100 1000
J vimos que o C permite converses de tipos. Assim possvel converter um apontador num inteiro (se tiverem os mesmo tamanhos - em geral 32 bits). O valor de ip na 3 instruo transferido para x. Finalmente transfere-se para o local apontado por ip o valor 3. Como ip contm o endereo de x para a que vai parar o valor 3. Aqui vo dois exemplos de usos simples de ponteiros:
#include <stdio.h> int main () { int num,valor; int *p; num=55; p=# /* Pega o endereco de num */ valor=*p; /* Valor e igualado a num de uma maneira indireta */ 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); } #include <stdio.h> int main () { int num,*p; num=55; p=# /* Pega o endereco de num */ printf ("\nValor inicial: %d\n",num); *p=100; /* Muda o valor de num de uma maneira indireta */ printf ("\nValor final: %d\n",num); return(0); }
Nos exemplos acima vemos um primeiro exemplo do funcionamento dos ponteiros. No primeiro exemplo, o cdigo %p usado na funo printf() indica funo que ela deve imprimir um endereo.
Ministrio da Educao Universidade Federal de Santa Maria Centro de Tecnologia Curso de Engenharia Eltrica Disciplina ELC 1022 Algoritmos e Programao
Ministrio da Educao Universidade Federal de Santa Maria Centro de Tecnologia Curso de Engenharia Eltrica Disciplina ELC 1022 Algoritmos e Programao
3) Qual o valor de y no final do programa? Tente primeiro descobrir e depois verifique no computador o resultado. A seguir, escreva um /* comentrio */ em cada comando de atribuio explicando o que ele faz e o valor da varivel esquerda do '=' aps sua execuo. int main() { int y, *p, x; y = 0; p = &y; x = *p; x = 4; (*p)++; x--; (*p) += x; printf ("y = %d\n", y); return(0); } 4) Escreva um /* comentrio */ em cada comando de atribuio explicando o que ele faz e o valor da varivel esquerda do '=' aps sua execuo. #include <stdio.h> int main() { int *flp, *flq, x; x = 0; flp = &x; flq = &x; *flp = *flq + 10; printf ("*flq + 10 = %d\n", *flp); ++*flp; printf ("++*flp = %d\n", *flp); (*flq)++; printf ("(*flq)++ = %d\n", *flq); flq = flp; return(0); } 5) Simule a execuo do seguinte programa:
#include stdio.h main() { int i, k,*pi,*pk; char a; i = 2; k = 0; puts(Qual sera o valor de k? ); pk = &k; pi = &i; *pk = i; printf(para *pk = i, temos k= %d\n,k); k = *pi; printf(para k = *pi, temos k= %d\n,k); scanf(%c,&a); }
Ministrio da Educao Universidade Federal de Santa Maria Centro de Tecnologia Curso de Engenharia Eltrica Disciplina ELC 1022 Algoritmos e Programao
Ministrio da Educao Universidade Federal de Santa Maria Centro de Tecnologia Curso de Engenharia Eltrica Disciplina ELC 1022 Algoritmos e Programao
for (i=0;i<50;i++) for (j=0;j<50;j++) matrx[i][j]=0.0; return(0); } Usando ponteiros, pode-se reescrever o cdigo conforme demonstrado abaixo: int main () { float matrx [50][50]; float *p; int count; p=&matrx[0][0]; for (count=0;count<2500;count++) { *p=0.0; p++; } return(0); } No primeiro programa, cada vez que se faz matrx[i][j] o programa tem que calcular o deslocamento do ponteiro. Ou seja, o programa tem que calcular 2500 deslocamentos. No segundo programa o nico clculo que deve ser feito o de um incremento de ponteiro. Fazer 2500 incrementos em um ponteiro muito mais rpido que calcular 2500 deslocamentos completos. H uma diferena entre o nome de um vetor e um ponteiro que deve ser frisada: um ponteiro uma varivel, mas o nome de um vetor no uma varivel. Isto significa, que no se consegue alterar o endereo que apontado pelo "nome do vetor". Seja: int vetor[10]; int *ponteiro, i; ponteiro = &i; /* as operaes a seguir so invlidas */ vetor = vetor + 2; /* ERRADO: vetor no varivel */ vetor++; /* ERRADO: vetor no varivel */ vetor = ponteiro; /* ERRADO: vetor no varivel */ /* as operaes a seguir so vlidas */ ponteiro = vetor; /* CERTO: ponteiro varivel */ ponteiro = vetor+2; /* CERTO: ponteiro varivel */
Ministrio da Educao Universidade Federal de Santa Maria Centro de Tecnologia Curso de Engenharia Eltrica Disciplina ELC 1022 Algoritmos e Programao
Strings tm um caractere nulo aps o ltimo elemento. Assim uma verso mais elegante do programa seria: #include <stdio.h> main(){ int i = 0; char rua[] = "nova"; char *ptr = rua; while( *ptr ) printf( "%d> %c\n", i++, *ptr++ ); } Entretanto o loop while permite o seguinte artifcio: *ptr ir parar o loop quando chegar no caractere nulo no final da string. Agora uma outra verso do programa: #include <stdio.h> main(){ int i; char rua[] = "nova"; char *ptr = rua; for (i=0; i<4; i++) printf( "%d> %c\n", i, *(rua+i) ); } Diferena: no ltimo argumento de printf foi usado *(rua+i) em lugar de *ptr++. Isso porque, conforme tpico anterior, o nome de uma array tambm um ponteiro para a mesma e pode ser usado como tal. Tambm poderia usar o clssico rua[i]. As notaes *ptr++ (isto incrementado para cada i), *(rua+i) e rua[i] se equivalem e podem ser usadas sem distino. Entretanto, muitos programadores preferem a notao como ponteiro por ser mais rpida em certas condies. Mas no s isso. Depois de voc se habituar com os ponteiros e de fazer uso intensivo deles, voc ir certamente preferir a notao como ponteiro para dar uma aparncia mais homognea aos seus cdigos. Exerccios: 1) Inverter os elementos de uma string, usando ponteiros: Ex: Dada a string Hoje tem sol retornar los met ejoh. A sada seria a mesma do anterior.
2) Ler uma array de inteiros [5][1] e imprimir os elementos do array usando ponteiros. 3) Considere o seguinte trecho de programa: int a=5, b=6, c=7; int v[10] = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90} int *pt1, *pt2, *pt3; pt1=&a; pt2=&b; pt3=&c; pt1=pt3; pt2=pt3; 7
Ministrio da Educao Universidade Federal de Santa Maria Centro de Tecnologia Curso de Engenharia Eltrica Disciplina ELC 1022 Algoritmos e Programao
*pt1 = *pt2 + *pt3; pt1 = &v[3]; for (int k=0; k<3; k++){ *pt1 = *pt1 + 1000; pt1 = pt1 + 2; } Qual o contedo final: a) Das variveis a, b e c? b) Do vetor v? 4) Considere o seguinte trecho de programa: int a=5, b=6, c=7; int v[10] = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90} int *pt1, *pt2, *pt3; pt1=&a; pt2=&b; pt3=&c; pt2=pt1; *pt3 = *pt2 + 2000; pt1 = &v[8]; for (int k=0; k<2; k++){ *pt1 = *pt1 - 5; pt1 = pt1 - 3; } Qual o contedo final: a) Das variveis a, b e c? b) Do vetor v? 5) Considere o seguinte trecho de programa: int a=5, b=6, c=7; int v[10] = {0, 10, 20, 30, 40, 50, 60, 70, 80, 90} int *pt1, *pt2, *pt3; pt1=&a; pt2=&b; pt3=&c; pt1 = pt2; pt3 = pt2; 8
Ministrio da Educao Universidade Federal de Santa Maria Centro de Tecnologia Curso de Engenharia Eltrica Disciplina ELC 1022 Algoritmos e Programao
*pt2 = *pt3 + 1000; pt1 = v; pt1 = pt1 + 1; for (int k=0; k<2; k++){ *pt1 = *pt1/2; pt1 = pt1 + 4; } Qual o contedo final: a) Das variveis a, b e c? b) Do vetor v?
Exerccios de Reviso
1. Qual das instrues abaixo correta para declarar um ponteiro para inteiro? a) *int pti; b) *pti; c) &i; d) int_pti pti; e) int *pti; 2. Seja a seguinte seqncia de instrues em um programa C: int *pti; int i = 10; pti = &i; Qual afirmativa falsa? a) pti armazena o endereo de i b) *pti igual a 10 c) ao se executar *pti = 20; i passar a ter o valor 20 d) ao se alterar o valor de i, *pti ser modificado e) pti igual a 10 3. Seja a seguinte seqncia de instrues em um programa C: int *pti; int veti[]={10,7,2,6,3}; pti = veti; Qual afirmativa falsa? a) *pti igual a 10 b) *(pti+2) igual a 2 c) pti[4] igual a 3 d) pti[1] igual a 10 e) *(veti+3) igual a 6 4. Na seqncia de instrues abaixo: float f; float *pf; pf = &f; scanf("%f", pf); 9
Ministrio da Educao Universidade Federal de Santa Maria Centro de Tecnologia Curso de Engenharia Eltrica Disciplina ELC 1022 Algoritmos e Programao
a) b) c) d) e)
Efetuamos a leitura de f No efetuamos a leitura de f Temos um erro de sintaxe Deveramos estar usando &pf no scanf Nenhuma das opes anteriores
5. Verifique o programa abaixo. Encontre o seu erro e corrija-o para que escreva o numero 10 na tela. #include <stdio.h> int main() { int x, *p, **q; p = &x; q = &p; x = 10; printf("\n%d\n", &q); return(0); } 6. O que est errado com os programas abaixos? Descubra e indique a soluo para consert-los. Execute-o no computador para ver se o erro foi resolvido. a) void main() /* esse programa esta errado */ { int x, *p; x = 10; *p = x; } b) void main() /* esse programa esta errado */ { int x, *p; x = 10; p = x; printf ("%d", *p); } 7. Simule a execuo do programa abaixo: #include stdio.h main() { int i,k,*pi,*pk; char a; i = 2; k = 0; puts(Qual sera o valor de k? ); pk = &k; pi = &i; *pk = i; printf(para *pk = i, temos k= %d\n,k); k = *pi; printf(para k = *pi, temos k= %d\n,k); scanf(%c,&a); 10
Ministrio da Educao Universidade Federal de Santa Maria Centro de Tecnologia Curso de Engenharia Eltrica Disciplina ELC 1022 Algoritmos e Programao
} 8. Simule a execuo do programa abaixo: main() { int x,y,*px,*py; printf(Digite um valor: ); scanf(%d,&x); px = &x; y = *px; printf(digitou= %d e y= %d\n,x,y); *px = 8; printf(valor mudou para %d\n,x); } 9. Simule a execuo do programa a seguir: main() { char a,b,*p; b = c; p = &a; *p = b; printf(%c,a); } 10. Escreva uma declarao para armazenar os seguintes valores em um vetor chamado rates: 12.9, 18.6, 11.4, 9.5, 15.2, 17.6. inclua a declarao em um programa que indique os valores no vetor usando a notao do ponteiro. 11. Escreva um programa em C para ler uma string e um nmero n e eliminar os n caracteres do incio da string. A string resultante deve ser mostrada na tela. Por exemplo, lida a string programa e o nmero 3, deve mostrar na tela a palavra grama. 12. Escrever um programa em C que l um caractere e uma string de at 20 caracteres, e passe estes valores para uma funo que elimine as ocorrncias do caractere na string. A string deve ser recebida como um ponteiro, e manipulada sem o uso de ndices.
11