我几乎可以肯定以前曾经问过这个问题,但我无法在任何地方找到答案。
我什么时候可以省略C中的花括号?我之前见过无括号return
语句,例如
if (condition)
return 5;
但这似乎并不总是适用于所有语句,即在声明方法时。
修改:
大括号遗漏的规则是否与Java相同?
答案 0 :(得分:11)
如果正文由单个语句组成,那么您可以省略括号的唯一位置是if-else
,for
,while
或do-while
语句的正文:< / p>
if (cond)
do_something();
for (;;)
do_something();
while(condition)
do_something();
do
do_something();
while(condition);
但是,请注意,上述每个示例都根据语法计为单个语句;这意味着您可以编写类似
的内容if (cond1)
if (cond2)
do_something();
这是完全合法的; if (cond2) do_something();
缩减为单个语句。所以,就此而言,是if (cond1) if (cond2) do_something();
,所以你可以用类似
for (i=0; i < N; i++)
if (cond1)
if (cond2)
while (cond3)
for (j=0; j < M; j++)
do_something();
不要这样做。
答案 1 :(得分:10)
如果查看C语法,有许多上下文需要语句,这是一个由语法本身定义的术语。
在任何上下文中,您可以使用的一种形式的语句是复合语句,它由一个左括号{
,一个零或多个声明的序列组成。 /或语句,以及右括号}
。 (在C90中,复合语句中的所有声明必须在所有语句之前; C99删除了该限制。)
function-definition 特别需要复合语句,而不仅仅是任何类型的语句。 (我认为这是唯一一种复合语句是你可以使用的唯一语句的情况)。如果没有这个限制,你可以写:
void say_hello(void) printf("Hello, world\n");
但是由于大多数函数定义包含多个声明和/或语句,因此在允许的情况下没有多大优势。
还有一个单独的问题:当应该时,你省略了大括号。在我个人看来,答案是“几乎没有”。这样:
if (condition)
statement;
完全合法,但是:
if (condition) {
statement;
}
恕我直言阅读更好,更容易维护(如果我想添加第二个语句,大括号已经存在)。这是我从Perl那里学到的一种习惯,在所有这些情况下都需要大括号。
我唯一一次省略大括号就是整个if语句或类似的东西适合单行,这样做会使代码更容易阅读,和我不太可能想要为每个if
添加更多语句:
if (cond1) puts("cond1");
if (cond2) puts("cond2");
if (cond3) puts("cond3");
/* ... */
我发现这种情况相当罕见。即便如此,我仍然会考虑添加大括号:
if (cond1) { puts("cond1"); }
if (cond2) { puts("cond2"); }
if (cond3) { puts("cond3"); }
/* ... */
答案 2 :(得分:3)
但这似乎并不总是适用于所有陈述。
具体?当预期单个语句时,它就完全有效。循环,if
语句等都需要一个语句,这可以是一个块,或者说是一个单独的语句,而不是被包含在一个块中。
答案 3 :(得分:3)
一个例子:
int a[2][2] = {{1, 2}, {3, 4}};
您可以使用有效的等效表格:
int a[2][2] = {1, 2, 3, 4};
有些冗长的编译器可能会发出警告,但它是有效的。
请注意,对于if
语句(while
,for
语句,...)相同,{}
不会被省略。他们只是没有要求。 if
语句具有以下语法:
if (expression) statement
如果您想要多个语句而不是单个语句,则可以使用包含{}
的复合语句。
答案 4 :(得分:3)
当您想要将多个语句或表达式组合成一个时,您主要需要大括号,例如:
{
x = 1;
y = 2;
}
因此,如果你将上面的内容放在if
或else
下,那么括号中的整个内容将作为一个整体执行,而如果省略大括号,则只会删除第一个({{1}在这种情况下)将用作x = 1;
或if
的一部分。
您通常也会将其与else
:
switch()
您通常需要使用switch (x)
{
case 1:
// do smth
break;
case 2:
// do smth else
break;
}
语句:
do-while
当您想在代码中间定义和使用临时变量时,需要使用C89编译器:
do
{
printf("%d\n", x);
x++;
} while (x < 10);
您可以使用它们来开始和结束函数体,结构/联合定义,枚举定义,结构/联合/数组的初始化,例如:
int main(void)
{
puts("Hello World!");
{
int x;
for (x = 0; x < 10; x++)
printf("%d\n", x);
}
return 0;
}
有时您可以在初始化中省略它们,例如:
void blah(void)
{
}
enum e
{
e1 = 1,
e2 = 2
};
struct s
{
int foo;
int bar;
} s = { 1, 2 };
int a[3] = { 1, 2, 3 };
答案 5 :(得分:2)
当您正在执行单个语句时,可以省略它们:
for(...)
printf("brackets can be omited here");
if(...)
printf("brackets can be omited here");
else
printf("brackets can be omited here too");
等等。你可以随时添加它们,它永远不会伤害并有助于澄清范围,但你很安全。我能想到的唯一“问题”是你是否试图在该范围内作出声明(顺便说一句,这是无用的):
if(...)
int a = 5;
这会导致错误,但这是因为您可以执行单个语句而不使用大括号,而不是声明。重要的区别。
从技术上讲,如果它们与,
运算符连接,您甚至可以执行多个操作而不使用括号...不是我建议这样做,只是值得注意:
if(...)
value++, printf("updated value with brackets");
在编辑中,您可以在java specification中看到规则相同。我专门链接到if
部分,但您可以在if
之后看到它的预期声明,因此您可以跳过大括号。
答案 6 :(得分:2)
任何时候都有一个包含多行的块(将行计为带有;的单个语句)
<强>示例:强>
for (i = 0; i < j; i++ )
foo(i);
while (1)
foo();
if( bool )
foo();
void cheese()
printf("CHEESE");
之后的一切;在上面的行中不计算块的“内部”,就好像有{}。
答案 7 :(得分:0)
如有疑问,请使用牙套。它们不会“花费”任何额外费用[除非你绝对错误地使用它们]。
一个相当基本的规则是“如果你在同一个缩进处有一个以上的分号,你应该有大括号”。这不是那么简单,但作为一个“没有ifs,buts或其他并发症的一句话”,它将不得不做。
是的,基于C语法的Java具有相同的基本规则 - 可能有一些奇怪的地方,Java与C或C ++不同,但这是不寻常/奇怪的事情,而不是你在写典型时通常会遇到的事情代码[我没有做太多的java,所以我不能说我找到了它们中的任何一个,但我很确定有一些差异 - 毕竟它们是不同的语言]。
答案 8 :(得分:0)
以下似乎有点棘手:
if (...)
printf("I'm conditional\n");
我猜C预处理器会处理空行,所以这句话很好。当然非常糟糕的做法。
答案 9 :(得分:0)
从我刚刚回答的另一个帖子中复制我自己的答案; 显然可以使用不带花括号的 for 循环,而且实际上不需要离开括号!
#include <stdio.h>
int
main(){
for(int i=0; i<10;i++,printf("%d ",i),printf("%d\n",i));
return 0;
}
1 ... 10
1 ... 10
希望有人觉得这有用!