关于c语言中的短路求值
&&左右两边同时为真才为真,一侧为假即假,如果左侧为假,右侧直接跳过进入下一句||左右两边任一边为真即为真,同时为假才为假,如果左侧为真,右侧直接跳过进入下一句
e.g. 先执行括号内的内容(程序由左向右执行判断完左侧真假至&&处就自动跳过右侧,即使右侧优先级高于&&)
a = 0 --> && false(跳过)
输出 a = 0(已给a赋值)
b = 3(原来定义的值)
a = 3 --> && true(赋值)
b = 5 --> && true(赋值)
输出 a = 3, b = 5
a = 0 --> || false(跳过)为什么这里左为假右为真,右侧却被跳过了?
输出 a = 0, b = 5(上一次赋值的值)
a = 1 --> || true(跳过)
输出 a = 1, b = 5(被跳过,保持不变)
#include <stdio.h>
int main()
{
int a = 1;
int b = 3;
(a = 0) && (b = 5);
printf("a = %d, b = %d\n", a, b);
(a = 3) && (b = 5);
printf("a = %d, b = %d\n", a, b);
(a = 0) || (b = 4);
printf("a = %d, b = %d\n", a, b);
(a = 1) || (b = 6);
printf("a = %d, b = %d\n", a, b);
return 0;
}
结果为:
a = 0, b = 3
a = 3, b = 5
a = 0, b = 5
a = 1, b = 5 我的编译器出了点毛病,问题已解决 = 是赋值运算符== 才是判断 a = 0, b = 3
a = 3, b = 5
a = 0, b = 4
a = 1, b = 4
我这里是这样的(Dev-C++) qiuyouzhi 发表于 2020-2-25 18:25
我这里是这样的(Dev-C++)
你用的是什么编译器? 一个账号 发表于 2020-2-25 18:25
你用的是什么编译器?
Dev-C++的GCC啊 qiuyouzhi 发表于 2020-2-25 18:27
Dev-C++的GCC啊
Dev - C++ 的默认编译器是 GCC 吗?我不知道 一个账号 发表于 2020-2-25 18:29
Dev - C++ 的默认编译器是 GCC 吗?我不知道
TDM-GCC 4.8.1 64-bit Release 你的操作是赋值,不是判断呀,判断是用==来对比
我用VC6.0反编译
9: int a = 1;
0040D748 C7 45 FC 01 00 00 00 mov dword ptr ,1
10: int b = 3;
0040D74F C7 45 F8 03 00 00 00 mov dword ptr ,3
11: (a = 0) && (b = 5);
0040D756 C7 45 FC 00 00 00 00 mov dword ptr ,0
0040D75D 83 7D FC 00 cmp dword ptr ,0
0040D761 74 07 je main+3Ah (0040d76a)
0040D763 C7 45 F8 05 00 00 00 mov dword ptr ,5
12: printf("a = %d, b = %d\n", a, b);
0040D76A 8B 45 F8 mov eax,dword ptr
0040D76D 50 push eax
0040D76E 8B 4D FC mov ecx,dword ptr
0040D771 51 push ecx
0040D772 68 AC 2F 42 00 push offset string "a = %d, b = %d\n" (00422fac)
0040D777 E8 24 39 FF FF call printf (004010a0)
0040D77C 83 C4 0C add esp,0Ch
13: (a = 3) && (b = 5);
0040D77F C7 45 FC 03 00 00 00 mov dword ptr ,3
0040D786 83 7D FC 00 cmp dword ptr ,0
0040D78A 74 07 je main+63h (0040d793)
0040D78C C7 45 F8 05 00 00 00 mov dword ptr ,5
14: printf("a = %d, b = %d\n", a, b);
0040D793 8B 55 F8 mov edx,dword ptr
0040D796 52 push edx
0040D797 8B 45 FC mov eax,dword ptr
0040D79A 50 push eax
0040D79B 68 AC 2F 42 00 push offset string "a = %d, b = %d\n" (00422fac)
0040D7A0 E8 FB 38 FF FF call printf (004010a0)
0040D7A5 83 C4 0C add esp,0Ch
15: (a = 0) || (b = 4);
0040D7A8 C7 45 FC 00 00 00 00 mov dword ptr ,0
0040D7AF 83 7D FC 00 cmp dword ptr ,0
0040D7B3 75 07 jne main+8Ch (0040d7bc)
0040D7B5 C7 45 F8 04 00 00 00 mov dword ptr ,4
16: printf("a = %d, b = %d\n", a, b);
0040D7BC 8B 4D F8 mov ecx,dword ptr
0040D7BF 51 push ecx
0040D7C0 8B 55 FC mov edx,dword ptr
0040D7C3 52 push edx
0040D7C4 68 AC 2F 42 00 push offset string "a = %d, b = %d\n" (00422fac)
0040D7C9 E8 D2 38 FF FF call printf (004010a0)
0040D7CE 83 C4 0C add esp,0Ch
17: (a = 1) || (b = 6);
0040D7D1 C7 45 FC 01 00 00 00 mov dword ptr ,1
0040D7D8 83 7D FC 00 cmp dword ptr ,0
0040D7DC 75 07 jne main+0B5h (0040d7e5)
0040D7DE C7 45 F8 06 00 00 00 mov dword ptr ,6
18: printf("a = %d, b = %d\n", a, b);
0040D7E5 8B 45 F8 mov eax,dword ptr
0040D7E8 50 push eax
0040D7E9 8B 4D FC mov ecx,dword ptr
0040D7EC 51 push ecx
0040D7ED 68 AC 2F 42 00 push offset string "a = %d, b = %d\n" (00422fac)
0040D7F2 E8 A9 38 FF FF call printf (004010a0)
0040D7F7 83 C4 0C add esp,0Ch
它这个短路好像是 &&或者 || 的左值与0进行一个比较,也就是a进行判断,其实a无非就两种可能0与非0,0是false 非0是true
然后根据
逻辑与 &&
&& 操作符的左操作数总是首先进行求值, 如果它的值为真, 则继续计算右操作数的值, 然后执行与操作得到表达式结果; 如果它的值为假, 根据与操作 有假则假 的性质可以断定该表达式的值为假, 所以不再计算右操作数的值.
逻辑或 ||
|| 操作符的左操作数也是首先进行求值, 如果它的值为假, 则继续计算右操作数的值, 然后执行与操作得到表达式结果; 如果它的值为真, 根据或操作 有真则真 的性质可以断定该表达式的值为真, 所以不再计算右操作数的值.
(a = 0) && (b = 5);//a=0 假 短路返回
printf("a = %d, b = %d\n", a, b);
(a = 3) && (b = 5);//a=3 真 不短路
printf("a = %d, b = %d\n", a, b);
(a = 0) || (b = 4);//a=0 假不短路
printf("a = %d, b = %d\n", a, b);
(a = 1) || (b = 6); //a=0 假短路返回
printf("a = %d, b = %d\n", a, b);
4goodworld 发表于 2020-2-25 21:46
你的操作是赋值,不是判断呀,判断是用==来对比
我用VC6.0反编译
怎么用 VC 6.0 反编译?Dev-C++ 能反编译吗? 一个账号 发表于 2020-2-25 22:21
怎么用 VC 6.0 反编译?Dev-C++ 能反编译吗?
可能表述上不够精准,应该是vc6.0查看汇编代码 左边是假的,右边就不会赋值 cc123hh 发表于 2020-2-26 11:29
左边是假的,右边就不会赋值
不是&&才有这样的性质吗,||不是左边为假再判断右边吗,可我这个||左边为假,然后它右边就跳过赋值了,b的值还是5.您再看看 qiuyouzhi 发表于 2020-2-25 18:25
我这里是这样的(Dev-C++)
对啊,我就认为是这样的,但是我输出的时候有错误出现 一个账号 发表于 2020-2-25 18:25
你用的是什么编译器?
vs2019community 4goodworld 发表于 2020-2-25 21:46
你的操作是赋值,不是判断呀,判断是用==来对比
我用VC6.0反编译
我的可能编译器出了点毛病 黑旋风君 发表于 2020-2-26 18:23
不是&&才有这样的性质吗,||不是左边为假再判断右边吗,可我这个||左边为假,然后它右边就跳过赋值了,b ...
额我也不是很懂,我记得||和&&好像是一样的
{:10_277:} cc123hh 发表于 2020-2-26 20:58
额我也不是很懂,我记得||和&&好像是一样的
不好意思啊,是我编译器出毛病了 emmmm
页:
[1]