Download - Linguaguem de Programação II Aula 5 Ponteiros Prof. Luiz José Hoffmann Filho [email protected]
Ponteiros• O que são ponteiros?
o Um ponteiro é uma variável que contém um endereço de memória. Esse endereço é normalmente a posição de uma outra variável na memória. Se uma variável contém o endereço de uma outra, então a primeira variável é dita para apontar para a segunda.
Ponteiros
1003
JOSE
Variável na
memória
Endereço na
memória
1001
1000
1002
1003
1004
1005
Ponteiros• Declaração:
o<tipo> *<nome da variável>;
• Exemplo:
o int *valor;o char *nome;
Ponteiros• Os operadores de Ponteiros:
o & - é um operador unário que devolve o endereço na memória do seu operando.
o Exemplo:• m = &count;
o * - é o complemento de &. É um operador unário que devolve o valor da variável localizada no endereço que o segue.
o Exemplo:• q = *m;
Ponteiros• Atribuição de ponteiros:#include <stdio.h>int main() {
int x;int *p1, *p2;x = 1000;p1 = &x;p2 = p1;printf("%p \n", p2); /*escreve o endereço de x, não seu valor*/printf("%d \n", *p2); /* escreve o valor de x */return 0;
}
Ponteiros• Aritmética de ponteiros:
o int *p1;o p1 = &x; /* supondo que a posição de x é igual a 2000 */o p1++; /* incrementando em uma posição, agora vale 2001*/o P1--; /* decrementando em uma posição, agora vale 2000*/o P1 = p1 +10; /* Soma de posições, agora vale 2010*/
• Comparação de ponteiros:o If (p<q) o printf(“p aponta para uma memória mais baixa que q”);o If (p == q) o printf(“p aponta para a memória mesma que q”);
Exercícios• Explique a diferença entre:
o p++;o (*p)++;o *(p++);
• O que quer dizer *(p+10);?• Explique o que você entendeu da comparação
entre ponteiros.
Exercícios• Qual o valor de y no final do programa? Tente primeiro
descobrir e depois verifique no computaadore o resultado. A seguir, escreva um /*comentário */ em cada comando de atribuição explicando o que ele faz e o valor da variável à esquerda do ‘=’ após sua execução.
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);}
Ponteiros• Ponteiros e Matrizes:
char str[80], *p1;p1 = str;
o p1 foi inicializado com o endereço de primeiro elemento da matriz str.o Para acessar o quinto elemento de str:
str[4];*(p1+4);
• Vetor/Matriz de Ponteiros:int *x[10];x[2] = &var;
o Atribuir o endereço a variável var a uma posição do vetor*x[2];
o Valor de var.
Ponteiros – Vetores/Matriz
• Programa para zerar uma matriz:int main() {float matrx[50][50];int i, j;for (i=0; i<50; i++) {for(j=0;j<50; j++) {matrx[i][j] =0.0;}}return(0);}Agora faça utilizando ponteiros?
Ponteiros – Vetores/Matriz
Programa para zerar um matriz usando ponteiros:int main() {float matrx[50][50];int i;float *p; p = matrx[0];for (i=0; i<2500; i++) {*p=0.0;p++;}return(0);}
Ponteiros – vetor/matriz
• Existe uma diferença entre o nome de um vetor e um ponteiro que deve ser frisada: um ponteiro é uma variável , mas o nome de um vetor não é uma variável. Isto significa que não se consegue alterar o endereço que é apontando pelo “nome do vetor”.
int vetor[10];int *p, i;p = &i;/* operações invalidas */vetor = vetor + 2;vetor++;vetor = ponteiro;/* operações validas */ponteiro = vetor;ponteiro = vetor + 2;
Ponteiros – Strings• Seguindo o raciocínio, nomes de strings, são do tipo char*. Isto nos permite
escrever a nossa função StrCpy(), que funcionará de forma semelhante à função strcpy() da biblioteca:
#include <stdio.h>#include <stdlib.h>void StrCpy(char *destino, char *origem) {
while(*origem) {*destino = *origem;origem++;destino++;
}*destino = '\0';
}int main() {
char str1[100], str2[100], str3[100];printf("Entre com um string: ");scanf("%s", str1);StrCpy(str2, str1);StrCpy(str3, "Voce digitou a String ");printf("\n\n %s%s", str3, str2);return (0);
}
Ponteiros• Vetor de ponteiros:
o int *pmatrx[10];É um vetor que armazena 10 ponteiros para inteiros.
Exercícios – Ponteiros + vetores
• Fizemos a função StrCpy(). Faça a função StrLen() e StrCat() que funcionem como a função strlen() e strcat() de string.h respectivamente.
Ponteiros• Indireção mútipla:
int main() {int x, *p, **q;x = 10;p = &x;q = &p;printf(“%d”, **q);return 0;
}• Inicialização de ponteiros:
o int *p = NULL;o char *p = “alo mundo”;
Exercício – Intereção múltiplas
• Verifique o programa abaixo. Encontre o seu erro e corrija-o para que escreva o número 10 na tela.int main() {
int x, *p, **q;p = &x;q = &p;X = 10;printf(“%d”, &q);return 0;
}
Inicialização de ponteiros
• Grande problema, quando não inicializamos um ponteiro, ele provavelmente irá apontar para “lixo”;
• Sempre inicializar um ponteiro com “NULL” ou algum valor válido.
Inicialização de ponteiros
#include <stdio.h>#include <string.h>int main() {
char *p = "Alo mundo";int i;printf("%s\n", p);for (i = strlen(p) -1; i > -1;i--) { printf( "%c ", p[i]);}
printf("\n");return;
}
Ponteiros• Alocação dinâmica: stdlib.h
o Malloc = aloca memóriaint *p;If (!(p=malloc(50*sizeof(int)) {
Printf(“sem memória.\n”);Return 0;
}o Free = desaloca memória
free(p);
Ponteiros – Alocação de matriz
#include <stdio.h>#include <string.h>int main() {
char *s;int t;s = malloc(80);if (!s) return 0;scanf("%s",s);for ( t = strlen(s) - 1; t >= 0; t--) printf("%c", s[t]); free(s);return 0;
}
ExemploComo exemplo de uso destas funções considere o problema de reservar n posições para armazenar variáveis do tipo int. Para isto usamos o trecho de programa mostrado em 5. Observe que após alocar o espaço foi usada a notação de vetores comuns.#include < stdlib .h >#include < stdio .h >int main (void){ int i , n , * pvetor ; float media ; /* Define um valor para n , scanf ou n = */ scanf ( " % d " , & n ); /* aloca espaco na memoria */ pvetor = (int *) malloc ( n * s i z e o f(int)); i f (! pvetor ) { puts ( " Sem memória . " ); return 1;
} /* A PARTIR DE AGORA VOLTAMOS PARA VETORES COMUNS */ /* aqui uso pvetor , vamos ler um vetor */ for (i = 0; i < n ; i ++) { scanf ( " % d " , &pvetor[ i ]); } /* faco alguma coisa */ media = 0.0; for (i = 0; i < n ; i ++) { media += pvetor [ i ]; } printf ( " % f \ n " , media ); /* aqui nao preciso mais de pvetor */ free ( pvetor ); return 0; }
Problemas com ponteiros 1
int main () {int x, *p;x = 10;*p = x;
}Ele atribui o valor 10 a alguma posição de memória desconhecida. O ponteio p nunca recebeu um valor.Como seria a forma correta?p = &x;
Problemas com ponteiros 2
int main () {int x, *p;x = 10;p = x;printf(“%d\n”, *p);
}• Printf não imprime o valor de x, que é 10, na tela.
Imprimi algum valor desconhecido por que a atribuição “p = x” esta incorreta.
• A forma correta é: “p = &x”
Problema com ponteiros 3
char s[80], y[80];char *p1, *p2;p1 = s;p2 = y;If (p1<p2) ….Problema fazer uma “suposição” que os vetores são contiguos.Fazer comparação entre ponteiros que não apontam para um objeto comum produz resultados inesperados.
Problema com ponteiros 4
int first[10], second[10];int *p, t;p = first;for(t=0;t<20; t++)
*p++ =t;Achar que dois vetores diferentes são adjacentes na memória.
Problema com ponteiros 5
int main() {char *p1, s[80];p1 = s;do {
gets(s);while(*p1)
printf(“ %d”,*p1++);} while (strcmp(s, “done”));return;
}Qual o problema aqui?Como posso resolver este problema?
Problema com ponteiros 5
int main() {char *p1, s[80];do {
p1 = s;gets(s);while(*p1)
printf(“ %d”,*p1++);} while (strcmp(s, “done”));return;
}
Exercícios• Escreva um programa que declare uma matriz
100x100 de inteiros. Você deve inicializar a matriz com zeros usando ponteiros para endereçar seus elementos. Preencha depois a matriz com os números de 1 a 10000, também usando ponteiros.
Bibliografia• Schildt, Herbet. C Completo e Total, 3ª ed. São
Paulo. Markron Books, 1996.