Является ли NULL указателем?

#c #pointers #null #conceptual #concept

#c #указатели #null #концептуальный #концепция

Вопрос:

Итак, ранее у меня был спор с моим профессором, защищавшим, что NULL не является указателем, но он продолжал настаивать, что это потому, что существует такая вещь, как нулевой указатель. Итак, теперь я немного запутался, действительно ли NULL является указателем или нет

Я уже пробовал поиск в Интернете, но не смог найти никакого ответа, поэтому мое последнее средство здесь

Комментарии:

1. Итак, что вы думаете о присвоении NULL указателю? Что он содержит?

2. Это зависит от того, что вы подразумеваете под «является указателем». Поскольку вы отметили это «концептуальным», я думаю, вы можете использовать термин «указатель» в смысле, отличном от определения формального языка.

3. @phuclv указатель указывает на ничто или ноль

4. указатель, который указывает на ничто, является нулевым указателем

5. @Joe: вы можете принять один из ответов, нажав на серую галочку под его оценкой.

Ответ №1:

В C NULL это макрос, который расширяется до константы нулевого указателя.

7.19p3

Макросы являются

NULL, которое расширяется до константы нулевого указателя, определенной реализацией; …

Константа нулевого указателя — это целочисленное постоянное выражение со значением 0 (например, 0 , 1-1 42*0LL , (void*) и т.д.) или такое выражение, приведенное к, , ,,,,,,,,, и т.д.).

6.3.2.3p3

Целочисленное константное выражение со значением 0 или такое выражение, приведенное к типу void *, называется константой нулевого указателя.66) Если константа нулевого указателя преобразуется в тип указателя, результирующий указатель, называемый нулевым указателем, гарантированно сравнивается неравным с указателем на любой объект или функцию.

Большинство распространенных реализаций C определяют NULL как 0 , 0L или ((void*)0) .

Итак, вы правы. NULL не обязательно быть указателем.

(IIRC, C даже не допускает (void*) приведения в NULL , что NULL означает, что в C всегда используется целочисленный тип. Из-за этого и потому что void* указатели не так легко сравниваются с обычными указателями в C , C > = 11 теперь имеет специальное nullptr ключевое слово.)

Комментарии:

1. @Joe Если в нем есть (void *) приведение, то у него действительно есть тип указателя (void).

2. @Joe NULL — это макрос, расширяющийся до неспецифического значения, которое можно сравнить с указателями на равенство. NULL Значение может иметь тип void-pointer или это может быть целое число. Обычно это 0 , 0L или ((void*)0) .

3. @PSkocik Обратите внимание, что этот вопрос был помечен как «концептуальный», а не «специалист по языку», поэтому я предполагаю, что вопрос касается не столько NULL макроса, сколько «нулевого указателя» как концепции.

Ответ №2:

NULL сам по себе не является указателем, это макрос, который может использоваться для инициализации указателя на значение нулевого указателя своего типа. При сравнении с указателем он сравнивается равным, если указатель является нулевым указателем, и неравным, если указатель является допустимым указателем на объект его типа.

Семантической разницы между char *p = 0; и char *p = NULL; нет, но последнее более явно, и использование NULL вместо 0 более информативно в обстоятельствах, когда другой операнд явно не является указателем или если сравнение с целым числом выглядит как несоответствие типов:

 FILE *fp = fopen("myfile", "r");
if (fp == NULL) {
    /* report the error */
}
  

Аналогично, в C нет семантической разницы между '' и 0 , они оба являются int константами. Первый — это нулевой байт, второй — нулевое значение. Использование 0 , '' и NULL с умом может показаться бесполезным, но делает код более читаемым для других программистов, а также для вас самих.

Путаница может возникнуть из-за неправильного написания нулевого указателя как NULL указателя. Стандарт C был тщательно вычитан, чтобы использовать только нулевой указатель и ссылаться на NULL только как на макрос NULL .

Обратите внимание, однако, что одно из принятых определений NULL , #define NULL ((void*)0) создает NULL нулевой указатель на void .

Ответ №3:

В идее «указателя на адрес 0» нет ничего такого, что представляло бы проблему.

Правило заключается в том, что вам запрещено разыменовывать его … ему разрешено существовать, и если оно создано, то будет соответствовать любым критериям «указательности», которые я могу придумать. Просто потому, что это не является значимым указателем на что-либо…