C中的枚举是否可以替换为常量?
在C语言中,即使下面的代码也会给出一个错误(因为C中的枚举是否可以替换为常量?,c,enums,C,Enums,在C语言中,即使下面的代码也会给出一个错误(因为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; }
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
s可以很容易地替换为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
方式是,您绝对不能更改cherry,apple,
的值,而使用const
s时,您可以尝试像int*y=&apple*y=-7代码>(使用gcc
我得到一个警告,但它可以编译)
这是唯一的区别还是我遗漏了什么?在enum
常量和const
限定对象之间有几个显著的区别
enum
类型声明,例如
enum fruit {cherry, apple, pear};
自动将从0
开始的顺序值与常量cherry
、apple
和pear
关联。(如果愿意,可以重写这些值。)这意味着(a)可以根据需要重新排列常量,编译器将处理这些值,并且(b)意外使用错误值的风险较小
替代方案,例如:
const int cherry = 0;
const int apple = 1;
const int pear = 2;
更难维护——也许最重要的是,名称cherry
等不是常量表达式。例如,这意味着您不能在大小写标签或任何其他需要常量表达式的上下文中使用它们
至于更改const
限定对象的值,直接这样做是违反约束的,需要编译时诊断。(默认情况下,gcc倾向于将此类诊断设置为非致命警告。)您可以尝试间接更改它,例如,使用指针强制转换,但其行为未定义
关于C的enum
类型,需要记住的一件事是常量的类型是int
,而不是枚举类型。通常这并不重要,因为在大多数上下文中,值将隐式转换为正确的类型。(C++有不同的规则,但问题是关于C。)enum
通常用作逻辑变量,如您在示例中提到的color
和fruit
,其中您并不真正关心每个元素的实际数值,而是关心它代表什么
另一方面,const
通常在您真正关心数值时使用。例如:
const float PI = 3.1415926;
至于你的问题,答案是肯定的,enum可以被const值替换,但问题是它是否有真正的用例const-fruit-apple=1;int*y=&apple*y=-7代码>。未定义的行为是修改const
变量所得到的行为。编辑:显然,它被称为“约束冲突”,需要一个C实现来警告这一点。如果您打算修改它,那么声明它const
有什么意义?@JacobStatnekov:Enums不会检查您是否使用了正确的类型。枚举类型的赋值与任何数值类型(enum-GetFruit=1.5;
)兼容,常量本身的类型是int
,而不是enum
类型。@JacobStatnekov:No,fruit-GetFruit(){return 1;}
是完全合法的,编译时不会出错。(C++有不同的规则,但问题是关于C.)投票重新开始问题。enum
常量和const
限定对象之间存在显著差异。
const float PI = 3.1415926;