我什么时候可以省略C中的花括号?

时间:2013-02-15 19:26:35

标签: c

我几乎可以肯定以前曾经问过这个问题,但我无法在任何地方找到答案。

我什么时候可以省略C中的花括号?我之前见过无括号return语句,例如

if (condition)
  return 5;

但这似乎并不总是适用于所有语句,即在声明方法时。

修改

大括号遗漏的规则是否与Java相同?

10 个答案:

答案 0 :(得分:11)

如果正文由单个语句组成,那么您可以省略括号的唯一位置是if-elseforwhiledo-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语句(whilefor语句,...)相同,{}不会被省略。他们只是没有要求。 if语句具有以下语法:

if (expression) statement

如果您想要多个语句而不是单个语句,则可以使用包含{}的复合语句。

答案 4 :(得分:3)

当您想要将多个语句或表达式组合成一个时,您主要需要大括号,例如:

{
  x = 1;
  y = 2;
}

因此,如果你将上面的内容放在ifelse下,那么括号中的整个内容将作为一个整体执行,而如果省略大括号,则只会删除第一个({{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

希望有人觉得这有用!