- Baixe este conteúdo: Apostila C Progressivo
Incremento, Decremento e Comparando ponteiros em C
Uma das maiores utilidades dos ponteiros é fazer com que
eles apontem para quantas variáveis desejarmos.
Por exemplo, podemos fazer com que um único ponteiro
percorra todas as variáveis de um vetor.
E através do operador asterisco, além de percorrer as
variáveis, também podemos fazer operações com elas.
A vantagem de usarmos ponteiros para percorrer e alterar
variáveis é a eficiência, pois o C trabalha bem mais rápido se usarmos
endereços de memória (ponteiros), ao invés de ficarmos declarando e alterando
valores de variáveis.
Além disso, o uso de ponteiros para o estudo de Arquivos,
Alocação Dinâmica de Memória e de Strings, na próxima seção, é essencial em
nosso curso de C.
Assim como outras
variáveis, podemos, por exemplo, incrementar e decrementar ponteiros.
Como os ponteiros são variáveis para armazenar endereços
de memória, se fizermos operações de incremento e decremento em ponteiros, é o
endereço que irá mudar.
Porém, quando incrementamos ou decrementamos um ponteiro,
seu endereço não percorre os endereços em uma unidade, ele percorre em sizeof(tipo_variável).
Por exemplo, sabemos que o tipo double ocupa 8 bytes em memória.
Se tivermos um ponteiro para um vetor tipo de variável,
ele guarda a primeira posição do vetor.
Vamos supor que esse endereço seja: 2112
Quando incrementamos o ponteiro: ptr++;
O valor que ele aponta não será o pro endereço 2113, e
sim pro endereço 2120, pois a próxima variável do vetor vai estar na posição
2120, já que cada variável ocupa 8 bytes e a primeira estava na posição 2112.
Ou seja, quando incrementamos ou decrementamos um
ponteiro, que aponta para um tipo, ele vai percorrer o número de bytes do
tamanho de seu tipo.
Se for char, o
ponteiro muda sua posição de 1 byte para frente ou para trás no endereço.
Se for int, o
ponteiro muda sua posição em 4 bytes,
para frente ou para trás no endereço.
O mesmo vale para outras operações matemáticas, como soma
e subtração:
ptr + 1 -> endereço de onde ptr apontava + sizeof(tipo).
ptr + 2 -> endereço de onde ptr apontava, deslocado de duas variáveis para frente.
ptr – 3 -> endereço de onde ptr apontava, deslocado de duvas variáveis para trás
Exemplo de código: Calcular os termos de uma P.A usando Ponteiros em C
Peça ao usuário dois inteiros, onde o primeiro será o
primeiro termo de uma P.A (Progressão Aritmética) e o segundo a razão. Em
segundo, através de ponteiros, preencha um vetor com os 10 primeiros elementos
dessa P.A.
Após declararmos um vetor de 10 elementos, fazemos com
que o ponteiro aponte para esse vetor. Como o nome vetor nada mais é que do que
o endereço do primeiro elemento.
Assim, inicialmente, nosso ponteiro aponta para o
primeiro elemento do vetor, que será o primeiro elemento da P.A.
Para calcular os elementos da P.A, basta fazermos com que
o próximo termo seja o atual mais a razão:
*(ptr+1) = *ptr + razao
Entramos no laço WHILE que irá percorrer todos os
elementos do vetor, exceto o último (pois o último elemento é calculado pelo
penúltimo, então não precisa ir até o último).
Ou seja, só irá parar depois de termos atingidos o penúltimo
elemento do vetor, que é pa[8].
Como vamos usar somente ponteiros para percorrer o vetor,
nosso WHILE deve continuar enquanto o endereço de nosso ponteiro for diferente
último endereço do vetor (que não precisará ser acessado, pois cada iteração do
looping calcula o próximo termo da PA).
Em seguida, usamos o laço FOR para você ver como podemos
manipular ponteiros dentre dele também.
Inicializamos, novamente, o ponteiro a partir do primeiro
elemento: ptr = pa;
Depois, imprimimos todos os elementos, enquanto o
endereço que o ponteiro aponta for menor ou igual ao último endereço do vetor.
Veja como ficou nosso código:
#include <stdio.h> // Curso C Progressivo: www.cprogessivo.net // O melhor curso de C! Online e gratuito ! // Artigos, apostilas, tutoriais e vídeo-aulas sobre // a linguagem de programação C !int main(void){ int pa[10], razao; int *ptr; printf("Insira o termo inicial da PA: "); scanf("%d", &pa[0]); ptr = pa; printf("Insira razao da PA: "); scanf("%d", &razao); while( ptr != &pa[9]) { *(ptr+1) = *ptr + razao; ptr++; } for(ptr = pa ; ptr <= &pa[9] ; ptr++) printf("-> %d ", *ptr);
return 0;
}
4 comentários:
Na seção onde diz:
ptr – 3 -> endereço de onde ptr apontava, deslocado de duvas variáveis para trás
o correto seria: ptr – 3 -> endereço de onde ptr apontava, deslocado de três variáveis para trás?
Muito bom, Parabéns. Agora consigo ler os trechos de código em C q contém ponteiros e entende-los, antes não entendia nada, confundia *ptr (declaração de ponteiro) com *ptr (extrair valor da memória para onde o ponteiro aponta.
Obrigado a toda e equipe do C Progressivo.!
Fiz a seguinte alteração no código mudando o 'while' para um laço 'for'. Mas parece que o que retornou foram os endereços de memória.
--------------------------------------
int main(void)
{
int pa[100], razao;
int *ptr;
printf("Insira o termo inicial da PA: ");
scanf("%d", &pa[0]);
ptr = pa;
printf("Insira razao da PA: ");
scanf("%d", &razao);
for(ptr =&pa[0]; ptr <= &pa[99]; ptr+=1)
{
*(ptr+1) = *ptr + razao;
printf("-> %d ", *ptr);
ptr++;
}
system("pause");
return 0;
}
A saída foi essa:
Insira o termo inicial da PA: 5
Insira razao da PA: 7
-> 5 -> 1999976654 -> 1999976618 -> 0 -> 3872520 -> 127 -> 1375732051 -> 1 -> 3866960 -> 3866624 -> 3872531 -> 3866960 -> 16777218 -> 2 -> 2000253429 -> -2 -> 1999977726 -> 1375732051 -> 3872528 -> 8 -> 1999895274 -> -1 -> 2686648 -> 0 -> 4199152 -> 0 -> 0 -> 16842752 -> 7536836 -> 3870328 -> 2686664 -> 3866624 -> 1972040841 -> 1719536184 -> 3870328 -> 2000031890 -> 36 -> 4 -> -2029387870 -> 1972041216 -> 0 -> 2686684 -> 1972634280 -> 1972040914 -> 1972048270 -> 332126055 -> 0 -> 4199152 -> -1 -> 1972145365
Pressione qualquer tecla para continuar. . .
Porque saíram os endereços de memória uma vez que eu escrevi para que me dê na saída um VALOR ?? *ptr ?? (asterisco antes do ponteiro) --
printf("-> %d ", *ptr);
O blog de vocês me ensina mais do que as aulas do meu professor de Algoritmos e Estruturas de Dados 1. Obrigado.
Postar um comentário