说我想遍历C语言中的一个列表。有两种常用的方法。
/* method a */
while (ptr = ptr->next) { /* do stuff */ }
或
/* method b */
ptr = head;
while (ptr) { /* do stuff */ ptr = ptr->next; }
CERT-C bans method A。为什么是这样?当然,B需要更多的手动编码来记住在所有可能的循环点处进行迭代(如果函数无效,则该函数可能需要continue
经过某些节点),并且方法A保证了一致的迭代。
答案 0 :(得分:2)
使用=
运算符的赋值可以容易地与相等性==
运算符混淆。这部分文字清楚地表明了这一点:
尽管代码的目的可能是将
b
分配给a
并测试结果等于0
的值,但程序员经常错误地使用这种情况赋值运算符=
而不是等于运算符==
。
我同意在while
循环的情况下-您希望每个循环都包含下一个元素-对于有成就的编码人员,惊喜元素实际上并不存在。对于新编码员,可能仍然会犯错。他们要么将分配误认为是测试相等性,要么不直接看到表达式的结果何时为0
。
我会确保将表达式写成while (ptr != NULL)
,因为这样可以使意图最明确,并且表达式没有任何副作用。如果您确实允许选择语句中有单一副作用,则可以使用while ((ptr = ptr->next) != NULL)
(我自己更喜欢术语“流控制语句”,但这更像Java)。
我本人要远离while ((ptr = ptr->next))
中的附加括号,因为这可能会误认为是草率的,并且代码美化程序可能会针对不必要的括号发出警告。