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
Endereço
na memória
Variável na
memória
1000
1003
1001
1002
1003
1004
1005
JOSE
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
o
o
o
o
int *p1;
p1 = &x; /* supondo que a posição de x é igual a 2000 */
p1++; /* incrementando em uma posição, agora vale 2001*/
P1--; /* decrementando em uma posição, agora vale 2000*/
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
o
o
p++;
(*p)++;
*(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ória
int *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;
}
Exemplo
Como exemplo de uso destas funções
return 1;
considere o problema de reservar n
}
posições para armazenar variáveis do
/* A PARTIR DE AGORA VOLTAMOS
tipo int. Para isto usamos o trecho de
PARA VETORES COMUNS */
programa mostrado em 5. Observe que
/* aqui uso pvetor , vamos ler um
após alocar o espaço foi usada a
vetor */
notação de vetores comuns.
for (i = 0; i < n ; i ++) {
#include < stdlib .h >
scanf ( " % d " , &pvetor[ i ]);
#include < stdio .h >
}
int main (void)
/* faco alguma coisa */
{
media = 0.0;
int i , n , * pvetor ;
for (i = 0; i < n ; i ++) {
float media ;
media += pvetor [ i ];
/* Define um valor para n , scanf ou n
}
= */
printf ( " % f \ n " , media );
scanf ( " % d " , & n );
/* aqui nao preciso mais de pvetor */
/* aloca espaco na memoria */
free ( pvetor );
pvetor = (int *) malloc ( n * s i z e o
f(int));
return 0;
i f (! pvetor ) {
}
puts ( " Sem memória . " );
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.
Download

PPT