找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

5917

积分

0

好友

751

主题
发表于 昨天 17:15 | 查看: 6| 回复: 0

有一个比较古老的C语言面试题,相信不少读者都刷到过。

C语言for循环两种写法笔试题

这两种写法的优缺点汇总如下:

写法1

优点:

  1. 代码结构简洁,整体逻辑集中,一眼就能看懂“循环N次,每次走分支”。
  2. 改造成本低:后续给单次循环增加逻辑、调整分支条件,改动范围小。

缺点:

  1. 额外开销:循环n次,每次都执行if判断,循环次数越多,冗余开销越大。
  2. CPU分支预测风险:频繁分支可能造成流水线停顿,嵌入式/高频场景下性能损耗更明显。
  3. 编译器难以做循环展开、常量传播等深度优化。

写法2

优点:

  1. 性能更优:if仅执行1次,循环体内纯函数调用,无多余判断,指令更少。
  2. 利于CPU流水线:循环内无分支,分支预测百分百命中,执行效率高。
  3. 编译器优化友好:单循环体结构简单,更容易被循环展开、寄存器优化。

缺点:

  1. 代码冗余:两个for循环结构完全重复,代码有重复片段。
  2. 可读性略降:分支嵌套循环,多层结构不如第一种直观。
  3. 维护麻烦:后续要修改循环体逻辑,两处for都要同步修改,易漏改。

总结 & 选型建议

  1. a/b在循环中固定不变(当前场景):追求性能→选写法2;追求代码简洁、易维护→选写法1。

补充:现代编译器(GCC/Clang)开启-O2及以上优化时,会自动把写法1优化成写法2,二者运行效率基本一致。

  1. a/b在循环内会被修改:只能用写法1,写法2逻辑不成立。

  2. 代码规范小提示:

    • 循环次数极大、嵌入式裸机、高频调度场景:优先外判(写法2)。
    • 业务逻辑简单、追求易读易维护、循环次数少:优先内判(写法1)。

汇编代码分析

下面通过一个基于ARM裸机开发工程的简单实例,讲解这两种不同写法被编译器翻译成的最终ARM汇编代码。

测试代码如下:

写法1与写法2的C语言代码对比

Makefile如下:

TARGET=gcd
TARGETC=main
all:
    arm-linux-gnueabihf-gcc -lto -g -c -o $(TARGETC).o $(TARGETC).c
    arm-linux-gnueabihf-gcc -lto -g -c -o $(TARGET).o $(TARGET).s
    arm-linux-gnueabihf-gcc -lto -g -S -o $(TARGETC).s $(TARGETC).c
    arm-linux-gnueabihf-ld $(TARGETC).o $(TARGET).o -Tmap.lds -o $(TARGET).elf
    arm-linux-gnueabihf-objcopy -O binary -S $(TARGET).elf $(TARGET).bin
    arm-linux-gnueabihf-objdump -D $(TARGET).elf > $(TARGET).dis
clean:
    rm -rf *.o *.elf *.dis *.bin

lto(Link Time Optimization,链接时优化)能做的优化(对你代码也生效):

  • 跨文件常量传播、死代码删除;
  • 跨函数内联、全局循环优化;
  • 进一步合并冗余分支、精简指令。

写法1的主函数汇编代码如下:

写法1的反汇编代码与源码对照

关键特征:

  1. 两层分支嵌套在循环体内,每一轮循环:cmp(56行)+ bge(57)+ ble(70行)3条分支相关指令必执行一遍。
  2. 循环总次数:20次 → 20次完整条件判断 + 20次条件分支跳转。
  3. 指令流被频繁打断。
  4. 代码段体积更小,主函数一共34条指令(写法2为45条),只有一套循环框架,没有重复的for循环汇编模板。

写法2的主函数汇编代码如下:

写法2的反汇编代码与源码对照

关键特征:

  1. 分支开销降到最低,全局仅1次比较 + 1次条件分支,进入循环后再无分支判断。ARM流水线持续满载,几乎无气泡。
  2. 两个循环体内部是纯顺序指令流,只有循环收尾的无条件/条件跳转。
  3. 缺点也很明显,代码冗余,ROM/Flash占用变大。

看完两种写法的汇编实现,内判与外判的本质区别就很清楚了:写法1牺牲了运行时的分支效率,换来了更紧凑的代码;写法2用代码体积换取执行效率。实际项目中如果你的编译器已经开了-O2,很多情况下编译器会帮你自动完成这个转换;但在嵌入式裸机、编译器优化受限的场景,手动选择写法2仍然是值得考虑的。

更多嵌入式与汇编学习资源,欢迎访问云栈社区




上一篇:字节员工吐槽:裁员为什么不官宣,非要暗戳戳用绩效软裁
下一篇:三人团队18个月做出卡牌Roguelike:不烧钱怎么做游戏美术?
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-9-10 16:01 , Processed in 1.128696 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表