首页 > 解决方案 > 为什么 Cert-C 禁止在 while 循环声明中进行赋值?

问题描述

假设我想遍历 C 中的列表。有两种常用的方法可以做到这一点。

/* method a */
while (ptr = ptr->next) { /* do stuff */ }

或者

/* method b */
ptr = head;
while (ptr) { /* do stuff */ ptr = ptr->next; }

CERT-C 禁止方法 A。为什么是这样?continue当然 B 需要更多的手动编码来记住在所有可能的循环点进行迭代(如果它们无效,函数可能需要通过一些节点)并且方法 A 保证一致的迭代。

标签: c

解决方案


使用运算符的赋值=很容易与相等==运算符混淆。这在这部分文本中清楚地表明了这一点:

尽管代码的意图可能是赋值ba测试结果的值是否相等0,但程序员经常错误地使用赋值运算符=而不是等于运算符==

我同意在while循环的情况下——您期望每个循环都采用下一个元素——这种惊喜元素对于有成就的编码人员来说并不真正存在。对于新的编码人员来说,它可能仍然是错误的。要么他们将赋值误认为是测试相等性,要么他们没有直接看到表达式的结果何时为0.


我会确保写出表达式,while (ptr != NULL)因为这样意图最清楚,并且表达式没有任何副作用。while ((ptr = ptr->next) != NULL)如果您确实允许在选择语句中出现单一副作用,则可以使用(我自己更喜欢术语“流控制语句”,但这更像 Java)。

我自己会远离额外的括号,while ((ptr = ptr->next))因为这可能会被误认为是草率,并且代码美化器可能会警告不必要的括号。


推荐阅读