【问题标题】:Switch statements in C: variable in case?C中的switch语句:变量以防万一?
【发布时间】:2011-08-13 14:10:45
【问题描述】:
#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

为什么不允许这样做?

【问题讨论】:

  • 我认为您只能在 switch 中使用常量 - 请参阅 cprogramming.com/tutorial/c/lesson5.html,第二个示例。
  • @Jonny:我相信他知道这一点。他在问为什么会这样——为什么 C 语言被设计为只允许常量?

标签: c switch-statement compiler-construction


【解决方案1】:

明确允许编译器使用高效的二叉树或跳转表来评估 case 语句。

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

【讨论】:

    【解决方案2】:

    想一想,如果你有以下情况会怎样:

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

    它会返回什么?

    case 标签需要保持不变,这样编译器才能证明没有歧义。

    【讨论】:

    • C 的“设计原则”是“我不会有那些空洞的运行时绒毛”;)
    • b等于c也无妨,先到先得。
    • @Delan Azabani,是的,但原因是什么?
    • @Je Rog:这将解决歧义,但(至少在我看来)这会很混乱。
    • 实际上我有一系列这样的疑问,我认为 Knuth 必须权衡一些东西(在这种特定情况下,允许 case 的变量甚至不会带来性能问题 IMO),所以我想了解设计原理。
    【解决方案3】:

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

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

    switch 的整个想法是与您的做法相反。将可变表达式a 放在switch 本身中,并将诸如'c' 之类的常量放在case 中。

    【讨论】:

      【解决方案4】:

      C99 标准是这么说的(C89 标准非常相似):

      §6.8.4.2 switch 语句

      约束

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

      [...]

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

      这就是语言要求:case 标签应该是整数常量表达式,并且单个 switch 中的所有 case 都应该是唯一的。这就是 C 的设计方式。现在更改的可能性很小(即使更改不会破坏任何当前有效的代码,甚至不会改变其含义)。

      【讨论】:

      • 我认为这个问题的意思是“为什么 C 是这样设计的?”。
      猜你喜欢
      • 1970-01-01
      • 2011-12-19
      • 2011-02-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-02
      • 1970-01-01
      • 1970-01-01
      • 2010-11-10
      相关资源
      最近更新 更多