Ponteiros são variáveis que permitem que você acesse outras variáveis sem referência-las diretamente.
Como o nome sugere, seu objetivo é apontar para uma variável. Mais especificamente para o endereço onde a variável apontada se encontra.
Os ponteiros dão a linguagem C grandes possibilidades para manipular endereços de memória e é representado por um asterisco (*) antes do nome da variável. Exemplo:
*var
Como funcionam os ponteiros?
Exemplo: temos a variável
x = 5 e a variável ponteiro
*y = &x.
A variável
x é uma variável comum com o valor
5 armazenado. Já a variável
*y esta apontando para o endereço da variável
x (&x).
O operador
"&" na frente de uma variável sempre retornará seu endereço de memória, por isso que ao ler uma variável com a função
"scanf" utilizamos as variáveis com este sinal na frente.
Neste caso, então,
*y tem o endereço de
x. Isso significa que se eu fizer a seguinte operação:
*y = 10
Estarei mudando o valor de
x que era
5 para
10.
Exemplo:
main()
{
int a = 3, b = 7, *pa = &a, *pb = &b, aux;
printf("a = %d\nb =%d\n",a,b);
printf("Invertendo...\n");
system("pause");
aux = a;
*pa = b;
*pb = aux;
printf("a = %d\nb =%d\n",a,b);
system("pause");
return 0;
}
A tabela a seguir representa o conteúdo das variáveis usadas nesse simples programa.
Endereço
|
Variável
|
Conteúdo
|
0x0100
|
a
|
3
|
0x0101
|
b
|
7
|
0x0102
|
pa
|
0x0100
|
0x0103
|
pb
|
0x0101
|
|
|
|
|
|
|
Observe que o conteúdo dos ponteiros sem o asterisco (*) são endereços.
Mais quando colocamos o asterisco (*) estou indicando que ela deve apontar para o endereço. Então quando informo que
*pa = b é a mesma coisa que dizer que o endereço de memória
0x0100 = b ou que a variável
a = b.
Como ou quando usar os ponteiros?
Ponteiros são utilizado principalmente em funções, quando há a necessidade de retornar mais valores para o programa principal.
Se você não conhece
funções na linguagem C acesse este link.
Sabemos que funções retornam apenas um valor por função. Sabemos também que as variáveis de uma função são destruídas depois que a função é executada. Então a solução para isso é mandar para uma função o endereço da variável que você deseja alterar, assim você estará alterando a variável do programa principal.
Exemplo: função para inverter valores de variáveis.
void troca(int *px, int *py)
{
int aux;
aux = *px;
*px = *py;
*py = aux;
}
main()
{
int x = 3, y = 7;
printf("x = %d\ny =%d\n",x,y);
printf("Invetendo...\n");
system("pause");
troca(&x,&y);
printf("x = %d\ny =%d\n",x,y);
system("pause");
return 0;
}
Na função
"troca" foi criado dois ponteiros apontando para os endereços das variáveis do programa principal (
x e
y) e usando esses ponteiros invertemos os valores das variáveis do programa principal.
Essa inversão é muito utilizada em muitos algoritmos e essa seria uma solução para não precisar repetir essas linhas sempre que precisar inverter variáveis.
As matrizes são ponteiros representados de uma maneira diferente.
Se você não sabe o que são
matrizes acesse esse link.
As matrizes são armazenadas em sequencia nas células de memórias. Sabemos que cada célula possui 1 Byte (8 bits), então se tivermos um valor do tipo inteiro armazenado em um ponteiro e somarmos 1 a esse endereço ele irá pular 4 células, ou seja, 4 Bytes onde está armazenado o valor da variável.
Aqui temos um programa que comprova isso:
main()
{
int i, a[5] = {2000,2001,2002,2003,2004}, *pa = &a;
for(i = 0; i < 5; i++)
printf("Endereço atual: %d\nValor: %d\n",&a[i],*pa+i);
system("pause");
return 0;
}
Criamos um vetor (
a) simples com 5 posições e percorremos ele com um ponteiro (
*pa) sendo incrementado por
i.
A cada vez que o ponteiro é incrementado é mostrado o endereço do vetor e seu valor, oque comprova que ao incrementar o ponteiro ele pula as 4 células (4 Bytes).
Veja o resultado na imagem abaixo: