-1

I am new to the pointer concepts.. i dont understand the following program.. please tell about the logic of this program..

function (int *p,int *q){
  return(*p = (*p + *q) - (*q = *p));
}

int main(){
  int y = 15, z = 25;
  function(&y, &z);

  printf("%d\t%d", z, y);
}
12
  • Please indent your code and put spaces between operators, it's impossible to read otherwise. Commented Mar 4, 2011 at 8:29
  • @Rafe: I have indented the code and fixed obvious syntax errors. Whether spaces between operators makes it more readable is a personal preference, not to be inflicted on everybody else. Commented Mar 4, 2011 at 8:31
  • @sbi most styles (GNU, K&R, BSD, etc.) feel the same way. For me, it's difficult to read when there's no space on either side of any binary operator. If it's a generally accepted personal preference, it should probably be enforced on beginners. Commented Mar 4, 2011 at 8:32
  • 3
    is it actually valid C? I mean, (*p + *q) - (*q = *p) seems to depend on which operand is first executed, which is undefined ? Commented Mar 4, 2011 at 8:35
  • I doubt K&R would even have bothered with the parentheses, but it's too long ago that I read it. And listing three styles (and I'm not even sure all of them follow what you consider good) in C is not a good argument. There's thousands of styles out there. I have learned to stick to the style used in any project I join, and move on to the next style as I move on to the next project. The only spacing everyone I know detested was this colleague who always wrote ( * p = ( * p + * q ) - ( * q = * p ) ). Everything else is personal preferences. Commented Mar 4, 2011 at 8:38

6 Answers 6

7

This program invokes undefined behavior. It both modifies and uses the value of *q without a sequence point between.

C99 standard, Section 6.5, paragraph 2:

Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be read only to determine the value to be stored.

*q is read in the sub-expression (*p + *q), and this is not done to determine the value to store in the sub-expression (*q = *p).

The intent appears to be to swap the two values pointed to, but a completely reasonable alternate interpretation also exists: evaluate (*q = *p) first, then (*p + *q) (which would equal *p + *p thanks to the assignment). This would result in *p being assigned *p + *p - *p, or just *p. As a result, z would be assigned the value of y (15), while y would remain 15.

I must emphasize that because this is undefined, your compiler can do pretty much whatever it wants, not just limited to this interpretation or swapping the two.

Sign up to request clarification or add additional context in comments.

2 Comments

Wouldn't this code rather be undefined because the order of evaluation is not specified by the standard for the operators used?
@Lundin: It's worse than that -- the order in which stores and loads take place can be entirely different than the order of evaluation.
0

Pointer means you pass the address of the variables instead of the value.

You can then dereference(get the value pointed to by this address) and perform operations using that value.

If you pass a variable by value, that is without using &, a new copy will be created inside the function. Any changes done, will not be visible outside the function. If you pass pointers, then manipulations done to the content of the pointer will be visible outside the function.

On last note, pointers are complex to understand for new programmers. You better read tutorials and spend some time thinking about how things are working.

Comments

0

This is example of function where you pass by reference that is you pass the location of actual variable instead of making a copy of it and passing.so in you function p is basically pointing to y which is 15 and q is pointing to z=25 .It should be easy from there on to find the answer. *p= (15+25)-(15) *q=15.So y=25 z=15 .

Comments

0

First of all you have to know about the pointer...

Pointer is a variable that contain memory address of another variable...

In above program...you have declared 2 variables y and z... and you have created a function namely function(&y,&z).... means ...it sends the reference (memory address) of y and z to the funcion...function(*p,*q)

so *p contain 15 and *q contain 25...

*p=(*p+*q) means y= 15+25 which is 40....

Comments

0

Variable, like y and z in your program, have ranges. They exist only in a limited logical space. For instance, y and z only "exists" in main ; that's why they're called "local variable". Would you write :

int x,y;

void main
{
  // Stuff 
}

x and y would be global variables, that any function in this file could access. Since global variable make things harder to debug, when you need to access variable declared in a function, you can use pointer (it's only one of the uses of pointers, useful in your example).

When you give parameters to a function, by default, those parameters are copies, not the original. So, function(int p, int q) creates two new variables : you can do whatever you want to q and p, the x and z would not change.

When you use pointers, you create a special variable, containing the adress of the variable. You can get the adress of any variable with the "&" sign. This is why, to call function(int* p, int* q) you need to write function(&y, &z).

To access the content of a pointer, you need to use the * sign in front of the pointer. Beware ! If you don't do this, you're not modifying the variable the pointer is pointing to, but the adress of the pointer (in your case, that would not be useful ; but in array manipulation, for instance, it can be very useful).

So, your function gets the adresses of two variables, and then do some computing. This function does two things :

  • It computes something and give the result ;
  • During the computing, it gives to q the value of p, so z's value becomes y's value in the main.

Do some printf in your main, checking the value of your variables, before and after the function. Do it with a function using pointers and another one that does not use them, and it'll be much clearer to you.

And add a "int" in front of your function, since it returns something.

Comments

0

wnoise's answer is correct with but if you want to understand why you have such results below you can find reasoning.

this is not a pointer challenge but rather operator precedence.

Just treat *p and *q as You would use y & z

and with this code: return(*p = (*p + *q) - (*q = *p)); remember that result of assigment is assigned value thus with *p = y = 15 and *q = z = 25

you have:

return(*p = (15 + 25) - (*q = *p));

return(*p = 40 - (*q = 15)); //*q -> z becomes 15

return(*p = 40 - 15);

return(*p = 25); // *p -> y becomes 25

return(25);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.