ステートメントの後にセミコロンが必要であることは知っていますが(Java、C ++、および同様の言語について話しています)、角かっこの後には必要ありません。なぜそうなのか?
if (a > b)
printf("hello!"); // semicolon is mandatory
if (a > b) {
printf("hello!");
} // semicolon is not required
理由は何ですか?つまり、この背後にある理論は何ですか?
ステートメントの後にセミコロンが必要であることは知っていますが(Java、C ++、および同様の言語について話しています)、角かっこの後には必要ありません。なぜそうなのか?
if (a > b)
printf("hello!"); // semicolon is mandatory
if (a > b) {
printf("hello!");
} // semicolon is not required
理由は何ですか?つまり、この背後にある理論は何ですか?
中括弧はステートメントのグループ化に使用されますが、ステートメント自体ではないためです。
言語は次のように定義されているためです。
statement:
labeled-statement
expression-statement
compound-statement
selection-statement
iteration-statement
jump-statement
declaration-statement
try-block
labeled-statement:
identifier : statement
case constant-expression : statement
default : statement
expression-statement:
expressionopt ;
compound-statement:
{ statement-seqopt }
statement-seq:
statement
statement-seq statement
selection-statement:
if ( condition ) statement
if ( condition ) statement else statement
switch ( condition ) statement
condition:
expression
type-specifier-seq declarator = assignment-expression
iteration-statement:
while ( condition ) statement
do statement while ( expression ) ;
for ( for-init-statement conditionopt ; expressionopt ) statement
for-init-statement:
expression-statement
simple-declaration
jump-statement:
break ;
continue ;
return expressionopt ;
goto identifier ;
declaration-statement:
block-declaration
すべての通常の制御ステートメントは、互いに再帰的に作成されます。実際の作業は によって行われますexpression-statement
。expression-statement
が常に で終了していることに気付いた場合;
。注目すべき他のステートメントはjump-statement
.
easy
しかし、主な理由は、ステートメントの解析を可能にするために {} ブロックの後に必要ではないということです。
哲学的な推論はさておき、内部的には、コンパイラが各コマンドを次のコマンドから分離する場所を知っていることが不可欠です。角かっこはそれ自体が区切り文字であるため、セミコロンは不要です。
ほとんどの人は、ステートメントを単純なコマンドであり、多くの場合キーワードと、「goto x」、「a = y + 2」などのいくつかのパラメーターであると考えています。あるステートメントがどこで終わり、別のステートメントがどこで終わるかを示す必要があります。英語の文がピリオドで終わる必要があるのと同じように、始まります。伝統的に、ほとんどの言語の文法は、そのような表示のようなステートメントの後にセミコロンを必要とします。
{...}「中括弧ペア」はブロックであり、特別な種類のステートメントですが、中括弧によって境界が明確になるため、セミコロンは必要ありません。
多くの言語でも「;」が許可されています それ自体で、空のステートメントを表します。なぜ必要なのですか?同じ理由で、自然数システムは「1」ではなく「0」を必要とし、セットは空にすることができます。
しかし、それはあなたが書くことができることを意味します:
{ ... } ;
そして、ほとんどの言語コンパイラは、コメントなしでそれを受け入れます。しかし、あなたはそれを次のように考える必要があります:
{ ... }
;
そして一般的にそれを書く正当な理由はありません。
実際問題として、{}を受け入れる言語 (たとえば、「空の角かっこ」)は空のステートメントを必要としません。、これらは意味的に同一であるため。しかし、言語デザイナーは伝統に固執しているようです。すべての「現代」言語がCの悪い構文コピーであるように見えることに気づきましたか?
これは公正な質問です。ブロックはステートメントです。統一性を求めるのは自然なことであり、すべてのステートメントが同じように終了しないのはなぜだろうかと思います。;
ブロックの後に必要な場合、技術的な問題はありません。しかし}
、ステートメントの終わりを明確にマークできるため、別のマーカーを入力する必要がないため、怠け者でもあります。
関連する観察: C++ では、クラス宣言を終了する必要があります。;
class A
{
...
}; // the semicolon is mandatory!
それは多くの人を悩ませています。言語は後に他のものを許可するため、セミコロンが必要です。その}
ため}
、信頼できるエンド マーカーではありません。
Java では、そうではありません。}
クラス宣言を終了し、それだけです。だから;
必要ありません。
セミコロンを入れるのはと同じ効果です
if (a > b) {
printf("hello!");
}printf("Goodbye");
パーツを省きprintf("Goodbye")
ます。
C#3以降でオブジェクト初期化構文を使用している場合は、角かっこの後にセミコロンが続きます
var foo = new Foo
{
Bar = "Fizzbuzz"
};
この場合、中括弧はステートメントのブロックを定義しています。他のブロックと同じように。配列を宣言して初期化しようとしているときに、;を指定する必要があります。この場合、ステートメントを書いているからです。
注 : この回答は、Java ではなく C++ 言語に固有のものです。
セミコロンは言語文法 (2003) では必要ないと思います。これは、言語が文法を定義する方法です。
あなたが書いたコードは複合ステートメントまたはブロックと呼ばれ、言語仕様 (2003) ではセクション §6.3/1 で複合ステートメントの文法が次のように定義されています。
必要な場所で複数のステートメントを使用できるように、複合ステートメント (「ブロック」とも呼ばれます) が用意されています。
複合ステートメント: { ステートメント シーケンスオプション} ステートメント シーケンス: 声明 ステートメント シーケンス ステートメント
上記の文法にセミコロンがありますか? いいえ。これが、コード内の中括弧の後にセミコロンが必要ない理由です。
右中括弧の後にセミコロンが必要になる唯一の場所は、行を続けることができるため、配列の初期化の後です。
int[] i= { 1,2,3}, j= {1};
ここの '}' はコンパイラに行末がどこにあるかを伝えないため、セミコロンが必要です。
同様に
Runnable r = new Runnable() {
public void run() {
}
}, r2 = new Runnable() {
public void run() {
}
}; // required as you could define another Runnable or an array of Runnable.
中括弧を使用してコードのブロックを囲む場合、セミコロンは必要ありません。
namespace Some
{
void fun(int i)
{
while(i != 0)
{
cout<<"i = "<<i<<endl;
i --;
} // semicolon not needed
} // semicolon not needed
} // semicolon not needed
その他の場合(初期化、宣言など)はセミコロンが必要です。
struct A {
// ... declare members
}; // declaration; put semicolon
int a[] = {0, 1, 2}; // initialization; put semicolon
curlyはステートメントではないため、ステートメントをグループ化するために使用されます。ターミネータは必要ありません。