NULL Pointer in C
The Null Pointer is the pointer that does not point to any location but NULL. According to C11 standard:
“An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant. If a null pointer constant is converted to a pointer type, the resulting pointer, called a null pointer, is guaranteed to compare unequal to a pointer to any object or function.”
Syntax of Null Pointer Declaration in C
We just have to assign the NULL value. Strictly speaking, NULL expands to an implementation-defined null pointer constant which is defined in many header files such as “stdio.h”, “stddef.h”, “stdlib.h” etc.
Uses of NULL Pointer in C
Following are some most common uses of the NULL pointer in C:
- To initialize a pointer variable when that pointer variable hasn’t been assigned any valid memory address yet.
- To check for a null pointer before accessing any pointer variable. By doing so, we can perform error handling in pointer-related code, e.g., dereference a pointer variable only if it’s not NULL.
- To pass a null pointer to a function argument when we don’t want to pass any valid memory address.
- A NULL pointer is used in data structures like trees, linked lists, etc. to indicate the end.
Check if the pointer is NULL
It is a valid operation in pointer arithmetic to check whether the pointer is NULL. We just have to use isequal to operator ( == ) as shown below:
The above equation will be true if the pointer is NULL, otherwise, it will be false.
A Guide to NULL in C
Most programming languages have some concept of null values. Generally, null is a value that represents nothing and therefore is usually used to represent the absence of a value when a variable is not initialized.
For example, JavaScript uses null , Python uses None , and Ruby uses nil .
While null is usually used to represent the absence of a value, in C, it is used to represent a null pointer.
When you want to initialize a pointer but don’t yet have a value, you can use NULL .
To ensure that you don’t get the use of undeclared identifier error, make sure to include the stdio.h header file that comes with C.
In addition to using it as a value to set a new pointer to, you can also use NULL to check if variables are pointing to a valid address or not.
Here’s how to check if a pointer is a null pointer or not in C:
Under the hood, NULL is just a constant pointer guaranteed to not point to any valid address.
In some cases, you could replace NULL with 0 to get the same result, but the intent of your code will be more clear if you use NULL instead.
Conclusion
Hopefully, this post gave you a quick overview of how NULL works in C.
You can use NULL to initialize a variable to point to nothing, or use it to check if a pointer is a null pointer or not.
If you want to learn about web development, founding a start-up, bootstrapping a SaaS, and more, follow me on Twitter! You can also join the conversation over at our official Discord!
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] .
См. также
Примечания
- ↑Страуструп Б. 5.1.1 «Ноль» // Язык программирования C++. Специальное издание = The C++ programming language. Special edition. — М .: Бином-Пресс, 2007. — 1104 с. — ISBN 5-7989-0223-4
- ↑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. (англ.)
- ↑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
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
5 . Null Pointers
For each pointer type, C defines a special pointer value, the null pointer, that is guaranteed not to point to any object or function of that type. (The null pointer is analogous to the nil pointer in Pascal and LISP.) C programmers are often confused about the proper use of null pointers and about their internal representation (even though the internal representation should not matter to most programmers). The null pointer constant used for representing null pointers in source code involves the integer 0, and many machines represent null pointers internally as a word with all bits zero, but the second fact is not guaranteed by the language.
Because confusion about null pointers is so common, this chapter discusses them rather exhaustively. (Question 5.13- 5.17 are a retrospective on the confusion itself.) If you are fortunate enough not to share the many misunderstandings covered or find the discussion too exhausting, you can skip to question 5.15 for a quick summary.
Q 5.1 악명높은 `널 포인터’란 게 도대체 뭔가요?
Answer 언어 정의에 의하면 각각의 포인터 타입에 대해, 특별한 값이 — 널(null) 포인터 — 있어서, 다른 포인터 값들과는 구별되며, 어떤 오브젝트나 함수를 가리키는 포인터와는 항상 구별되는 포인터를 말합니다. 즉, 주소를 리턴하는 & 연산자는 절대로 널 포인터를 만들어 낼 수 없으며, 실패하지 않는 한 malloc() 함수도 널 포인터를 리턴하지 않습니다 ( malloc() 은 실패할 경우, 널 포인터를 리턴합니다. 그리고 이 것이 널 포인터의 쓰임새 — “할당되지 않은” 또는 “어떠한 것도 가리키지 않는”을 의미하는 특별한 포인터로 쓰이는 것 — 중 하나입니다.)
널 포인터와 초기화되지 않은 포인터 5 . 1 와는 개념상 완전히 다릅니다. 널 포인터는 어떠한 오브젝트나 함수도 가리키지 않는 포인터이고, 초기화되지 않는 포인터는 어떤 값을 가지는 지 모르므로, 아무 오브젝트나 가리킬 수 있는 포인터입니다. 질문 1.30, 7.1, 7.31을 참고하기 바랍니다.
위에서 설명한 것처럼, C 언어는 각각의 포인터 타입에 따라 널 포인터가 존재합니다. 그리고 널 포인터의 실제 값은 각 타입에 따라 서로 다를 수 있습니다. 컴파일러가 각 타입에 따른 실제 값으로 변경해 주기 때문에 프로그래머들은 각 타입에 따라 서로 다른 널 포인터의 내부적인 값을 알 필요가 전혀 없습니다 (질문 5.2, 5.5, 5.6을 참고).
Q 5.2 프로그램에서 어떻게 널 포인터를 쓰나요? Answer 널 포인터 상수를 ( null pointer constant ) 이용합니다. 언어 정의에 따라, 포인터가 쓰일 곳(context)에 상수 0을 — 좀 더 정확히 말해서, 0을 가지는 정수 상수 수식 5 . 2 을 — 쓰면 컴파일할 때 자동으로 널 포인터로 변경됩니다. 즉, 초기화나, 대입, 비교할 때, 한쪽이 포인터 타입의 변수나 수식일 경우, 다른 쪽의 0은 컴파일러가 자동으로 널 포인터로 바꾸어 준다는 뜻입니다. 컴파일러는 이 상수 0을 실제 널 포인터 값으로 바꾸어 줍니다. 따라서 다음과 같은 코드는 전혀 문제될 것이 없습니다 (질문 5.3 참고):
덧붙여 질문 5.3도 참고하시기 바랍니다.
그러나, 함수의 인자로 포인터를 전달할 경우, 포인터가 쓰일 곳(pointer context)으로 인식하지 못하고, 단순히 정수 0으로 인식할 가능성이 있습니다. 이럴 때에는 널 포인터라는 것을 강제적으로 캐스팅을 써서 알려 주어야 합니다. 예를 들어, UNIX 시스템 콜인 execl 은 가변 인자 리스트 5 . 3 를 받습니다. 이 함수는 인자의 끝을 알리기 위해서 널 포인터를 마지막으로 전달해야 합니다. 즉:
마지막 인자의 (char *) 캐스팅이 생략될 경우, 컴파일러는 이를 널 포인터로 인식하지 못하고 단순히 정수 0으로 인식합니다. (대부분의 UNIX 매뉴얼은 이 부분을 잘못 설명하고 있으니 주의해야 합니다. 덧붙여 질문 5.11도 참고하시기 바랍니다.)
함수의 프로토타입(prototype)이 있을 경우, 인자 전달은 대입(assignment) 연산으로 인식되기 때문에, 캐스팅을 할 필요가 없습니다. 왜냐하면 함수 프로토타입이 컴파일러에게 적절한 타입이 무엇이라는 것을 알려주기 때문입니다. 따라서 단순히 0만 전달해도, 컴파일러가 알아서 널 포인터로 바꾸어 줍니다. 그러나 가변 인자 리스트를 쓰는 함수의 인자는 프로토타입을 알더라도, 각각의 인자에 대한 타입을 알 수 없으므로 이런 함수의 인자로 쓰인 널 포인터에는 반드시 캐스팅을 써 주어야 합니다. (질문 15.3을 참고하시기 바랍니다.) varargs 함수에 쓰일 것을 대비하고, 함수 프로토타입이 없을 경우도 대비하고, ANSI 호환이 아닌 컴파일러에 쓰일 것을 대비하기 위해 널 포인터 상수 0에 항상 캐스팅을 하는 것이 혼동되지 않고 안전할 수 있습니다.
아래 표는 널 포인터 상수(0)를 그대로 써도 좋은 경우와, 그렇지 않는 경우에 대한 상황을 알려줍니다:
| 그냥 0을 써도 좋은 경우: | 캐스팅이 반드시 필요한 경우: |
| 초기화(initialization) | |
| 대입(assignment) | |
| 비교(comparison) | |