关于switch语句:谁能解释一下这个C程序的输出?

Can anyone explain the output of this C program?

本问题已经有最佳答案,请猛点这里访问。

Possible Duplicate:
Why can't variables be declared in a switch statement?
How can a variable be used when its definition is bypassed?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include<stdio.h>
  int main()
  {
      int a=1;
      switch(a)
      {   int b=20;
          case 1: printf("b is %d
"
,b);
                  break;
          default:printf("%d
"
,b);
                  break;
      }
      return 0;
  }

在GCC 4.6.3上运行,输出不是20。这是怎么回事?


switch语句中变量的初始化是不好的实践和未定义的行为。


switch语句具有以下结构:

1
2
3
4
5
6
7
8
9
10
11
switch ( expression ){

    // declarations

   case constant-expression :
      ...
   case constant-expression :
      ...
   default :
      ...
}

declarations部分在编译时用于声明变量,但在运行时不用于初始化变量(实际上该部分中没有执行任何语句)。不是声明和初始化变量的区别。由于b从未初始化,您的代码的结果与以下结果相同:

1
2
3
4
5
6
7
int main(){
    int b;
    printf("b is %d
"
, b);

    return 0;
}

这显然是未定义的。使用-Wall标志编译将捕获您使用的是未初始化的值。


如果打开编译器警告,您将看到:

1
warning: ‘b’ may be used uninitialized in this function

这不是初始化b的有效位置,因此它在打印时包含未初始化的数据,而不是20。你的行为不明确。


根据switch变量的值,switch语句对相应的case语句执行goto,而不执行其他操作。现在您绕过了EDOCX1的初始化过程(0),所以它将打印出当时在该位置内存中的内容。


这是一个VaR范围问题。如果你移动

1
int b=20;

在开关组外,它可以工作。