【问题标题】:Why is "switch-case" considering a #define'd identifier as constant but not a const-qualified variable?为什么“switch-case”将#define'd标识符视为常量而不是const限定变量?
【发布时间】:2013-04-20 14:39:48
【问题描述】:

此程序产生以下错误:

case 标签不会缩减为整数常量|

我根本无法理解为什么显式声明的常量third_cond,分配的初始化程序3,也在函数体内,不被视为case 3的常量,而#define的标识符second_value同时被认为是一个常量。如果我使用文字 3 而不是 third_cond 或简单地将 #define third_cond 用作 3,则程序可以正常工作。请解释为什么会这样,除非这个问题是重复的。我查了,但没有找到答案。

#include<stdio.h>
#define second_cond 2

int main()
{
   const int third_cond=3;
   int choice;
   printf("Enter your choice\n");
   scanf("%d",&choice);

   switch(choice)
   {
       case 1:
       printf("Beggar");
       break;
       case second_cond:
       printf("Mugger");
       break;
       case third_cond:
       printf("Lugger");
       break;
       default:
       printf("Bugger");
   }
}

【问题讨论】:

  • 您似乎正在努力掌握所有基础知识,这非常好。潜伏的好地方是comp.lang.c。我从那些家伙那里学到了很多东西(他们中的大多数也在这里)。
  • @luserdroog 既然你已经明确建议了,我会检查一下。希望它适用于像我这样的普通学习者,而不是编程高手。
  • 就像 SO,它适用于两者。但是 usenet 是一种不同的格式。它更像是一个巨大的电子邮件列表。没有节制。尽管常客们努力保持话题。 (有一个单独的主持小组,但活跃度要低得多。)但是您不必成为王牌也能享受观看王牌辩论的乐趣。
  • @luserdroog 我确实在努力理解基础知识,因为我在编程方面不是那么好。但我很惊讶你是如何注意到这一点的。是什么让你得出结论?我相信你没有从我的一个问题中得出结论。你以前认识我吗,因为我在其他地方也使用了这个别名,而且早在我加入 SO 之前。(对于绝对的初学者来说,SO 老实说有点令人生畏!)
  • 不能代表 luser droog,但并不难注意到。当您不了解问题的某些细节时,您经常在 cmets 中要求对其他人的答案进行进一步解释。一旦您多次看到特定用户名,您就会认出它(如果它不是类似 user123654 的名称)。保持好奇,你会比你预期的更快被认为是专家。

标签: c switch-statement constants c-preprocessor


【解决方案1】:

常量实际上是一个值:"string constant", 1L, 0.5, 0xAF, ...

您可以使用enum 定义自己的常量:

enum
{
    MY_CONSTANT_1,
    MY_CONSTANT_2,
    /* ... */
}

switch-case 等待可以转换为 int 的常量(因此,enumintlong、...)。

#define 声明一个宏,因此在编译时,second_cond 被替换为 2,这是一个常量。

但是third_cond 仍然是一个变量,一个只读变量(因为const),因此,不能保证它的值保持不变(即使存在const,它只标记标识符是只读的,而不是相关的内存)。

【讨论】:

  • 挑剔:“A #define 声明一个宏,因此在编译时,second_cond 被替换为 2 ...”应为:“.. . 所以在编译时, second_cond 已经被替换为 2 被预处理器 ..."
  • @alk:尽管名称为“预处理”,但按照 C 标准的定义,宏扩展是 C 源代码转换为可执行程序的一部分,而不是之前发生的事情翻译开始。这是八个翻译阶段的第四阶段。
【解决方案2】:

在 C 中,const 不是常量而是只读的。 const 限定变量绝不是常量,不能在需要常量表达式的地方使用。

请注意,您也可以将enum 常量用于case 常量表达式,因为enum 常量是实数常量。

【讨论】:

  • 我从来不知道enum 变量是常量,这句话听起来很矛盾!!
  • 所以枚举变量是常量嗯?我的陈述的正确表达方式是什么?枚举 variables are constants 听起来很奇怪。
  • 不,enum 变量不是常量。但是enum 成员是常量。
  • 谢谢。没想到。
  • @SheerFish 这在这个问题中是题外话,但是是的,C 中没有全局变量,唯一的原因是没有全局范围。 C 中有文件作用域变量,这是人们在谈论全局变量时通常所指的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-05
  • 2016-03-25
  • 2019-08-27
  • 1970-01-01
相关资源
最近更新 更多