[转载]精解C++的switch语句

入门书籍对switch语句的介绍相对较浅,我也因此而产生了很多想当然的误解。为解惑而写了以下一小篇精解switch语句,相信会对很多朋友有所帮助,同时顺便补充一些相关知识。

  先抛出个题目,见下程序:

//原代码出自《C语言参考手册(原书第5版)》

//为了表达我的意图,特做了部分改动

switch(x)

{

    default:

    if(prime(x))

    {

       case 2: case 3: case 5: case 7:

           process_prime(x);

    }

    else

    {

       case 4: case 6: case 8: case 9: case 10:

           process_composite(x);

    }

}

  你能说出它如何执行吗?

  switch语句的格式为:

switch(条件)语句

  其中,条件的类型可以是整数类型,枚举类型,或者类类型(但该类需要有单一的转换到整数类型或(可以是字符类型,但不能是浮点类型、字符串、指针类型等),语句部分不一定非得是一条复合语句。因此,switch("123"[2]+(int)3.1);是条合法的switch语句,switch(j)case 5:i++;也是条合法的switch语句。如果switch的语句部分是一条非复合语句,则其内定义的变量作用域,效果上等同于该条语句加上了{}。如int i=3;switch(i)int i=4;,相当于int i=3;switch(i){int i=4;},因此这并不会导致同一局部域下的重复定义错误。

 case标号后为一个整数类型的常量表达式,因此int i=3;switch(i){case 3:;}合法,而int i=3;switch(3){case i:;}不合法,因为case i:的i不是个静态表达式。如果将int i=3;换成const int i=3;则后者在C++中就合法了,但在C中仍然不合法。原因是C和C++对const的处理不同,在C中,const限定的量是不能直接去修改的,但它本身并不是常量表达式;在C++中,const限定的量,如果其值能在编译时确定,则其可出现在必须使用常量表达式之处。

  同一个switch的各个case标号的值不能够相互重复。要注意的是,case标号在实现中是有上限的:C89标准要求至少257个,这保证了ASCII被switch列举一遍。

  虽然要求case标号是常量表达式,看起来似乎不是很零活方便(比如对比VB的Select Case),但是这样的设计可以保证更高的效率,而效率则是C和C++最为看重的因素。因为case标号的值是编译时可确定的整数类型,又因为其不可有重复,因此编译器可以进行优化。

 

最后要强调的问题是,C++中goto不能从前往后跳过变量定义,因此switch内出现的变量定义语句,最好放在复合语句{}中包起来。

请看以下代码:

switch(x)

{

case 0: f0(); break;

case 1:CTest i(3); f1(); break;

default: fdef();

}

其伪代码为:

{

    if(x==0)goto case 0;

    else if(x==1)goto case 1;

    else goto default;

    {

    case 0:

       f0();goto end_of_switch;

    case 1:

       CTest i(3);

       f1();

       goto end_of_switch;

    default:

       fdef();

    end_of_switch:

       CTest::~CTest();

    }

}

当x为0或1时,不会有问题,问题是当转到default时,相当于从外层直接跳过了i的构造,然后在default自己的代码执行完毕后,还要执行i的析构。改成:

switch(x)

{

case 0: f0(); break;

case 1:{CTest i(3); f1(); break;}

default: fdef();

}

则i的作用域被限制在{}中,不会再出现未构造就析构的问题。 

 

 

 

posted @ 2010-03-22 19:36  geekemacser  阅读(5833)  评论(0)    收藏  举报