02 de maio de 2010

Ponteiros de C e C++ possuem várias características avançadas e até mesmo alguns detalhes irritantes, que confundem qualquer um. Procurarei em 2 ou 3 tutoriais cobrir detalhes obscuros de ponteiros.

Nesse artigo, vou cobrir a relação ponteiro vs. constantes:

  1. Ponteiro:
    tipo *nome;
  2. Ponteiro não constante para dados constantes:
    const tipo *nome;
  3. Ponteiro constante para dados não constantes:
    tipo *const nome;
  4. Ponteiro e dados constantes:
    const tipo *const nome;

A idéia é que se o operador * vem depois de const são assumidos os dados bases (assim, é um ponteiro para dados constantes). Se o operador vem antes de const, então é um ponteiro constante.

Isso pode ser facilmente identificado quando é feita uma leitura da direita para a esquerda:

// Leitura de declarações <-
int *x;             // x é um ponteiro para int
const int *y;       // y é um ponteiro não constante para um int constante
const int *const p; // p é um ponteiro constante para um int constante
int *const w;       // w é um ponteiro constante para um int não constante

Exemplo completo

    // +--------------------------------------------------------------------+
    // | Ponteiro não constante para dados não constantes                   |
    // +--------------------------------------------------------------------+
    char *p, a, b;

    p  = &a;  // Recebe endereço de a
    *p = 'A'; // Altera conteúdo de a
    p  = &b;  // Recebe endereço de b

    // +--------------------------------------------------------------------+
    // | Ponteiro não constante para dados constantes                       |
    // +--------------------------------------------------------------------+
    const int *p;
    int i = 25, z;

    // p aponta para i, o qual não pode ser alterado.
    p = &i;

    // Mas, p pode apontar para outra variável
    p = &z;
    // Esse comando gera falha, porque p vai tentar alterar
    // o conteúdo de z, mas não pode pois foi declarado para
    // apontar para dados constantes
    // *p = 35;

    // Comando válido, por não se referenciar ao ponteiro, e sim,
    // diretamente na variável
    i = 45;

    // +--------------------------------------------------------------------+
    // | Ponteiro constante para dados não constantes                       |
    // +--------------------------------------------------------------------+
    int i = 25, z;

    // Como é ponteiro constante, atribuição de endereço deve ser feito
    // na definição.
    int *const p = &i;

    // Comando inválido, não se pode alterar para onde p aponta
    // p = &i;

    // Comando válido, por se tratar de dados não constantes
    *p = 45;

    // +--------------------------------------------------------------------+
    // | Ponteiro constante para dados constantes                           |
    // +--------------------------------------------------------------------+
    int i = 25, z;

    // Como é ponteiro constante, atribuição de endereço deve ser feito
    // na definição.
    const int *const p = &i;

    // Comando inválido, não se pode alterar para onde p aponta
    // p = &i;

    // Comando inválido, por se tratar de dados constantes
    // *p = 45;

    // Comando válido, por não se referenciar ao ponteiro, e sim,
    // diretamente na variável
    i = 45;

Mapa mental

C - Ponteiros constantes e não constantes

C - Ponteiros constantes e não constantes


Deixe uma resposta

Nome Obrigatório:

Email Obrigatório:

Website

Comentário Obrigatório:

RSS
Livros de Ruby e Rails no Submarino Livros de Ruby e Rails na Amazon