我对指针声明中的解引用运算符如何起作用感到困惑。
考虑这两种情况:
int y = 5;
int *x = &y;
int y = 5;
int *x;
x = &y;
第二种情况(单独声明和初始化)对我来说很有意义。在阅读了许多类似的问题后,我注意到声明类似于用法。也就是说,
*x
是一个整数,所以x
是一个指向整数的指针。因此,将 x
赋值给 y
指针是有意义的。
令我困惑的是第一个场景(组合声明和初始化)。我很难理解为什么
int *x = &y;
应该起作用。 *x
不是指针,那为什么要用指针来初始化呢?
我曾多次尝试合理化第一种情况。主要是,我试图确定 C 中的声明是否只有特殊语法,其中使用
int *x = &y;
分配的值是 x
,而不是 *x
。对我来说,没有什么真正有意义的。
我看到的一个我不太满意的解释是更高级别的“将
int*
视为一种类型”的解释。我对它不满意,因为它失败了int* x, z
。
一元
*
始终表示取消引用。
这在表达式中可能感觉熟悉且直观:
*x
表示获取x
指向的值。相比之下,您可能会发现声明不太直观; *
中 int *x
是什么意思?
思考这个问题的方法是,声明给出了如何使用某物的图片。声明
int *x
表示 *x
将用作 int
。换句话说,当我们得到x
指向的值时,它就是一个int
。声明中的 *
表示与表达式中发生的事情相同:取消引用指针。
Kernighan 和 Ritchie 在《C 编程语言》,1978 年,第 90 页中告诉我们这一点:
指针px
的声明是新的。
int *px;
旨在作为助记符;它表示组合*px
是一个
,也就是说,如果int
出现在上下文px
中,则它相当于*px
类型的变量。实际上,变量声明的语法模仿了变量可能出现的表达式的语法。 作为一个更复杂的示例,请考虑int
int (*p)[];
。这告诉我们
(*p)[]
是一个 int
。由于 []
用于访问数组元素,这意味着 (*p)
必须是 int
的数组。这意味着 p
必须是指向 int
数组的指针。就像 *
一样,[]
在声明中没有相反的含义。它并不意味着“是一个数组”,而是“访问一个元素”;它仍然是如何在表达式中使用该事物的图像。在int *x = &y;
中,
=
字符并不意味着赋值。意思就是初始化了。而被初始化的并不是=
左边的表达式,因为左边没有表达式。在声明中 *x
不是表达式;它只是如何在表达式中使用 x
的图像。在
int *x = &y;
中,int *x
正在声明
x
,因此正在初始化的是
x
。