问这个问题的问题是,你会得到如此多的主观答案,只是简单地说"我更喜欢这个……".与其说这些毫无意义的话,我会试着用事实和参考资料来回答这个问题,而不是个人观点.
根据经验,我们可能可以从排除do-while选项(和goto)开始,因为它们并不常用.我不记得在专业人士编写的实时生产代码中见过它们.
while(1)
、while(true)
和for(;;)
是真实代码中常见的三个不同版本.当然,它们是完全等价的,并产生相同的机器代码.
100
这是一个永恒循环的原始的、规范的例子.在Kernighan和Ritchie的古代C圣经The C Programming Language中,我们可以读到:
K&;R第二版3.5:
for (;;) {
...
}
是一个"无限"循环,想必要用其他方法来打破,比如
作为休息或返回.是边用边用在很大程度上是个问题.
个人喜好.
有很长一段时间(但不是永远),这本书被认为是C语言的典范和定义.自从K&;R决定展示一个for(;;)
的例子以来,至少在1990年C标准化之前,这一直被认为是最正确的形式.
然而,K&;R本人已经表示,这是一个偏好问题.
今天,K&;R作为规范的C参考资料是一个非常值得怀疑的来源.它不仅已经过时了好几次(不涉及C99和C11),而且还鼓吹在现代C编程中经常被认为是糟糕的或明显危险的编程实践.
但尽管K&;R作为一个可疑的来源,这一历史方面似乎是支持for(;;)
人的最有力的论据.
反对for(;;)
循环的理由是,它有点晦涩难懂.要理解代码的功能,您必须了解标准中的以下规则:
ISO 9899:2011 6.8.5.3:
for ( clause-1 ; expression-2 ; expression-3 ) statement
/--/
子句-1和表达式-3都可以省略.省略的表达式-2
替换为非零常量.
基于标准中的这一文本,我想大多数人都会同意,它不仅晦涩难懂,而且很微妙,因为当省略for循环的第一部分和第三部分时,其处理方式与第二部分不同.
100
这应该是一种比for(;;)
更可读的形式.然而,它依赖于另一条模糊但众所周知的规则,即C将所有非零表达式视为布尔逻辑true.每个C程序员都知道这一点,所以这不太可能是个大问题.
这种形式有一个很大的实际问题,即编译器倾向于给它一个警告:"条件始终为真"或类似的警告.这是一个很好的警告,是一种你真的不想禁用的警告,因为它对查找各种错误很有用.例如一个bug,比如while(i = 1)
,当程序员打算写while(i == 1)
时.
此外,外部静态代码分析器可能会抱怨"条件总是正确的".
100
为了让while(1)
更具可读性,有些人使用while(true)
.程序员之间的共识似乎是,这是最具可读性的形式.
但是,此表单与while(1)
有相同的问题,如上所述:"条件始终为真"警告.
说到C,这种形式还有另一个缺点,即它使用stdbool中的宏true
.h、 因此,为了进行编译,我们需要包含一个头文件,这可能不方便,也可能不方便.在C++中,这不是问题,因为bool
作为原始数据类型存在,true
是语言关键字.
这种形式的另一个缺点是它使用C99布尔类型,该类型仅在现代编译器上可用,不能向后兼容.同样,这只是C中的问题,而不是C++中的问题.
那么应该使用哪种形式呢?两者似乎都不完美.正如K&;R在黑暗时代已经说过的那样,这是个人喜好的问题.
就我个人而言,我总是使用for(;;)
只是为了避免其他表单经常生成的编译器/分析器警告.但也许更重要的是因为:
If even a C beginner knows that 100 means an eternal loop, then who are you trying to make the code more readable for?
我想这就是这一切真正归结起来的原因.如果您发现自己试图使您的源代码可读,而非程序员甚至不了解编程语言的基本部分,那么您只是在浪费时间.他们不应该读取您的代码.
而且,因 for each 正在阅读你的代码的人都已经知道for(;;)
的意思,所以没有必要让它更具可读性——它已经是尽可能地可读了.