Increment, pre-increment and post-increment
Help me solve this please. The steps following these expressions:
//Expression
offSpring1[m1++] = temp1;
//Steps:
1. - increment m1
2.- assign temp1 to offSpring
I always thought the expression inside the brackets was the first one. But now I am embarrassed. Therefore, if you write this:
//Expression
offSpring1[++m1] = temp1;
//Steps would be:
1.- assign temp1 to offSpring
2.- increment m1
If the steps are the same as the first, what is the difference between i ++ and ++ i?
source to share
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 currently in the expression, and then increments that variable.
++i
will increment the variable and then return the value that will be used in the current expression.
source to share
Just run these two different test programs to understand the difference between post-increment and pre-increment statements
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, you will get 10 for the value of offSpring [m1]. What for? Since this is a pre-increment operator, it means the first m1 gets incremented and the rest are 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, since the post-increment operator is used, you will get a value of 0, since you first assign 10 to offSpring [m1] and then m1 is incremented.
source to share
The description of the first is the correct description for the second. The correct description of the first is very similar, you just need to add the value "copy the current value of m1" before the others.
But you obviously don't have sequence points if it m1
is of a primitive type. The rules change slightly between C ++ 03 and C ++ 11.
If m1
is of a user-defined type, then there are function calls involved that affect the sequence.
This code
offSpring1[m1++] = temp1;
does the following (if it 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 it lhs
binds with new_m1
instead of old_m1
.
In any case, it is not specified whether it is recorded lhs
before or after m1
.
If m1
not a primitive type, it looks more like:
auto const& index = m1.operator++(0); // one argument
auto& lhs = offSpring.operator[](index);
lhs = temp1;
against
auto const& index = m1.operator++(); // no arguments
auto& lhs = offSpring.operator[](index);
lhs = temp1;
In both cases, the change to m1
is certainly made before the write to lhs
.
source to share
It works exactly as you described:
offSpring1[m1++] = temp1
coincides with
offSpring[m1] = temp1; m1 = m1 + 1;
OffSpring1[++m1] = temp1
coincides with
m1 = m1 + 1; OffSpring1[m1] = temp1;
Prefix notation is incremented before the expression is evaluated Postfix notation is incremented after the expression is evaluated
source to share
There are two aspects of an expression (or subexpression): its meaning, and its side effects. Value i ++
is a value i
; value ++ i
is the value i + 1
converted to type i
. This is the value used in the expression. Side effects of both for increasing the variable i
. This can happen anytime after the previous point in the sequence and before the next. Suppose i
a variable is global and you write something like:
i = 0; f()[i ++] = g(); f()[++ i] = g();
The standard doesn't say anything about whether the value is visible i
in f()
or g()
is it before the increment or after. Anyway. The entire standard says that incrementing effects will occur after the start of the full expression (but perhaps as the first in the full expression) until the end. (And that they won't be interleaved with the function call, so if f()
they read it twice i
, it's guaranteed to see the same value.)
source to share
Unfortunately, there is no guaranteed evaluation order in the two code snippets you posted there. If your expressions are inappropriate, more or less anything can happen.
To start with the difference between ++ and ++ a:
- a ++ will increment the value of a, but the expression using it will see the value of a before incrementing
- ++ a will increment a, and the expression using it will see the incremented value.
- List item
from
buffer[a++] = b;
the compiler may decide to execute ++ at any point in the expression. Thus, if "b" is actually an expression involving a, you might get different results for different compilers. Both values will be valid:
- get the value of a;
- increment a
- select where buffer [old value] points to
- rate b
- shop b
or
- evaluate b;
- where buffer [a] points to
- shop b
- increment a
If "b" is to happen with a, these 2 realizations will lead to different results. Both are valid.
source to share