Ponteiros para void
O tipo peculiar void *
, um ponteiro cujo tipo apontado é void
, é usado com frequência em C. Ele representa um ponteiro para “não dizemos o quê”. Por exemplo:
void *numbered_slot_pointer(int);
declara uma função numbered_slot_pointer
que recebe um parâmetro inteiro e retorna um ponteiro — mas não dizemos para que tipo de dado ele aponta.
As funções de alocação dinâmica de memória (veja ) usam o tipo void *
para se referir a blocos de memória, independentemente do tipo de dado que o programa armazenará nesses blocos.
Com o tipo void *
, é possível passar o ponteiro adiante e testar se ele é nulo. No entanto, desreferenciá-lo fornece um valor void
, que não pode ser usado (veja O Tipo void
). Para desreferenciar o ponteiro, é necessário convertê-lo para algum outro tipo de ponteiro primeiro.
Atribuições convertem automaticamente void *
para qualquer outro tipo de ponteiro, desde que o operando à esquerda tenha um tipo de ponteiro. Por exemplo:
{
int *p;
/* Converte o valor de retorno para int *. */
p = numbered_slot_pointer(5);
…
}
Ao passar um argumento do tipo void *
para um parâmetro que exige um tipo de ponteiro específico, também ocorre a conversão. Por exemplo, suponha que a função hack
tenha sido declarada com um parâmetro do tipo float *
:
/* Declaramos hack assim.
Assumimos que está definida em outro lugar. */
void hack(float *);
…
/* Agora chamamos hack. */
{
/* Converte o valor de retorno de numbered_slot_pointer
para float * para passá-lo para hack. */
hack(numbered_slot_pointer(5));
…
}
Também é possível converter para outro tipo de ponteiro usando um cast explícito (veja ), como neste exemplo:
(int *) numbered_slot_pointer(5)
Aqui está um exemplo que decide em tempo de execução para qual tipo de ponteiro converter:
void
extract_int_or_double(void *ptr, bool its_an_int)
{
if (its_an_int)
handle_an_int(*(int *)ptr);
else
handle_a_double(*(double *)ptr);
}
A expressão *(int *)ptr
significa: converter ptr
para o tipo int *
, depois desreferenciá-lo.
Atualizado
Isto foi útil?