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

时间:2014-09-14 20:46:49

标签: c pointers

#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 个答案:

答案 0 :(得分:3)

你是对,(*x).yx->y意思相同,这就是为什么你应该写(*n1.next).data(相当于n1.next->data为{ {1}}是您的n1.next)。

编辑:由于评估顺序,括号是:

  1. 取n1:x(a n1
  2. 接下来的成员:struct node(a (n1).next
  3. 尊重指针:struct node *(a *((n1).next)
  4. 获取会员资料:struct node(*((n1).next)).data
  5. 阅读@Christophe答案中C11标准所说的内容,并注意上面步骤2和4中使用的int运算符如何与.一起用作第一个操作数(参见步骤1和3)和成员名称为秒操作数。

答案 1 :(得分:2)

语法需要i = (*n1.next).data;

为什么?

  • C11标准说“。运算符的第一个操作数应具有原子,限定或非限定结构或联合类型,第二个操作数应指定该类型的成员。 “(§6.5.2.3)。因此n1.*nextn1.*(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。幸运的是.->的优先级相同,并且它们从左到右进行评估,因此不需要括号。