Что такое null в си
Перейти к содержимому

Что такое null в си

null – константа нулевого указателя

Запись была обновлена

NULL в языках программирования Си и C++ – макрос, объявленный в заголовочном файле stddef.h. Значением этого макроса является зависящая от реализации константа нулевого указателя (от англ. null pointer constant).

Константа нулевого указателя – это целочисленное константное выражение со значением 0 или (только в Си) такое же выражение, но приведённое к типу void*. Константа нулевого указателя, приведённая к любому типу указателей, является нулевым указателем. Гарантируется, что нулевой указатель не равен указателю на любой объект (в широком смысле слова, любые данные) или функцию. Гарантируется, что любые два нулевых указателя равны между собой. Разыменовывание нулевого указателя является операцией с неопределённым поведением.

Реализация предоставляет специальное значение – константу нулевого указателя, которую можно присвоить любому указателю и такой указатель при сравнении не будет равен любому «корректному» указателю. То есть, можно считать, что нулевой указатель не содержит корректного адреса в памяти.

Использование

Нулевые указатели придуманы как удобный способ «отметить» указатели, которые заведомо не указывают на корректный адрес в памяти. Например, при объявлении указателя как автоматической переменной его значение не определено. Чтобы отметить, что этот указатель ещё не содержит корректный адрес в памяти, такому указателю присваивают константу нулевого указателя:

void f(void) < int *x = NULL; /* . */ >

Хорошим стилем программирования является присваивание указателю после освобождения памяти, на которую он ссылался, нулевого указателя. Кроме этого, применение обнуления указателей актуально для безопасности освобождения памяти: операция delete в C++ (free в Си) безопасна для нулевого указателя

TYPE *foo = new TYPE(); //использование foo delete foo; // foo != NULL foo = NULL; // foo == NULL //некоторый код программы delete foo; //ошибки нет: delete проверяет значение foo

Нулевые указатели в C++

Если брать конкретную реализацию NULL по исходным файлам, то он может быть определен как (void*)0 или как 0. Использование NULL в проектах на языке C++ может приводить к ошибкам.

int (ClassName::*pf)() = NULL;

приведет к ошибке компиляции в случае, если NULL определен как (void*)0 (например опосредованно был включен заголовок, где стандартное для C++ определение NULL перекрывается). Поэтому в программах на C++ не рекомендуется использовать NULL.

NULL (Си)

NULL в языках программирования Си и C++ — макрос, объявленный в заголовочном файле stddef.h (и других заголовочных файлах). Значением этого макроса является зависящая от реализации константа нулевого указателя (англ. null pointer constant ). Константа нулевого указателя — это целочисленное константное выражение со значением 0, или (только в Си) такое же выражение, но приведённое к типу void * . Константа нулевого указателя, приведённая к любому типу указателей, является нулевым указателем. Гарантируется, что нулевой указатель не равен указателю на любой объект (в широком смысле слова, любые данные) или функцию. Гарантируется, что любые два нулевых указателя равны между собой. Разыменовывание нулевого указателя является операцией с неопределённым поведением.

Иначе говоря, реализация предоставляет специальное значение — константу нулевого указателя, которую можно присвоить любому указателю и такой указатель при сравнении не будет равен любому «корректному» указателю. То есть, можно считать, что нулевой указатель не содержит корректный адрес в памяти.

Использование

Нулевые указатели придуманы как удобный способ «отметить» указатели, которые заведомо не указывают на корректный адрес в памяти. Например, при объявлении указателя как автоматической переменной его значение не определено. Чтобы отметить, что этот указатель ещё не содержит корректный адрес в памяти, такому указателю присваивают константу нулевого указателя:

void f(void)  int *x = NULL; /* . */ > 

Хорошим стилем программирования является присваивание указателю после освобождения памяти, на которую он ссылался, нулевого указателя. Кроме этого, применение обнуления указателей актуально для безопасности освобождения памяти: операция delete в C++ (free в Си) безопасна для нулевого указателя. Например:

TYPE *foo = new TYPE(); //использование foo delete foo;// foo != NULL //еще 100 строк кода delete foo;//ОШИБКА! память уже недоступна 

в то время как в таком варианте ошибки не будет

TYPE *foo = new TYPE(); //использование foo delete foo;// foo != NULL foo = NULL;// foo == NULL //еще 100 строк кода delete foo;//ошибки нет: delete проверяет значение foo 

