web-dev-qa-db-ja.com

セミコロンとカンマがforループで交換されるのはなぜですか?

多くの言語(CからJavaScriptまでの幅広いリスト):

  • コンマ_,_個別の引数(例:func(a, b, c))、一方
  • セミコロン_;_個別の順次命令(例:_instruction1; instruction2; instruction3_)。

それで、なぜこのマッピングが同じ言語でfor loopsに対して逆になっているのですか?

_for ( init1, init2; condition; inc1, inc2 )
{
    instruction1;
    instruction2;
}
_

の代わりに(私にとってはより自然に見えるもの)

_for ( init1; init2, condition, inc1; inc2 )
{
    instruction1;
    instruction2;
}
_

確かに、forは(通常)関数ではなく、引数(つまりinitconditionincrement)は関数の引数に似ています命令のシーケンス。

それは歴史的な理由/慣習によるものですか、それとも_,_と_;_をループで交換するための適切な根拠はありますか?

50
Piotr Migdal

したがって、同じ言語でforループのマッピングが逆になっているのはなぜですか。

技術的には、マッピングは「逆転」されません。

  • コンマで区切られたものはパラメーターではありません。 (少なくとも)C++とJavaでは、それらは宣言である可能性があるため、式でさえありません。
  • セミコロンで区切られたものも(単一の)ステートメントではありません。

実際には、ここにあるのは、同じシンボルが異なる方法で使用されている異なる構文コンテキストです。 likeとlikeを比較しているわけではないので、マッピングはなく、セマンティックの一貫性に基づく一貫したマッピングについての強力な議論もありません。

それでは、逆にしてみませんか?

理由は、,;の「自然な」意味にあると思います。英語で書かれた言語では、セミコロンはコンマより「強い」改行であり、セミコロンのグリフはコンマよりも見やすくなっています。これら2つを組み合わせると、現在の配置が(私には!)より自然に見えるようになります。

しかし、構文の選択が行われた理由を確実に知る唯一の方法は、Cの設計者が1970年頃に考えていたことを教えてくれるかどうかです。私は、彼らがそれまでさかのぼって行われた技術的な決定の明確な記憶を持っているとは思えません。


それは歴史的な理由/慣習によるものですか

"for"ループにCのような構文を使用したCの前の言語については知りません。

  • Donal Fellowsは、BCPLとBには同等の構成がなかったと述べています。

  • FORTRAN、COBOL、およびALGOL-60(およびPascal)の同等の機能は表現力が弱く、Cの「for」構文に似ていない構文がありました。

しかし、C、C++、およびJavaのようなCの後に来る言語はすべて、Cから「for」構文を明確に借りています。

18
Stephen C

次のようなループを作成します。

 for(x = 0; x < 10; x++)

ループが次のようになるように言語を定義できます。

 for(x = 0, x < 10, x++)

ただし、whileループを使用して実装された同じループについて考えてみます。

 x = 0;
 while(x < 10)
 {
     x++;
 }

x=0およびx++はセミコロンで終了するステートメントです。これらは、関数呼び出しで使用するような式ではありません。セミコロンはステートメントを区切るために使用され、forループの3つの要素のうち2つはステートメントであるため、そこで使用されます。 forループは、そのようなwhileループの単なるショートカットです。

さらに、引数は実際には関数の引数のようには機能しません。 2番目と3番目は繰り返し評価されます。シーケンスではないのは事実ですが、関数の引数でもありません。

また、コンマを使用してforループで複数のステートメントを使用できるという事実は、実際にはforループの外で実行できるものです。

x = 0, y= 3;

forループの外でも完全に有効なステートメントです。 forループ以外での実用的な使い方は知りません。しかし重要なのは、コンマは常にステートメントを細分するということです。これはforループの特別な機能ではありません。

60
Winston Ewert

CおよびC++では、これは単なるコンマではなく、コンマ演算子です。

forループの文法は次のようなものです

for ([pre-expression]; [terminate-condition]; [increment-expression]) body-expression

