Buscar

02 Ponteiros em C Parte II - Ponteiros e Vetores

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes
Você viu 3, do total de 4 páginas

Faça como milhares de estudantes: teste grátis o Passei Direto

Esse e outros conteúdos desbloqueados

16 milhões de materiais de várias disciplinas

Impressão de materiais

Agora você pode testar o

Passei Direto grátis

Você também pode ser Premium ajudando estudantes

Prévia do material em texto

1 
LINGUAGEM E TÉCNICA DE PROGRAMAÇÃO I 
 
Profa. Gisele Busichia Baioco 
gisele@ceset.unicamp.br 
 
 
Algoritmos Estruturados e 
Linguagem de Programação Estruturada 
 
Ponteiros em C 
Parte II – Ponteiros e Vetores 
1 Introdução 
A linguagem C permite, essencialmente, dois métodos de acesso aos elementos de um 
vetor: a indexação do vetor e a aritmética dos ponteiros. 
 A aritmética dos ponteiros é mais rápida que a indexação de vetores, pois C leva muito 
mais tempo para indexar um vetor do que para usar um operador *. Pode-se considerar, então, 
que não se deve usar a indexação de vetores pelo fato dos ponteiros serem mais eficientes. 
Mas isso só é verdade se o objetivo é acessar um vetor estritamente na ordem crescente ou 
decrescente. Caso se queira acessar um vetor de maneira aleatória, a indexação será mais fácil 
de usar e tão rápida quanto o ponteiro, pois o uso deste implica em um código mais complexo 
(mais difícil de escrever e entender). 
 Exemplo: 
 
 /* versão com vetor */ 
 #include <stdio.h> 
 #include <ctype.h> 
 
main() 
 { 
 char str[80]; 
 int i; 
 printf("digite uma string em letras maiúsculas: "); 
 gets(str); 
 printf("eis aqui a string em letras minúsculas: "); 
 for(i = 0; str[i] != ‘\0’; i++) 
 printf("%c", tolower(str[i])); 
 } 
 
 A seguir, usando a aritmética dos ponteiros, o programa fica: 
 
 /* versão com ponteiro */ 
 #include <stdio.h> 
 #include <ctype.h> 
 
main() 
 { 
 char str[80], *p; 
 printf("digite uma string com letras maiúsculas: "); 
 gets(str); 
 printf("eis aqui a string em letras minúsculas: "); 
 2 
 p = str; /* obtém o endereço de str */ 
 while (*p != ‘\0’) { 
 printf("%c", tolower(*p)); 
 p++; 
 } 
 } 
 
Deve-se observar que o programa faz com que p aponte para o endereço do primeiro 
elemento do vetor str com o comando p = str. Em C, o nome de um vetor sem um índice é 
o endereço do início do vetor. Entretanto, para obter o endereço de um elemento específico 
de um vetor deve-se utilizar o operador & normalmente. Por exemplo, o comando seguinte 
coloca o endereço do terceiro elemento de um vetor x no ponteiro p, ou seja, p aponta para o 
terceiro elemento do vetor x: 
 
 p = &x[2]; 
2 Indexando um Ponteiro 
Um ponteiro pode ser indexado como se fosse um vetor. Por exemplo, o programa 
seguinte imprime na tela os números pares de 2 a 10: 
 
 /* indexando um ponteiro */ 
 #include <stdio.h> 
 
main() 
 { 
 int v[5] = {2,4,6,8,10}; 
 int *p, i; 
 p = v; 
 for(i = 0; i < 5; i++) 
 printf("%d ", p[i]); 
 } 
 
 Em C, o comando p[i] é idêntico a *(p+i). 
3 Vetores de Ponteiros 
 Pode-se fazer vetores de ponteiros da mesma maneira que se faz vetores de qualquer 
outro tipo de dado. Por exemplo, a declaração de um vetor x de ponteiros do tipo inteiro de 
tamanho 10 fica: 
 
 int *x[10]; 
 
 Para atribuir o endereço de uma variável do tipo inteiro var ao terceiro elemento do 
