22

私の知る限り、「if」ブロックに中括弧が指定されていない場合、その内部では1つのステートメントのみが考慮されます。例えば

if(..)
  statement_1;
  statement_2;

タブに関係なく、ブロックstatement_1内のみが考慮されます。if

次のコードはそれとうまくいきません:

int main ()
{
  if(false)  // outer - if
    if(false)  // nested - if
      cout << "false false\n";
  else if(true)
    cout << "true\n";
}

上記のコードは何も出力しません。印刷されているはず"true"です。外側のブロック内に自動的にネストされている
ように表示されます。警告を発行しますが、それはここでは問題ではありません。中括弧を配置すると、すべてが期待どおりにうまくいきます。else if ifg++ -Wall

なぜそのような異なる動作ですか?
[GCC デモ:中括弧なしと中括弧あり]。

4

5 に答える 5

58
于 2012-07-31T06:51:14.177 に答える
6

elseは実際には外側ではなく内側 とグループ化されているためifです。実際には次のように解析されています

int main ()
{
  if(false)  // outer - if (never gets executed)
  { 
    if(false)  // nested - if
    {
        cout << "false false\n";
    } else if(true) {
        cout << "true\n";
    }
  }
}

中括弧を必要な場所に明示的に配置することで、問題を解決できます。

于 2012-07-31T06:52:17.970 に答える
2

これは、C パーサーの観点からはごく自然なことです。

パーサーは、if ステートメントの解析中に、最初に条件式を解析し、次に条件の後の最初のステートメントを解析し、次にelseキーワードを探し、 elseが存在する場合は 2 番目の (代替) ステートメントを解析します。

ただし、最初のステートメントも if ステートメントであるため、パーサーは「if パーサー」を再帰的に呼び出します ( elseキーワードをテストする前に!)。この再帰呼び出しは、内側の if-else ステートメントを完全に ( elseを含めて) 解析し、トークンの位置をコード フラグメント全体の「末尾を過ぎて」移動します。

代替の動作を実装しようとする場合は、「外部」と「内部」の if-parser 間の通信を追加する必要があります。外部パーサーは「内部」に貪欲にならないように (つまり、elseステートメントを食べないように) 通知する必要があります。これにより、言語構文がさらに複雑になります。

于 2012-07-31T08:03:13.283 に答える
2

何も印刷されるべきではありません。2 番目の if/else if は最初の if に属する 1 つのブロックであるため、これと同等です。

  if(false) {
    if(false)  // nested - if
      cout << "false false\n";
    else if(true)
      cout << "true\n";
  } 
于 2012-07-31T06:51:30.317 に答える
1

elseステートメントは常に Nearest にアタッチしifます。ブランチがネストされifていないこと自体は意味のあるステートメントを形成しないため、パーサーは続行します。

于 2012-07-31T06:56:36.533 に答える