通过指针访问另一个结构体的成员

3
#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).yx->y意思相同。

2个回答

3
你是对的,(*x).yx->y 意思相同,这就是为什么你应该写(*n1.next).data(等同于 n1.next->data 因为 n1.next 是你的 x)。 编辑: 括号是由于评估顺序而产生的:
  1. 取 n1:n1(一个struct node
  2. 取成员 next:(n1).next(一个struct node *
  3. 解除指针引用:*((n1).next)(一个struct node
  4. 取成员 data:(*((n1).next)).data(一个int
阅读 C11 标准中 @Christophe 的答案,并注意在步骤 2 和 4 中使用的 . 运算符与第一操作数(参见步骤 1 和 3)和成员名称作为第二操作数的 struct node 相关。

n1为什么在括号里? - user1010101

2
这句话的意思是:“语法要求使用i = (*n1.next).data;”
为什么呢?
C11标准中写道:“点运算符的第一个操作数必须是原子、限定或未限定的结构体或联合体类型,第二个操作数必须是该类型的成员名称。”(§6.5.2.3)。因此,n1.*nextn1.*(next)都不合法,因为点运算符只能后跟成员名称n1.next的类型是“指向结构体节点的指针”,可以使用操作符*->对其进行解引用。
通过解引用,*n1.next将成为类型为“结构体节点”的值。不幸的是,前缀运算符*.的优先级。这就是为什么*n1.next.data意味着*(n1.next.data),当然这是无效的,因为n1.next是一个指针,指针本身没有成员。但是,(*n1.next)是类型为“结构体节点”的,因此(*n1.next).data正确地引用了成员的值。
这种解引用非常常见,因此有->。标准中写道:“箭头运算符的第一个操作数必须是‘指向原子、限定或未限定结构体的指针’类型(...),第二个操作数必须是所指向类型的成员名称。”这就解释了n1.next->data。幸运的是,点运算符和箭头运算符的优先级相同,并且它们从左到右计算,因此不需要括号。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接