这两个陈述有什么区别?

时间:2016-03-12 08:11:51

标签: c

int a = 5;
int b = 6;
int c;

第一声明:

c = a > b ? 1 : 0;

第二声明:

c = (a > b);

上述两者有什么区别?

4 个答案:

答案 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

第一个将ba进行比较,并相应地设置处理器标志。如果结果为“更大”,则第二个将al(寄存器eax / rax的最低字节)设置为1(注意比较在上面反转!),否则为0;第3个,movzbl将一个字节零扩展为32位整数,因为我们在这里返回 int

答案 1 :(得分:3)

在第一个a>b?1:0中,您将整数值10分配给变量c

在第二个(a > b)中,您将比较的布尔结果分配给变量c

语义上有很大差异,在现实世界中没有任何区别,因为在C中,true的值是1而false的值是0。因此,c无论如何都会获得值10

答案 2 :(得分:1)

两个语句都是相同的,因为在C语言中没有布尔值的概念。因此,true表示为1,false表示为0。

参考https://www.le.ac.uk/users/rjm1/cotter/page_37.htm

答案 3 :(得分:-1)

差异在于执行而不在结果中。像C这样的语言,广泛用于嵌入式系统;执行是一个重要的考虑因素。

对于语句1,将评估表达式a>b的结果,并根据输出将值赋给变量c。在第二种情况下,直接分配表达式a>b的输出。

执行明智的第二个陈述更为理想。第一个陈述是基于决策,而第二个是简单的分配。它并不需要提及你在声明一的情况下仍然有更多的灵活性,因为你可以做更多的事情而不是分配1和0&#39>

从运行语句的硬件角度来看,需要比语句2更多的周期