Compartilhar via


Operadores de indireção e address-of

O operador unário de indireção (*) acessa um valor indiretamente, por meio de um ponteiro. O operando deve ser um tipo de ponteiro. O resultado da operação é o valor resolvido pelo operando; isto é, o valor no endereço para o qual o operando aponta. O tipo do resultado é o tipo endereçado pelo operando.

O resultado do operador de indireção será tipo se o operando for do tipo ponteiro para tipo. Se o operando apontar para uma função, o resultado será um designador de função. Se ele apontar para um objeto, o resultado será um lvalue que designa o objeto.

Se o valor do ponteiro não for válido, o resultado do operador de indireção será indefinido. Aqui estão algumas das condições mais comuns que invalidam um valor de ponteiro:

  • O ponteiro é um ponteiro nulo.

  • O ponteiro especifica o endereço de um objeto após o fim de seu tempo de vida no momento da referência. (Por exemplo, um objeto que saiu do escopo ou que foi desalocado).

  • O ponteiro especifica um endereço que está alinhado de forma inadequada para o tipo do objeto apontado.

  • O ponteiro especifica um endereço não usado pelo programa em execução.

O operador unário address-of (&) fornece o endereço de seu operando. O operando deve ser uma destas coisas:

  • Um lvalue que designa um objeto register que não é declarado e não é um campo de bits.

  • O resultado de um operador de desreferenciar unário (*) ou matriz de desreferenciar ([]).

  • Um designador de função.

O resultado é do tipo ponteiro para operand_type para um operando do tipo operand_type.

Se o operando for o resultado de um operador unário *, o operador e o resultado não serão avaliados e ambos serão omitidos. O resultado não é um lvalue e as restrições ainda se aplicam aos operadores. Se o operando for o resultado de um operador [], o operador & e o unário * implicados pelo operador [] não serão avaliados. O resultado tem o mesmo efeito de remover o operador & e alterar o operador [] para um operador +. Caso contrário, o resultado será um ponteiro para o objeto ou função designado pelo operando.

Exemplos

Os exemplos a seguir usam estas declarações comuns:

int *pa, x;
int a[20];

Esta instrução usa o operador address-of (&) para utilizar o endereço do sexto elemento da matriz a. O resultado é armazenado na variável de ponteiro pa:

pa = &a[5];

O operador de indireção (*) é usado neste exemplo para acessar o valor int no endereço armazenado em pa. O valor é atribuído à variável de inteiro x:

x = *pa;

Este exemplo demonstra que o resultado da aplicação do operador de indireção ao endereço de x é o mesmo que x:

assert( x == *&x );

Este exemplo mostra as formas semelhantes de declarar um ponteiro para uma função:

int roundup( void );     /* Function declaration */

int  *proundup  = roundup;
int  *pround  = &roundup;
assert( pround == proundup );

Uma vez que a função roundup é declarada, dois ponteiros para roundup são declarados e inicializados. O primeiro ponteiro, proundup, é inicializado usando apenas o nome da função, enquanto o segundo, pround, usa o operador address-of na inicialização. As inicializações são equivalentes.

Confira também

Operador de indireção: *
Operador Address-of: &