13

「Writing Solid Code」という本を買いました。

最初の章には、次のコードがあります。

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

NULLそのループでそれが何をするのか本当にわかりません。

4

4 に答える 4

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

于 2013-05-06T14:12:15.190 に答える
3

そのループは文字列をコピーします。はNULL、ループ本体を提供するためだけに存在します。

于 2013-05-06T14:12:02.273 に答える
3

It's likely inspired by the syntax of Ada's null statement:

while condition loop
    null;
end loop;

Ada uses the null keyword both for the null pointer constant and for the null statement (and a few other things).

It does have some advantages over C's null statement, which is just a semicolon. In particular, it's much more explicit. A fairly common error in C code is to insert an accidental null statement by adding a semicolon, particularly among inexperienced C programmers who haven't yet worked out where semicolons are necessary and where they aren't:

while (condition);
{
    /* statements */
}

Without the semicolon, the statements are controlled by the while loop. With it, the body of the while loop is empty, and the loop is likely be infinite if the condition has no side effects.

On the other hand, if you really want a null statement, using just a semicolon can leave the reader wondering if something was unintentionally left out.

In C, NULL is a macro that expands to an implementation-defined null pointer constant. The author is using it here:

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

as a kind of null statement -- which actually works, because an expression followed by a semicolon is a statement expression in which the statement is evaluated for its side effects. Since it has no side effects, it does nothing; it acts just like a real null statement:

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

Another equivalent form:

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

In my opinion, this is well intended but a bad idea. It's easily recognizable to those few of us who happen to be familiar with both C and Ada, but most experienced C programmers will look at it and wonder what the heck that null pointer constant is doing there.

It's not quite as bad as defining a set of macros to make C look like another language's syntax:

#define IF if (
#define THEN )
#define BEGIN {
#define END }
#define ELSE } else {

but it's in the same spirit.

My advice: Don't do this kind of thing. If you want your C code to be easily understandable by readers who know C, write idiomatic C code; don't invent clever tricks to make it look like something else. Null statements can be confusing, leading the reader to wonder if something was left out accidentally. The best solution that, IMHO, is to use a comment:

while(*pchTo++ = *pchFrom++) {
    /* empty body */
}
于 2013-05-06T14:56:02.423 に答える
2

このコンストラクトは、デバッガーで作業するときにブレークポイントを配置するための優れた方法を提供します。一部の IDE では、ループにブレークポイントを配置できず、空の本体を持つループがありました。ループ本体にステートメントがある場合、そのステートメントが役に立たなくても、それにブレークポイントを配置する方が簡単です。

それ以外の場合は、既に述べたように、空のボディを持つボディとまったく同じことを行う必要があります。

于 2013-05-06T14:28:06.623 に答える