views:

343

answers:

6

In learning C, I've just begun studying pointers to structures and have some questions.

Suppose I were to create a structure named myStructure, and then create a pointer myStructurePointer, pointing to myStructure. Is *myStructurePointer, and myStructure two ways of referencing the same thing? If so, why is it necessary to have the -> operator? It seems simpler to use *myStructurePointer.variable_name than myStructurePointer->variable_name.

+7  A: 

You're right,

(*structurePointer).field

is exactly the same as

structurePointer->field

What you have, however, is :

*structurePointer.field

Which really tries to use the . operator on the pointer variable, then dereference the result of that - it won't even compile. You need the parentheses as I have them in the first example above if you want the expressions to be equivalent. The arrow saves at least a couple of keystrokes in this simple case.

The use of -> might make more sense if you think about the case where the structure field has pointer type, maybe to another structure:

structurePointer->field->field2

vs.

(*(*structurePointer).field).field2
Carl Norum
Yeah, it took me a while to figure that one out. Personally, I like the '->' syntax because it reminds me of Perl.
amphetamachine
+4  A: 

The problem with *myStructurePointer.variable_name is that * binds less tight than ., so it would be interpreted as *(myStructurePointer.variable_name). The equivalent of myStructurePointer->variable_name would be (*myStructurePointer).variable_name, where the parenthesis are required.

There is not difference between a->b and (*a).b, but -> is easier to use, especially if there are nested structures. (*(*(*a).b).c).d is much less readable than ´a->b->c->d`.

sth
A: 

Using the * dereferences the pointer, so you can use dot syntax to access the fields. If you don't dereference the pointer, then you use -> to access the fields. You can use whichever you prefer.

David Kanarek
+4  A: 

To generalize, learn your C operator precedence:

http://www.difranco.net/cop2220/op-prec.htm

Here the "." operator is processed before the "*" -> hence the need for parentheses

Michael Mullany
You can force the `*` to be processed before the `.` with liberal use of parenthesis, but the `->` notation was created as an easier-to-read alternative.
bta
@Michael, I think what the OP is really asking is the difference between `(*p).f` and `p->f`. The missing `()` are due to inexperience, I expect.
Carl Norum
Well, apparently not...
Carl Norum
My answer made more sense when it was added below yours @Carl :-)
Michael Mullany
Sorry Carl. It's hard to choose between multiple helpful answers. I chose Mike's answer because it more thoroughly addressed my confusion; I am new to C, and understand precedence as much as it directly translates from Java, so the link provided by Michael was very helpful; however, you two seem to agree on who deserves credit, so I'm moving it.
Hurpe
No big deal, I thought I misunderstood the question, is all.
Carl Norum
A: 

I have been learning C recently, and i found this resource to be extremely helpful.

http://claymore.engineer.gvsu.edu/~steriana/226/C.CheatSheet.pdf

Programming Enthusiast
+1  A: 

Dennis Ritchie did note once that deref should probably have been a postfix operator1

Right, the following are equivalent:

pointer->field
(*pointer).field
pointer[0].field

If the indirection operator had postfix syntax C would have looked rather different but in that case it would not have needed -> at all.

It's interesting to think about how the common C idioms would look in that alternate universe...

do s1*++ = c = s2*++;
   while(c);

while(n-- > 0)
    s*++ = '\0';

p*.x = 1;
p*.y = 2;
. . .
. . .
. . .

1. See The Development of the C Language., Dennis M. Ritchie

DigitalRoss