在C中使用null语句

null语句的典型用法是什么

; 

在C?

我知道它基本上用于跳过编译器所期望的表达式,但是在这里我只对这种用例的实际例子感兴趣。

它通常是由预处理器剥离的代码块的副作用,如

 #if DEBUG #define ASSERT(_x) Assert(_x) #else #define ASSERT(_x) #endif ASSERT(test); // Results in null statement in non-debug builds 

那个,或者在你的条件已经包含每次迭代中需要完成的任何循环中。

 while (*(dst++) = *(src++)) ; 

在函数结尾处的标签之后(或者更确切地说,在任何块的末尾),例如

 void foo(void) { // ... exit: ; } 
 while (somethingWithSideEffects()) ; 

虽然我很少使用它,但是在一个可能不寻常的情况下(并且有些/很多人会发现错误的情况)。 我有时必须编写一个非常复杂的if条件而没有else子句,其中if条件必须被否定。 显然它可能是这样的:

 if ( !( overly complex condition ) ) { do stuff } 

从积极逻辑的角度来看,有时候(至少对我来说)更有意义。 换句话说,如果overly complex condition成立,我不希望代码运行。 所以我把它写成:

 if ( overly complex condition ) ; // do nothing else { do stuff } 

例:

  while (!kbhit()) ; 

应该是不言自明的。

我能想到scanfvalidation。 当用户没有给出正确的输入时, scanf会卡住。 因此,为了防止scanf被卡住,必须删除直到行尾的字符。

 if( scanf("%d",&integer) == 0 ) { while( getchar() != '\n' ) ; // .... } 

我能想到的唯一用途是:

1-在循环结束时,操作已在循环语句中编码。 例如while(a[i--]);

2-在标签的末尾,不需要进行任何操作。 例如Label: ;

一个有点不同寻常的用法 – 但我非常欣赏null语句的存在 – 就是当我有两个条件和两个动作时,我发现我最自然地表达如下:

 if(condition1) /* do nothing */ ; else if(condition2) do_something; else do_something_else; 

通常condition1测试一切都没问题,但如果不是,则condition2区分两个不同的exception动作do_somethingdo_something_else

当然,这不是表达这种事情的唯一方式。 有可能重复condition1

 if(!condition1 && condition2) do_something; else if(!condition1) do_something_else; 

但这似乎是次等的,因为它重复了condition1 。 或者可以使用嵌套的if语句:

 if(!condition1) { if(condition2) do_something; else do_something_else; } 

但当然嵌套的if语句也非常容易出现过度复杂和混淆。 所以我经常更喜欢第一个版本,使用null语句。

对兼容编译器进行unit testing。

它更像是一个空表达式而不是一个空语句,但它经常出现在for循环中。

 for (;;) // Loop "forever" for (int i=10; i--; ) // 9..0 

等等

null语句的示例:

对于(;;);