网站建设 cms,粮油移动端网页设计素材,什么建设网站,无线网络网站dns解析失败简介
先说i和i的区别#xff0c;判断语句中if(i)是拿i的值先判断#xff0c;而后自增#xff1b;if(i)是先自增i再进行判断。涉及到左值与右值也有点区别#xff0c;i返回的是右值#xff0c;i返回的是左值。也就是下面的代码要解释的东西。
#include iostreami…简介
先说i和i的区别判断语句中if(i)是拿i的值先判断而后自增if(i)是先自增i再进行判断。涉及到左值与右值也有点区别i返回的是右值i返回的是左值。也就是下面的代码要解释的东西。
#include iostreamint main()
{//后置自增返回右值int i 0;auto pi (i); 错误 右值无法取地址//前置自增返回左值int j 0;auto pj (j);// 正确std::cout Hello World!\n;
}转折
老生常谈的经验是i比i性能好因为i中间会产生临时变量参考这篇文章的解释http://t.csdn.cn/2A7PT。实际上较新的编译器简单的自增没有差别了。我们看下汇编代码
int i 0;
00007FF73AD21C9B mov dword ptr [i],0 i;
00007FF73AD21CA2 mov eax,dword ptr [i]
00007FF73AD21CA5 inc eax
00007FF73AD21CA7 mov dword ptr [i],eax int j 0;
00007FF73AD21CAA mov dword ptr [j],0 j;
00007FF73AD21CB1 mov eax,dword ptr [j]
00007FF73AD21CB4 inc eax
00007FF73AD21CB6 mov dword ptr [j],eax i与j的汇编代码一模一样基本不涉及临时变量。
我们加上if进行观察 int i 0;
00007FF7BEB91C9B mov dword ptr [i],0 if (i)
00007FF7BEB91CA2 mov eax,dword ptr [i]
00007FF7BEB91CA5 mov dword ptr [rbp0F4h],eax
00007FF7BEB91CAB mov eax,dword ptr [i]
00007FF7BEB91CAE inc eax
00007FF7BEB91CB0 mov dword ptr [i],eax {}//前置自增返回左值int j 0;
00007FF7BEB91CB3 mov dword ptr [j],0 if (j)
00007FF7BEB91CBA mov eax,dword ptr [j]
00007FF7BEB91CBD inc eax
00007FF7BEB91CBF mov dword ptr [j],eax {}注意00007FF7BEB91CA5 mov dword ptr [rbp0F4h],eax 这行代码是把i前的值拷贝到临时变量了临时变量的地址是rbp0F4h。而后才对i进行自增操作。
总结
也就是说编译器优化仅对简单的自增进行了优化但是复杂的甚至仅仅是套了一层if编译器是不会优化的因为要兼容已有的代码。如果if里面的也做优化则之前那么多的程序岂不是要炸了也就是语义上要保持连贯性已经形成共识的东西编译器是会传承下去的。
再一个也是不理解既然汇编语言i和i都一样为什么i还是会报无法对右值取地址其实也是编译器对这种复杂点的语句不会对前置自增后置自增进行优化生成汇编代码的时候还是对右值取的地址导致的报错。