Указатель объекта любого типа может быть неявно преобразован в void *
без приведения, и обратное также верно.
Однако спецификатор формата %p
для printf
явно ожидает void *
аргумент, и потому что printf
является функцией c от variadi, неявное преобразование не произойдет.
Это один из редких случаев, когда требуется явное приведение к void *
:
printf("%p\n", (void *)array);
printf("%p\n", (void *)p);
printf("%p\n", (void *)&array[0]);
printf("%p\n", (void *)&p[0]);
printf("%p\n", (void *)&(*array));
В большинстве реализаций, с которыми вы можете соприкасаться, указатели объектов и void *
имеют такое же представление. Однако в общем случае это не обязательно так, и неудачное приведение может вызвать неопределенное поведение в системах, где это не так.
Напротив, для вызова функции foo
ниже не требуется приведение:
void foo(void *p)
{
printf("p=%p\n", p);
}
int main()
{
int x;
foo(&x);
}
Поскольку тип параметра известен во время компиляции.