void describe(void *thing);
void *move(void *location, Direction direction);
Первая функция ничего не возвращает. Вторая функция возвращает пустой указатель. Я бы объявил эту вторую функцию как
void* move(void* location, Direction direction);
Если может помочь, если вы думаете, что «пустота» означает «без значения». Возвращаемое значение describe
- «без значения». Возврат значения из такой функции недопустим, потому что вы сказали компилятору, что возвращаемое значение не имеет смысла. Вы не можете получить возвращаемое значение из этой функции, потому что оно не имеет смысла. Вы не можете объявить переменную типа, void
потому что она не имеет смысла. Например void nonsense;
, чепуха и фактически незаконна. Также обратите внимание, что массив void void void_array[42];
- это тоже нонсенс.
Указатель на void ( void*
) - это нечто иное. Это указатель, а не массив. Читайте void*
как означающий указатель, который указывает на что-то "без значения". Указатель «без значения», что означает, что нет смысла разыменовывать такой указатель. Попытка сделать это фактически незаконна. Код, разыменовывающий пустой указатель, не будет компилироваться.
Так что, если вы не можете разыменовать пустой указатель, и вы не можете создать массив пустот, как вы можете их использовать? Ответ в том, что указатель на любой тип может быть приведен к и от void*
. Приведение некоторого указателя на void*
и возвращение указателя на исходный тип приведет к значению, равному исходному указателю. Стандарт C гарантирует такое поведение. Основная причина, по которой вы видите так много пустых указателей в C, заключается в том, что эта возможность обеспечивает способ реализации скрытия информации и объектно-ориентированного программирования на языке, который в значительной степени не является объектно-ориентированным языком.
Наконец, причина, по которой вы часто видите move
объявленный void *move(...)
скорее, чем тот void* move(...)
, что в том, что размещение звездочки рядом с именем, а не с типом, является очень распространенной практикой в C. Причина в том, что следующее объявление доставит вам большие неприятности: int* iptr, jptr;
Это сделает вас Я думаю, что вы объявляете два указателя на int
. Ты не. Это заявление делает , а не указатель на . Правильное объявление: Вы можете делать вид, что звездочка принадлежит типу, если придерживаетесь практики объявления только одной переменной на оператор объявления. Но имейте в виду, что вы притворяетесь.jptr
int
int
int *iptr, *jptr;
void
том, что в примере кода используетсяvoid*
нечто совершенно иное.