Reputation: 37
I am asked to write a C module that provides
void swap(struct posn *p, struct posn *q);
A function for swapping the fields of a
and b
.
Example:
struct posn { int x; int y; };
struct posn a = {1, 2};
struct posn b = {3, 4};
swap(&a, &b);
assert(a.x == 3);
assert(a.y == 4);
assert(b.x == 1);
assert(b.y == 2);
However, both *p
, *q
are pointers, so the following code I wrote does not work:
void swap(struct posn *p, struct posn *q)
{
int temp1 = *p.x;
int temp2 = *p.y;
*p.x = *q.x;
*p.y = *q.y;
*q.x = temp1;
*q.y = temp2;
}
How to swap the pointers? Any help/advice is appreciated!
Upvotes: 1
Views: 525
Reputation: 72177
You are almost there. It seems you understood how pointers work but you didn't pay enough attention at operators precedence.
As you can see in the list, the "Structure and union member access" operator (.
) has higher precedence than the "Indirection (dereference)" operator (*
).
This is why *p.x
is evaluated as *(p.x)
but you want it evaluated as (*p).x
.
If you add the parenthesis around *p
and *q
everywhere in the code of the function it will work (now it doesn't even compile).
Because this combination of operators (dereference followed by member access) is very common, the language provides the ->
operator, called "Structure and union member access through pointer".
The code p->x
is equivalent with (*p).x
but it's shorter and more readable.
The solution to your problem is very simple: replace *p.x
with p->x
everywhere:
void swap(struct posn *p, struct posn *q)
{
int temp1 = p->x;
int temp2 = p->y;
p->x = q->x;
p->y = q->y;
q->x = temp1;
q->y = temp2;
}
Upvotes: 6
Reputation: 11691
The *
operator is acting over the .
operator. So when you do:
*p.x
You're actually doing
*(p.x)
You can use:
(*p).x
But this is better written as:
p->x
Upvotes: 2
Reputation: 41528
In the expression *p.x
, the .
operator has higher precedence than the *
operator, so the compiler understands it as *(p.x)
, which is invalid because p
is not a struct with a field x
(it's a pointer). You can either write it as (*p).x
, or use the ->
operator which does this for you: p->x
.
Upvotes: 7