Increment, preincrement and postincrement

ぐ巨炮叔叔 提交于 2019-12-11 05:17:08

问题


Help me to resolve this please. The steps that follows that expressions are:

//Expression
offSpring1[m1++] = temp1;

//Steps:

1.- increment m1

2.- assign temp1 to offSpring

I have always thought that the expression inside the brackets was the first to be done. But now I am confuse. So if a write this:

//Expression
offSpring1[++m1] = temp1;
//Steps would be:

1.- assign temp1 to offSpring
2.- increment m1

If the steps would be the same as first ones, what is the difference between i++ and ++i?


回答1:


int i = 0;
std::cout << i++ << std::endl;
std::cout << i << "\nreset" << std::endl;
i = 0;
std::cout << ++i << std::endl;
std::cout << i << std::endl;

output:

0
1
reset
1
1

i++ returns the value as it currently stands in the expression, then increments the variable. ++i will increment the variable, then return the value to use in the current expression.




回答2:


offSpring1[m1++] = temp1;

is

offSpring1[m1] = temp1;
m1 += 1;

and

offSpring1[++m1] = temp1;

is

m1 += 1;
offSpring1[m1] = temp1;



回答3:


  • j = ++i is the same as i = i+1; j = i;
  • j = i++ is the same as j = i; i = i+1;



回答4:


Just run these two different test programs to understand the difference between the post-increment and the pre-increment operators

For ++i (pre-increment)

int main()
{
    int* offSpring = calloc(20,sizeof(int));
    int m1 =1;
    offSpring[++m1] = 10;
    printf("%d,%d",offSpring[m1],m1);
}

In the first one you will get 10 as the value of offSpring[m1]. Why? Because this is the pre-increment operator which means that first m1 gets incremented and the the rest gets evaluated.

For i++(post-increment)

int main()
{
    int* offSpring = calloc(20,sizeof(int));
    int m1 =1;
    offSpring[m1++] = 10;
    printf("%d,%d",offSpring[m1],m1);
}

In the second because the post-increment operator is used you will get a 0 value since you are first assigning 10 to offSpring[m1] and then m1 gets incremented.




回答5:


offSpring1[m1++] = temp1; doesn't do what you said.

  1. assign temp_m1 = m1.
  2. increment m1.
  3. index offSpring1[temp_m1]
  4. assign temp1 into indexed value.

On the other hand offSpring1[++m1] = temp1; works like this:

  1. increment m1.
  2. index offSpring1[m1]
  3. assign temp1 into indexed value.



回答6:


Even though postfix increment is the first to be evaluated in your first example, its value is the original value of the variable being incremented.

offSpring1[m1++] = temp1;

So even though m1 is incremented before array idexing, the value of temp1 is assigned at position m1 - 1.




回答7:


There are two aspects to an expression (or sub-expression): its value, and its side effects. The value of i ++ is the value of i; the value of ++ i is the value i + 1, converted to the type of i. This is the value used in the expression. The side effects of both is to increment the variable i. This may occur at any time after the preceding sequence point and before the next. Supposing i is a global variable, and you write something like:

i = 0;
f()[i ++] = g();
f()[++ i] = g();

The standard says nothing about whether the value of i seen in f() or g() is that before the incrementation, or after. In neither case. All the standard says is that the effects of the incrementation will take place after the start of the full expression (but perhaps as the first thing in the full expression) and before the end of it. (And that they won't be interleaved with a function call, so that if f() reads i twice, it is guaranteed to see the same value.)




回答8:


Unfortunately, in those 2 code snippets you've posted there, there's no guaranteed order of evaluation. If your expressions are inappropriate, more or less anything could happen.

To start with the difference between a++ and ++a:

  • a++ will increment a but the expression using it will see the value of a before the increment
  • ++a will increment a, and the expression using it will see the incremented value.
  • List item

with

buffer[a++] = b;

the compiler can decide to do the ++ at any point within the expression. Thus if 'b' is actually an expression involving a, you can get different results on different compilers. Both of the following would be valid:

  • get the value of a;
  • increment a
  • work out where buffer[old value] points to
  • evaluate b
  • store b

or this

  • evaluate b;
  • work out where buffer[a] points to
  • store b
  • increment a

if 'b' should happen to involve a, those 2 implementations would produce different results. Both are valid.




回答9:


It works precisely the opposite of what you described:

offSpring1[m1++] = temp1 is the same as offSpring[m1] = temp1; m1 = m1 + 1;

OffSpring1[++m1] = temp1 is the same as m1 = m1 + 1; OffSpring1[m1] = temp1;

Prefix notation increments before evaluating the expression Postfix notation increments after evaluating the expression




回答10:


The description of the first is the correct description for the second. The correct description of the first is very similar, you just need a "copy current value of m1" step added before the others.

But you do have a distinct lack of sequence points here, if m1 has a primitive type. The rules change somewhat between C++03 and C++11.

If m1 has a user-defined type, then there are function calls involved which influence sequencing.


This code

offSpring1[m1++] = temp1;

performs the following (if m1 is a primitive type):

auto const old_m1(m1);
auto const new_m1(old_m1 + 1);
auto& lhs(offSpring[old_m1]);
parallel { lhs = temp1; m1 = new_m1; }

This code

offSpring1[++m1] = temp1;

is exactly the same except that lhs is bound using new_m1 instead of old_m1.

In either case, it is unspecified whether lhs is written to before or after m1.

If m1 is not a primitive type, it looks more like:

auto const& index = m1.operator++(0); // one argument
auto& lhs = offSpring.operator[](index);
lhs = temp1;

vs

auto const& index = m1.operator++(); // no arguments
auto& lhs = offSpring.operator[](index);
lhs = temp1;

In both these cases, the change to m1 is definitely made before the write to lhs.



来源:https://stackoverflow.com/questions/9298020/increment-preincrement-and-postincrement

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!