黑旋风君 发表于 2020-2-25 18:20:29

关于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

黑旋风君 发表于 2020-2-26 20:23:39

我的编译器出了点毛病,问题已解决

te___amo 发表于 2020-2-25 18:22:43

= 是赋值运算符== 才是判断

qiuyouzhi 发表于 2020-2-25 18:25:06

a = 0, b = 3
a = 3, b = 5
a = 0, b = 4
a = 1, b = 4
我这里是这样的(Dev-C++)

一个账号 发表于 2020-2-25 18:25:35

qiuyouzhi 发表于 2020-2-25 18:25
我这里是这样的(Dev-C++)

你用的是什么编译器?

qiuyouzhi 发表于 2020-2-25 18:27:55

一个账号 发表于 2020-2-25 18:25
你用的是什么编译器?

Dev-C++的GCC啊

一个账号 发表于 2020-2-25 18:29:15

qiuyouzhi 发表于 2020-2-25 18:27
Dev-C++的GCC啊

Dev - C++ 的默认编译器是 GCC 吗?我不知道

qiuyouzhi 发表于 2020-2-25 18:30:04

一个账号 发表于 2020-2-25 18:29
Dev - C++ 的默认编译器是 GCC 吗?我不知道

TDM-GCC 4.8.1 64-bit Release

4goodworld 发表于 2020-2-25 21:46:45

你的操作是赋值,不是判断呀,判断是用==来对比
我用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);

一个账号 发表于 2020-2-25 22:21:00

4goodworld 发表于 2020-2-25 21:46
你的操作是赋值,不是判断呀,判断是用==来对比
我用VC6.0反编译



怎么用 VC 6.0 反编译?Dev-C++ 能反编译吗?

4goodworld 发表于 2020-2-25 22:38:09

一个账号 发表于 2020-2-25 22:21
怎么用 VC 6.0 反编译?Dev-C++ 能反编译吗?

可能表述上不够精准,应该是vc6.0查看汇编代码

cc123hh 发表于 2020-2-26 11:29:26

左边是假的,右边就不会赋值

黑旋风君 发表于 2020-2-26 18:23:00

cc123hh 发表于 2020-2-26 11:29
左边是假的,右边就不会赋值

不是&&才有这样的性质吗,||不是左边为假再判断右边吗,可我这个||左边为假,然后它右边就跳过赋值了,b的值还是5.您再看看

黑旋风君 发表于 2020-2-26 18:25:15

qiuyouzhi 发表于 2020-2-25 18:25
我这里是这样的(Dev-C++)

对啊,我就认为是这样的,但是我输出的时候有错误出现

黑旋风君 发表于 2020-2-26 18:25:58

一个账号 发表于 2020-2-25 18:25
你用的是什么编译器?

vs2019community

黑旋风君 发表于 2020-2-26 18:35:40

4goodworld 发表于 2020-2-25 21:46
你的操作是赋值,不是判断呀,判断是用==来对比
我用VC6.0反编译



我的可能编译器出了点毛病

cc123hh 发表于 2020-2-26 20:58:18

黑旋风君 发表于 2020-2-26 18:23
不是&&才有这样的性质吗,||不是左边为假再判断右边吗,可我这个||左边为假,然后它右边就跳过赋值了,b ...

额我也不是很懂,我记得||和&&好像是一样的
{:10_277:}

黑旋风君 发表于 2020-2-27 21:34:32

cc123hh 发表于 2020-2-26 20:58
额我也不是很懂,我记得||和&&好像是一样的

不好意思啊,是我编译器出毛病了

cc123hh 发表于 2020-2-28 13:46:54

emmmm
页: [1]
查看完整版本: 关于c语言中的短路求值