c - 这两种说法有什么区别?

标签 c

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 yield 1 if the specified relation is true and 0 if it is false.) The result has type int.

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

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

关于c - 这两种说法有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35955297/

相关文章:

c - 解释c中near、far和huge指针的区别?

c - 使用 system() 时依赖 PATH 或提供显式路径

c - 将汇编代码逆向工程为 C 代码

c - 为什么客户端调用shutdown(sockfd, SHUT_RD)后,客户端程序中的recv()可以接收到发送给客户端的消息?

c - 与 coccinelle 匹配 *ptr = value

c - 在 C 中实现类似 shell 的作业控制

收集数据并将其存储到 EEPROM

c - 如何用 clone() 替换 pthread_join() 和 pthread_create()

c - 如何从字符串数组中访问数据? C

c++ - C中有const吗?