5

I'm confused in how this code will get executed. Suppose we have

int x=30,*y,*z;
y=&x;

what is the difference between *y++ and ++*y? and also what will be the output of this program?

#include<stdio.h>
int main(){

    int x=30,*y,*z;
    y=&x;
    z=y;
    *y++=*z++;
   x++;
   printf("%d %d %d ",x,y,z);
   return 0;
}
Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
Ravi Bisla
  • 405
  • 1
  • 4
  • 10

4 Answers4

9

The expression x = *y++ is in effects same as:

x = *y;
y = y + 1;

And if expression is just *y++; (without assignment) then its nothing but same as y++;, that is y start pointing to next location after increment.

Second expression ++*y means to increment the value pointed by y that same as: *y = *y + 1; (pointer not incremented) It will be better clear with answer to your first question:

Suppose your code is:

int x = 30, *y;
int temp;
y = &x;

temp = *y++; //this is same as:  temp = *y;  y = y + 1;

First *y will be assigned to temp variable; hence temp assigned 30, then value of y increments by one and it start point to next location after location of x (where really no variable is present).

Next case: Suppose your code is:

int x = 30, *y;
int temp;
y = &x;

temp = ++*y;  //this is same as *y = *y + 1; temp = *y;

First value of *y increments from 30 to 31 and then 31 is assigned to temp (note: x is now 31).

next part of your question (read comments):

int x = 30, *y, *z;

y = &x;       // y ---> x , y points to x
z = y;        // z ---> x , z points to x
*y++ = *z++;  // *y = *z, y++, z++ , that is 
              // x = x, y++, z++
x++;          // increment x to 31
Grijesh Chauhan
  • 57,103
  • 20
  • 141
  • 208
6

what is the difference between *y++ and ++*y?

In case of expression *y++ and *z++; because the postfix version ++ takes precedence over *, the compiler sees this as;

*(y++) = *(z++);

In case of ++*y; compiler sees this as ++(*p) and it will first increment the value of the object it points to ( x in this case) and then return its incremented value.

Summary table for other possibilities;

Expression                 Meaning
-------------------------------------------------------------------------------------
*y++ or *(y++)         Value of expression is *y before increment; increment y latter
(*y)++                 Value of expression is *y before increment; increment *t later
*++y or *(++y)         Increment y first; value of expression is *y after increment
++*y or ++(*y)         Increment *y first; value of expression is *y after increment

EDIT: As pointed out by Eric Lippert in his comment that saying: value of expression is *y before increment, increment y later is misleading, I want to clarify here that the words I used latter and after to emphasize that previous or next value of *y, respectively, will be used in expressions.
Note that, the side-effect can be produced in any order, either side-effect produce first and value assigned latter or value assigned first and side-effect produce latter. For more detail read the answers :-- 1, 2 given by Eric Lippert.

Community
  • 1
  • 1
haccks
  • 104,019
  • 25
  • 176
  • 264
  • do you think `*y++` == `*(y++)` **?** – Grijesh Chauhan Jul 31 '13 at 19:17
  • I read the answer given by [Eric Lippert](http://stackoverflow.com/a/17935062/2455888). I think that is different issue. – haccks Jul 31 '13 at 19:20
  • No at first attemps I was confuse that why Thanks! – Grijesh Chauhan Jul 31 '13 at 19:22
  • 1
    This answer confuses the *values* that are operated on with the *order* that the side effects are produced in. C does not mandate a particular order for those side effects, so when you say "value of expression is `*y` before increment, increment y later", that's misleading. C is allowed to do the increment *first* as long as the original value has been saved somewhere. – Eric Lippert Aug 01 '13 at 18:24
  • @EricLippert; Before reading [c-faq](http://www.c-faq.com/expr/evalorder2.html),I always thought that for expressions like `a = b++ + c++;`, *increment is performed immediately after giving up the previous value and before any other part of the expression is evaluated* i.e `b` must be incremented (if `b++` is evaluating before `c++`) before the evaluation of expression `c++` always! Of course I was in dilemma. After that I came to know that the side effect will be performed (merely) sometime before the expression is considered finished. *[Continued....]* – haccks Aug 02 '13 at 01:16
  • .....Even after that I was not aware of *order of side effect* before reading this [answer](http://stackoverflow.com/a/17935062/2455888) of your's! Thanks for your valuable answer. I neglected this fact in my answer just because OP was interested to know only the *difference between `*y++` and `++*y`*. – haccks Aug 02 '13 at 01:16
  • 1
    @haacks: many people believe what you did, and it is *legal* for that to be true, but it is not *required* for it to be true. C# is as you describe. When the increment expression is evaluated the variable is determined, the original value is determined, the new value is determined, and the variable is updated, in that order. The value of the expression is either the new or the old value, depending on whether it was postfix or prefix. – Eric Lippert Aug 02 '13 at 04:43
6

what is the difference between *y++ and ++*y?

The meaning of an expression in C is characterized by two things: what value it produces and what side effects it produces.

Let's examine the first expression.

Postfix increment is of higher priority than dereferencing, so this is *(y++).

The postfix increment produces a side effect: it changes the value of y to point to a different location. The postfix increment also produces a value: the value that y had before it was incremented. The * operator then dereferences that value to produce an lvalue: that is, something you can use as a variable, either to store to or to fetch from.

I note that the side effect can happen at any point before or after the dereferencing. If you said

q = *y++ 

then the side effect of the ++ could happen at any point. This could be:

q = *y;
y = y + 1;

or it could be treated as

t = y;
y = y + 1;
q = *t;

Both are perfectly legal. (Except of course that if y is itself an expression with side effects, those side effects must be produced only once. For clarity, I'll make that assumption throughout.)

How about ++*y? That is straightforward: *y produces a variable, the content of the variable is incremented, and the value of the expression is the incremented value. Note that again, the side effect can be produced out-of-order:

q = ++*y

could be treated as:

t = *y + 1;
*y = t;
q = t;

or as

t = *y + 1;
q = t;
*y = t;

Remember, C does not produce very many restrictions on the order in which side effects may happen, so be careful.

Eric Lippert
  • 647,829
  • 179
  • 1,238
  • 2,067
1

I trust that you understand what the operators ++ and * means when used separately. When used together then operator precedence comes into play. In C++ the ++ operator has a higher precedence than the * operator. So effectively *y++ means *(y++) and ++y* means (++y)*. I hope this helps.

P.P
  • 117,907
  • 20
  • 175
  • 238
Thomas Nguyen
  • 464
  • 1
  • 5
  • 16