Nesta seção, vamos estudar sobre o tipo de dado ponteiro(pointer). Uma variável do tipo ponteiro também armazena valores assim como os tipos já estudados. Porém, os valores armazenados são endereços de memória.

O uso do tipo ponteiro nos permite trabalhar com manipulação de variáveis ou tipos complexos de forma indireta, sendo possível atribuir e recuperar suas informação.

A declaração de uma variável do tipo ponteiro é feita utilizando o o perador "*" como na sintaxe a seguir:

Sintaxe
tipo_dado *nome_variavel;
Onde
tipo_dado: tipos de dados estudados anteriormente ou complexo.
*: operador que indica que a variável é um ponteiro e irá armazenar um endereço de memória.
nome_variavel:nome da variável desejada para utilização.
Exemplo 1
#include <stdio.h>

int main()
{
    int *ponteiro1;
    float *ponteiro2;
    double *ponteiro3;
    char *ponteiro4;
    //enum nome_enum *ponteiro5;
    //struct nome_struct *ponteiro6;
}

A linguagem C possui recursos para alocação dinâmica de memória que também é manipulada utilizando ponteiros. Porém, nesta parte, vamos apenas utilizar variáveis ao longo do tutorial.

Para atribuir um valor a um ponteiro, utilizamos o operador &. Esse deve ser prefixado ao nome de uma variável, vetor, matriz , função, procedimento e outro.

Sintaxe
tipo_dado *nome_ponteiro = NULL; //não iniciado
tipo_dado *nome_ponteiro = &nome_variavel; //iniciado
nome_ponteiro = &nome_variavel; //atribuição
Exemplo 2
#include <stdio.h>
int main ()
{
    int var=999;
    int *ponteiro = &var;
    printf("%d",var); //valor inicial
}
Saída
999

Quando um ponteiro é declarado sem ser iniciado, seu valor padrão é NULL. Sempre que um ponteiro não for mais utilizado, por boa prática, devemos atribuir o valor NULL.

Exemplo 3
#include <stdio.h>

int main()
{
    int *pnt;
    //uso omitido
    pnt = NULL;
}
Saída
-

Como mencionado anteriormente, podemos alterar valores de variáveis de forma indireta com a utilização de ponteiro. Essa alteração é feita com o auxílio do operador (*).

Sintaxe
*nome_ponteiro = valor;
*(nome_ponteiro) = valor;
Exemplo 4
#include <stdio.h>
int main ()
{
    int var=999;  // valor inicial
    int *ponteiro = &var; 
    printf("%d \n",var);
    *ponteiro = 9; //atualização indireta
    printf("%d \n",var); //novo valor
}
Saída
9

Em C Básico : Entrada e saída de dados, utilizamos a função printf para exibirmos o conteúdo de uma variável. Com uma variável do tipo ponteiro isso também é possível.

Caso seja necessário sabermos o endereço para o local de memória que um ponteiro esteja apontando, utilizamos o especificador de formatação: %p.

Sintaxe
printf("%p", varivel_ponteiro);

A saída de dados é formata automaticamente para a base numérica hexadecimal como pode ser visto no exemplo abaixo:

Exemplo 5
#include <stdio.h>
int main ()
{
    int var=999;
    int *ponteiro = &var;
    printf("%d \n",var);
    printf("%p \n",ponteiro );
}
Saída
999 
0x7ffd675b41cc

De forma semelhante ao tipo ponteiro, um ponteiro para um ponteiro armazena um endereço que aponta para um endereço de memória ou outro ponteiro.

Sintaxe: não iniciado
tipo_dado **nome_variavel;
Sintaxe: iniciado
tipo_dado **nome_variavel = &variavel_ponteiro;

No exemplo abaixo, acessamos uma variável inteira, de forma indireta, utilizando um ponteiro para o tipo ponteiro.

Exemplo 6
#include <stdio.h>
int main()
{
    int **ppint; //declaração
    int  *pint;
    int vint = 999;

    //atribuição
    pint = &vint; //ponteiro -> vint
    ppint = &pint; // ponteiro -> ponteiro -> vint
    
    printf("%d\n",**ppint); //acesso indireto
}
Saída
999
  1. 05/05/2025 - revisão 4 - Adição de ponteiro para ponteiro
  2. 11/03/2025 - revisão 3 - Correções em intro; Ajustes pontuais
  3. 07/10/2024 - revisão 2 - Correção: Exs. 1 e 3; Ajustes pontuais
  4. 29/09/2023 - revisão 1 - Correção em referências, erros gramaticais e sintaxe
  5. 19/05/2023 - versão inicial