int a = 5;
int b = 6;
int c;
第一条声明:
c = a > b ? 1 : 0;
第二条声明:
c = (a > b);
上面两者有什么区别?
最佳答案
在普通编译器上绝对没有区别(除了第一个有更多的击键,第二个有不必要的括号 (...)
)。在某些优化非常糟糕的编译器上,其中一种形式可能会更慢。
x > y
的 true 结果表示为 1
, false 表示为 0
。引用 ISO/IEC 9899:201x 委员会草案 2011 年 4 月 12 日 N1570:
Each of the operators
<
(less than),>
(greater than),<=
(less than or equal to), and>=
(greater than or equal to) shall yield1
if the specified relation is true and0
if it is false.) The result has typeint
.
a ? b : c
是一个表达式,如果 a
计算结果为 true 则给出值 b
否则为 c
。
因此,从结果来看,两者是相同的。实际上,如果您编译此代码并反汇编它,您会发现编译后的代码也可能没有不同:
int test1(int a, int b) {
return a > b;
}
int test2(int a, int b){
return a > b ? 1 : 0;
}
在 GCC 4.7.2、x86-64 上编译,调试 ( -g
) - 这应该确保尽可能禁用所有优化 - 然后使用 objdump -d foo.o
反汇编:
0000000000000000 <test1>:
0: 55 push %rbp
1: 48 89 e5 mov %rsp,%rbp
4: 89 7d fc mov %edi,-0x4(%rbp)
7: 89 75 f8 mov %esi,-0x8(%rbp)
a: 8b 45 fc mov -0x4(%rbp),%eax
d: 3b 45 f8 cmp -0x8(%rbp),%eax
10: 0f 9f c0 setg %al
13: 0f b6 c0 movzbl %al,%eax
16: 5d pop %rbp
17: c3 retq
0000000000000018 <test2>:
18: 55 push %rbp
19: 48 89 e5 mov %rsp,%rbp
1c: 89 7d fc mov %edi,-0x4(%rbp)
1f: 89 75 f8 mov %esi,-0x8(%rbp)
22: 8b 45 fc mov -0x4(%rbp),%eax
25: 3b 45 f8 cmp -0x8(%rbp),%eax
28: 0f 9f c0 setg %al
2b: 0f b6 c0 movzbl %al,%eax
2e: 5d pop %rbp
2f: c3 retq
您可以看到这两个函数的代码完全相同;你无法推断哪一个编译为哪一个。表达式共 3 行:
d: 3b 45 f8 cmp -0x8(%rbp),%eax
10: 0f 9f c0 setg %al
13: 0f b6 c0 movzbl %al,%eax
第一个比较 b
和 a
并适当设置处理器标志。如果结果“更大”,第二个将 al
(寄存器 eax/rax 的最低字节)设置为 1(请注意,上面的比较已反转!),否则设置为 0;第三个,movzbl
将一个字节零扩展为 32 位整数,因为我们在这里返回 int
。
关于c - 这两种说法有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35955297/