为什么会有人使用它?
if(a==1){;}
没有声明,只有一个分号,并且不会抛出错误.这个分号的用途是什么?
这是一个空洞的陈述.单个分号本身不执行任何操作.
在这种情况下,它意味着如果if
条件为真,则什么都不做.
没有else
部分,这段代码没什么用处.如果存在,那么条件是否应该被反转并且应该仅包含非空if
部分是一个问题.
在这种情况下,它是一个简单的条件,所以在样式方面它可能更好地反转它,但是如果条件更复杂,那么用这种方式编写可能更清楚.例如,这个:
if ((a==1) && (b==2) && (c==3) && (d==4)) { ; } else { // do something useful }
可能比这更清楚:
if (!((a==1) && (b==2) && (c==3) && (d==4))) { // do something useful }
或这个:
if ((a!=1) || (b!=2) || (c!=3) || (d!=4)) { // do something useful }
评论中的一个更好的例子(感谢Ben):
if (not_found) { ; } else { // do something }
与:
if (!not_found) { // do something }
使用哪种方法很大程度上取决于被比较的内容,有多少项,如何嵌套这些术语,甚至涉及的变量/函数的名称.
另一个可能使用此示例的示例是,当您有一组if..else
语句来检查一系列值时,您希望在代码中记录特定范围不应发生任何事情:
if (a < 0) { process_negative(a); } else if (a >=0 && a < 10) { process_under_10(a); } else if (a >=10 && a < 20) { ; // do nothing } else if (a >=20 && a < 30) { process_20s(a); } else if (a >= 30) { process_30s_and_up(a); }
如果if
遗漏了空白,读者可能会想知道是否应该发生某些事情并且开发人员忘了它.通过包含空if
,它向读者说"是的,我解释了这个,在这种情况下什么都不应该发生".
某些编码标准要求在代码中明确说明所有可能的结果.所以遵守这样一个标准的代码可能看起来像这样.
它被称为null语句.
从6.8.3 Expression和null语句:
空语句(仅由分号组成)不执行任何操作.
在这个特定的例子中if(a==1){;}
,它没有做任何有用的事情(除非可能更明显),因为它与if(a==1){}
或相同if(a==1);
.
完全没有目的.这是一个空洞的陈述.开发人员可能想要做一些事情,如果a
不是1
在哪种情况下代码会是这样的(即使;
仍然可以省略):
if(a==1) { ; } else { //useful code... }
但在那种情况下,它可以很容易地写成if(a != 1)
.
但请注意,如果这是C++(标签尚不清楚),那么operator==
类型的类型a
可能会过载,并且可能会观察到一些副作用.这意味着代码是疯了.
它被称为null语句.这是表达式遗漏的表达式.
有时它会在if-else语句中使用,因为你很容易编写if条件而不是它的否定(或者if条件更清楚),但是当if条件被评估为false时应该执行代码.
例如
if ( some_condition ) { ; // do nothing } else { // here there is some code }
通常,null语句仅用于展示,以显示例如函数体,或类构造函数或for循环为空.例如
struct A { A( int x ) : x( x ) { ; } //... };
要么
char * copy_string( char *dsn, const char *src ) { char *p = dsn; while ( ( *dsn++ = *src++ ) ) ; ^^^ return p; }
这里while循环需要null语句.你也可以改写它
while ( ( *dsn++ = *src++ ) ) {}
有时需要使用null语句,尤其是在使用goto语句的极少数情况下.例如,在C声明中不是语句.如果要将程序控制传递到某个声明之前的某个点,则可以在声明之前放置标签.但是在C中,标签可能只在声明之前放置.在这种情况下,您可以在声明之前放置带有标签的null语句.例如
Repeat:; ^^^ int a[n]; //.... n++; goto Repeat;
注意标签后面的null语句.如果要删除它,那么C编译器将发出错误.
此技巧还用于将程序控制传递给复合语句的末尾.例如
{ // some code goto Done; //... Done:; }
虽然你不应该使用goto语句,但你应该知道这些情况.:)
正如许多人所说 - 它什么也没做.
为什么会这样?这是一种可能性......
我厌倦了我的团队中的坏程序员,而不是检查函数的返回值.
因此,由于我们使用GCC编译器在Linux中进行开发,因此我添加__attribute__((warn_unused_result))
了所有类型函数的声明.有关MS VC等效项,请参阅此问题.
如果用户未检查返回值,则编译器会生成警告.
当然,牛仔们已经玩if (foo() != SUCCESS) ;
满足编译器的系统和代码(虽然它不能满足我 :-).
单个;
是null语句,它什么都不做.它通常用于long if/else链,例如:
if (a == 1) { // Do nothing. ; } else if (...) { ... } else if (...) { ... }
这也可以写成:
if (a != 1) { if (...) { ... } else if (...) { ... } }
后者增加了另一级别的缩进,但IMO,它更清晰.但是,如果有多个没有代码的分支,则null语句有时可以避免过度缩进.
请注意,空复合语句(也称为块)具有相同的效果:
if (a == 1) {}
从技术上讲,如果要直接使用表达式语句,则只需要分号:
if (a == 1) ; else if (...) { ... } else if (...) { ... }
因此,写作{;}
是多余的,仅用于可疑的说明目的.
另一个来自C标准的例子,其中null语句用于提供空循环体:
char *s; /* ... */ while (*s++ != '\0') ;
但在这里我也更喜欢一个空的复合语句.