#include<stdio.h>
int main()
{
struct node
{
int data;
struct node *next;
};
struct node n1,n2,n3;
int i;
n1.data = 100;
n2.data = 200;
n3.data = 300;
n1.next = &n2;
n2.next = &n3;
i = n1.(*next).data;
printf("%i\n",i);
printf("%i\n", n2.next->data);
return 0;
}
我的问题很简单。为什么我使用此i = n1.(*next).data;
时无法通过n1节点访问n2节点我收到错误。但是,如果我将其更改为i=n1.next->data
我认为(*x).y
和x->y
意味着同样的事情。
答案 0 :(得分:3)
你是对,(*x).y
和x->y
意思相同,这就是为什么你应该写(*n1.next).data
(相当于n1.next->data
为{ {1}}是您的n1.next
)。
编辑:由于评估顺序,括号是:
x
(a n1
)struct node
(a (n1).next
)struct node *
(a *((n1).next)
)struct node
((*((n1).next)).data
)阅读@Christophe答案中C11标准所说的内容,并注意上面步骤2和4中使用的int
运算符如何与.
一起用作第一个操作数(参见步骤1和3)和成员名称为秒操作数。
答案 1 :(得分:2)
语法需要i = (*n1.next).data
;
为什么?
C11标准说“。运算符的第一个操作数应具有原子,限定或非限定结构或联合类型,第二个操作数应指定该类型的成员。 “(§6.5.2.3)。因此n1.*next
和n1.*(next)
不合法,因为只有成员名称才能跟踪运营商.
。
n1.next
的类型为“指向结构节点的指针”,您可以使用运算符*
或->
取消引用它。
通过解除引用,*n1.next
将是“struct node”类型的值。不幸的是,前缀运算符*
的{{3}}不是.
。这就是为什么*n1.next.data
意味着*(n1.next.data)
,这当然是无效的,因为n1.next
是一个指针,而指针本身不具有成员。但(*n1.next)
的类型为“struct node”,因此(*n1.next).data
正确引用成员的值。
这种derefenrcing很常见,所以有->
。标准说“ - &gt;运算符的第一个操作数应具有指向原子,限定或非限定结构的类型''('),第二个操作数应指定指向的类型的成员”。这解释了n1.next->data
。幸运的是.
和->
的优先级相同,并且它们从左到右进行评估,因此不需要括号。