我几乎可以肯定以前有人问过这个问题,但我在任何地方都找不到答案。
我什么时候可以在 C 中省略花括号?我以前看过无括号的return
陈述,例如
if (condition)
return 5;
但这似乎并不总是适用于所有语句,即在声明方法时。
编辑:
大括号省略的规则与 Java 中的规则相同吗?
我几乎可以肯定以前有人问过这个问题,但我在任何地方都找不到答案。
我什么时候可以在 C 中省略花括号?我以前看过无括号的return
陈述,例如
if (condition)
return 5;
但这似乎并不总是适用于所有语句,即在声明方法时。
编辑:
大括号省略的规则与 Java 中的规则相同吗?
唯一可以省略括号的地方是if-else
, for
, while
, 或do-while
语句的主体,如果主体由单个语句组成:
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();
不要那样做。
如果您查看 C 语法,则有许多上下文需要statement,该术语由语法本身定义。
在任何这些上下文中,您可以使用的一种语句形式是复合语句,它由一个左大括号{
、一个零个或多个声明和/或语句的序列以及一个右大括号组成}
。(在 C90 中,复合语句中的所有声明必须在所有语句之前;C99 删除了该限制。)
函数定义特别需要复合语句,而不仅仅是任何类型的语句。(我相当确定这是复合语句是您可以使用的唯一一种语句的唯一情况)。如果没有这个限制,你可以写:
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"); }
/* ... */
但这似乎并不总是适用于所有陈述。
具体来说?当需要单个语句时,它是完全有效的。循环、if
语句等都需要一个语句,它要么是一个块,要么是一个没有包含在块中的单个语句。
一个例子:
int a[2][2] = {{1, 2}, {3, 4}};
您可以使用有效的等效形式:
int a[2][2] = {1, 2, 3, 4};
一些冗长的编译器可能会发出警告,但它是有效的。
请注意,对于if
语句(对于while
,for
语句,... 相同),{}
不会省略。他们只是没有被要求。该if
语句具有以下语法:
if (expression) statement
如果你想要一个多语句而不是单个语句,你可以使用一个被包围的复合语句{}
。
当您想将多个语句或表达式组合为一个时,您主要需要花括号,例如:
{
x = 1;
y = 2;
}
因此,如果您将上述内容放在if
或else
大括号中的整个内容将作为一个整体执行,而如果您省略大括号,则只有第一个(x = 1;
在这种情况下)将用作if
or的一部分else
。
您通常还可以将它们用于switch()
:
switch (x)
{
case 1:
// do smth
break;
case 2:
// do smth else
break;
}
您通常需要将它们与以下do-while
语句一起使用:
do
{
printf("%d\n", x);
x++;
} while (x < 10);
当您想在代码中间定义和使用临时变量时,您需要使用 C89 编译器:
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 };
您有时可以在初始化时省略它们,例如:
char str2[] = { "abc" };
char str1[] = "abc";
当您正在执行单个语句时,您可以省略它们:
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 规范中看到规则是相同的。我专门链接到该if
部分,但您可以在if
它预期的声明之后看到,因此您可以跳过大括号。
任何时候都有一个多行的块(将行计数为带有 ; 的单个语句)
例子:
for (i = 0; i < j; i++ )
foo(i);
while (1)
foo();
if( bool )
foo();
void cheese()
printf("CHEESE");
; 之后的所有内容 在上面的几行中,就像有 {} 一样,不算在块的“内部”。
如果有疑问,请使用大括号。它们不会“花费”任何额外费用[除非您绝对错误地使用它们]。
一个相当基本的规则是“如果你在同一个缩进中有多个分号,你应该有大括号”。这并不完全那么简单,但作为“一个没有如果、但是或其他并发症的句子”,它必须这样做。
是的,基于 C 语法的 Java 具有相同的基本规则 - Java 与 C 或 C++ 不同的地方可能存在一些奇怪之处,但这是不寻常/奇怪的事情,而不是您在编写典型代码时通常会遇到的事情 [I没有做过太多的java,所以我不能说我找到了它们,但我很确定存在一些差异——毕竟它们是不同的语言]。
从我刚刚回答的另一篇帖子中复制我自己的答案;显然可以使用没有花括号的 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
希望任何人都觉得这很有用!
以下似乎有点棘手:
if (...)
printf("I'm conditional\n");
我猜 C 预处理器会处理空行,所以这个语句很好。当然是非常糟糕的做法。