Programação
 › Algoritmo  › C/C++  › Java
Web
 › HTML/XHTML  › JavaScript  › PHP
Sistema Operacional
 › Comandos de DOS  › Windows  › Linux  › Mac/BSD
Office
 › Word / Writer  › Excel / Calc
Áreas do Site
 › Download  › Fórum  › Blog
Recomendamos
Computadores e Informática em Lisboa
TI Expert » Programação » C/C++ » Ponteiros para Ponteiros

Ponteiros para Ponteiros

C/C++ nos permite criar, também, ponteiros com níveis de apontamento. O que isso quer dizer? Simples. É possível criar um ponteiro que aponte para outro ponteiro, criando assim níveis, pois um ponteiro poderá apontar para outro ponteiro, que, por sua vez, aponta para outro ponteiro, que aponta para um ponteiro diferente e assim por diante.

A sintaxe para se criar ponteiros para ponteiros é a mesma de ponteiros comuns, apenas a forma de acessar seus valores é diferente, pois para cada nível de apontamento usaremos um dereferenciador. Por exemplo, se um ponteiro aponta para um ponteiro que aponta para um valor inteiro, para acessarmos esse valor inteiro a partir do primeiro ponteiro usaríamos dois asteríscos (**), ao invés de apenas um (*).

Isso se dá ao fato que um ponteiro pode mudar o valor de outro ponteiro de acordo com seu nível.

O exemplo abaixo demonstra uma sintaxe simples.

#include <iostream>
using namespace std;
   
int main (void) {
    int a=10, b=50;
    int *ptr;      // ponteiro de inteiro
    int **ptrPtr;  // ponteiro de um ponteiro inteiro
    ptr = &a;
    ptrPtr = &ptr;
    cout << "O valor final de ptrPtr e " << **ptrPtr << endl;
    system("pause");
    return EXIT_SUCCESS;
}

O código acima contem duas variáveis inteiras (a e b) inicializados com os valores 10 e 50 respectivamente. Logo após, há uma variável de ponteiro (*ptr) e uma variável de ponteiro para ponteiro (**ptrPtr).

Então, atribuimos o endereço da variável inteira a em *ptr. Agora *prt aponta para a. Após isso, atribuimos o endereço do ponteiro *ptr ao ponteiro **ptrPtr. Neste momento **ptrPtr passa apontar para *ptr.

Nesse instante devemos prestar atencão no seguinte detalhe, no momento da impressão da mensagem "O valor final de ptrPtr e "... usamos o ponteiro do ponteiro para chegar até o valor de a.

Entendendo os Níveis de Apontamento

Quando usamos ponteiros de ponteiros podemos usar os níveis de apontamento que são determinados pelo número de asteriscos que precedem o ponteiro.

Portanto, se um ponteiro aponta para um ponteiro que também aponta para um ponteiro que contem um endereço de uma variável char, usaríamos neste caso três asteríscos.

#include <iostream>
using namespace std;
 
int main (void) {
    char letra='a';
    char *ptrChar;
    char **ptrPtrChar;
    char ***ptrPtr;
    ptrChar = &letra;
    ptrPtrChar = &ptrChar;
    ptrPtr = &ptrPtrChar;
    cout << "O valor final de ptrPtr e " << ***ptrPtr << endl;
    system("pause");
    return EXIT_SUCCESS;
}

Para entender melhor o acesso indireto que o ponteiro executa, vejamos o diagrama abaixo.

Funcionamento de ponteiro para ponteiro na memória

Este diagrama demonstra o que cada um dos asteriscos representa. Sabendo disso é possível alterar tanto o valor final da variável quanto o endereço apontado pelos ponteiros intermediários.

Vejamos a exemplificação abaixo.

#include <iostream>
using namespace std;
 
int main (void) {
    float var1 = 25.5;
    float var2 = 72.8;
    float *ptr;
    float **ptrPtr;
    ptr = &var1;
    ptrPtr = &ptr;
    cout << "O valor final de ptrPtr e " << **ptrPtr << endl;
    cout << "Pois o endereco de ptr e " << ptr << endl;
    *ptrPtr = &var2;  //novo endereço no ponteiro intermediário
    cout << "\nO valor final de ptrPtr e " << **ptrPtr << endl;
    cout << "Pois o endereco de ptr e " << ptr << endl;
    system("pause");
    return EXIT_SUCCESS;
}

No código acima podemos perceber a troca de um ponteiro intermediário.

A princípio atribuimos o endereço da variável var1 ao ponteiro ptr. Depois, atribuimos o endereço do ponteiro ptr ao ponteiro ptrPtr.

Na primeira vez que mandamos imprimir **ptrPtr (Importante! Note os dois asteriscos) será apresentado o valor contido em var1, porque ptrPtr acessa var1 indiretamente pelo ponteiro ptr.

Quando fazemos a operação *ptrPtr = &var2;, na verdade, não estamos alterando o valor contido em var1, mas o endereço contido no ponteiro ptr, porque usamos apenas um asterisco em ptrPtr.

Ou seja, usando apenas um asterisco acessaremos o ponteiro, não o valor apontado pelo ponteiro. Vejamos:

Funcionamento do nível de acesso representado por cada asterisco em um ponteiro para ponteiro em C/C++

Esse asterísco representa exatamente o ponteiro intermediário. Portanto, agora o ponteiro ptr não aponta mais para var1, ele aponta para var2.

Na segunda vez que imprimimos o valor de **ptrPtr não aparecerá o valor de var1, mas o valor de var2, porque o endereço contido no ponteiro intermediário ptr foi alterado para apontar para var2.

Creative Commons License
Autor: Denys William Xavier
Este artigo está sob Licença Creative Commons.

Faça o download da versão em PDF Indique nosso site Gostou?
Indique nosso site!
Este artigo foi
lido 29900 vezes
Bookmark e Compartilhe

Páginas Relacionadas

Enquete
O Google Chrome OS irá desbancar o Microsoft Windows 7?
» ProgramaçãoAlgorítmo | C/C++ | Java

» WebHTML/XHTML | JavaScript | PHP

» Sistema OperacionalComandos de DOS | Windows | Linux | Mac/BSD

» OfficeWord/Wirter | Excel/Calc

» Áreas do SiteDownloads | Fórum | Blog