问题
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 asi = i+1; j = i;
j = i++
is the same asj = 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.
- assign temp_m1 = m1.
- increment m1.
- index
offSpring1[temp_m1]
- assign
temp1
into indexed value.
On the other hand offSpring1[++m1] = temp1;
works like this:
- increment m1.
- index
offSpring1[m1]
- 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