在 C 语言层面除了写法以外没什么区别。

int a = 5;

a == 0 ? puts("x") : puts("z");

if (a == 0) {
    puts("x");
} else {
    puts("z");
}

在汇编语言层面上有一些区别,if 倾向于使用条件控制转移j 系列)命令,三元表达式倾向于使用条件数据传输cmov 系列)命令。

void set1(int *a, int *b)
{
    if (*a < *b) {
        *a = *a;
    } else {
        *a = *b;
    }
}

void set2(int *a, int *b)
{
    *a = *a < *b ? *a : *b;
}

O1优化等级编译(经测试 O2, O3 汇编代码相同),反汇编得

a in %rdi, b in %rsi

Dump of assembler code for function set1:
   0x0000000000401166 <+0>:     mov    (%rsi),%eax
   0x0000000000401168 <+2>:     cmp    %eax,(%rdi)
   0x000000000040116a <+4>:     jl     0x40116e <set1+8>
   0x000000000040116c <+6>:     mov    %eax,(%rdi)
   0x000000000040116e <+8>:     retq   
End of assembler dump.

Dump of assembler code for function set2:
   0x000000000040116f <+0>:     mov    (%rdi),%eax
   0x0000000000401171 <+2>:     mov    (%rsi),%edx
   0x0000000000401173 <+4>:     cmp    %edx,%eax
   0x0000000000401175 <+6>:     cmovg  %edx,%eax
   0x0000000000401178 <+9>:     mov    %eax,(%rdi)
   0x000000000040117a <+11>:    retq   
End of assembler dump.

在只进行简单的条件赋值时,条件数据传输命令比条件控制转移要好一些。

  • C 语言层面的代码会更简洁(只要不把三元表达式写得过于复杂);
  • 汇编语言层面,j 需要进行分支预测(也就是是否要进行跳转),预测错误时会损失性能(约 \(15 \sim 30\) 个时钟周期),因为跳转意味着执行另一个地方的命令,因此 cmov 性能上会更好。

当然 if 用来进行更复杂的判断和命令是更合适的。

if 、三元表达式和汇编代码之间并不是简单的一对一的关系,倾向于也只是倾向罢了,在实际操作时不必过于在意这些。

参考书籍

原文地址:http://www.cnblogs.com/violeshnv/p/16831716.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性