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

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

  • автор:

NULL (Си)

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

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

Содержание

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

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

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

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

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

Разыменовывание нулевого указателя является операцией с неопределённым поведением. На реализацию не накладывается никаких ограничений: может произойти, например, обращение к памяти, не предназначенной для использования данной программой (то есть при чтении будет считан «мусор», а при записи — значение будет записано в область памяти, не принадлежащую программе). Например, в 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

Ссылки

      (англ.)   (англ.)
  • C++
  • Язык программирования Си

Wikimedia Foundation . 2010 .

Полезное

Смотреть что такое «NULL (Си)» в других словарях:

Null — (de) … Kölsch Dialekt Lexikon

null — null … Hochdeutsch — Plautdietsch Wörterbuch

Null —  Pour le musicien japonais, voir Kazuyuki K. Null. NULL est un mot clef présent dans de nombreux langages informatiques, et qui désigne l état d un pointeur qui n a pas de cible ou d une variable qui n a pas de valeur. La notion de valeur ou … Wikipédia en Français

Null — may refer to: Contents 1 In computing 2 In art 3 In mathematics 4 In science 5 People … Wikipedia

Null — «Null» redirige aquí. Para otras acepciones, véase Null (desambiguación). El término null o nulo es a menudo utilizado en la computación, haciendo referencia a la nada. En programación, null resulta ser un valor especial aplicado a un puntero (o… … Wikipedia Español

null — [nʌl] adjective [only before a noun] 1. STATISTICS a null effect, result etc is one that is zero or nothing 2. LAW another name for null and void: • Their suit also asks the court to declare null the buyer s shareholder rights plan. * * * … Financial and business terms

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

null — / nəl/ adj [Anglo French nul, literally, not any, from Latin nullus, from ne not + ullus any]: having no legal or binding force: void a null contract Merriam Webster’s Dictionary of Law. Merriam Webster. 1996 … Law dictionary

Null — Null, a. [L. nullus not any, none; ne not + ullus any, a dim. of unus one; cf. F. nul. See , and , and cf. .] 1. Of no legal or binding force or validity; of no efficacy; invalid; void; nugatory; useless. [1913 Webster] Faultily… … The Collaborative International Dictionary of English

Null-O — is a 1958 science fiction short story by Philip K. Dick. This rather brief story examines the concept of totally unempathic and logical humans ( Null O s) in an obvious parody of the plot and concepts of The Players of Null A by A. E. van Vogt.… … Wikipedia

Null — Sf std. (16. Jh.) Entlehnung. Entlehnt aus l. nulla gleicher Bedeutung, feminine Substantivierung von l. nullus keiner . Dieses ist eine Lehnbedeutung von arab. ṣifr, das ebenfalls Null und leer bedeutet und das seinerseits ai. śūnya Null, leer… … Etymologisches Wörterbuch der deutschen sprache

What type is NULL?

I’m wondering what type Null is in C. This is probably a duplicate, but I kept getting information about void type on searches. Maybe a better way is can NULL be returned for any type function? For example:

Hovestar's user avatar

2 Answers 2

The type of NULL may be either an integer type or void * . This is because the C standard allows it to be defined as either an integer constant expression or the result of a cast to void * .

C 2018 7.19 3 says NULL “expands to an implementation-defined null pointer constant” (when any of several headers have been included: <locale.h> , <stddef.h> , <stdio.h> , <stdlib.h> , <string.h> , <time.h> , or <wchar.h> ).

C 6.3.2.3 3 says a null pointer constant is “An integer constant expression with the value 0, or such an expression cast to a type void * .”

Thus, a C implementation may define NULL as, for example:

  • 0 , which has type int ,
  • ((void *) 0) , which has type void * , or
  • (1+5-6) , which is an integer constant expression with value 0 and type int .

Even though NULL may have an integer type, it may be compared to and assigned to pointers, as in if (p == NULL) … . The rules for these operations say that an integer constant zero will be converted to the appropriate pointer type for the operation.

Although NULL may be defined to be 0 , it is intended to be used for pointers, not as an integer zero. Programs should avoid doing that, and C implementations are generally better off defining it as ((void *) 0) to help avoid mistakes where it might be accepted as an integer value.

In most C implementations, converting NULL to an integer will yield zero. However, this is not guaranteed in the C standard. It is allowed that (int) NULL or (uintptr_t) NULL will produce the address of some special “do not use” location rather than zero. Even (int) (void *) 0 might produce such an address rather than zero.

When an integer constant zero is converted to a pointer type, it is treated specially by the C implementation; it produces a null pointer for that implementation even if its null pointer uses an address other than zero. The fact that it is an integer constant means the compiler can apply this special treatment where it recognizes the conversion in the source code. If we have some non-constant expression, such as an int variable x , then (void *) x is not guaranteed to yield a null pointer even if the value of x is zero.

Указатели

Э то, пожалуй, самая сложная и самая важная тема во всём курсе. Без понимания указателей дальнейшее изучении си будет бессмысленным. Указатели – очень простая концепция, очень логичная, но требующая внимания к деталям.

Определение

У казатель – это переменная, которая хранит адрес области памяти. Указатель, как и переменная, имеет тип. Синтаксис объявления указателей

Например
float *a;
long long *b;
Два основных оператора для работы с указателями – это оператор & взятия адреса, и оператор * разыменования. Рассмотрим простой пример.

Рассмотрим код внимательно, ещё раз

Была объявлена переменная с именем A. Она располагается по какому-то адресу в памяти. По этому адресу хранится значение 100.

Создали указатель типа int.

Теперь переменная p хранит адрес переменной A. Используя оператор * мы получаем доступ до содержимого переменной A.
Чтобы изменить содержимое, пишем

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

Будет выведено
4
4
8
4
Несмотря на то, что переменные имеют разный тип и размер, указатели на них имеют один размер. Действительно, если указатели хранят адреса, то они должны быть целочисленного типа. Так и есть, указатель сам по себе хранится в переменной типа size_t (а также ptrdiff_t), это тип, который ведёт себя как целочисленный, однако его размер зависит от разрядности системы. В большинстве случаев разницы между ними нет. Зачем тогда указателю нужен тип?

Арифметика указателей

В о-первых, указателю нужен тип для того, чтобы корректно работала операция разыменования (получения содержимого по адресу). Если указатель хранит адрес переменной, необходимо знать, сколько байт нужно взять, начиная от этого адреса, чтобы получить всю переменную.
Во-вторых, указатели поддерживают арифметические операции. Для их выполнения необходимо знать размер.
операция + N сдвигает указатель вперёд на N*sizeof(тип) байт.
Например, если указатель int *p; хранит адрес CC02, то после p += 10; он будет хранить адрес СС02 + sizeof(int)*10 = CC02 + 28 = CC2A (Все операции выполняются в шестнадцатиричном формате). Пусть мы создали указатель на начало массива. После этого мы можем «двигаться» по этому массиву, получая доступ до отдельных элементов.

Заметьте, каким образом мы получили адрес первого элемента массива

Массив, по сути, сам является указателем, поэтому не нужно использовать оператор &. Мы можем переписать пример по-другому

Получить адрес первого элемента и относительно него двигаться по массиву.
Кроме операторов + и — указатели поддерживают операции сравнения. Если у нас есть два указателя a и b, то a > b, если адрес, который хранит a, больше адреса, который хранит b.

Если же указатели равны, то они указывают на одну и ту же область памяти.

Указатель на указатель

У казатель хранит адрес области памяти. Можно создать указатель на указатель, тогда он будет хранить адрес указателя и сможет обращаться к его содержимому. Указатель на указатель определяется как

Очевидно, ничто не мешает создать и указатель на указатель на указатель, и указатель на указатель на указатель на указатель и так далее. Это нам понадобится при работе с двумерными и многомерными массивами. А вот простой пример, как можно работать с указателем на указатель.

Указатели и приведение типов

Т ак как указатель хранит адрес, можно кастовать его до другого типа. Это может понадобиться, например, если мы хотим взять часть переменной, или если мы знаем, что переменная хранит нужный нам тип.

В этом примере мы пользуемся тем, что размер типа int равен 4 байта, а char 1 байт. За счёт этого, получив адрес первого байта, можно пройти по остальным байтам числа и вывести их содержимое.

NULL pointer — нулевой указатель

У казатель до инициализации хранит мусор, как и любая другая переменная. Но в то же время, этот «мусор» вполне может оказаться валидным адресом. Пусть, к примеру, у нас есть указатель. Каким образом узнать, инициализирован он или нет? В общем случае никак. Для решения этой проблемы был введён макрос NULL библиотеки stdlib.
Принято при определении указателя, если он не инициализируется конкретным значением, делать его равным NULL.

По стандарту гарантировано, что в этом случае указатель равен NULL, и равен нулю, и может быть использован как булево значение false. Хотя в зависимости от реализации NULL может и не быть равным 0 (в смысле, не равен нулю в побитовом представлении, как например, int или float).
Это значит, что в данном случае

вполне корректная операция, а в случае

поведение не определено. То есть указатель можно сравнивать с нулём, или с NULL, но нельзя NULL сравнивать с переменной целого типа или типа с плавающей точкой.

Примеры

Теперь несколько примеров работы с указателями
1. Пройдём по массиву и найдём все чётные элементы.

2. Когда мы сортируем элементы часто приходится их перемещать. Если объект занимает много места, то операция обмена местами двух элементов будет дорогостоящей. Вместо этого можно создать массив указателей на исходные элементы и отсортировать его. Так как размер указателей меньше, чем размер элементов целевого массива, то и сортировка будет происходить быстрее. Кроме того, массив не будет изменён, часто это важно.

3. Более интересный пример. Так как размер типа char всегда равен 1 байт, то с его помощью можно реализовать операцию swap – обмена местами содержимого двух переменных.

В этом примере можно поменять тип переменных a и b на double или любой другой (с соответствующим изменением вывода и вызова sizeof), всё равно мы будет обменивать местами байты двух переменных.

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

Wikimedia Foundation . 2010 .

Null — (de) … Kölsch Dialekt Lexikon

null — null … Hochdeutsch — Plautdietsch Wörterbuch

Null — Pour le musicien japonais, voir Kazuyuki K. Null. NULL est un mot clef présent dans de nombreux langages informatiques, et qui désigne l état d un pointeur qui n a pas de cible ou d une variable qui n a pas de valeur. La notion de valeur ou … Wikipédia en Français

Null — may refer to: Contents 1 In computing 2 In art 3 In mathematics 4 In science 5 People … Wikipedia

Null — «Null» redirige aquí. Para otras acepciones, véase Null (desambiguación). El término null o nulo es a menudo utilizado en la computación, haciendo referencia a la nada. En programación, null resulta ser un valor especial aplicado a un puntero (o… … Wikipedia Español

null — [nʌl] adjective [only before a noun] 1. STATISTICS a null effect, result etc is one that is zero or nothing 2. LAW another name for null and void: • Their suit also asks the court to declare null the buyer s shareholder rights plan. * * * … Financial and business terms

null — / nəl/ adj [Anglo French nul, literally, not any, from Latin nullus, from ne not + ullus any]: having no legal or binding force: void a null contract Merriam Webster’s Dictionary of Law. Merriam Webster. 1996 … Law dictionary

Null — Null, a. [L. nullus not any, none; ne not + ullus any, a dim. of unus one; cf. F. nul. See , and , and cf. .] 1. Of no legal or binding force or validity; of no efficacy; invalid; void; nugatory; useless. [1913 Webster] Faultily… … The Collaborative International Dictionary of English

Null-O — is a 1958 science fiction short story by Philip K. Dick. This rather brief story examines the concept of totally unempathic and logical humans ( Null O s) in an obvious parody of the plot and concepts of The Players of Null A by A. E. van Vogt.… … Wikipedia

Null — Sf std. (16. Jh.) Entlehnung. Entlehnt aus l. nulla gleicher Bedeutung, feminine Substantivierung von l. nullus keiner . Dieses ist eine Lehnbedeutung von arab. ṣifr, das ebenfalls Null und leer bedeutet und das seinerseits ai. śūnya Null, leer… … Etymologisches Wörterbuch der deutschen sprache

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

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