The only legal operations on a structure are copying it, assigning to it as a unit, taking its address with & and accessing its members. Structures may not be compared. Let’s see how we can pass structures to functions as well as use structures as return values.
struct point construct_point(float x, float y) { struct point tmp; tmp.x = x; tmp.y = y; return tmp; }
Let’s now write a function to add two points.
struct point add_points(struct point p1, struct point p2) { p1.x += p2.x; p1.y += p2.y; return p1; }
In the above example, we passed two pointers by value. Directly modifying p1 doesn’t affect the actual argument passed in the calling function.
When passing a large structure to a function, it is more efficient to pass a pointer as it would not lead to copying of the whole structure. We could declare a pointer to struct point like this:
struct point *ptr;
We could assign it the address of a struct point variable.
int main() { struct point *ptr; struct point origin = construct_point(0, 0); ptr = &origin; printf("%f, %fn", (*ptr).x, (*ptr).y); }
Here, ptr points to origin, so *ptr will have the value of origin, which is a structure, and (*ptr).x and (*ptr).y will be its members. The parentheses is necessary because the precedence of structure member operator “.” is higher than the indirection operator “*”. The expression *ptr.x is same as *(ptr.x), which is illegal since x is not a pointer.
Pointers to structures are frequently used, so an alternate notation is provided as a shorthand. If ptr is a pointer to a structure, then
ptr->member
refers to a particular member. We could re-write the printf used above as:
printf("%f, %fn", ptr->x, ptr->y);
The structure operators . and ->, along with () for function calls and [] for array subscripts, are at the top of the precedence hierarchy and thus bind very tightly. Given the declaration
struct { int len; char *str; } *ptr;
then
++ptr->len
increments len, not ptr as -> has higher precedence. To increment ptr before accessing len, we need to do
(++ptr)->len
Similarly,
*ptr->str
fetches whatever str points to as -> has higher precedence.