切换C:变量中的语句以防万一?

时间:2011-08-13 14:10:46

标签: c switch-statement compiler-construction

#include <stdio.h>
int main(int argc, char *argv[]){
    char a = 'c';
    switch('c'){
        case a:
            printf("hi\n");
    }
    return 0;
}

以上内容不会针对此错误进行编译:

case label does not reduce to an integer constant

为什么不允许这样做?

4 个答案:

答案 0 :(得分:5)

想一想,如果你有以下内容怎么办:

int a = 1, b = 1, c = 1;

switch (a)
{
case b: return 1;
case c: return 2;
}

会有什么回报?

案例标签需要保持不变,以便编译器可以证明没有歧义。

答案 1 :(得分:5)

显式允许编译器使用有效的二叉树或跳转表来评估case语句。

因此,case语句是编译时常量。

答案 2 :(得分:3)

switch语句的概念是编译器可以生成仅在运行时检查switch表达式的代码,并推断出要跳转到的位置。

如果case标签可能是非常量的表达式,则必须评估所有此类case表达式以查看是否存在匹配的表达式。因此,不必评估一个表达式,而是必须评估n个表达式,其中ncase的{​​{1}}个标签数。

switch的整个想法是以相反的方式做到这一点。将变量表达式switch放在a本身中,并将switch等常量放在案例中。

答案 3 :(得分:2)

C99标准说明了这一点(和C89标准非常相似):

  

§6.8.4.2开关语句

     

约束

     

¶1switch语句的控制表达式应为整数类型。

     

[...]

     

¶3每个case标签的表达式应该是一个整数常量表达式,而不是两个   同一switch语句中的case常量表达式应具有相同的值   转换后。在switch语句中最多可能有一个默认标签。

这是语言要求:案例标签应为整数常量表达式,单个开关中的所有案例都应是唯一的。这就是C的设计方式。它现在不太可能改变(即使改变不会破坏任何当前有效的代码,甚至改变其含义)。