Разыменовывание нулевых указателей

Разыменовывание нулевого указателя является операцией с неопределённым поведением. На реализацию не накладывается никаких ограничений: может произойти, например, обращение к памяти, не предназначенной для использования данной программой (то есть при чтении будет считан «мусор», а при записи — значение будет записано в область памяти, не принадлежащую программе). Например, в DOS запись по нулевому адресу затрёт как минимум нулевой вектор прерываний, так что следующий вызов int 0 приведёт, скорее всего, к зависанию системы. Однако чаще всего это приводит к ошибке времени выполнения (если в операционной системе реализована защита памяти и доступ в невыделенную процессу память блокируется). Например, в Windows 9x сообщение «Общая ошибка защиты» — «Программа выполнила недопустимую операцию и будет закрыта» (англ. general protection fault, GPF ) выдаётся чаще всего в тех случаях, когда программа обращается в память по некорректному (в том числе неинициализированному или уже освобождённому) указателю. В Unix-подобных операционных системах в таких ситуациях процесс получает сигнал SIGSEGV и его обработчик выводит сообщение «Segmentation fault».

Нулевые указатели в C++

В отличие от классического Си в C++ значение пустого указателя предопределено стандартом языка и всегда равно 0 (целочисленному нулю, приведённому к типу «указатель»). Поэтому в программах на C++ не только возможно, но и рекомендуется использовать значение 0 вместо NULL [1] , однако некоторые программисты считают, что это ухудшает читаемость исходного кода. В стандарте C++11 для обозначения нулевого указателя добавлено новое ключевое слово nullptr [2] [3] .

См. также

Примечания

  1. Страуструп Б. 5.1.1 «Ноль» // Язык программирования C++. Специальное издание = The C++ programming language. Special edition. — М .: Бином-Пресс, 2007. — 1104 с. — ISBN 5-7989-0223-4
  2. JTC1/SC22/WG21 — The C++ Standards CommitteeSC22/WG21/N2431 = J16/07-0301 «A name for the null pointer: nullptr» (англ.) (PDF). JTC1.22.32. The C++ Standards Committee (2 October 2007). Архивировано из первоисточника 11 февраля 2012.Проверено 4 октября 2010. (англ.)
  3. Scott Meyers, Summary of C++11 Feature Availability in gcc and MSVC, 16 August 2011

Ссылки

  • http://c-faq.com/null/null1.html (англ.)
  • http://c-faq.com/null/varieties.html (англ.)
  • C++
  • Язык программирования Си

Как использовать NULL в C

Null in C

Несколько языков программирования используют концепцию null.

У Go есть nil, у JavaScript null, у Python None и так далее.

C имеет значение NULL.

NULL используется иначе в других языках. В C NULL ограничивается определением null указателя.

Когда мы инициализируем указатель, мы не всегда можем знать, на что он указывает. Вот когда это полезно:

int * p_some_variable = NULL;

По умолчанию NULL недоступен: вам нужно включить stdio.h, чтобы использовать его (или stddef.h если хотите):

#include

int main(void)  
int * p_some_variable = NULL;

В противном случае компилятор C выдаст вам ошибку:

hello.c:3:26: error: use of undeclared identifier
'NULL'
int * p_some_variable = NULL;
1 error generated.

Вы можете проверить, является ли указатель null указателем, сравнив его с NULL:

#include

int main(void)  
int * p_some_variable = NULL;
if (p_some_variable == NULL)  
printf("equal");
> На практике NULL является постоянным эквивалентом 0 или "\ 0".

Вот почему вы можете установить строку в NULL, используя:

char *a_string = '\0';
Понравилось то, что вы прочитали?

Подписывайтесь на нашу рассылку и получайте ежедневные обновления о новых учебниках, статьях, курсах и о многом другом!

Просто введите ваш адрес электронной почты, чтобы подписаться.

(Без спамов; ежемесячно два письма; отписаться от рассылки можно в любое время)

Спасибо!

Подписка успешно оформлена. ��

Что значит "NULL"?

Что значит Handle hf? Что в эту функцию нужно передавать
мне нужно создать функцию Node * ReadNode(HANDLE hf); (Node это структура) Так вот вопрос в том.

Sleep(8000) - что значит? На что можно заменить в борланд с++?
Не распознаёт Sleep(8000) . Если за комментировать пишет что f заданно но не используется. Как.

Что это значит srand(time(NULL))?
srand(time(NULL));

