下面的代码:
int _tmain(int argc, _TCHAR* argv[])
{
int sum=0,i=1;
for(i=1;i<=10;++i)
sum+=i;
std::cout<<i<<std::endl
<<i++<<std::endl
<<i<<std::endl;
getchar();
getchar();
return 0;
}
输出结果为:
12
11
12
为什么第二个数是11而第一个数是12?
若是把上句换成
std::cout<<i<<std::endl
<<++i<<std::endl
<<i<<std::endl;
结果就变成了
12
12
12
不懂啊。在下刚学C++,请教大家。
i++,++i的关系楼上已经将的很清楚了,就不赘述了。
补充@LN 的回答,就如宏(MIN)的使用一样,不建议这样使用。
经过本人查看汇编代码,发现编译器编译期做了很多事。
编译器对std::cout 语句进行了优化,具体说分两步:
1, 组织参数压栈;
2, 调用std::cout执行打印。
注意:只执行一次打印操作,这样既省去了很多压栈退栈工作,也省去了多次i/o操作,大大提高效率。
这里我们只需理解参数压栈就行了,如以下汇编代码。
0120319F mov eax,dword ptr [i]
012031A2 mov dword ptr [ebp-0DCh],eax //暂存i值副本于[ebp-0DCh]
012031A8 mov ecx,dword ptr [i] //取i值
012031AB add ecx,1 //+1
012031AE mov dword ptr [i],ecx //i+1 了
012031B1 mov esi,esp
012031B3 mov edx,dword ptr [__imp_std::endl (120F3C8h)]
012031B9 push edx //std::endl压栈,注意栈特性:先进后出
012031BA mov edi,esp
012031BC mov eax,dword ptr [i] //
012031BF push eax // i压栈,注意i已经是+1后的值了
012031C0 mov ebx,esp
012031C2 mov ecx,dword ptr [__imp_std::endl (120F3C8h)]
012031C8 push ecx //std::endl压栈
012031C9 mov eax,esp
012031CB mov edx,dword ptr [ebp-0DCh]
012031D1 push edx // i值副本压栈
012031D2 mov ecx,esp
012031D4 mov edx,dword ptr [__imp_std::endl (120F3C8h)]
012031DA push edx //std::endl压栈
012031DB mov edx,esp
012031DD mov dword ptr [ebp-0E0h],esi
012031E3 mov esi,dword ptr [i]
012031E6 push esi // i压栈
i++ 表示先运算后自己+1
++i 先+1后运算
应该与std::cout的实现有关系,不建议这样使用,因为这样的结果很容易混淆.
在i==11的情况下, i++表达式的值是11, 而++i表达式的值是12, 输出的结果和流操作的执行顺序有关, 知道这些就行了. 同意ls的, 别太纠缠这些, 没什么用..
一楼正解
先后增值的问值的问题,影响结果表达式的值!
先后增值赋给左边的变量!
1楼牛逼,用汇编说明问题