考虑我有一个结构
typedef struct point_t
{
int x;
int y;
}POINT;
我创建了一个指向POINT的指针,并将其初始化为NULL
。
POINT **ppPoint = NULL;
*ppPoint
还应该返回NULL
吗?
答案 0 :(得分:11)
这里有2层指针的事实实际上是无关紧要的。 NULL
中的外部指针这一事实意味着取消引用它是非法。因此,询问通过取消引用将获得什么价值没有意义。
考虑一下:
int *p = NULL; // modern practice would be to use nullptr anyway
if (0 == *p) // this is Undefined Behaviour!
{
// do something, maybe?
}
您只是在此添加了另一层,其中有int
而不是point_t*
,但这确实没有区别。
Undefined Behaviour的作用是一切皆有可能!您的程序可能崩溃,或者出现运行,或者有时为您提供垃圾值,或者...
答案 1 :(得分:3)
您不能取消引用值为NULL
的指针。因此,您将无法访问*ppPoint
。
您可以使用%p
中的printf()
格式化程序检查变量的地址。
printf("Address of ppPoint: %p", *ppPoint);
printf("Address of *ppPoint: %p", *ppPoint);
答案 2 :(得分:3)
空指针不会指向任何内容。这适用于普通指针,函数指针和成员指针。它也适用于指向指针的指针。
因此,谈论“它指向什么”的价值没有意义。
答案 3 :(得分:3)
首先,人们通常会误解神秘的null。在这种情况下,有3个相关术语:
NULL
宏空指针常量是整数0
或转换为指针(void*)0
的整数。保证NULL
宏是可移植的空指针常量。
每当将空指针常量(例如NULL
)分配给任何指针时,该指针都将成为空指针。这使编译器内部可以将空指针表示为0
以外的其他内容,因为地址0x00...00
在许多系统上通常是有效的物理地址。
具体来说,C17 6.3.2.3/3对此进行了定义:
具有值
0
的整数常量表达式,或此类强制类型转换的表达式void *
被称为空指针常量。如果将空指针常量转换为指针类型,则保证生成的指针称为 null指针,可以将不相等的指针与指向任何对象或函数的指针进行比较。
通过取消引用访问空指针时,不会得到任何可预测的结果。根据C17 6.5.3.2/4,这是未定义的行为:
如果已将无效值分配给指针,则一元*运算符的行为是不确定的。
意味着任何事情都可能发生。如果幸运的话,只会导致系统崩溃。
不过,您可以将一个空指针与另一个空指针或一个空指针常量进行比较,并保证它们相等(C17 6.5.9)。
至于指针到指针是一种特殊情况,事实并非如此。指向类型与上述任何规则都不相关。总体而言,C语言中的指针指向没有什么特别的-从来都不是特例,但总是被视为指向类型的指针。