Во-первых, существуют обычные заблуждения о таинственном нуле.В этом случае есть 3 связанных термина:
- нулевой указатель
- константа нулевого указателя
NULL
macro
Константа нулевого указателя - это целое число 0
или это целое число, приведенное к указателю (void*)0
.Макрос NULL
гарантированно будет переносимой константой нулевого указателя.
Всякий раз, когда вы назначаете константу нулевого указателя, например NULL
, любому указателю, этот указатель становится нулевым указателем .Это позволяет компиляторам внутренне представлять нулевой указатель как нечто иное, чем 0
, потому что адрес 0x00...00
часто является допустимым физическим адресом во многих системах.
В частности, C17 6.3.2.3/3 определяет это:
Целочисленное константное выражение со значением 0
или такое выражение, приведенное к типу void *
, называется константой нулевого указателя .Если константа нулевого указателя преобразуется в тип указателя, результирующий указатель, называемый нулевой указатель , гарантированно сравнивается с неравным указателем на любой объект или функцию.
При обращении к нулевому указателю путем разыменования его, с не получить никакого предсказуемого результата.Это неопределенное поведение в соответствии с C17 6.5.3.2/4:
Если указателю было присвоено недопустимое значение, поведение унарного оператора * не определено.
Значит, может случиться что угодно.Если вам повезет, вы просто получите сбой системы.
Однако вы можете сравнить нулевой указатель с другим нулевым указателем или с константой нулевого указателя, и они гарантированно будут равны (C17 6.5.9).
Что касается указателя на- указатель, являющийся каким-то особым случаем, это не так.Указанный тип не имеет значения для любого из вышеупомянутых правил.В целом, в C нет ничего особенного с указателем на указатель - это никогда не особый случай, но всегда должен рассматриваться как указатель на тип.