22

これは以前に尋ねられたことはほぼ確実ですが、どこにも答えられていません。

Cで中括弧を省略できるのはいつですか? 次のような中括弧のないreturnステートメントを見たことがあります

if (condition)
  return 5;

しかし、これはすべてのステートメント、つまりメソッドを宣言する場合に常に機能するとは限りません。

編集

中括弧の省略の規則は Java と同じですか?

4

10 に答える 10

21

ブラケットを省略できる唯一の場所はif-else、 、forwhile、または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(); 

そうしないでください。

于 2013-02-15T21:39:06.997 に答える
12

C構文を見ると、ステートメントを必要とするコンテキストがいくつかあります。これは、文法自体によって定義される用語です。

これらのコンテキストのいずれにおいても、使用できるステートメントの形式の1つは、開始中括弧、0個以上の宣言および/またはステートメントのシーケンス、および終了中括弧で構成される複合ステートメントです。(C90では、複合ステートメント内のすべての宣言がすべてのステートメントの前にある必要があります。C99はその制限を削除しました。){}

関数定義には、特定の種類のステートメントだけでなく、複合ステートメントが特に必要です。(これが、複合ステートメントが使用できる唯一の種類のステートメントである唯一のケースであると確信しています)。その制限がなければ、次のように書くことができます。

void say_hello(void) printf("Hello, world\n");

ただし、ほとんどの関数定義には複数の宣言やステートメントが含まれているため、それを許可してもあまり利点はありません。

別の質問があります:中かっこをいつ省略する必要がありますか。私の個人的な意見では、答えは「ほとんどありません」です。これ:

if (condition)
     statement;

完全に合法ですが、これは:

if (condition) {
    statement;
}

IMHOは読みやすく、保守も簡単です(2番目のステートメントを追加したい場合は、中括弧はすでにあります)。それは私がPerlから習得した習慣であり、そのような場合はすべて中括弧が必要です。

中かっこを省略するのは、ifステートメント全体または同様のものが1行に収まる場合のみです。そうすることで、コードが読みやすくなり、それぞれにステートメントを追加する可能性は低くなります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"); }
/* ... */
于 2013-02-15T19:59:31.680 に答える
3

例:

int a[2][2] = {{1, 2}, {3, 4}};

有効な同等の形式を使用できます。

int a[2][2] = {1, 2, 3, 4};

一部の冗長コンパイラは警告を発する場合がありますが、これは有効です。

ifステートメント ( whileforステートメント、... と同じ) の場合、{}は省略されないことに注意してください。それらは要求されていません。ステートメントのif構文は次のとおりです。

if (expression) statement

単一のステートメントではなく複数のステートメントが必要な場合は、囲まれた複合ステートメントを使用できます{}

于 2013-02-15T19:30:52.773 に答える
3

しかし、これは常にすべてのステートメントで機能するとは限りません。

具体的には?単一のステートメントが期待される場合、それは完全に有効です。ループ、ifステートメントなどはすべてステートメントを想定しており、それはブロックであるか、ブロックに囲まれていない単一のステートメントです。

于 2013-02-15T19:29:51.240 に答える
3

複数のステートメントまたは式を 1 つに結合する場合は、主に中括弧が必要です。たとえば、次のようになります。

{
  x = 1;
  y = 2;
}

したがって、上記を下に置くと、ifまたはelse中かっこ内のすべてが全体として実行されますが、中かっこを省略すると、最初のもの (x = 1;この場合)のみがiforの一部として使用され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";
于 2013-02-15T19:40:18.087 に答える
2

実行しているステートメントが 1 つしかない場合は、それらを省略できます。

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ます。したがって、中括弧をスキップできます。

于 2013-02-15T19:33:28.283 に答える
2

複数の行を持つブロックがある場合はいつでも (行を ; で 1 つのステートメントとして数えます)

例:

for (i = 0; i < j; i++ ) 
   foo(i);

while (1) 
   foo();

if( bool )
   foo();

void cheese()
   printf("CHEESE");

; の後のすべて 上記の行の は、{ } があるかのようにブロックの「内部」としてカウントされません。

于 2013-02-15T19:34:16.593 に答える
1

疑わしい場合は、ブレースを使用してください。[絶対に間違って使用しない限り]、追加の「費用」はかかりません。

かなり基本的なルールは、「同じインデントに複数のセミコロンがある場合は、中かっこを使用する必要がある」です。それはそれほど単純ではありませんが、「ifs、buts、またはその他の複雑さのない1つの文」として実行する必要があります.

そして、そうです、C 構文に基づく Java には同じ基本的なルールがあります。Java が C や C++ と異なるところに奇妙な点がいくつかある可能性がありますが、それは珍しい/奇妙なことであり、典型的なコードを書くときに通常ヒットするものではありません [I私は Java をあまりやったことがないので、それらのいずれかを見つけたとは言えませんが、いくつかの違いがあることは確かです - 結局、それらは異なる言語です].

于 2013-02-15T20:00:40.010 に答える