本文转自:http://bbs.chinaunix.net/viewthread.php?tid=544415&extra=&page=7
帖子里讨论了C语言中的空指针、空指针常量、NULL、0等概念及相互关系及区别。这里摘录whyglinux兄的总结。做个标签,呵呵^_^
- 什么是空指针常量(null pointer constant)?
[6.3.2.3-3] An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.
这里告诉我们:0、0L、'\0'、3 - 3、0 * 17 (它们都是“integer constant expression”)以及 (void*)0 (tyc: 我觉得(void*)0应该算是一个空指针吧,更恰当一点)等都是空指针常量(注意 (char*) 0 不叫空指针常量,只是一个空指针值)。至于系统选取哪种形式作为空指针常量使用,则是实现相关的。一般的 C 系统选择 (void*)0 或者 0 的居多(也有个别的选择 0L);至于 C++ 系统,由于存在严格的类型转化的要求,void* 不能象 C 中那样自由转换为其它指针类型,所以通常选 0 作为空指针常量(tyc: C++标准推荐),而不选择 (void*)0。
- 什么是空指针(null pointer)?
[6.3.2.3-3] 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.
因此,如果 p 是一个指针变量,则 p = 0;、p = 0L;、p = '\0';、p = 3 - 3;、p = 0 * 17; 中的任何一种赋值操作之后(对于 C 来说还可以是 p = (void*)0;), p 都成为一个空指针,由系统保证空指针不指向任何实际的对象或者函数。反过来说,任何对象或者函数的地址都不可能是空指针。(tyc: 比如这里的(void*)0就是一个空指针。把它理解为null pointer还是null pointer constant会有微秒的不同,当然也不是紧要了)
- 什么是 NULL?
[6.3.2.3-Footnote] The macro NULL is defined in <stddef.h> (and other headers) as a null pointer constant
即 NULL 是一个标准规定的宏定义,用来表示空指针常量。因此,除了上面的各种赋值方式之外,还可以用 p = NULL; 来使 p 成为一个空指针。(tyc:很多系统中的实现:#define NULL (void*)0,与这里的“a null pointer constant”并不是完全一致的)
-
空指针(null pointer)指向了内存的什么地方(空指针的内部实现)?
标准并没有对空指针指向内存中的什么地方这一个问题作出规定,也就是说用哪个具体的地址值(0x0 地址还是某一特定地址)表示空指针取决于系统的实现。我们常见的空指针一般指向 0 地址,即空指针的内部用全 0 来表示(zero null pointer,零空指针);也有一些系统用一些特殊的地址值或者特殊的方式表示空指针(nonzero null pointer,非零空指针),具体请参见C FAQ。
幸运的是,在实际编程中不需要了解在我们的系统上空指针到底是一个 zero null pointer 还是 nonzero null pointer,我们只需要了解一个指针是否是空指针就可以了——编译器会自动实现其中的转换,为我们屏蔽其中的实现细节。注意:不要把空指针的内部表示等同于整数 0 的对象表示——如上所述,有时它们是不同的。
-
如何判断一个指针是否是一个空指针?
这可以通过与空指针常量或者其它的空指针的比较来实现(注意与空指针的内部表示无关)。例如,假设 p 是一个指针变量,q 是一个同类型的空指针,要检查 p 是否是一个空指针,可以采用下列任意形式之一——它们在实现的功能上都是等价的,所不同的只是风格的差别。
指针变量 p 是空指针的判断:
if ( p == 0 )
if ( p == '\0' )
if ( p == 3 - 3 )
if ( p == NULL ) /* 使用 NULL 必须包含相应的标准库的头文件 */
if ( NULL == p )
if ( !p )
if ( p == q )
...
指针变量 p 不是空指针的判断:
if ( p != 0 )
if ( p != '\0' )
if ( p != 3 - 3 )
if ( p != NULL ) /* 使用 NULL 必须包含相应的标准库的头文件 */
if ( NULL != p )
if ( p )
if ( p != q )
...
- 可以用 memset 函数来得到一个空指针吗?
这个问题等同于:如果 p 是一个指针变量,那么
memset( &p, 0, sizeof(p) ); 和 p = 0;
是等价的吗?
答案是否定的,虽然在大多数系统上是等价的,但是因为有的系统存在着“非零空指针” (nonzero null pointer),所以这时两者不等价。由于这个原因,要注意当想将指针设置为空指针的时候不应该使用 memset,而应该用空指针常量或空指针对指针变量赋值或者初始化的方法。
- 可以定义自己的 NULL 的实现吗?兼答"NULL 的值可以是 1、2、3 等值吗?"类似问题
[7.1.3-2] If the program declares or defines an identifier in a context in which it is reserved (other than as allowed by 7.1.4), or defines a reserved identifier as a macro name, the behavior is undefined.
NULL 是标准库中的一个符合上述条件的 reserved identifier (保留标识符)。所以,如果包含了相应的标准头文件而引入了 NULL 的话,则再在程序中重新定义 NULL 为不同的内容是非法的,其行为是未定义的。也就是说,如果是符合标准的程序,其 NULL 的值只能是 0,不可能是除 0 之外的其它值,比如 1、2、3 等。
- malloc 函数在分配内存失败时返回 0 还是 NULL?
malloc 函数是标准 C 规定的库函数。在标准中明确规定了在其内存分配失败时返回的是一个 “null pointer”(空指针):
[7.20.3-1] If the space cannot be allocated, a null pointer is returned.
对于空指针值,一般的文档(比如 man)中倾向于用 NULL 表示,而没有直接说成 0。但是我们应该清楚:对于指针类型来说,返回 NULL 和 返回 0 是完全等价的,因为 NULL 和 0 都表示 “null pointer”(空指针)。(tyc:一般系统中手册中都返回NULL,那我们就用NULL吧)
分享到:
相关推荐
在C语言中,空指针、空指针常量、NULL和0是编程时经常会遇到的概念,它们在处理指针时扮演着至关重要的角色。下面将详细解释这些概念及其关系。 1. 空指针常量(null pointer constant): 空指针常量是指具有值为...
在C语言中,空指针、空指针常量、NULL和0是极其重要的概念,它们在程序设计中起到关键作用,确保了对未初始化或无有效数据的指针进行安全处理。 首先,空指针常量(null pointer constant)是指能够被转化为指针...
在C语言中,空指针、空指针常量、NULL和0是程序设计中非常重要的概念,它们在处理指针时起到关键的作用。本文将深入解析这些概念及其相互关系。 首先,空指针常量(null pointer constant)是指那些在数值上等于0或...
什么是空指针常量(null pointer constant)?[6.3.2.3-3] An integer constant expression with the value 0, or such an expression cast to type void *, is called a null pointer constant.这里告诉我们:0、0L...
` 将指针`p`赋值为空指针,即不指向任何对象。 ##### 2.2 指针的算术运算 指针的算术运算包括加法、减法等,它们允许程序员通过指针来遍历数组等数据结构: - `p++` 或 `p--` 分别表示指针`p`向后移动一个位置或...
数组名、变量的地址符号`&`以及`NULL`(表示空指针)都是指针常量的例子。此外,指针的运算包括赋值、比较以及加上或减去整数,但不允许无意义的数学运算,如加法、减法、乘法和除法。 在教学过程中,提供实际的...
这意味着,在C语言中,空指针常量可以是多种形式的,但是系统选择哪种形式作为空指针常量是实现相关的。一般来说,C系统选择 (void*)0 或者 0 作为空指针常量,而C++系统由于存在严格的类型转换要求,void* 不能自由...
1. 空指针:`NULL`常量表示没有特定地址的指针,赋值给指针变量表示其未被初始化。 2. 解引用:`*`运算符用于解引用指针,访问或修改指针所指向的变量的值,如`*p = 10;`。 3. 指针加减:对指针进行加减运算会改变其...
空指针常量通常用`NULL`表示,它是一个特殊的值,表明指针未指向任何有效的内存位置。在C语言中,`NULL`的定义可能因实现而异,但它的目的始终是为了保证指针的安全使用。 在C语言中,空指针可以被初始化为`0`、`...
- 空指针:指针可被赋值为NULL,表示不指向任何变量,如`int *ptr = NULL`。 - 指向指针的指针:可以定义指向指针变量的指针,如`int **pptr`,这在处理多级指针时非常有用。 - 指向常量的指针:`const int *ptr`,...
- **初始化指针变量**:指针变量可以被初始化为一个具体的地址,或者初始化为`NULL`表示空指针。例如,`int a = 10; int *p = &a;`表示将指针`p`初始化为指向变量`a`的地址。 - **解引用操作**:使用指针变量访问其...
此外,空指针常量(NULL)是一种特殊的指针常量,表示指针不指向任何对象。 指针的声明和定义需要十分小心,以避免指针悬空和野指针的问题。指针悬空是指指针指向的内存已被释放或不再有效,而野指针是指未初始化的...
10. **空指针和NULL**:`NULL`或`0`表示一个未初始化或无效的指针,使用空指针时需要特别小心,以防止未定义的行为。 11. **指针安全**:在处理指针时,确保始终有有效的内存地址,避免悬垂指针(指向已被释放的...
- NULL指针常量可以用来表示指针不指向任何有效内存位置,防止未初始化的使用。 3. **指针操作** - `*`运算符,也称为解引用操作符,用于获取指针所指向的变量的值,如`int value = *p`。 - `++`和`--`运算符...
常见的空指针常量包括`0`、`0L`、`'\0'`、`3-3`、`0*17`等,这些值都可以用来初始化指针变量,使其指向无效地址。此外,`(void*)0`也被广泛认为是一种表示空指针的方式,尽管它与直接使用`0`有所不同。在C语言中,...
此外,C语言中的`NULL`指针常量表示空指针,任何指针变量在未赋值前都应设为`NULL`,以避免未定义行为。`void *`类型的指针可以指向任何类型的数据,但需要强制类型转换才能安全地访问。 最后,别忘了在使用完动态...
`NULL`或`0`代表空指针,表示指针没有指向任何特定的内存地址。初始化指针时通常用`NULL`来确保安全。 10. **指针的const限定符** `const`关键字可以用来限制指针所指向的数据不可修改,如`const int *p`,或限制...
1. **空指针常量(null pointer constant)**:根据C语言标准(C99,ISO/IEC 9899:1999)6.3.2.3-3,一个值为0的整型常量表达式或这种表达式转换为`void*`类型被称为空指针常量。这意味着0、0L、'\0'、3 - 3、0 * 17...
9. **C语言空指针**:空指针`NULL`或`void *`是一个可以指向任何类型数据的指针。指针存储的是内存地址,空指针不指向任何特定对象。在使用空指针前,需要将其转换为相应的数据类型并解引用。 10. **C语言递归**:...
在C语言中,系统可以选择`0`或`(void *)0`作为默认的空指针常量。而在C++中,因为类型转换更为严格,通常使用整数`0`作为空指针常量。 #### 二、空指针(Null Pointer) 空指针是指经过转换后的空指针常量,该指针...