“if”块中的“;”是什么意思?
为什么有人会用这个?
if(a==1){;}
没有声明,只有一个分号,并没有抛出一个错误。 这个分号的用途是什么?
这是一个空话。 一个分号本身不执行任何操作。
在这种情况下,这意味着if
条件成立,则什么都不做。
没有else
部分,这个代码没有太多的用处。 如果存在的话,那么这个条件是否应该被颠倒是一个风格问题,并且应该只包含一个非空的部分。
在这种情况下,这是一个简单的条件,所以风格明智的倒置它可能会更好,但是如果条件更复杂,可以更清楚地写这种方式。 例如,这个:
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 }
来自评论的一个更好的例子(感谢本):
if (not_found) { ; } else { // do something }
与:
if (!not_found) { // do something }
使用哪种方法在很大程度上取决于正在比较什么,有多less条款,条款是如何嵌套的,甚至是所涉及的variables/函数的名称。
当你可能使用这个的另一个例子是,当你有一组if..else
语句来检查一个值的范围,并且你想要在代码中logging什么东西不应该发生在一个特定的范围:
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
包含空白的if
,它对读者说:“是的,我解释了这一点,在这种情况下什么也不应该发生”。
某些编码标准要求以代码明确说明所有可能的结果。 所以遵守这样的标准的代码可能看起来像这样。
它被称为空声明 。
从6.8.3expression式和空语句 :
空语句(仅由分号组成)不执行任何操作。
在这个特定的例子中, if(a==1){;}
,它没有做任何有用的事情(除了可能更明显一点),因为它是相同的, if(a==1){}
或if(a==1);
。
没有目的。 这是一个空话。 如果a
不是1
,那么开发者可能会想要做些什么,在这种情况下,代码会是这样的(尽pipe这个代码仍然可以省略):
if(a==1) { ; } else { //useful code... }
但在这种情况下,它可以很容易地写成, if(a != 1)
。
但是请注意,如果这是C ++(标签还不清楚),则可能会出现atypes的operator==
被重载并且可能会观察到一些副作用。 这意味着代码是疯了。
这就是所谓的空声明。 这是一种expression错误的expression语句。
有时在if-else语句中使用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语句是必需的。 你也可以重写它
while ( ( *dsn++ = *src++ ) ) {}
有时,在使用goto语句的情况下,特别是在less数情况下需要空语句。 例如在C中的声明不是语句。 如果你想在某个声明之前把程序控制传递给某个点,你可以在声明之前放置一个标签。 然而,在C中,标签可能只在语句之前放置。 在这种情况下,您可以在声明之前放置带有标签的空语句。 例如
Repeat:; ^^^ int a[n]; //.... n++; goto Repeat;
注意标签后面的空语句。 如果删除它,那么C编译器将发出一个错误。
这个技巧也被用来将程序控制传递到复合语句的末尾。 例如
{ // some code goto Done; //... Done:; }
虽然你不应该使用goto语句,但你应该知道这些情况。
正如许多人所说的 – 它什么都不做。
为什么呢? 这是一个可能性…
我厌倦了我的团队不好的编码器检查函数的返回值。
因此,我们使用GCC编译器在Linux中进行开发,我将__attribute__((warn_unused_result))
到所有types函数的声明中。 另请参阅此问题的MS VC等效。
如果用户没有检查返回值,那么编译器会产生一个警告。
当然, if (foo() != SUCCESS) ;
牛仔们已经玩过了系统和代码if (foo() != SUCCESS) ;
它满足了编译器(尽pipe它不满足我 :-)。
一个;
是什么也不做的空声明 。 它通常用在很长的if / else链中,如:
if (a == 1) { // Do nothing. ; } else if (...) { ... } else if (...) { ... }
这也可以写成:
if (a != 1) { if (...) { ... } else if (...) { ... } }
后者增加了另一个级别的缩进,但国际海事组织,它更清楚。 但是如果有多个没有代码的分支,空语句有时可以用来避免过多的缩进。
请注意,空的复合语句 (也称为块 )具有相同的效果:
if (a == 1) {}
从技术上讲,如果你想直接使用expression式语句 ,你只需要分号:
if (a == 1) ; else if (...) { ... } else if (...) { ... }
所以写{;}
是多余的,只是一个可疑的说明目的。
另一个来自C语言标准的例子是null语句用来提供一个空的循环体:
char *s; /* ... */ while (*s++ != '\0') ;
但在这里,我也更喜欢一个空的复合语句。
;
本身就是一个空话 。 如果a
是一个初始化的非指针types,那么
if(a==1){;}
在C中总是没有任何操作。使用大括号可以增加额外的权重,断言没有错字。 也许有一个直接在它下面,如果不是1就执行。
它基本上是一个空/空的陈述,它什么都不做 ,在自然界中是预期的良性(没有错误)。
C规格草案N1570澄清:
- expression式是可选的: expression [opt];
- 空语句(仅由分号组成)不执行任何操作。
另一方面,Bjarne在他的C ++书中引用了#9.2 Statement Summary
:
分号本身就是一个陈述,是空的陈述。
请注意, if(1) {;}
和if(1) {}
这两个代码在生成的gcc指令中没有差异 。
你为什么要这样做? 在debugging时,我总是做类似的事情,给我一些(我希望)不会被优化的东西,所以我可以把它放在一个断点上。
通常情况下,虽然我明确表示它是一个debugging标记
if( (a==1) && (b==2) && (c==3) && (d==4) ){ int debug=1; }
否则,我最终会遇到一些怪异的代码,即使对我来说也是毫无意义的。
但是,这不能保证这是什么。
; 是一个空的声明noop
它的目的是什么?
有时候我们只是想比较一下在这种情况下,a和1是否相等。对于像integer这样的基本types,这将设置条件寄存器,所以如果在if(a> 1)或if(a <1 ),同时a不会被改变,这可能不会被再次评估,这取决于编译器的决定。
这个代码
int f(int a){ if(a == 1){;} if(a > 1){return 3;} if(a < 1){return 5;} return 0; }
会给
.file "c_rcrYxj" .text .p2align 2,,3 .globl f .type f, @function f: .LFB0: .cfi_startproc cmpl $1, 4(%esp) jle .L6 movl $3, %eax ret .p2align 2,,3 .L6: setne %al movzbl %al, %eax leal (%eax,%eax,4), %eax ret .cfi_endproc .LFE0: .size f, .-f .ident "GCC: (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4" .section .note.GNU-stack,"",@progbits
比较只需要完成一次cmpl $ 1,4(%esp) ,正好在写入(a == 1)的地方。
您可能已经知道分号是一个空的陈述。 关于“这个分号用于什么目的”的实际问题,答案是(除非这个代码的作者想用一些奇怪的表情来使代码活跃起来),它根本没有任何用处 。 也就是说, {;}
在任何上下文 (在预期的语句中,我认为是{;}
可以使用的唯一位置)完全等价于{}
。 分号的存在将具有0个组成语句的复合语句转换为具有1个组成语句的复合语句,这是一个空语句,但就语义而言这两个语句是等价的。
我会添加一个个人的观点,为了可读性而不被读者忽略, {;}
并不比{}
(如果是,那么也许{;;;;;;;;}
还是更好),虽然两者都比孤独好很多;
(因此,语言本来不会变得更好,因为这是空话,因为用{}
replace它总是有利的)。