有读者问题了类似这样的问题:while (1) 和 for (;;) 它们不都是无限循环吗,作用应该一样啊,它们到底有什么区别?
要回答这个问题,其实你各自编写一段 while (1) 和 for (;;) 的代码,编译对比一下代码大小和汇编文件,你就大概知道了。
while (1) 和 for (;;) 语法表达
这里先说一下 while (1) 和 for (;;) 语法表达式。
1.while 语法表达
while( 表达式 )
{
语句
}
其中:
表达式:是循环条件
语句:为循环体。
while 语句的语义是:计算表达式的值,当值为真 (非 0) 时, 执行循环体语句。其执行过程可用下图表示:
2.for 语法表达
for(表达式1; 表达式2; 表达式3)
{
语句
}
它的执行过程如下:
1. 先求解表达式 1
2. 求解表达式 2
若其值为真(非 0),则执行 for 语句中指定的内嵌语句,然后执行下面第 3)步;
若其值为假(0),则结束循环,转到第 5)步。
3. 求解表达式 3
4. 转回上面第 2)步继续执行。
5. 循环结束,执行 for 语句下面的一个语句。
执行过程可用下图表示:
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.c
intmain(int argc, charconst *argv[])
{
while(1)
{}
return 0;
}
for.c:
// filename: for.c
intmain(int argc, charconst *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
你会发现,除了文件名不同,其余都相同。
当然,这里额外说一下,不同代码、不同编译器,以及不同优化等级,可能最终结果有所差异。
文章来源于网络,版权归原作者所有,如有侵权,请联系删除。
关注【一起学嵌入式】,回复“加群”进技术交流群。
觉得文章不错,点击“分享”、“赞”、“在看” 呗!