什么是空指针常数?
[6.3.2.3-3] anintegerconstantexpressionwiththevalue 0,
orsuchanexpressioncasttotypevoid *,is called a null
指针常数。
其中0,0l、' '、3 - 3、0 * 17 (它们都是“integer constant”)
expression”()和) void* )0) tyc:) void* ) 0可能可以说是空指针,但更合适)等等都是空指针常数。 (注意
(char* ) 0不称为空指针常量,而只是空指针值。)。 有关系统使用何种格式作为空指针常量的信息,与实现有关。 常规c系统选择(void* ) 0或
0的比较多(也有个别的选择0L ); 对于c系统,由于有严格的类型转换要求,所以void*不能像c那样
因为可以自由转换为其他指针类型,所以通常选择0作为空指针常量(tyc: )
(不选择void*)标准推荐) )。
什么是空指针?
[6.3.2.3-3] ifanullpointerconstantisconvertedtoapointer
type,the resulting pointer,called a null pointer,is guaranteed
tocompareunequaltoapointertoanyobjectorfunction。
因此,在p是指针变量情况下,p=0;p=0L;p=' ';p=3 - 3;p=0 * 17;
中的任意赋值操作之后(对c来说是p=(void* ) 0;p都是空指针,系统确保空指针不指向实际对象或函数。 反过来说,任何对象或函数的地址都不是空指针。 (tyc: )
例如,这里的(void* ) 0是空指针。 将它理解为空指针还是空指针
常数有微秒的差异,当然不重要)
什么是空值?
[6.3.2.3- footnote ] themacronullisdefinedin
(和其他头戴式) as a
空指针常数
即NULL
是表示空指针常数的标准宏定义。 因此,除了上述各种代入方式之外,p=NULL; 制作p
变成空指针。 (tyc )在许多系统上实现) #define NULL
(void* ) 0并不完全与这里的“a null pointer constant”一致)
“空指针”(null pointer )指向内存中的哪里?
标准没有规定空指针指向内存中的哪个位置,即使用哪个具体地址值(0x0)
地址还是特定地址)表示空指针取决于系统实现。 我们经常看到的空指针一般指向0地址。 也就是说,空指针的内部用全0表示(
空指针、零空指针; 在某些系统中,特殊地址值或以特殊方式为空指针(nonzero null )
pointer,非零空指针),具体请参见c常见问题解答。
幸运的是,在实际的编程中,我们不需要知道我们系统上的指针是zero null pointer还是nonzero null
pointer,只要知道指针是否为空指针,——编译器就会自动实现转换并屏蔽实现详细信息。 注意:空指针的内部表示形式不应与整数相同
的对象表示——可能如上所述不同。
如何确定指针是否为空指针?
这可以通过空指针常量或与其他空指针的比较来实现(注意,这与空指针的内部表示无关)。 例如,假设p是指针变量,则q
用同一类型的空指针检查p
是否为空指针可以采用以下格式之一: ——等效于已实现的功能,只是样式差异。
判断指针变量p为空指针:
if(p==0) if ) p==' '
)
if(p==3-3) ) )。
if (p==空值
(if ) null==p ) ) )。
if (! p )
if(p==q ) ) )。
.
判断指针变量p不是空指针:
if(p!=0)
if(p!=' ' )
if(p!=3 - 3)
if ( p != 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吧