Accepting another structure member via a pointer

#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;
}

      

My question is simple. Why can't I access n2 node via n1 node, when I use this i = n1.(*next).data;

one I get an error. However, if I change it toi=n1.next->data

I thought (*x).y

u x->y

meant the same thing.

+3


source to share


2 answers


You are right, (*x).y

and x->y

mean the same thing: why should you write (*n1.next).data

(which is equivalent to n1.next->data

how n1.next

is yours x

).

EDIT: The parentheses are that the order of evaluation is:



  • Take n1: n1

    (a struct node

    )
  • Take the next term: (n1).next

    (a struct node *

    )
  • Mark pointer: *((n1).next)

    (a struct node

    )
  • Take item data: (*((n1).next)).data

    (a int

    )

Read what the C11 standard says in @ Christophe's answer, and notice how the operator .

used in steps 2 and 4 above is used with struct node

as the first operands (see steps 1 and 3) and the member names as second operands.

+3


source


The syntax requires i = (*n1.next).data

;

Why?



  • The C11 standard says: "The first operand of an operator must be an atomic, qualified or unqualified structure or union type, and the second operand must name a member of that type." (§ 6.5.2.3). In this way, n1.*next

    and n1.*(next)

    they are not legitimate, because the operator .

    can follow only a member name .

  • n1.next

    is of type "pointer to struct node", you can dereference it using the *

    or operator ->

    .

  • Through dereference, it *n1.next

    will be a value of type "struct node". Unfortunately, the prefix operator *

    has a lower precedence than .

    . This is why *n1.next.data

    means *(n1.next.data)

    , which of course is not valid because it n1.next

    is a pointer and a pointer itself has no members. But it (*n1.next)

    is of type "struct node", so it (*n1.next).data

    correctly refers to the member value.

  • This kind of break is quite common, and therefore exists ->

    . The standard says: "The first operand of the → operator must have a pointer of type" "to an atomic, qualified, or unqualified structure (...), and the second operand must name the member of the type it points to." This explains n1.next->data

    . Fortunately, the priority .

    and ->

    the same, and they are evaluated from left to right, so no parentheses are required.

+2


source







All Articles