あなたの質問の場合:

pre-expression -> init1, init2
terminate-condition -> condition
increment-expression -> inc1, inc2

コンマ演算子を使用すると、1つのステートメントで複数のアクションを実行できます(コンパイラーがそれを認識するため)。提案が実装された場合、プログラマーがコンマ演算子ステートメントまたは区切り文字をいつ記述したかに関して、文法に曖昧さが存在します。

つまり、;はステートメントの終わりを意味します。 forループは、()で囲まれたオプションのステートメントのリストが続くキーワードです。コンマ演算子ステートメントでは、単一のステートメントで,を使用できます。

15
James

概念的な逆転はありません。

Cのセミコロンは、コンマよりも主要な区分を表します。ステートメントと宣言を分離します。

Forループの主な分割は、3つの式(または宣言と2つの式)と本体があることです。

Cのforループに表示されるコンマは、特にforループの構文の一部ではありません。これらは、カンマ演算子の単なる現れです。

コンマは、関数呼び出しの引数と関数宣言のパラメーターの間の主要な区切り文字ですが、セミコロンは使用されません。 forループは特別な構文です。関数や関数呼び出しとは関係ありません。

8
Kaz

おそらくこれはC/C++に固有のことかもしれませんが、私がこの回答を投稿しました。あなたが説明した言語の構文は、主にC-Syntaxに影響されているからです。

以前に回答された質問に加えて、技術的な観点からも当てはまります。これは、C(およびC++)ではコンマが実際には operator であるため、- overload 。セミコロンは公理式のターミネータであるため、セミコロン演算子(operator;())を使用すると、コンパイラの記述が難しくなる可能性があります。

これが興味深いのは、コンマが言語全体でseperatorとして広く使用されているという事実です。コンマ演算子は例外のようです。これは主に、複数の条件が機能するfor- loopsを機能させるために使用されるので、何が問題ですか?

実際、operator,は、定義、引数リストなどと同じことを行うように構築されています。これは、seperate式に構築されています-構文構成要素,できません。標準で定義されているものだけを分離できます。

ただし、セミコロンは分離されません-セミコロンで終了します。そして、これは私たちを元の質問に戻すものでもあります:

for (int a = 0, float b = 0.0f; a < 100 && b < 100.0f; a++, b += 1.0f)
    printf("%d: %f", a, b);

カンマは3つのループ部分の式を区切りますが、セミコロンはループ定義の一部(初期化、条件、後付け)を終了します。

新しいプログラミング言語(C#など)では、コンマ演算子のオーバーロードが許可されていない場合がありますが、構文の変更は不自然に感じられるため、構文を保持している可能性があります。

2
Aschratt

私にとっては、言語的意味とはあまり似ていません。カンマは、リストとセミコロンとともに使用され、パーツがさらに分離されます。

func(a, b, c)には、引数のリストがあります。

_instruction1; instruction2; instruction3_はおそらくリストですが、個別の独立した命令のリストです。

for ( init1, init2; condition; inc1, inc2 )では、3つの部分に分かれています-初期化のリスト、条件、およびインクリメント式のリストです。

0
ludwika

それを確認する最も簡単な方法は次のとおりです。

for(x = 0; x < 10; x++)

です:

for(
x = 0;
x < 10;
x++
)

言い換えると、これらのx = 0は、実際にはパラメーターではなくステートメント/命令です。そこにステートメントを挿入します。したがって、セミコロンで区切られます。

実際、カンマで区切る方法はありません。最後にx <10のようなものをパラメーターとして挿入するのはいつですか? x <10を1回コンピューター化し、その操作の結果をパラメーターとして挿入する場合は、これを行います。したがって、コンマの世界では、x <0の値を関数に渡したい場合、x <10を指定します。

ここでは、ループを通過するたびにプログラムがx <10をチェックするように指定します。だからそれは指示です。

x ++は間違いなく別の指示です。

これらはすべて指示です。したがって、セミコロンで区切られています。

0
user4951