比较中 NULL 和零的区别
Difference Between NULL and Zero in Comparing
我对NULL略知一二,但是一说到比较就糊涂了。
例如:
int* p;
if(p == NULL){
//do stuff
}
if(p == 0){
//do stuff
}
在第一次比较中“p”与什么地址进行比较?
是否在寻找“p”的参考点,看是否有效?
NULL
在 C++ 编译器中只是一个定义 "null pointer constant"(通常值为 0)的宏。所以没有区别,除了 NULL
被用来表示一个意图(这很重要)。例如,您可以创建一个值为 NULL
的 int
变量,它没有对标准声明 (int a = 0;
).
进行任何特殊处理。
NULL
是 不是 "an empty space in memory"。它只是一个符号(通常)表示缺少某些东西(值、指针等...)。
但是,现在不鼓励在 C++ 中使用 NULL
,应该使用更高级的 nullptr。
在 C 的每个现代实现中,NULL 为零,通常作为指针值:
#define NULL (void *) 0
因此,比方说,将一个字符与 NULL 进行比较可能是无效的:
char ch = 'a';
if (ch == NULL) // probably "invalid comparison of pointer with scalar"
作为指针值,NULL 选择指向无效内存,因此取消引用它(在合适的体系结构上)将导致内存错误。大多数虚拟机仅为此目的保留较低内存,并通过将低内存未映射到物理内存来实现。有多少内存未保留?可能是几千字节,但许多实现保留几兆字节。
来自 C99 标准:
7.17 Common definitions <stddef.h>
3 The macros are
NULL
which expands to an implementation-defined null pointer constant; ...
来自 C++11 标准:
18.2 Types
3 The macro NULL
is an implementation-defined C++ null pointer constant in this International Standard (4.10).194
脚注 194:
194) Possible definitions include 0
and 0L
, but not (void*)0
.
Microsoft VS 2008 将其定义为:
/* Define NULL pointer value */
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
gcc/g++ 4.9.3 定义为:
#if defined (_STDDEF_H) || defined (__need_NULL)
#undef NULL /* in case <stdio.h> has defined it. */
#ifdef __GNUG__
#define NULL __null
#else /* G++ */
#ifndef __cplusplus
#define NULL ((void *)0)
#else /* C++ */
#define NULL 0
#endif /* C++ */
#endif /* G++ */
#endif /* NULL not defined and <stddef.h> or need NULL. */
我怀疑其他现代编译器也有类似的定义。
鉴于 NULL
的上述定义,
行
if(p == NULL){
扩展为:
if(p == ((void*)0) ){
在 C.
扩展为
if(p == 0){
在 C++ 中。
在其他 C++ 编译器中,该行可以扩展为
if(p == 0L){
使用 C++11 时,最好避免使用 NULL
并开始使用 nullptr
。
if ( p == nullptr ) {
从概念上讲,NULL
是指向任何地方的单数 pointer-value,并且可以隐式转换为任何 pointer-type。
实际上,不幸的是,你不能依赖它作为指针值,除非你在 pointer-only 上下文中使用它。
因此,在 C++11 和更高版本中分别使用 nullptr
向右转换 0 pointer-type,尤其是在整数零不会转换为指针的上下文中。
顺便说一句:虽然在大多数现代系统上,空指针实际上是 all-bits-zero,但标准并不要求它(可能有许多 bit-patterns 表示空指针,而 none all-zero),并且对空指针常量在源代码中的表示方式没有任何影响。
在 C++ 中:
The macro NULL
is an implementation-defined C++ null pointer constant in this International Standard (4.10).
定义为:
A null pointer constant is an integer literal (2.14.2) with value zero or a prvalue of type std::nullptr_t
.
Pre-C++11 最后一个选项明显不可用...
而post-C++11,因为不知道是什么,所以直接用nullptr
。
在 C:
The macros are
NULL
which expands to an implementation-defined null pointer constant; ...
定义为:
An integer constant expression with the value 0, or such an expression cast to type void *
, is called a null pointer constant.
NULL 表示未被任何有效指针使用的值。因此,如果指针为 NULL,则它根本不指向任何变量。在指针上下文中,值零与 NULL 的含义相同,但是使用 NULL 比使用零更清楚。这就是您需要了解的有关 NULL 的全部信息。
know that NULL is a empty space in memory
不完全 - NULL
是 well-defined "nowhere" 不对应于任何有效的内存地址。
在 C 和 C++ 中,NULL
宏被定义为一个 空指针常量 ,这是一个 zero-valued 整数表达式。 C++ 还提供了 nullptr
字面值,它的计算结果也是空指针常量。当空指针常量出现在指针上下文中时,它将被转换为implementation-defined空指针值。空指针值可能为也可能不是 0 值,但保证与任何有效指针值进行比较时不相等。
6.3.2.3 Pointers
...
3 An integer constant expression with the value 0, or such an expression cast to type
void *, is called a null pointer constant.
66) 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.
66)) The macro NULL
is defined in <stddef.h>
(and other headers) as a null pointer constant; see 7.19
2.13.7 Pointer literals [lex.nullptr]
pointer-literal:
nullptr
1 The pointer literal is the keyword nullptr
. It is a prvalue of type std::nullptr_t
. [Note: std::nullptr_t
is a distinct type that is neither a pointer type nor a pointer to member type; rather, a prvalue of this type is
a null pointer constant and can be converted to a null pointer value or null member pointer value. See 4.10
and 4.11. — end note ]
4.10 Pointer conversions [conv.ptr]
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 ]
...
18.2 Types [support.types]
...
3 The macro NULL
is an implementation-defined C++ null pointer constant in this International Standard
(4.10).194
194) Possible definitions include 0 and 0L, but not (void*)0
要敲定一些要点:
NULL
宏、nullptr
文字(仅限 C++)和空指针 常量 始终为 0 值;
- 空指针值不必为0值;
- 空指针值永远不会等于有效的内存地址;
- 编译器的工作是将源代码中的空指针 constant 映射到生成的机器代码中的等效空指针 value ;作为程序员,您(通常)不需要担心实现中的实际空指针 value;
- 由于空指针常量始终为 0 值,因此将指针值与
0
进行比较应该等同于将其与 NULL
或 nullptr
进行比较。
我对NULL略知一二,但是一说到比较就糊涂了。
例如:
int* p;
if(p == NULL){
//do stuff
}
if(p == 0){
//do stuff
}
在第一次比较中“p”与什么地址进行比较?
是否在寻找“p”的参考点,看是否有效?
NULL
在 C++ 编译器中只是一个定义 "null pointer constant"(通常值为 0)的宏。所以没有区别,除了 NULL
被用来表示一个意图(这很重要)。例如,您可以创建一个值为 NULL
的 int
变量,它没有对标准声明 (int a = 0;
).
NULL
是 不是 "an empty space in memory"。它只是一个符号(通常)表示缺少某些东西(值、指针等...)。
但是,现在不鼓励在 C++ 中使用 NULL
,应该使用更高级的 nullptr。
在 C 的每个现代实现中,NULL 为零,通常作为指针值:
#define NULL (void *) 0
因此,比方说,将一个字符与 NULL 进行比较可能是无效的:
char ch = 'a';
if (ch == NULL) // probably "invalid comparison of pointer with scalar"
作为指针值,NULL 选择指向无效内存,因此取消引用它(在合适的体系结构上)将导致内存错误。大多数虚拟机仅为此目的保留较低内存,并通过将低内存未映射到物理内存来实现。有多少内存未保留?可能是几千字节,但许多实现保留几兆字节。
来自 C99 标准:
7.17 Common definitions
<stddef.h>
3 The macros are
NULL
which expands to an implementation-defined null pointer constant; ...
来自 C++11 标准:
18.2 Types
3 The macro
NULL
is an implementation-defined C++ null pointer constant in this International Standard (4.10).194
脚注 194:
194) Possible definitions include
0
and0L
, but not(void*)0
.
Microsoft VS 2008 将其定义为:
/* Define NULL pointer value */
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
gcc/g++ 4.9.3 定义为:
#if defined (_STDDEF_H) || defined (__need_NULL)
#undef NULL /* in case <stdio.h> has defined it. */
#ifdef __GNUG__
#define NULL __null
#else /* G++ */
#ifndef __cplusplus
#define NULL ((void *)0)
#else /* C++ */
#define NULL 0
#endif /* C++ */
#endif /* G++ */
#endif /* NULL not defined and <stddef.h> or need NULL. */
我怀疑其他现代编译器也有类似的定义。
鉴于 NULL
的上述定义,
if(p == NULL){
扩展为:
if(p == ((void*)0) ){
在 C.
扩展为
if(p == 0){
在 C++ 中。
在其他 C++ 编译器中,该行可以扩展为
if(p == 0L){
使用 C++11 时,最好避免使用 NULL
并开始使用 nullptr
。
if ( p == nullptr ) {
从概念上讲,NULL
是指向任何地方的单数 pointer-value,并且可以隐式转换为任何 pointer-type。
实际上,不幸的是,你不能依赖它作为指针值,除非你在 pointer-only 上下文中使用它。
因此,在 C++11 和更高版本中分别使用 nullptr
向右转换 0 pointer-type,尤其是在整数零不会转换为指针的上下文中。
顺便说一句:虽然在大多数现代系统上,空指针实际上是 all-bits-zero,但标准并不要求它(可能有许多 bit-patterns 表示空指针,而 none all-zero),并且对空指针常量在源代码中的表示方式没有任何影响。
在 C++ 中:
The macro
NULL
is an implementation-defined C++ null pointer constant in this International Standard (4.10).
定义为:
A null pointer constant is an integer literal (2.14.2) with value zero or a prvalue of type
std::nullptr_t
.
Pre-C++11 最后一个选项明显不可用...
而post-C++11,因为不知道是什么,所以直接用nullptr
。
在 C:
The macros are
NULL
which expands to an implementation-defined null pointer constant; ...
定义为:
An integer constant expression with the value 0, or such an expression cast to type
void *
, is called a null pointer constant.
NULL 表示未被任何有效指针使用的值。因此,如果指针为 NULL,则它根本不指向任何变量。在指针上下文中,值零与 NULL 的含义相同,但是使用 NULL 比使用零更清楚。这就是您需要了解的有关 NULL 的全部信息。
know that NULL is a empty space in memory
不完全 - NULL
是 well-defined "nowhere" 不对应于任何有效的内存地址。
在 C 和 C++ 中,NULL
宏被定义为一个 空指针常量 ,这是一个 zero-valued 整数表达式。 C++ 还提供了 nullptr
字面值,它的计算结果也是空指针常量。当空指针常量出现在指针上下文中时,它将被转换为implementation-defined空指针值。空指针值可能为也可能不是 0 值,但保证与任何有效指针值进行比较时不相等。
6.3.2.3 Pointers
...
3 An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant. 66) 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.
66)) The macroNULL
is defined in<stddef.h>
(and other headers) as a null pointer constant; see 7.19
2.13.7 Pointer literals [lex.nullptr]
pointer-literal:
nullptr
1 The pointer literal is the keywordnullptr
. It is a prvalue of typestd::nullptr_t
. [Note:std::nullptr_t
is a distinct type that is neither a pointer type nor a pointer to member type; rather, a prvalue of this type is a null pointer constant and can be converted to a null pointer value or null member pointer value. See 4.10 and 4.11. — end note ]
4.10 Pointer conversions [conv.ptr]
1 A null pointer constant is an integer literal (2.13.2) with value zero or a prvalue of typestd::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 typestd::nullptr_t
. [ Note: The resulting prvalue is not a null pointer value. — end note ]
...
18.2 Types [support.types]
...
3 The macroNULL
is an implementation-defined C++ null pointer constant in this International Standard (4.10).194
194) Possible definitions include 0 and 0L, but not (void*)0
要敲定一些要点:
NULL
宏、nullptr
文字(仅限 C++)和空指针 常量 始终为 0 值;- 空指针值不必为0值;
- 空指针值永远不会等于有效的内存地址;
- 编译器的工作是将源代码中的空指针 constant 映射到生成的机器代码中的等效空指针 value ;作为程序员,您(通常)不需要担心实现中的实际空指针 value;
- 由于空指针常量始终为 0 值,因此将指针值与
0
进行比较应该等同于将其与NULL
或nullptr
进行比较。