Что значит DB-Library Error 10001: NULL DBPROCESS pointer encountered?
Cho snachit etot error msg: DB-Library Error 10001: NULL DBPROCESS pointer encountered

Эксперт С++

1936 / 1048 / 109
Регистрация: 29.03.2010
Сообщений: 3,167

на примере ниже, создаётся строка, которая содержит в себе текст: "NULL"
а вообще NULL это:
#define NULL 0
если мне склероз не изменяет.

Форумчанин

Эксперт CЭксперт С++

8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453

ЦитатаСообщение от Maxim Prishchepa Посмотреть сообщение

#define NULL 0

Не обязательно. Где-то Evg рассказывал, что встречается и NULL == -1.

NULL - это дефайн, который указывает на участок памяти, в котором гарантировано не лежат никакие данные.
Сейчас это уже пережиток С, с появлением С++11 для таким целей нужно использовать nullptr.

Fatmarmelad, в вашем примере "NULL" - Это вообще строковый литерал. С таким же успехом там мог оказаться любой другой текст.

3434 / 2813 / 1249
Регистрация: 29.01.2016
Сообщений: 9,426

ЦитатаСообщение от Fatmarmelad Посмотреть сообщение

и когда он применяется ?

NULL - обычно, для инициализации нулём указателя (подчёркивается, что инициализируется именно указатель). Сейчас для этого есть nullptr .

Форумчанин

Эксперт CЭксперт С++

8215 / 5045 / 1437
Регистрация: 29.11.2010
Сообщений: 13,453

ЦитатаСообщение от nd2 Посмотреть сообщение

для инициализации нулём

Для инициализации адресом, в котором не содержаться никакие данные (переменные, функции и т.д.). Это не обязательно ноль. См. объяснение от Evg по ссылке выше.

18467 / 9625 / 2355
Регистрация: 30.01.2014
Сообщений: 16,876

ЦитатаСообщение от MrGluck Посмотреть сообщение

Где-то Evg рассказывал, что встречается и NULL == -1.

NULL не может быть -1 , по крайней мере в стандартном С++.
-1 - может быть значением (численным представлением) null pointer value после null pointer conversion. Иными словами:

int * p = 0; // p может содержать численное значение 0xFFFFFFFF

Т.е. фраза по ссылке, что выражение

if(p != 0)

непереносимо - неверна применительно к С++. Т.к. тут спутаны понятия null pointer constant и null pointer value.
4.10/1

A null pointer constant is an integer literal (2.13.2) with value zero or a prvalue of type std::nullptr_t.
A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type
and is distinguishable from every other value of object pointer or function pointer type. Such a conversion
is called a null pointer conversion. Two null pointer values of the same type shall compare equal. The
conversion of a null pointer constant to a pointer to cv-qualified type is a single conversion, and not the
sequence of a pointer conversion followed by a qualification conversion (4.4). A null pointer constant of
integral type can be converted to a prvalue of type std::nullptr_t. [ Note: The resulting prvalue is not a
null pointer value. — end note ]

Эксперт CЭксперт С++

11177 / 6122 / 1675
Регистрация: 18.10.2014
Сообщений: 15,416

ЦитатаСообщение от MrGluck Посмотреть сообщение

См. объяснение от Evg по ссылке выше.

Объясенение по ссылке не соответствует действительности. В "классическом" С++ макро NULL в С++ всегда строго означает целочисленное константное выражение со значением 0 . Это может быть 0 или 0L или 0LL , но всегда строго ноль. Без вариантов.

Утверждение по ссылке, что код if (p != 0) якобы не переносим соврешенно не верно - для указателя p код if (p != 0) всегда строго эквивалентен if (p) и if (p != NULL) .

В "классическом" С++ вы можете писать int a[10]; a[NULL] = 42; и вы гарантированно присвоите 42 именно элементу a[0] , хоть NULL и не предназначен дял такого использования.

В современном C++ однако NULL может быть определен как nullptr . В современном С++ также запрещено определять NULL через константные выражения. В "классическом" С++ можно было определять NULL как (4 - 2 * 2) , а теперь этог делать нельзя.

Утверждение "null - это не обязательно нуль" верно для null pointer value, т.е. для физического значения, которое фактически хранится в указателе p после p = NULL . Оно действительно не обязательно является нулем. Однако само макро NULL - это null pointer constant - совсем другая сущность и всегда строго только нуль (или теперь nullptr).

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *