在C语言中的switch语句:case中可以使用变量吗?

8
#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

为什么这不被允许?

1
我认为你只能在switch语句中使用常量 - 参见http://www.cprogramming.com/tutorial/c/lesson5.html,第二个例子。 - Jonathon
2
@Jonny:我相信他已经知道了。他在问为什么C语言只允许常量? - Peter Alexander
4个回答

6
编译器可以明确地使用高效的二叉树或跳转表来评估 case 语句。因此,case 语句是编译时常量。

5

想象一下,如果你拥有以下内容:

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

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

它会返回什么?

案例标签需要是常量,这样编译器才能证明没有歧义。


C语言的“设计原则”是“我不会使用任何模糊不清的运行时花哨东西” ;) - Delan Azabani
@Delan Azabani,是的,但是这背后的原理是什么? - Je Rog
@Je Rog:这样做可以解决歧义,但是(至少在我看来)会令人相当困惑。 - Peter Alexander
实际上我有一系列这样的疑问,我认为Knuth肯定在权衡某些东西(在这种情况下,允许case使用变量甚至不会带来性能问题),所以我想了解设计原则。 - Je Rog
抱歉,那就把Knuth替换成C的设计者吧 :) - Je Rog
显示剩余3条评论

3
switch语句的思想是编译器只在运行时检查switch表达式,并通过此推断要跳转的位置。如果case标签可以是非常量表达式,则必须评估所有这些case表达式以查看是否有一个匹配。因此,它不仅需要评估一个表达式,还需要评估n个表达式,其中n是该switchcase标签的数量。整个switch的思想与您的方法相反。将变化的表达式a放入switch本身中,并将常量(例如'c')放入case中。

2
C99标准(C89标准也非常相似)如下所述:
§6.8.4.2 switch语句
约束
1. switch语句的控制表达式应具有整数类型。
[...]
3. 每个case标签的表达式都必须是整数常量表达式,并且在同一个switch语句中的任意两个case常量表达式在转换后的值都不能相同。一个switch语句中最多只能有一个default标签。
这是语言要求:case标签应为整数常量表达式,并且单个switch中的所有case应该是唯一的。 这就是C语言的设计方式。即使更改不会破坏当前有效的代码,甚至不会改变其含义,现在也很难发生变化。

1
我认为这个问题的意思是“为什么C语言被设计成那样?” - Karl Knechtel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接