vetor de ponteiros x, faz-se: 
 
 x[2] = &var; 
 
 Para obter o valor de var indiretamente no terceiro elemento de x e atribuir a uma 
variável y, faz-se: 
 
 y = *x[2]; /* y possui o valor do terceiro elemento do vetor */ 
 
 
 3 
Um vetor de ponteiros é muito utilizado nas mensagens de erro. Por exemplo: 
 
 #include <stdio.h> 
 
 main() 
 { 
 char *err[] = { 
 "mensagem1", 
 "mensagem2", 
 "mensagem3" 
 }; 
 int i; 
 for (i = 0; i < 3; i++) 
 puts(err[i]); 
 } 
 
 Deve-se observar que quando se inicializa o vetor de ponteiros err diretamente na 
declaração, pode-se omitir o número de elementos do vetor. 
4 Ponteiros para Ponteiros 
 Um ponteiro para outro ponteiro é um modo de indireção múltipla. Essa indireção 
pode ter a extensão que for desejada. No caso de um ponteiro para outro ponteiro, o primeiro 
ponteiro contém o endereço do segundo, que aponta para a variável que contém o valor 
desejado. 
 Esquematicamente tem-se: 
 
endereço valor 
Ponteiro Variável 
Indireção Simples 
endereço endereço valor 
Ponteiro Ponteiro Variável 
Indireção Múltipla 
 
 
 A forma geral de declaração de um ponteiro para ponteiro é a seguinte: 
 
 tipo-de-dado **nome; 
 
onde: 
tipo-de-dado: é um tipo de dado válido em C; 
nome: é um identificador válido para a variável ponteiro. São os asteriscos (**) que fazem o 
compilador saber que é um ponteiro para outro ponteiro. 
 
 Exemplo: 
 
 #include <stdio.h> 
 
main() 
 { 
 int x, *p, **q; 
 x = 10; 
 p = &x; 
 4 
 q = &p; 
 printf("%d", **q); /* imprime valor de x indiretamente */ 
 } 
 
 Tem-se que p é um ponteiro do tipo inteiro e q é um ponteiro para um ponteiro do tipo 
um inteiro. A chamada de printf() imprimirá o número 10 na tela. 
5 Problemas com Ponteiros 
O maior problema é um ponteiro "perdido". Pode-se verificar esse problema no 
exemplo a seguir: 
 
 main() 
 { 
 int x, *p; 
 x = 10; 
 *p = x; 
 } 
 
 Esse programa atribui o valor 10 a um endereço de memória desconhecido. O 
programa nunca atribui um valor (endereço) ao ponteiro p. Portanto, ele contém apenas 
“lixo”. Logo, o ponteiro não inicializado p fará com que o programa não funcione direito. 
Quando se executa uma operação que usa p, se estará lendo ou gravando para um pedaço 
desconhecido da memória. A solução para esse tipo de problema com ponteiros é sempre se 
certificar de que o ponteiro está apontando para algum endereço de memória válido antes de 
usá-lo. 
 Outro problema com ponteiros é causado por uma má interpretação de como usar um 
ponteiro. No exemplo a seguir: 
 
 main() 
 { 
 int x, *p; 
 x = 10; 
 p = x; 
 printf("%d", *p); 
 } 
 
 A chamada de printf() não imprimirá o valor de x, que é 10, mas sim algum valor 
desconhecido. O motivo para isso é o fato da atribuição p = x estar errada, deveria ser p = &x. 
6 Exercícios de Fixação 
1) Escreva um programa C que declare um vetor de 100 inteiros e preencha o vetor com 
números de 1 a 100 usando ponteiros para endereçar seus elementos. 
 
2) Verifique o programa abaixo. Encontre o seu erro e corrija-o para que escreva 10 na tela. 
#include <stdio.h> 
main() 
{ 
 int x, *p, **q; 
 p = &x; 
 q = &p; 
 x = 10; 
 printf("\n%d\n", &q); 
}

Outros materiais