枚举可以用C中的consts替换吗?

时间:2016-03-18 18:50:50

标签: c enums

在C中,即使以下代码也会出错(因为orange):

enum color {yellow, blue, green, red, brown, black, white, purple, orange};
enum fruit {cherry, apple, pear, melon, banana, strawberry, raspberry, orange};

但是像这样的代码:

enum fruit {cherry = 1, apple = 2, pear = 3, melon = 4, banana = 5, strawberry = 6, raspberry = 7, orange = 8};

int main(int argc, char *argv[]){
  enum fruit f;
  int x;

  x = apple;
  f = -7;

  return 0;
}

使用gcc --std=c89 -pedantic进行编译。

似乎enum可以很容易地被const变量取代:

typedef int fruit;
const fruit cherry = 1, apple = 2, pear = 3, melon = 4, banana = 5, strawberry = 6, raspberry = 7, orange = 8;

int main(int argc, char *argv[]){
  fruit f;
  int x;

  x = apple;
  f = -7;

  return 0;
}

方式enum的行为方式不同,因为使用{{1}时绝对无法更改cherry, apple, ...的值我可以尝试像const这样的常用技巧(int *y = &apple; *y = -7;我收到警告,但它会编译)。

这是唯一的区别还是我错过了什么?

2 个答案:

答案 0 :(得分:4)

enum常量与const之间存在若干显着差异 - 合格对象。

enum类型声明,例如

enum fruit {cherry, apple, pear};

自动将以0开头的连续值与常量cherryapplepear相关联。 (如果您愿意,可以覆盖这些值。)这意味着(a)您可以根据需要重新排列常量,编译器将处理这些值,(b)不小心使用不正确的值的风险较小。

另类如:

const int cherry = 0;
const int apple = 1;
const int pear = 2;

更难维护 - 也许最重要的是,名称cherry et al 不是常量表达式。这意味着,例如,您不能在案例标签或需要常量表达的任何其他上下文中使用它们。

至于更改const限定对象的值,直接执行此操作是约束违规,需要编译时诊断。 (默认情况下,gcc倾向于进行此类诊断非致命警告。)您可以尝试间接更改它,例如,通过使用指针强制转换,但具有未定义的行为。

有关C enum类型的一件事要记住,常量类型为int不是枚举类型。通常这无关紧要,因为在大多数情况下,该值将隐式转换为正确的类型。 (C ++有不同的规则,但问题是关于C.)

答案 1 :(得分:0)

enum通常用作您在示例中提到的逻辑变量,例如colorfruit您并不真正关心每个变量的实际数值元素,而不是它代表什么。

另一方面,

const通常在您真正关心数值时使用。例如:

const float PI = 3.1415926;

至于你的问题,答案是肯定的,enum可以用const值代替,但问题是它是否有真正的用例