9 de jun. de 2010

Desmistificando Ponteiros

image

Um ponteiro é uma variável que contém um endereço de memória ( e um determinado tipo).
Esse endereço é normalmente a posição de outra variável na memória. Acompanhe o exemplo da figura:

image

Temos as variáveis P e Q, ambas apontando para o mesmo local na memória, aliás é por isso que se chamam ponteiros, pois apontam para um local de memória.

Sua declaração é marcada pelo *. Se eu desejar saber o endereço de memória para o qual estou apontando então utilizo o operador &. Resumindo:

  • * para acessar o dado no endereço de memória.
  • & para acessar o endereço de memória.

Veja um breve exemplo:

#include <stdio.h>
#include <conio.h>

void main()
{
    int numero = 100;
    int *ponteiro = &numero;
    int valor = *ponteiro;
    printf("Valor: %d", valor);
    printf("\nEndereco de Memoria: %d", ponteiro);

    getch();
}

 

A saída do programa é:

image

É importante que um ponteiro tem um endereço de memória, e tem que ter o tipo também (assim o compilador saberá até onde os dados da variável vão estar armazenados). Este tipo também pode ser uma struct. ?Além disso podemos usar ponteiros em parâmetros de Funções, acompanhe:

#include <stdio.h>
#include <conio.h>

void Trocar(int *x, int *y)
{
    int temp;
    temp = *x;
    *x = *y;
    *y = temp;
}

void main()
{
    int a = 10;
    int b = 20;
    Trocar(&a, &b);

    printf("Valor de A: %i - Valor de B: %i", a , b);
    getch();
}

 

A saída do código acima é:

image

Não é muito difícil: O que está acontecendo é que passamos para a função Trocar() o endereço das variáveis i e j. Estes endereços são copiados nos ponteiros x e y. Através do operador * estamos acessando o conteúdo apontado pelos ponteiros e modificando-os. Mas, quem é este conteúdo? Nada mais que os valores armazenados em i e j, que, portanto, estão sendo modificados!

Pare e pense, você já viu isso!? quando você usa o scanf()! Para armazenar o valor lido do teclado, você informa o endereço de memória, através do  &, da variável em que deseja armazenar.

Sendo assim, poderíamos retornar valor pelos próprios parâmetros de uma função.

Imagine uma situação em que há a necessidade de fazer uma busca em um vetor de inteiros. Então acompanhe o exemplo abaixo:

#include <stdio.h>
#include <conio.h>

bool Pesquisar(int numeros[10], int valor, int *posicao)
{
    *posicao = 0;

    while(*posicao < 10 && numeros[*posicao] != valor)
    {
        *posicao = *posicao + 1;
    }

    // -> Verifica se foi encontrado
    if (*posicao < 10)
        return true;
    else
        return false;
}

void main()
{
    int vetor[10];
    int numero;
    int posicao;
    int i;

    for (i=0;i<10;i++)
    {
        printf("Digite o %i valor do vetor...: ", i);
        scanf("%i", &vetor[i]);
    }

    printf("\nDigite um valor para pesquisa: ");
    scanf("%i",&numero);

    if (Pesquisar(vetor, numero,&posicao) == true)
    {
        printf("Encontrado na posicao %i", posicao);
    }
    else
    {
        printf("Nao encontrado!");
    }

    getch();
}

 

A saída seria a seguinte:

image 

Tenha os ponteiro como seu amigo, ele é uma mão na roda, principalmente quando o assunto é Listas dinâmicas.

Em breve escreverei mais sobre passagem de valores por referência e por valor… E falarei de listas também. Até a próxima.

1 comentários:

lucas alencar pedro disse...

óia, não é que esse Jesus é esperto msm! ahuahauahu!!!