电子产业一站式赋能平台

PCB联盟网

搜索
查看: 16|回复: 0
收起左侧

单片机项目中while(1) 和 for(;;)区别

[复制链接]

589

主题

589

帖子

7326

积分

高级会员

Rank: 5Rank: 5

积分
7326
发表于 昨天 11:45 | 显示全部楼层 |阅读模式
关注+星标公众,不错过精彩内容

aujpg3rrvb064037169628.gif

aujpg3rrvb064037169628.gif

作者 | strongerHuang微信公众号 | 嵌入式专栏
有读者好奇:有的代码是用while(1),而有的是for(;;),while(1) 和 for(;;)它们不都是无限循环吗,作用应该一样啊,它们到底有什么区别?
要回答这个问题,其实你各自编写一段while(1) 和 for(;;)的代码,编译对比一下代码大小和汇编文件,你就大概知道了。
while(1)和for(;;)语法表达
这里先说一下while(1)和for(;;)语法表达式。
1.while语法表达
  • while( 表达式 ){  语句}
    其中:表达式:是循环条件语句:为循环体。
    while语句的语义是:计算表达式的值,当值为真(非0)时, 执行循环体语句。其执行过程可用下图表示:

    uhnp5wwlz3m64037169728.jpg

    uhnp5wwlz3m64037169728.jpg

    2.for语法表达
  • for(表达式1; 表达式2; 表达式3) {  语句}
    它的执行过程如下:1.先求解表达式1
    2.求解表达式2若其值为真(非0),则执行for语句中指定的内嵌语句,然后执行下面第3)步;若其值为假(0),则结束循环,转到第5)步。
    3.求解表达式3
    4.转回上面第2)步继续执行。
    5.循环结束,执行for语句下面的一个语句。

    执行过程可用下图表示:

    hlmypbqvulv64037169828.png

    hlmypbqvulv64037169828.png

    while(1)和for(;;)异同点
    这里先说一下结论,然后再验证验证结论。
    1.相同点作用和效果都一样:都是实现无限循环的功能。
    2.不同点while(1):其中括号里面是一个条件,程序会判断真假。而括号里面的“1”永远是一个“真值”。
    其中,每一次循环,编译器都要判断常量1是不是等于零。
    for(;;):这两个;;空语句,编译器一般会优化掉的,直接进入死循环。
    根据上面的描述,你可能会觉得:while(1) 比 for(;;) 要做更多事,汇编代码更多,代码量也更大。
    但事实是这样吗?下面验证一下。
    验证while(1)和for(;;)差异
    我们编写分别两个文件for.c和while.c,然后分别生成汇编代码,看下情况。
    1.源代码while.c:
  • // filename: while.cint main(int argc, char const *argv[]){    while(1)    {}
        return 0;}
    for.c:
  • // filename: for.cint main(int argc, char const *argv[]){    for(;;)    {}
        return 0;}
    2.生成汇编我们这里使用gcc编译器生成汇编,执行命令如下:
  • gcc -S -o while.s while.cgcc -S -o for.s for.c
    while汇编代码:
  • ; filename: whiles  .file  "while.c"  .text  .globl  main  .type  main, @functionmain:.LFB0:  .cfi_startproc  pushq  %rbp  .cfi_def_cfa_offset 16  .cfi_offset 6, -16  movq  %rsp, %rbp  .cfi_def_cfa_register 6  movl  %edi, -4(%rbp)  movq  %rsi, -16(%rbp).L2:  jmp  .L2  .cfi_endproc.LFE0:  .size  main, .-main  .ident  "GCC: (GNU) 9.3.0"  .section  .note.GNU-stack,"",@progbits
    for汇编代码:
  • ; filename: for.s  .file  "for.c"  .text  .globl  main  .type  main, @functionmain:.LFB0:  .cfi_startproc  pushq  %rbp  .cfi_def_cfa_offset 16  .cfi_offset 6, -16  movq  %rsp, %rbp  .cfi_def_cfa_register 6  movl  %edi, -4(%rbp)  movq  %rsi, -16(%rbp).L2:  jmp  .L2  .cfi_endproc.LFE0:  .size  main, .-main  .ident  "GCC: (GNU) 9.3.0"  .section  .note.GNU-stack,"",@progbits
    你会发现,除了文件名不同,其余都相同。
    当然,这里额外说一下,不同代码、不同编译器,以及不同优化等级,可能最终结果有所差异。------------ END ------------

    vm5j1x0ojm364037169928.gif

    vm5j1x0ojm364037169928.gif

    ●专栏《嵌入式工具●专栏《嵌入式开发》●专栏《Keil教程》●嵌入式专栏精选教程
    关注公众号回复“加群”按规则加入技术交流群,回复“1024”查看更多内容。
    点击“阅读原文”查看更多分享。
  • 回复

    使用道具 举报

    发表回复

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则


    联系客服 关注微信 下载APP 返回顶部 返回列表