Это вопрос конвенции и вы должны четко иметь один в вашей голове и документ (по крайней мере, в комментариях).
Иногда указатель действительно должен всегда указывать на действительный адрес (см. Пример thisintSwap
, оба аргумента должны быть действительными указателями). В других случаях он должен быть либо таким действительным адресом, либо быть NULL
. Концептуально тип указателя тогда по соглашению a sum type (между подлинными адресами указателей и специальным значением NULL
).
Обратите внимание, что язык C не имеет типа (или обозначения), который гарантирует, что определенный указатель всегда действителен и не равен нулю. BTW, с GCC, вы можете annotate a function с __attribute__
с использованием nonnull
, чтобы выразить, что данный аргумент никогда не является нулевым.
Типичный пример: FILE*
указатели в <stdio.h>
. Функция fopen
документирована, чтобы иметь возможность возвращать NULL
(при сбое) или какой-либо действительный указатель. Но функция fprintf
ожидает действительный указатель (и минус NULL
ему первый аргумент undefined behavior, часто segmentation fault; и UB действительно bad).
Некоторые непереносимые программы используют даже несколько специальных значений указателя (которые не должны быть разыменованы), например. (на Linux/x86-64) #define SPECIAL_SLOT (void*)((intptr_t)-1)
(что мы знаем, что на Linux это никогда не действительный адрес).Тогда мы могли бы иметь соглашение о том, что указатель является действительным указателем на действительную зону памяти или NULL
или SPECIAL_SLOT
(следовательно, если он рассматривается как abstract data type, это тип суммы двух разных недействительных указателей NULL
и SPECIAL_SLOT
и набор действительных адреса). Другим примером является MAP_FAILURE
как результат mmap(2) на Linux.
Кстати, при использовании указателей в C осыпать выделенные данные (косвенно полученные с malloc
), необходимы также соглашениями о том, кто отвечает за отпуская данные (с помощью free
, часто через введённую функцию, чтобы освободить данные и все его внутренние вещи).
Хорошего программирование C требует много явных конвенций относительно указателей, и очень важно, чтобы понять их точно и документировать их. Посмотрите пример [s] на GTK. Читайте также о restrict
.
Указатель против не указатель. «NULL» - значение нулевого указателя. –
http://stackoverflow.com/questions/27096623/unable-to-return-null-in-a-function-that-expects-an-integer-return-type Эта ссылка поможет вам –