c 语言的 enum 是个残废设计吧?

2018-03-29 18:40:53 +08:00
 miaowei
enum 设计的初衷是好的,像
enum colorbase{red = 0xff0000, green =0xff00, blue=0xff};
它定义了一个整型,且这个整型比正常的 int 的取值范围小,因为三基色只有三个值. 用枚举很合适.
但我们对 enum 类型的变量赋值时,C 编译器又不做类型检查(肯定是 C 标准没要求):
enum colorbase x;
x = red; //正确
x = 0; //也正确 ?!
那 enum 的意义何在?仅仅是增加一点代码可读性?用它当然是想让编译器帮着检查啊.

c++对 enum 的实现就很让人满意,上面的 x=0, g++会报错:
error: invalid conversion from ‘ int ’ to ‘ colorbase ’

我对 C 的 enum 好奇很久了,对 C++又不熟,今天是偶然发现 C++的实现正合我意,赶紧发帖子唠叨两句...哎,其实我用过一阵子 C++, 其它都还好,就是受不了 void *赋值给指针时还要显式的做类型转换,不然大概早切换过去了.
3578 次点击
所在节点    问与答
24 条回复
Tompes
2018-03-29 19:01:41 +08:00


惊了,这算自己吃设定么......
liuminghao233
2018-03-29 19:17:33 +08:00
enum 我是拿来放 switch 用的
but0n
2018-03-29 23:14:09 +08:00
<img src="https://user-images.githubusercontent.com/7625588/38096736-30e4b026-33a6-11e8-9bac-529e4ee58e8b.png">
https://user-images.githubusercontent.com/7625588/38096736-30e4b026-33a6-11e8-9bac-529e4ee58e8b.png

main.cpp:30:9: error: assigning to 'enum cb' from incompatible type 'int'
b = 0;
^
1 error generated.
make[1]: *** [main.o] Error 1
make: *** [main] Error 2



enum cb {
r = 0xFF0000,
g = 0xFF00,
b = 0xFF,
};

int main(int argc, char const *argv[]) {
enum cb a, b;
a = r;
b = 0;
printf("hello, %d\, %dn", a, b);

return 0;
}

怎么说
ysc3839
2018-03-29 23:20:08 +08:00
@but0n 你这是 C++,楼主也说了 C++ 有类型检查。
am241
2018-03-29 23:31:42 +08:00
c 本来就是弱类型语言,在明白怎么回事的情况下,允许用户使用各种黑科技。把"0"强制转换成函数指针然后 call 过去的用法也很常见

enum 至少有个用途是可以自增:如果一个变量代表了 n 个状态,用户又不在乎用哪些值来代表这些状态的时候,用 enum 就很合适了
but0n
2018-03-30 00:25:12 +08:00
@ysc3839 忘改后缀名了……我是拿 gcc 编译的 印象中-Wall 会有警告的,明天试试
sinxccc
2018-03-30 00:49:49 +08:00
能增加代码可读性还不够么?

代码写出来是让人读的。
geelaw
2018-03-30 01:01:41 +08:00
就很迷…… void * 换类型需要显式转换难道不是和 int to enum 需要显式转换一样是好事儿么
vincentxue
2018-03-30 03:33:03 +08:00
楼主你没说错。

C 中的枚举类型的作用是让程序员更清楚地编写程序,它实际上就是一组整数(其实也不一定,只是通常这样假设)常量,最主要的作用就是省去你要写很多 #define。

C++ 中的 enum 是你创建的一个类型。

clang 是支持 C enum 类型检查的。
vincentxue
2018-03-30 03:35:42 +08:00
@Tompes 你这输出没毛病啊。。
liuhaotian
2018-03-30 07:06:59 +08:00
You can do a enum like

enum status {
ST_READY = 1 << 0, /* 1 */
ST_WAIT = 1 << 1, /* 2 */
ST_ERROR = 1 << 2, /* 4 */
ST_HALT = 1 << 3, /* 8 */
ST_ETC = 1 << 4, /* 16 */
};
Then define an object of that type

enum status status;
and set it to the bitwise OR of some 'simple' statuses

status = ST_WAIT | ST_ERROR; /* recoverable error */
Note that the value ST_WAIT | ST_ERROR is 6 and that that value is not part of the enum.

SOF: https://stackoverflow.com/a/7431680
pkookp8
2018-03-30 07:20:42 +08:00
在我看来枚举和宏定义没差别。。。
blahgeek
2018-03-30 08:25:21 +08:00

rust 的 enum 了解一下
Tompes
2018-03-30 09:47:42 +08:00
@vincentxue
从语言设定来说 C 的 enum 是不能赋值为除定义的枚举值以外值的啊!
而且就这 0 也不是任何枚举元素的序号...
gggxxxx
2018-03-30 10:01:49 +08:00
enum 的意义是一种常用的抽象方法啊,大多数编程语言都有。赋值需求直接用变量来做不是更合理?
另一方面 c 语言算很古老的了,不能拿现代新编程语言来对比。
geelaw
2018-03-30 10:11:17 +08:00
@liuhaotian #11 an enum
@Tompes #14 C 语言没有这样的设定,通常来说支持 enum 的语言都允许 enum 类型取所有 underlying type 允许的值
xeaglex
2018-03-30 19:33:52 +08:00
@am241 C 是弱类型语言?
miaowei
2018-03-30 22:26:19 +08:00
@am241 自增的确是方便,我也经常用到,但不支持类型检查,感觉这个关键字就废了一大半。
miaowei
2018-03-30 22:28:00 +08:00
@but0n 加_Wall 没用,我试过了。
miaowei
2018-03-30 22:32:48 +08:00
@geelaw 一个指针,我声明为 void*显然是想避开类型检查,一个整型,我声明为 enum,显然是需要编译器给我掌个眼。就我一个人是这样想的?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/442603

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX