118

この問題に対するいくつかの回答を見ましたが、わかりました — 内で変数を宣言して代入することはできませんswitch。しかし、エラーをスローする際に次のことが正しいかどうか疑問に思っています

エラー: 'int' の前に式が必要です

コード:

switch (i) {
    case 0:
        int j = 1;
        break;
}

を呼び出すNSLog()前にエラーが発生しないのはなぜですか?

switch (i) {
    case 0:
        NSLog(@"wtf");
        int j = 1;
        break;
}
4

3 に答える 3

146

言語の構文に従って行うと、実際にスイッチ内で変数を宣言できます。" " はラベルであるため、エラーが発生します。C では、ラベルの後の最初のステートメントとして宣言case 0:を行うことは違法です — コンパイラは、メソッド呼び出し、通常の代入などのを想定していることに注意してください(奇妙かもしれませんが、それがルールです。)

NSLog() を最初に配置すると、この制限が回避されます。ケースの内容を { } 中かっこで囲んでスコープ ブロックを導入するか、変数宣言をスイッチの外に移動することができます。どちらを選択するかは、個人の好みの問題です。{ } 中かっこで宣言された変数はそのスコープ内でのみ有効であるため、それを使用する他のコードもこれらの中かっこ内に表示する必要があることに注意してください。


編集:

ところで、この癖はあなたが思っているほど珍しいものではありません。C および Java では、 forwhile、またはdoループ、さらにはifおよびelse句で、ローカル変数宣言を単独のステートメント (「中かっこで囲まれていない」という意味) として使用することも違法です (実際、これは「Java Puzzlers」のパズラー #55 で取り上げられているので、これを強くお勧めします。) 私は、変数をそのようなコンテキストで唯一のステートメントとして宣言することはほとんど意味がないので、一般的に、最初からそのようなエラーを記述しないと思います。ただし、 case構文では、改行以降、中括弧を省略する人もいます。statement は、制御フローの重要なステートメントです。

コンパイラが適合することを確認するには、この恐ろしい、無意味なスニペットを (Objective-)C コードにコピーします。

if (1)
    int i;
else
    int i;
for (int answer = 1; answer <= 42; answer ++)
    int i;
while (1)
    int i;
do
    int i;
while (1);

そのような構成体の本体を区切るために { } 中かっこを常に使用するもう 1 つの理由があります。:-)

于 2009-08-05T04:37:15.970 に答える
49

以前にこの問題に遭遇したことがありますが、結論は、コードをブロック内に配置しただけでした。

switch (i) {
case 0:
    {
        int j = 1;
        break;
    }
}
于 2009-08-05T04:38:05.003 に答える
4

私が使用するもう1つの簡単な回避策は、宣言の前に空の式(セミコロン)を追加することです。これにより、変数スコープをコードブロックに制限することを回避できます(または、コードブロックを含むケースステートメントとコードブロックを含まないケースステートメントがあります)。

switch (i) {
    case 0:;
        int j = 1;
        break;
}
于 2013-01-12T20:01:55.917 に答える