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.
source to share
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
(astruct node
) - Take the next term:
(n1).next
(astruct node *
) - Mark pointer:
*((n1).next)
(astruct node
) - Take item data:
(*((n1).next)).data
(aint
)
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.
source to share
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
andn1.*(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 itn1.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 explainsn1.next->data
. Fortunately, the priority.
and->
the same, and they are evaluated from left to right, so no parentheses are required.
source to share