关于此特定代码中的“NULL”

时间:2013-05-06 14:09:50

标签: c

我买了这本名为“编写固体代码”的书。

在第一章中,有这段代码:

while(*pchTo++ = *pchFrom++)
   NULL;

我真的不明白NULL在那个循环中做了什么。

4 个答案:

答案 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没有让我在循环上放置一个断点而且我有一个空体循环。如果循环体中有一个语句,则更容易在其上放置断点,即使该语句无效。

否则,正如已经说过的那样,它应该与身体空虚的身体完全相同。