Reputation: 1148
I have a function which takes pointers to int
as its parameters, when I first run the code the result is:
-47 30 30
I want to know why, after the second pass through, the values are now
47 -46 -46
I can't seem to wrap my head around it, please help me understand the flow of the code.
#include <stdio.h>
void mystery(int *, int *, int *);
int main(void) {
int p = -47, *q, r = 31;
q = &r;
printf("%d %d %d\n", p++, *q, --r);
mystery(q, &r, &p);
printf("%d %d %d\n", p, *q, r);
return 0;
} /* End of main. */
void mystery (int *x, int *y, int *z) {
*x = *y;
*y = (*z)++;
*z = 47;
return;
} /* End of mystery */
Upvotes: 1
Views: 143
Reputation: 10526
After your initial print you made call to function
Here p=-47 and *q=r=30
mystery(q, &r, &p); // made a call to function same as mystery(&r, &r, &p);
initializes *x=30,*y=30 and *z=-47
//Here x and y are pointing to same reference.These consists address of `r`
*x = *y; // this statement makes *q=r=30
*y = (*z)++; // this statement makes *q=r=-46 , increment -47 by 1 and assign to *y
*z = 47; //this makes p=47
and AS @kevin said
*q
and r
are the same variable, using both *q
and --r
in the
printf("%d %d %d\n", p++, *q, --r);
is undefined behavior due to changing value in between sequence points.
Upvotes: 1
Reputation: 3334
You have two integer variables on the stack, p
and r
. In the mystery()
function, both x
and y
point to the variable r
and z
points to the variable p
. In the line
*y = (*z)++;
The value of r
is changed to 46 and in the next line
*z = 47;
p
is set to 47.
Upvotes: 1
Reputation: 91159
Well, let's see what happens.
int p = -47, *q, r = 31;
q = &r;
Now we have the following variables:
p
is an int
and contains -47
r
is an int
and contains 31
q
is an int *
and points to r
.Now we do
printf("%d %d %d\n", p++, *q, --r);
p++
means that -47
is printed and the value of p
is incremented, so we have -46
.
*q
means that we use the value where q
points to, i. e. the value of r
.
As r
is pre-decremented and the order of execution of the arguments is not specified, it is not exactly specified what is the result of this call.
But we know that afterwards, r
has the value 30
.
When calling mystery()
, the parameter x
is assigned the argument q
, y
gets &r
and z
gets &p
.
What happens here now?
We do
*x = *y;
and thus set *q = r
, a NOP operation (as q
points to r
).
*y = (*z)++;
which means we increment *z
(=p
), putting the old value to *y
(=r
).
So now, r
is -46
and p
is -45
.
The latter is irrelevant, as now we do
*z = 47;
which affects p
again.
So the values after mystery are p = 47
and r = -46
. q
still points to r
, so
printf("%d %d %d\n", p, *q, r);
prints 47 -46 -46
.
Upvotes: 1
Reputation: 3951
The mystery
function performs the following actions:
x
points to to the value of the integer y
points to.y
points to to the value of the integer z
points to and then increment the value of the integer z
points to.z
points to to 47.Note that, since mystery
is using post-increment, the incrementing never actually does anything. That is, y
is assigned before incrementing z
, and after z
is incremented it is set explicitly to 47.
Now, in main
:
Note that q
is a pointer to r
. This means that when you call mystery
on (q, &r, &p)
, it takes the following actions:
q
points to to the value of the integer &r
points to (this does nothing since q == &r
).&r
points to to the value of the integer &p
points to and then increment the value of the integer &p
points to.&p
points to to 47.As for the printf
functions, as other comments have said since q == &r
the behavior of printf("%d %d %d\n", p++, *q, --r);
is undefined.
Upvotes: 3