假设我们有以下代码,它接受
x
,将值4
存储在其中,然后将x
的地址存储在指针变量中:
int x = 4;
int *address_of_x = &x;
*
中的int *address_of_x
的用途是什么?
我理解 *
用于取消引用指针 - 它需要一个地址并告诉您那里存储的内容。但是如果存储了地址,那么我们要取消引用什么呢?或者我们根本就没有取消引用任何东西?为什么不写成:
int address_of_x = &x;
*
中的 int *address_of_x = &x;
并未解除引用 @Eugene Sh。int x = 4;
int *address_of_x = &x;
与
相同int x = 4; // declare x as int
int *address_of_x; // declare address_of_x as pointer to int
address_of_x = &x; // Assign the address of x to address_of_x
为什么不写成:
int address_of_x = &x;
&x
不是 int
。 &x
是一个 int *
,一个指针(或地址)。指针不是整数。
在表达式中,
*
是解引用运算符。在声明(这里有)中,它是指针声明器语法的一部分。您声明 address_of_x
是指向 int
的 指针,而不仅仅是 int
。
此语法背后的想法是,为了方便起见,标识符的声明和使用应该看起来相似(通常通过取消引用来使用指针)。 另请注意,声明为指针的每个标识符都需要
*
,即使您在单个声明中声明多个标识符,如下所示:
int *a, *b;
如果你写
int *a, b;
相反,
b
将
不是是指针。一般来说,最佳实践是避免每个声明声明多个标识符。
int *address_of_x = &x;
不是作业。
int *address_of_x = &x;
是一个带有 初始化(
int *address_of_x
) 的 声明(
= &x
)(请注意,在史前 C 中,初始化(而不是赋值)是在没有 =
的情况下完成的,这使得它们甚至与作业更加不同)。 C 镜像使用中的声明。
int *address_of_x
声明
*address_of_x
的类型为 int
,因此 address_of_x
的类型为 指向 int的指针。然后,
= &x
部分将这个指向int的指针初始化为
&x
(x
的地址)。address_of_x
变量的类型是
int *
,指向int
的指针。那里没有发生“取消引用”。
为什么不写成:嗯,有两件事
int address_of_x = &x;
C 是一种强类型语言。
相反,它是修饰符。 在给定的上下文中,星号表示“将 mext 标识符定义为指向基本类型的指针”。
你肯定不会问为什么
[10]
在
int a[10]
中并不意味着“取数组的第10个元素”。嗯,一般般。出于完全相同的原因,这里的括号也不是括号运算符。为什么不写成:
从不
int address_of_x = &x;
编译器
尝试解释标识符的字面含义。它仅在确定声明语句中标识符的类型时查找修饰符。 也就是说,这段代码不会像看起来那样工作:
int *not_a_pointer, not_an_array[10];
float a_character;
int *address_of_x = &x;
声明“指向 int 的指针”类型的变量 (
int *address_of_x
),然后使用 x 的地址初始化(
= &x
)。所以这个
*
不是解除引用,而是声明的一部分。
int *address_of_x = &x;
和
int *address_of_x;
address_of_x = &x;
在第一种情况下,您在一个语句中定义并初始化了指针,但它可能看起来
像是错误的语法。第二个例子中定义和赋值是单独的语句,代码更清晰。 还没有取消引用。