5

私は高レベルの OOP 言語である C# と Java を使用しており、最近 C で頭を悩ませ始めました。C は、JS と同じように少し奇妙に感じます。したがって、以下を明確にしたい:

以下にエラーが表示されますが、OOP 言語でも構文が正しくないように見えるため、直感的に見えます。

int i=0,1,2;  

/*
Error : expected identifier or ‘(’ before numeric constant
 int i = 0, 1, 2;
            ^
*/

ただし、以下は驚くほど機能します。

int i;
i = 0,1,2;    //works

この動作はなぜですか?そのような動作を維持することは重要ですか、それとも単にいくつかの解析技術ですか?

4

3 に答える 3

7

これは、複雑な C 文法の詳細に依存しているため、実際にはトリッキーな質問です。それを理解するための最良の情報源はドラフト標準です。Annex A 言語構文の概要を参照として使用できます。

基本的な考え方は次のとおりです。

int i=0,1,2; 

は宣言であり、次のとおりです。

i = 0,1,2; 

は表現です。

式では、左辺を評価し (通常は副作用の場合)、結果を破棄してから右辺を評価するコンマ演算子を使用できます。

宣言では、カンマはカンマ演算子ではなく文法上の区切り記号です。,分離宣言子 および since1および2は、宣言のコンテキストでは宣言子ではありません。これは構文が正しくありません。

 int i=0,1,2;
        ^^^^

C99 標準の関連する文法は次のとおりです。

init-declarator-list:
    init-declarator
    init-declarator-list , init-declarator   <--- here comma is just a seperator
init-declarator:
    declarator
    declarator = initializer

したがって、この場合、宣言子または宣言子 = 初期化子のいずれかである可能性のある,分離されたinit-declaratorは、宣言子でも宣言子でもないため、構文が正しくありません。12

初期化子が代入式になる可能性があることは何の価値もありませんが、このは裸のコンマ演算子()のパスを提供しません。セパレーター。

セクションの関連する文法6.5.17は次のとおりです。

expression:
    assignment-expression
    expression , assignment-expression

コンマ演算子の説明は次のとおりです。

コンマ演算子の左側のオペランドは void 式として評価されます。その評価の後にシーケンス ポイントがあります。次に、右側のオペランドが評価されます。結果には型と値があります。[...]

次の式では、コンマ演算子の優先順位が最も低いことに注意してください。

i = 0,1,2; 

次と同等です。

(i = 0),1,2; 

iの値が取得され、それ0以降の評価の結果は破棄されます。

于 2014-10-22T12:01:05.073 に答える
0

1.

  int i, j;
  i = 3,0,1,2;
  printf("%d\n", i); => prints 3

2.

  i = 3,j =7;
  printf("%d, %d\n", i, j); => prints 3 and 7

i = 3,0,1,2;これは割り当て3 to iてから実行し0, 1 and 2ます。私が言及した2番目の例を確認してください。

また、Try i=3;0;1;2;This はエラーを報告しません。実行するだけ(i=3), (0), (1) and (2)です。

于 2014-10-22T11:00:08.377 に答える