我有一个小问题:
struct point {int x ; int y;};
int main(){
struct point p = {10,20};
struct point *pp = &p;
(∗ pp).x = 10; // what is happening here
int y= (∗ pp).y; return 0} // what is happening here
更一般地说,为什么需要()?
(这是一个教程,但他们没有得到答案。)
因为.
的优先级高于*
。也就是说,没有括号,
*pp.x = 10;
代表
*(pp.x) = 10;
但是,pp
是一个指针。因此,.
运算符不会对其进行操作。您需要使用->
运算符来访问指向结构的指针的成员,或者在访问其成员之前使用括号来取消引用指针。
如果您有一个指针,比如您的变量pp
,您可以使用解引用运算符*
来解引用它。它的作用与运算符&
的地址相反。Foe示例:
int a = 5;
int *pa = &a; /* Use address-of operator to get a pointer to `a` */
int b = *pa; /* Use dereference operator to get the value that `pa` points to */
对于结构,通常使用->
运算符来访问结构指针的成员字段,或者使用非指针结构的.
运算符。当您取消引用指向结构的指针时,您将获得该结构的非指针版本,并且必须使用.
运算符来访问成员字段。
括号是因为.
运算符的运算符优先级高于解引用运算符*
。
在数学中,括号用于表示运算符的优先级。
在C中,.
运算符的优先级高于*
运算符。因此,如果没有括号,pp.x
将在*pp
之前被解释,从而导致编译错误。实际上,pp
是一个指针,不具有成员变量x
。
确保评估顺序。p和pp都是指向某种类型结构点的指针("&"取的地址),而不是指向点本身。
您有一个名为p
的point
,它有x和y坐标。
然后,您就得到了pp
,它的类型是pointer to a point
。该pp
指向非常相同的点p
。因此,现在有两种方法可以访问您的点:p
(简单的一种)和*pp
(pp
指向的东西)。使用这些方式中的哪一种并不重要,您访问的是相同的point
。
这里有两个操作符:.
和*
。其中.
结合更紧密。所以表达式*pp.x
的意思是:首先,得到pp.x
的值,然后看看它指向什么
但代码希望它反过来:首先,查看pp
指向什么,然后访问它的字段x
。
括号的功能与(2 + 3) * 5
中的相同,你在学校里就知道。