这个逻辑与运算是怎样优化的 求告知 感谢!
RT:
#include<stdio.h>
void main()
{
int a=0,b=2,c;
c=!a||++b&&a--;
printf("%d,%d,%d\n",a,b,c);
}
结果:0,2,1
上面是编译器运行的结果
但是 我觉得 结果应该是:a=-1,b=3,c=1
所以有点不明白 与运算和自增自减 在这里是怎么优化的
希望各位鱼油指教,谢谢!{:10_254:} {:10_287:} 为什么b不自增呢? 本帖最后由 pheron 于 2018-10-26 10:22 编辑
我觉得楼下说的对 本帖最后由 风扫地 于 2018-10-27 08:59 编辑
可能和短路原则有关。
因为你的 !a||++b&&a--代码里面没括号,我不熟悉结合关系和计算顺序(学的时候弄明白就行,因为考试肯定要考,但确实很难记住那么多运算符的结合顺序和优先级,在工作工程中必须用小括号明确运算结合关系和运算顺序),不具体分析。
短路原则是指:
对于 &&|| 这两个运算符,
若 a && b 中的a已经为0,b就不算了,因为0 && x = 0
若 a || b 中的a已经为1,b就不算了,因为 1 || x = 1
Ref:
https://bbs.csdn.net/topics/190096722
https://fishc.com.cn/forum.php?mod=viewthread&tid=93862&highlight=%B6%CC%C2%B7 嗷嗷记起来了
&&和||语句的判断都是从左至右的。
即a && b会先判断a,如果a为True,则还需要判断b的Boolean值,不管b的Boolean值是什么,最后一个判断的是b,所以会输出b的Boolean值;反之,如果a为False,则不需要再判断b的Boolean值了,因为结果肯定为False,所以最后进行判断的就是a,也就是会输出a的Boolean值。
而a || b也是会先判断a,如果a的Boolean值为True,则不需要再判断b的Boolean值了,因为结果肯定是True了,也就是会输出a的Boolean值;如果a的Boolean值为False,则就需要再去判断b的Boolean值,不管b的Boolean值为多少,最后进行判断的都是b,也就是输出就为b的Boolean值。
//为了回答这道题,以下以C注释形式分析以下汇编代码
#include<stdio.h>
void main()
{
010F13C0push ebp
010F13C1mov ebp,esp
010F13C3sub esp,0E8h
010F13C9push ebx
010F13CApush esi
010F13CBpush edi
010F13CClea edi,
010F13D2mov ecx,3Ah
010F13D7mov eax,0CCCCCCCCh
010F13DCrep stos dword ptr es:
int a = 0, b = 2, c;
010F13DEmov dword ptr ,0
010F13E5mov dword ptr ,2
//以上代码与问题无关不做解释
//------------------------------------------完美分割线--------------------------------------
c = !a || ++b && a--;
//以下两句为!a计算并实现||运算符的短路原则
010F13ECcmp dword ptr ,0 //将a与0比较
010F13F0je main+59h (010F1419h) //a为0则跳到地址010F1419h处,其实这里就直接跳转了,从这道010F1419h代码都没执行
//以下三句为++b实现代码
010F13F2mov eax,dword ptr //将b内存中的值移动到寄存器eax中
010F13F5add eax,1 //eax寄存器自加1
010F13F8mov dword ptr ,eax //将eax的值移动回到b内存处
//当b为0则跳到010F140Dh处,不为0则继续
010F13FBje main+4Dh (010F140Dh)
//以下四句位为a--对应代码
010F13FDmov ecx,dword ptr //a移动到ecx寄存器(备份a的值,以便后序判断使用)
010F1400mov edx,dword ptr //a移动到edx寄存器
010F1403sub edx,1 //edx-1
010F1406mov dword ptr ,edx //将edx存会a
//ecx为刚才对a的备份,以下一句测试原来的a值是否为0,也就是实现后 -- 的先使用后自减的特性
010F1409test ecx,ecx
010F140Bjne main+59h (010F1419h)//原a不为0则表示逻辑与 && 成立, 跳到010F1419h
//原a为0则逻辑与表达式为假
010F140Dmov dword ptr ,0 //用一个临时变量来存放记过(ebp-0E8h)
010F1417jmp main+63h (010F1423h) //跳到010F1423h处
//原a不为0则表达式为真将1赋值到临时变量
010F1419mov dword ptr ,1
//将临时变量赋值个c变量
010F1423mov eax,dword ptr
010F1429mov dword ptr ,eax
//以下调用printf函数,不做解释
//---------------------------------------------完美分割线再现----------------------------------------
printf("%d,%d,%d\n", a, b, c);
010F142Cmov esi,esp
010F142Emov eax,dword ptr
010F1431push eax
010F1432mov ecx,dword ptr
010F1435push ecx
010F1436mov edx,dword ptr
010F1439push edx
010F143Apush 10F5858h
010F143Fcall dword ptr ds:
010F1445add esp,10h
010F1448cmp esi,esp
010F144Acall __RTC_CheckEsp (010F1136h) //堆栈平衡检测
} 因为!a一定为真,所以||后面的代码都不执行了,好像是叫短路原则 短路原则,竟然这么神奇!又学习了。 在这里谢过各位鱼油了 么么哒
{:10_281:}
页:
[1]