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.