int a = 5;
int b = 6;
int c;
第一声明:
c = a > b ? 1 : 0;
第二声明:
c = (a > b);
上述两者有什么区别?
答案 0 :(得分:8)
在普通的编译器上,绝对没有区别(除了第一个有更多击键,第二个有不必要的括号(...)
)。在一些非常糟糕的优化编译器上,一种形式或另一种形式可能会更慢。
x > y
的真实结果表示为1
,false表示为0
。引用 ISO / IEC 9899:201x委员会草案2011年4月12日N1570 :
每个运算符
<
(小于),>
(大于),<=
(小于或等于)和>=
(大于或等于)如果指定的关系是真,则会产生1
;如果是 false ,则会产生0
。) 结果的类型为int
。
而a ? b : c
是一个表达式,如果a
的计算结果为true,则会为b
提供值c
。
因此,结果2是相同的。实际上,如果您编译此代码并反汇编它,您会注意到编译后的代码可能也不同:
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
您可以看到2个功能的代码完全相同;你不能推断哪一个编译到哪一个。表达式分为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;第3个,movzbl
将一个字节零扩展为32位整数,因为我们在这里返回 int
。
答案 1 :(得分:3)
在第一个a>b?1:0
中,您将整数值1
或0
分配给变量c
。
在第二个(a > b)
中,您将比较的布尔结果分配给变量c
。
语义上有很大差异,在现实世界中没有任何区别,因为在C中,true的值是1
而false的值是0
。因此,c
无论如何都会获得值1
或0
。
答案 2 :(得分:1)
两个语句都是相同的,因为在C语言中没有布尔值的概念。因此,true
表示为1,false
表示为0。
答案 3 :(得分:-1)
差异在于执行而不在结果中。像C这样的语言,广泛用于嵌入式系统;执行是一个重要的考虑因素。
对于语句1,将评估表达式a>b
的结果,并根据输出将值赋给变量c
。在第二种情况下,直接分配表达式a>b
的输出。
执行明智的第二个陈述更为理想。第一个陈述是基于决策,而第二个是简单的分配。它并不需要提及你在声明一的情况下仍然有更多的灵活性,因为你可以做更多的事情而不是分配1和0&#39>
从运行语句的硬件角度来看,需要比语句2更多的周期。