This question already has answers here:
Why does C have a distinction between -> and .?
(7 answers)
Closed 6 years ago.
What is the difference between -> and . while calling variables in a structure?I have seen both of them used in various scenarios but couldn't identify the difference between them.
-> means you have a variable that points to a piece of memory containing the struct. To access its members, you must dereference the pointer and then add the offset to the member. the -> does that for you.
the . means your variable is the structure and you only need to add the offset to the member.
As user Eliot B points out, if you have a pointer s to a struct, then accessing the member elem can be done in two ways: s->elem or (*s).elem.
With (*s) you have an expression that "is" the struct and you now use the dot-operator to access elem.
s->elem is equal to (*s).elem
https://en.wikipedia.org/wiki/Dereference_operator
The difference is about the structure's defined instance. '->' and '.' operators is always about the left operand.
If left operand is a pointer, then you use '->', else you use '.'.
For example.
struct Foo bar1;
struct Foo* bar2 = malloc(sizeof(struct Foo));
bar1.variable = "text";
bar2->variable = "text";
x->y (-> is the pointer to member operator) is equivalent to (*x).y. Because of operator precedence, you can't write *x.y as that would be evaluated as *(x.y).
The former is easier to type and is a lot clearer. It's used when x is a pointer to a structure containing the member y.
Related
In particular I'd like to know what ->val does in the
sizeof(((stoken_t*)(0))->val)
and what stoken_t*(0) pointer do, in particular what the (0) means?
I hope I have formulated my question clearly enough.
This is a way of accessing a member of a structure at compile time, without needing to have a variable defined of that structure type.
The cast (stoken_t*) to a value of 0 emulates a pointer of that structure type, allowing you to make use of the -> operator on that, just like you would use it on a pointer variable of that type.
To add, as sizeof is a compile time operator, the expression is not evaluated at run-time, so unlike other cases, here there is no null-pointer dereference happening.
It is analogous to something like
stoken_t * ptr;
sizeof(ptr->val);
In detail:
(stoken_t*)(0) simply casts 0 (this could be an arbitrary numeric literal) to a pointer to stoken_t, ((stoken_t*)(0)->val) is then the type of the val member of stoken_t and sizeof returns the number of bytes this type occupies in memory. In short, this expression finds the size of a struct member at compile time without the need for an instance of that struct type.
I haven't used C in a while, and now i'm trying to go back to it.
My problem is that my code actually works, although I was sure I will get syntax errors. He'res What I want to have:
A dynamic array of polygons, each has a dynamic array of points.
struct point{
int x,y;
};
struct polygon{
int quantity;
struct point* point_list;
};
I will then initialize an array of polygons:
struct polygon* poly_array = (struct polygon*) malloc(sizeof(struct polygon)*num);
and also, initialize each polygon's point array:
poly_array[i].quantity = points;
poly_array[i].point_list = (struct point*) malloc (sizeof( struct point) * poly_array[i].quantity);
Now, what I thought I was doing, was create arrays of pointers to the object. So, to access inner fields, I would need to use the "->" operator. But no, it works with "direct" access to the fields (short version, without the loop code):
poly_array[i].point_list[j].x = i;
poly_array[i].point_list[j].y = j;
and also to print:
printf ("poly %d: (%d, %d)\n", j, poly_array[i].point_list[j].x, poly_array[i].point_list[j].y);
So, to make my question clear, I will ask again: since I'm iterating on pointers to objects, shouldn't I use the -> operator?
In your code, poly_array is of type struct polygon*, so, poly_array[i] will be of type struct polygon. Thus, you have to use the . operator.
same logic applies for point_list[j] also.
To elaborate, quoting C11, chapter §6.5.2.1, Array subscripting (emphasis mine)
syntax
postfix-expression [ expression ]
Constraints
One of the expressions shall have type ‘‘pointer to complete object type’’, the other
expression shall have integer type, and the result has type ‘‘type’’.
That said, please see this discussion on why not to cast the return value of malloc() and family in C..
Short answer is referring to the array by index already dereferences the indexed item, so you are correct using dot syntax.
poly_array[i].point_list[j].x
You could as well use the "->" operator to dereference the item directly without using index operator []. In that case you would use pointer arithmetic.
(((poly_array+i)->point_list)+j)->x
This question already has answers here:
How does the C offsetof macro work? [duplicate]
(4 answers)
Closed 7 years ago.
What does ((struct name *)0)->member) do in C?
The actual C statement I came across was this:
(char *) &((struct name *)0)->member)
This is a trick for getting the offset of struct's member called member. The idea behind this approach is to have the compiler compute the address of member assuming that the structure itself is located at address zero.
Using offsetof offers a more readable alternative to this syntax:
size_t offset = offsetof(struct name, member);
(struct name *)0 is casting 0 to pointer to struct name.
&((struct name *)0)->member) is getting the address of member member.
(char *) &((struct name *)0)->member) is casting that address to char *.
In case anyone thinks that the above expression is dereferencing a NULL pointer, then note that there is no dereferencing here. It's all for getting the address of member number.
(struct name*)0 gives you a struct pointer.
((struct name*)0)->member gives you the member of the struct where the pointer points to.
Adding & gives you the address of that member, and lastly
(char *) is to cast the obtained address to a char pointer.
On many compilers, the above expression will yield a char* which, while it isn't a valid pointer, has a one or both of the following properties:
Casting the pointer directly to an integer type will yield the displacement of the indicated member within the structure.
Subtracting (char*)0 from the pointer will yield the displacement of the indicated member within the structure.
Note that the C Standard imposes no requirements with regard to what may happen if code forms an invalid pointer value via the above means or any other, even if the code makes no attempt to dereference the pointer. While many compilers produce pointers with the indicated qualities, such behavior is not universal. Even on platforms where there exists a clear natural relationship between pointers and integers, some compiler vendors may decide that having programs behave as implied by such a relationship, it would be more "efficient" to instead have the compiler to assume that a program will never receive inputs that would cause the generation of invalid pointers and, consequently, that any code which would only be relevant if such inputs were received should be omitted.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why does the arrow (->) operator in C exist?
Why does C have both . and -> for addressing struct members?
Is it possible to have such modified language syntax, where we can take p as a pointer to struct and get a struct member's value just as p.value?
You can think of p->m as shorthand for (*p).m
From the C99 Spec.
The first operand of the . operator shall have a qualified or unqualified structure or union
type, and the second operand shall name a member of that type.
The first operand of the -> operator shall have type pointer to qualified or unqualified
structure or pointer to qualified or unqualified union, and the second operand shall
name a member of the type pointed to.
My guess is, for identification purpose they used two operators for member access. i.e for pointer type struct variable is -> and . for ordinary struct variable.
For example:
struct sample E, *E1;
the expression (&E)->MOS is the same as E.MOS and (*E1).MOS is the same as E1->MOS
Is it possible? Yes. The syntax is as follows:
(*ptr).member
The parentheses are required because the structure member operator . has higher precedence than the indirection operator *. But after using that a few times you will agree that the following is easier to use:
ptr->member
Why does C have both? Pointers to structures are used so often in C that a special operator was created, called the structure pointer operator ->. It's job is to more clearly and conveniently express pointers to structures.
. is for struct variable, and -> is for pointer. If p is a pointer, you can do p->value or (*p).value, they are same.
Is there any difference about p.a and p->a where p is pointer? or they are just same thing.
The . operator is actually the operator for structure member access.
struct Foo
{
int bar;
int baz;
} aFoo;
aFoo.bar = 3;
If you have a pointer to a struct, (very common) you can access its members using pointer dereferencing and the . operator.
struct Foo *p;
p = &aFoo;
(*p).baz = 4;
The parentheses are needed because . has higher precendence than *. The above dereferencing a member of a structure pointed to by something is extremely common, so -> was introduced as a shorthand.
p->baz = 4; // identical to (*p).baz = 4
If p is a pointer, you never see p.anything in plain C, at least not in anything that compiles. However, it is used to denote property access in Objective-C which was a mistake IMO.
Yes, you can't do p.a on a pointer, the dot operator requires an actual instance, i.e. a value of the proper struct type.
Note that "under the hood", p->a is equivalent to (*p).a, but easier to type and read. Nobody ever uses the latter form, but it's sometimes handy as a way of understanding what the arrow operator does.
try (*p).a or (&p)->a where p is a pointer and an instance respectively ;-)
If p is a pointer then p.a isn't valid syntax.
It's compile time error.. p->a is valid only.