flylib
flylib

Reputation: 1148

Please explain how this function works with pointer parameters

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

Answers (4)

Gangadhar
Gangadhar

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

digital_revenant
digital_revenant

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

glglgl
glglgl

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

CmdrMoozy
CmdrMoozy

Reputation: 3951

The mystery function performs the following actions:

  1. Set the integer x points to to the value of the integer y points to.
  2. Set the integer y points to to the value of the integer z points to and then increment the value of the integer z points to.
  3. Set the integer 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:

  1. Set the integer q points to to the value of the integer &r points to (this does nothing since q == &r).
  2. Set the integer &r points to to the value of the integer &p points to and then increment the value of the integer &p points to.
  3. Set the integer &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

Related Questions