while(1) 和 for(;;)区别是什么?

目录
文章目录隐藏
  1. while(1)和 for(;;)语法表达
  2. while(1)和 for(;;)异同点

有读者问题了类似这样的问题:while(1)for(;;)它们不都是无限循环吗,作用应该一样啊,它们到底有什么区别?

要回答这个问题,其实你各自编写一段while(1)for(;;)的代码,编译对比一下代码大小和汇编文件,你就大概知道了。

while(1)和 for(;;)语法表达

这里先说一下while(1)for(;;)语法表达式。

1. while 语法表达

while( 表达式 )
{
  语句
}

其中:

  • 表达式:是循环条件
  • 语句:为循环体。

while语句的语义是:计算表达式的值,当值为真(非 0)时, 执行循环体语句。其执行过程可用下图表示:

while 语句执行过程

2. for 语法表达

for(表达式 1; 表达式 2; 表达式 3) 
{
  语句
}

它的执行过程如下:

1. 先求解表达式 1

2. 求解表达式 2

若其值为真(非 0),则执行 for 语句中指定的内嵌语句,然后执行下面第 3)步;

若其值为假(0),则结束循环,转到第 5)步。

3. 求解表达式 3

4. 转回上面第 2 步继续执行。

5. 循环结束,执行 for 语句下面的一个语句。

执行过程可用下图表示:

for 语句执行过程

while(1)和 for(;;)异同点

这里先说一下结论,然后再验证验证结论。

1.相同点

作用和效果都一样:都是实现无限循环的功能。

2.不同点

while(1):其中括号里面是一个条件,程序会判断真假。而括号里面的“1”永远是一个“真值”。

其中,每一次循环,编译器都要判断常量 1 是不是等于零。

for(;;):这两个;;空语句,编译器一般会优化掉的,直接进入死循环。

根据上面的描述,你可能会觉得:while(1)for(;;) 要做更多事,汇编代码更多,代码量也更大。

但事实是这样吗?下面验证一下。

验证 while(1)和 for(;;)差异

我们编写分别两个文件for.cwhile.c,然后分别生成汇编代码,看下情况。

1.源代码

while.c:

// filename: while.c
int main(int argc, char const *argv[])
{
    while(1)
    {}

    return 0;
}

for.c:

// filename: for.c
int main(int argc, char const *argv[])
{
    for(;;)
    {}

    return 0;
}

2.生成汇编

我们这里使用 gcc 编译器生成汇编,执行命令如下:

gcc -S -o while.s while.c
gcc -S -o for.s for.c

while 汇编代码:

; filename: whiles
  .file  "while.c"
  .text
  .globl  main
  .type  main, @function
main:
.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, @function
main:
.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

你会发现,除了文件名不同,其余都相同。

当然,这里额外说一下,不同代码、不同编译器,以及不同优化等级,可能最终结果有所差异。

「点点赞赏,手留余香」

1

给作者打赏,鼓励TA抓紧创作!

微信微信 支付宝支付宝

还没有人赞赏,快来当第一个赞赏的人吧!

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。
码云笔记 » while(1) 和 for(;;)区别是什么?

发表回复