C语言 如果指针到指针为 NULL,那么指针是否也必须为 NULL?



考虑我有一个结构

typedef struct point_t
{
int x;
int y;
}POINT;

我为 POINT 创建一个指向指针的指针并将其初始化为NULL

POINT **ppPoint = NULL;

*ppPoint也应该返回NULL吗?

这里有 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*,但这真的没有区别。

未定义行为的问题是任何事情都可能发生!您的程序可能会崩溃,或者它可能看起来可以正常工作,或者它有时可能会给您垃圾值,或者它可能......

空指针不指向任何内容。这适用于普通指针、函数指针和成员指针。它也适用于指向指针的指针。

因此,谈论"它所指向的东西"的价值是没有意义的。

不能取消引用值为NULL的指针。因此,您将无法访问*ppPoint.

您可以使用要检查的printf()中的%p格式化器检查变量的地址。

printf("Address of ppPoint: %p", *ppPoint);
printf("Address of *ppPoint: %p", *ppPoint);

首先,对神秘的空值存在常见的误解。在这种情况下,有 3 个相关术语:

  • 空指针
  • 空指针常量
  • NULL

空指针常量是整数0或转换为指针的整数,(void*)0NULL宏保证是可移植的空指针常量。

每当将空指针常量(如NULL(分配给任何指针时,该指针都会变为空指针。这允许编译器在内部表示一个空指针作为0以外的其他东西,因为地址0x00...00在许多系统上通常是一个有效的物理地址。

具体来说,C17 6.3.2.3/3 对此进行了定义:

值为0的整数常量表达式,或转换为类型的此类表达式void *,称为空指针常量。如果将 null 指针常量转换为指针类型,则生成的指针(称为null指针(保证与指向任何对象或函数的指针不相等进行比较。


通过取消引用来访问空指针时,不会得到任何可预测的结果。这是根据 C17 6.5.3.2/4 定义的未定义行为:

如果为指针分配了无效值,则未定义一元 * 运算符的行为。

这意味着任何事情都可能发生。如果幸运的话,您只会崩溃。

但是,您可以将空指针与另一个空指针或空指针常量进行比较,并且保证它们相等 (C17 6.5.9(。

至于指针到指针是一种特例,事实并非如此。指向类型与上述任何规则无关。总的来说,在 C 语言中,指针到指针并没有什么特别之处 - 它从来都不是特例,而是始终被视为指针到类型。

相关内容

  • 没有找到相关文章

最新更新