本节书摘来自华章计算机《编写高质量代码:改善c程序代码的125个建议》一书中的第3章,建议22,作者:马 伟 更多章节内容可以访问云栖社区“华章计算机”公众号查看。
建议22:谨慎使用do/while与while循环
前面已经说过,在C语言中,循环控制语句除for循环语句之外,还提供另外两种循环控制语句:while循环语句和do/while循环语句。在实际应用中,for 循环语句的使用频率最高,while循环语句其次,do/while循环语句很少用。
建议22-1:无限循环优先选用for( ; ; ),而不是while(1)
在C语言中,最常用的无限循环语句主要有两种:while (1) 和for( ; ; )。从功能上讲,这两种语句的效果完全一样。那么,我们究竟该选择哪一种呢?
其实,从while和for的语义上来看,显然for( ; ; ) 语句运行速度要快一些。按照for的语法规则,两个分号“;”分开的是3个表达式。现在表达式为空,很自然地被编译成无条件的跳转(即无条件循环,不用判断条件)。如代码for( ; ; ) 在Microsoft Visual Studio 2010集成开发环境VC++的Debug模式下将生成如下汇编代码:
for( ; ; )
00931451 jmp main+41h (931451h)
相比之下,while语句就不一样了。按照while的语法规则,while() 语句中必须有一个表达式(这里是1)判断条件,生成的代码用它进行条件跳转。即while语句()属于有条件循环,有条件就要判断条件是否成立,所以其相对于for( ; ; ) 语句需要多几条指令。如代码while (1) 在Microsoft Visual Studio 2010集成开发环境VC++的Debug模式下将生成如下汇编代码:
while(1)
011A1451 mov eax,1
011A1456 test eax,eax
011A1458 je main+55h (11A1465h)
011A1463 jmp main+41h (11A1451h)
根据上面的分析结果,很显然,for( ; ; ) 语句指令少,不占用寄存器,而且没有判断、跳转指令。当然,如果从实际的编译结果来看,两者的效果常常是一样的,因为大部分编译器都会对while (1) 语句做一定的优化。但是,这还需要取决于编译器。因此,我们还是应该优先选用for( ; ; ) 语句。
建议22-2:优先使用for循环替代do/while与while循环
在C语言中,while循环与do/while循环的区别在于:while循环语句先测试控制表达式的值,再执行循环体,如下面的示例代码所示:
unsigned int i=0;
while (i<1000)
{
i++;
/*处理程序*/
}
相比之下,do/while循环语句则先执行循环体,再测试控制表达式的值,如下面的示例代码所示:
unsigned int i=1000;
do
{
i--;
/*处理程序*/
}
while (i>0);
如果控制表达式的值一开始为假,则while循环语句的循环体一次都不执行,而do/while循环语句的循环体仍然要执行一次再跳出循环。
在实际开发环境中,无论是do/while与while循环,还是for循环,它们之间都是可以相互替换的。但从代码的可读性而言,建议优先选用for循环。尤其面对多层循环嵌套,for循环的代码相比之下就更易读懂了。当然,如果在循环的次数不明确的情况下,还是要使用do/while和while循环。