在实现无限循环时,使用while(1)vs for(;;)vs goto(在C中)是否存在差异?

在实现无限循环时,使用while(1) vs for(;;) vs goto是否有区别?

谢谢,陈兹

即使您关闭优化器,它们也是等效的。

例:

 #include  extern void f(void) { while(1) { putchar(' '); } } extern void g(void) { for(;;){ putchar(' '); } } extern void h(void) { z: putchar(' '); goto z; } 

使用gcc -O0编译为所有3个函数提供等效程序集:

  f: ; [ EXTERNAL ] ; +00000 00000fb4 80402DE9 stmdb sp!,{r7,lr} +00004 00000fb8 00708DE2 add r7,sp,#0x0 +00008 00000fbc 2000A0E3 loc_000008: mov r0,#0x20 +0000c 00000fc0 0A0000EB bl putchar (stub) +00010 00000fc4 FCFFFFEA b loc_000008 ; ; g: ; [ EXTERNAL ] ; +00000 00000fc8 80402DE9 stmdb sp!,{r7,lr} +00004 00000fcc 00708DE2 add r7,sp,#0x0 +00008 00000fd0 2000A0E3 loc_000008: mov r0,#0x20 +0000c 00000fd4 050000EB bl putchar (stub) +00010 00000fd8 FCFFFFEA b loc_000008 ; ; h: ; [ EXTERNAL ] ; +00000 00000fdc 80402DE9 stmdb sp!,{r7,lr} +00004 00000fe0 00708DE2 add r7,sp,#0x0 +00008 00000fe4 2000A0E3 loc_000008: mov r0,#0x20 +0000c 00000fe8 000000EB bl putchar (stub) +00010 00000fec FCFFFFEA b loc_000008 

我只是比较了gcc的未经优化的汇编程序输出:

 # cat while.c int main() { while(1) {}; return 0; } # cat forloop.c int main() { for (;;) { }; return 0; } 

make汇编输出:

 # gcc -S while.c # gcc -S forloop.c 

比较汇编程序文件:

 # diff forloop.s while.s 1c1 < .file "forloop.c" --- > .file "while.c" 

如您所见,没有显着差异。 这是输出

 # cat while.s .file "while.c" .text .globl main .type main, @function main: pushl %ebp movl %esp, %ebp .L2: jmp .L2 # this is the loop in both cases .size main, .-main .ident "GCC: (GNU) 4.4.3" .section .note.GNU-stack,"",@progbits 

虽然这不是技术certificate它们是相同的,但我认为它占99.9%。

生成的组件几乎没有任何差异。 这更像是一个风格问题:

转到 – 只是ooogly:向后跳,没有明确的无限块

虽然(1) – 更好,但需要“虚拟”条件,你会经常被编译器(警告级别4)或静态分析工具警告

for(;;)可能不是最漂亮的,但imho最适合,因为这个结构不能有任何其他含义(与while相比)。 但是其他一些人更喜欢(1)因为“相同”的原因……

while(1)for(;;)完全等价,两者都是易于理解的习惯用于编码无限循环。

我会避免使用goto :从无限循环中断或继续下一次迭代,使用breakcontinue

没有。 使用最易读的内容

在C中, true实现如下(取决于编译器)

 #define TRUE 1 

要么

 #define TRUE (-1) 

AND false实现为

 #define FALSE 0 

所以while (1)等于while (true)因为0被认为是假的。

while (1) == for (; ;)因为没有停止条件。

这被翻译成汇编程序

 :loop ... ... ... goto loop 

因此,如果汇编程序代码没有retexit指令,则认为它是无限循环。

虽然在其他post中没有显着差异,但使用for (;;)而不是while (1)的常见原因是静态分析工具(以及某些具有某些警告级别的编译器)经常抱怨while循环。

Goto有点讨厌,但应该生成与其他代码相同的代码。 就个人而言,我坚持for (;;) (保持Lint快乐),但我while (1)没有问题。

从我回忆起我的“拆解年代”,它不会产生太大的影响(编译器足够聪明 )。 它更多的是关于美学IMO。