切换C:变量中的语句以防万一?
#include 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
为什么不允许这样做?
想一想,如果你有以下内容怎么办:
int a = 1, b = 1, c = 1; switch (a) { case b: return 1; case c: return 2; }
会有什么回报?
案例标签需要是常量,以便编译器可以certificate没有歧义。
显式允许编译器使用有效的二叉树或跳转表来评估case语句。
因此,case语句是编译时常量。
switch
语句的想法是编译器可以生成仅在运行时检查switch
表达式的代码,并通过它推断跳转到的位置。
如果case
标签可能是非常量的表达式,则必须评估所有这样的case
表达式以查看是否存在匹配的表达式。 因此,不是评估一个表达式,而是必须评估n
表达式,其中n
是该switch
的case
标签数。
转换的整个想法是以相反的方式做到这一点。 将变量表达式a
放在switch
本身中,并在表壳中放置诸如'c'
常量。
C99标准说明了这一点(和C89标准非常相似):
§6.8.4.2开关语句
约束
¶1switch语句的控制表达式应具有整数类型。
[…]
¶3每个case标签的表达式应该是一个整型常量表达式,并且同一switch语句中的两个case常量表达式在转换后不应具有相同的值。 switch语句中最多可能有一个默认标签。
这是语言要求:案例标签应为整数常量表达式,单个开关中的所有案例都应是唯一的。 这就是C的设计方式。 它现在不太可能改变(即使改变不会破坏任何当前有效的代码,甚至改变其含义)。