c - 为什么 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 保证一致的迭代。
解决方案
使用运算符的赋值=
很容易与相等==
运算符混淆。这在这部分文本中清楚地表明了这一点:
尽管代码的意图可能是赋值
b
并a
测试结果的值是否相等0
,但程序员经常错误地使用赋值运算符=
而不是等于运算符==
。
我同意在while
循环的情况下——您期望每个循环都采用下一个元素——这种惊喜元素对于有成就的编码人员来说并不真正存在。对于新的编码人员来说,它可能仍然是错误的。要么他们将赋值误认为是测试相等性,要么他们没有直接看到表达式的结果何时为0
.
我会确保写出表达式,while (ptr != NULL)
因为这样意图最清楚,并且表达式没有任何副作用。while ((ptr = ptr->next) != NULL)
如果您确实允许在选择语句中出现单一副作用,则可以使用(我自己更喜欢术语“流控制语句”,但这更像 Java)。
我自己会远离额外的括号,while ((ptr = ptr->next))
因为这可能会被误认为是草率,并且代码美化器可能会警告不必要的括号。
推荐阅读
- mysql - 在表中创建一个数据类型,该数据类型是对其他表的引用列表
- python - 可能的 django 竞争条件
- django - Django 表单 - 引发 ValidationError 时我可以返回任何变量吗
- javascript - 我的页面如何在外部站点上填写用户名和密码?
- c++ - KNN字符识别读取数字的对角线
- google-cloud-platform - 谷歌是否存储通过谷歌 DLP API 发送的请求
- python - 如何使用 Gmail API 创建只允许发送电子邮件的 client_secret.json?
- android - 如何在 WhatsApp 中同时分享图片和文字
- python - 如何使 form.py 中的电子邮件字段成为必填字段?
- hyperledger-fabric - Allow participants to view transactions they submitted