有读者提出这样的问题:while(1)和for(;;)不都是无限循环吗,它们的功能应该是一样的,它们有什么区别?要回答这个问题,其实你分别写一段while(1)和for(;;)的代码,编译比较一下代码大小和汇编文件,你大概就知道了。while(1)和for(;;)语法表达式先说一下while(1)和for(;;)语法表达式。1、while语法表示while(expression){statement}其中:Expression:是循环条件Statement:是循环体。while语句的语义是:计算表达式的值,当值为真(非零)时执行循环体中的语句。执行过程可以如下图所示:2.for语法表达式for(expression1;expression2;expression3){statement}如下:1.先求解表达式12.求解表达式2ifIfitsvalue为真(非0),执行for语句中指定的嵌入语句,然后执行下面的步骤3);如果它的值为false(0),则结束循环并转到步骤5)。3.求解表达式3。4.回到上面的步骤2)继续执行。5.在循环结束时,执行for语句下面的语句。执行过程可以用下图来表示:while(1)和for(;;)的异同这里先说结论,再验证验证结论。1、相同的功能和效果是一样的:都是实现无限循环的功能。2、区别在于while(1):括号内有一个条件,程序会判断是真还是假。而括号中的“1”永远是“真值”。其中,每一次循环,编译器都要判断常量1是否等于0。for(;;):这两个;;空语句,编译器一般会优化掉,直接进入死循环。根据上面的描述,你可能会觉得while(1)比for(;;)做的工作多,汇编代码多,代码量也大。但真的是这样吗?下面验证一下。验证while(1)和for(;;)的区别我们分别写for.c和while.c两个文件,然后分别生成汇编代码,看看情况。1.源码while.c://filename:while.cintmain(intargc,charconst*argv[]){while(1){}return0;}for.c://filename:for.cintmain(intargc,charconst*argv[]){for(;;){}return0;}2.生成程序集我们这里使用gcc编译器生成程序集,执行命令如下:gcc-S-owwhile.swhile.cgcc-S-ofor.sfor.cwhileassembly代码:;filename:whiles.file"while.c".text.globlmain.typemain,@functionmain:.LFB0:.cfi_startprocpushq%rbp.cfi_def_cfa_offset16.cfi_offset6,-16movq??%rsp,%rbp.cfi_def_cfa_register6movl%edi,-4(%rbp)movq%rsi,-16(%rbp).L2:jmp.L2.cfi_endproc.LFE0:.sizemain,.-main.ident"GCC:(GNU)9.3.0".section.note.GNU-stack,"",@progbitsfor汇编代码:;文件名:for.s.file"for.c".text.globlmain.typemain,@functionmain:.LFB0:.cfi_startprocpushq%rbp.cfi_def_cfa_offset16.cfi_offset6,-16movq??%rsp,%rbp.cfi_def_cfa_register6movl%edi,-4(%rbp)movq%rsi,-16(%rbp).L2:jmp.L2.cfi_endproc.LFE0:.sizemain,.-main.ident"GCC:(GNU)9.3.0".section.note.GNU-stack,"",@progbits你会发现,除了文件名不同,其他都是一样的。当然,这里要多说一句,不同的代码,不同的编译器,不同的优化级别,最终的结果可能不同。
