0

C Puzzlesでこのコードを見つけました:

#include<stdio.h>
 
int main()
{
  int a=1;
  switch(a)
  {   int b=20;
      case 1: printf("b is %d\n",b);
              break;
      default:printf("b is %d\n",b);
              break;
  }
  return 0;
}

出力:

b is 51

この出力を理解できないようです。

4

4 に答える 4

13

変数の初期化をスキップして、不確定な値を持つ変数を使用しています (未定義の動作を呼び出しますb) 。プログラムは任意の値を生成でき、それは正しいものになります。

C 標準では、このケースもカバーしています (非規範的な例)。

ISO/IEC 9899:2011 §6.8.4.2switchステートメント:

7 例 人工的なプログラム断片

switch (expr)
{
        int i = 4;
        f(i);
    case 0:
        i = 17;
        /* falls through into default code */
    default:
        printf("%d\n", i);
}

識別子がi自動保存期間 (ブロック内) で存在するが、初期化されていないオブジェクト。したがって、制御式にゼロ以外の値がある場合、printf 関数の呼び出しは不定値にアクセスします。同様に、関数の呼び出しにf到達できません。

「不定値」コメントに注意してください。


不確定な値へのアクセスが未定義の動作につながるかどうかについては、議論の余地があります。状況によっては (トラップ表現)、未定義の動作につながる可能性があります。「おそらく未定義の動作」を「未定義の動作」と見なすべきかどうかを判断するには、しばらく時間がかかります。初期化されていない変数にアクセスすることは悪い考えであり、コードに出力される値については何も言えません。

于 2013-07-19T14:50:18.680 に答える
2

やのように内部switch statementには何も受け入れられません。b 値が必要な場合は、スイッチの外側に割り当てます。また、b値は、特定の場所に値を割り当てるまで変更できないガベージ値のようにする必要があります。assigning values to the variableprinting except inside case

于 2013-07-19T15:07:58.580 に答える
2
#include<stdio.h>
int main()
{
    int a = 1;
    switch(a) {   
        int b=20;
        printf("This gets called!\n");
        case 1: 
                printf("b is %d\n",b);
                break;
        default:
                printf("b is %d\n",b);
                break;
    }
    return 0;
}

ここで重要なのは、int b=20;呼び出されないことです。コンパイラは変数を作成しますbが、初期化されません。

于 2013-07-19T14:58:08.577 に答える