AlessandroF
AlessandroF

Reputation: 562

Why is *ptr.member wrong and (*ptr).member right?

I know that if I have a pointer in C programming language, and I have to point to a struct, I do:

struct mystruct S;
struct mystruct *ptr;
ptr=&S;
ptr->member=5;

I understood this, but I do not understand the reason why, if I do:

ptr=&S;
(*ptr).member=5;

*ptr should point to the first address of the struct, but why doesn't it work if I do this:

*ptr.member=5;

Upvotes: 0

Views: 157

Answers (5)

Vlad from Moscow
Vlad from Moscow

Reputation: 310990

If you have a structure

struct A
{
    int x;
};

and an object of the structure type

A a;

then to access its data member x you have to write

a.x = 5;

Or you can write

( &a )->x = 5;

Now if you have a pointer of type struct A * that initialized by the address of the object a

struct A *pa = &a;

then expression *pa gives the object a itself. So you may write

( *pa ).x = 5;

So now compare. On the one hand

a.x = 5;       and      ( *pa ).x = 5;

and on the other hand

( &a )->x = 5; and      pa->x = 5;

Upvotes: 1

John Bode
John Bode

Reputation: 123468

Unary * has a lower precedence than the . and -> member selection operators, so *p.member is parsed as *(p.member); in other words, you're attempting to dereference the result of p.member. This has two problems:

  • p is a pointer type, so the compiler will complain that you're trying to use the . operator on something that isn't a struct or union type;

  • member isn't a pointer type, so you can't apply the unary * to it.

(*p).member is equivalent to p->member; both dereference p before accessing member.

Upvotes: 1

user7140484
user7140484

Reputation: 920

You have a struct and a pointer to the struct:

  struct mystruct S;
  struct mystruct *ptr;

Now you store in ptr the address of that struct

  ptr = &S;

When you need to access one member of that struct through a pointer, you have TWO alternative syntaxes

  (*ptr).member = 5;

and

  ptr->member = 5;

The two syntaxes are equivalent and do exactly the same action.

Is only a matter of personal taste.

In your question you have an error, because you wrote:

(*p).member = 5;

Instead of

(*ptr).member = 5;

Hence the error

One last tip:

(*ptr).member = 5;

and

*ptr.member = 5;

Are different things

(*ptr).member = 5; means that you get the address pointed by ptr and then store 5 in the field named member

*ptr.member = 5; means that you get the address pointed by ptr.member and then store 5 in the memory pointed by that address.

Upvotes: 0

Chris
Chris

Reputation: 1623

Operators have precedence: the member access operator . has the highest precedence, while dereference * has the next highest precedence. So *p.member attempts to find the member member of a pointer to mystruct and then dereference it. Since a *mystruct does not have a member called member, this is an error.

Upvotes: 2

ABu
ABu

Reputation: 12259

Because the access to member operator (the dot) has precedence over the dereferenciation (*).

So, your expression is equivalent to:

*(p.member) = 5

And p.member is not a pointer.

Upvotes: 1

Related Questions