Answers:
这里的大多数答案都没有解决(至少没有明确指出)的一点是,空指针是在执行期间存在的值,而空指针常量是C源代码中存在的语法构造。
甲空指针常量,如卡尔森的答案正确地指出,或者是一个整数常量表达式用值0(一个简单的0
是最常见的例子),或这样的表达浇铸到void*
(如(void*)0
)。
NULL
是一个宏,在<stddef.h>
和其他几个标准头中定义,它扩展为实现定义的null指针常量。扩展通常为0
或((void*)0)
(需要用括号括起来才能满足其他语言规则)。
因此0
,当在需要指针类型表达式的上下文中使用文字时,字面量始终求值为null pointer
,即唯一指针值,该指针值指向任何对象。但这并不意味着有关的任何表示空指针。空指针通常表示为全零位,但是它们可以表示为任何东西。但是,即使一个空指针表示为0xDEADBEEF
,0
或(void*)0
仍是一个空指针常量。
这意味着,除其他事项外,memset()
或者calloc()
,它可以设置内存的所有位归零区域,不一定会设置在该区域中任何指向空指针。他们可能会在大多数实现中这样做,但是语言并不能保证做到这一点。
我不知道为什么这个问题是没有考虑重复这一块,或者它是如何的外用这里。
NULL
或任何null指针常量,都会将该对象的值设置为null指针。在机器级别,它很可能指向一些有效的内存块。取消引用空指针具有未定义的行为;在地址处访问大块内存0x0000000
是有效的行为,正如其他任何事情一样。该地址与任何其他地址的不同之处在于(a)比较等于NULL
,以及(b)比较不等于指向C对象的任何指针。空指针是一个任意指针值,用于指示它没有指向任何东西。
每个平台都可以随意定义NULL。
根据C标准,如果为指针分配零,则它将转换为NULL值(针对该平台。)但是,如果采用NULL指针并将其强制转换为int,则不能保证将得到零。在每个平台上。但是事实是,在大多数平台上,它将为零。
有关这些内容的信息,请参见《 C语言规范》。我无法保证其可靠性的一个来源是:http : //www.winapi.co.kr/pds/doc/ISO-C-FDIS.1999-04.pdf
NULL pointer constant
。据我所知,没有编译器可以做到这一点。
NULL
宏的定义(必须0
在C ++和C 0
或(void *)0
C中扩展为)之间存在混淆,因为那是真正的“空指针常量”。
它是用C语言定义的,因为它没有一个不变的机器地址。如果是这样,我们就不需要抽象了!即使在大多数平台上,NULL最终可能会被实现为某种类型或其他类型的0,但如果您根本不关心可移植性,则认为这是普遍错误的做法是完全错误的。
根据C标准文档部分6.3.2.3
:
一个值为0的整数常量表达式,或将这种类型强制转换为void *类型的表达式称为空指针常量。55)如果将空指针常量转换为指针类型,则得到的指针称为空指针。保证比较不等于指向任何对象或函数的指针。
到目前为止,我还没有看到可以摆脱这种情况的编译器。