我买了这本名为“编写固体代码”的书。
在第一章中,有这段代码:
while(*pchTo++ = *pchFrom++)
NULL;
我真的不明白NULL
在那个循环中做了什么。
答案 0 :(得分:6)
作者可以编写一个完全空的while
循环,就像你可以写一个无体for
循环一样。那看起来像是:
while (*pchTo++ = *pchFrom++);
/* or */
while (*pchTo++ = *pchFrom++)
;
对于某些人来说,这两者可能会让人感到困惑,因此他们添加了NULL以使其成为一个正文并使其更容易混淆。
修改强>
请注意,您可以使用for循环执行相同的操作:
for (head = list->head; head->next; head = head->next);
/* or */
for (head = list->head; head->next; head = head->next)
;
/* or */
for (head = list->head; head->next; head = head->next)
NULL;
所有这一切都是通过转到下一个元素来遍历列表,而下一个元素不是NULL
答案 1 :(得分:3)
该循环复制一个字符串。 NULL
只是提供一个循环体。
答案 2 :(得分:3)
它可能受到Ada的null语句语法的启发:
while condition loop
null;
end loop;
Ada将null
关键字用于空指针常量和null语句(以及其他一些内容)。
它确实比C的null语句有一些优势,它只是一个分号。特别是,它更明确。 C代码中一个相当常见的错误是通过添加分号来插入意外的空语句,特别是在没有经验的C程序员中,这些程序员还没有必要的分号和不分号的地方:
while (condition);
{
/* statements */
}
没有分号,语句由while循环控制。有了它,while循环的主体是空的,如果条件没有副作用,循环可能是无限的。
另一方面,如果你真的想要一个空语句,只使用一个分号会让读者想知道是否有人无意中遗漏了这些内容。
在C中,NULL
是一个扩展为实现定义的空指针常量的宏。作者在这里使用它:
while(*pchTo++ = *pchFrom++)
NULL;
作为一种空语句 - 实际上有效,因为后跟分号的表达式是语句表达式,其中语句的副作用被评估。由于它没有副作用,它什么也没做;它就像一个真正的空语句:
while(*pchTo++ = *pchFrom++)
;
另一种等效形式:
while(*pchTo++ = *pchFrom++)
42;
在我看来,这是有目的的,但是一个坏主意。对于那些碰巧熟悉C和Ada的人来说,这很容易识别,但是大多数有经验的C程序员会仔细研究它,并想知道空指针常量在那里做了什么。
与相当并不像定义一组宏那样使C看起来像另一种语言的语法:
#define IF if (
#define THEN )
#define BEGIN {
#define END }
#define ELSE } else {
但这是同样的精神。
我的建议:不要做这种事。如果您希望C 的读者能够轻松理解您的C代码,请编写惯用的C代码;不要发明聪明的技巧让它看起来像别的东西。无效的陈述可能会让人感到困惑,导致读者怀疑是否有意外遗漏了某些内容。恕我直言,最佳解决方案是使用评论:
while(*pchTo++ = *pchFrom++) {
/* empty body */
}
答案 3 :(得分:2)
此构造提供了一种在使用调试器时放置断点的好方法。有些IDE没有让我在循环上放置一个断点而且我有一个空体循环。如果循环体中有一个语句,则更容易在其上放置断点,即使该语句无效。
否则,正如已经说过的那样,它应该与身体空虚的身体完全相同。