读书人

C语言枚举类型的疑惑

发布时间: 2012-03-19 22:03:05 作者: rapoo

C语言枚举类型的疑惑,高手进
一直以来都以为C语言的枚举类型是有符号整形,今天无意中发现好像不是这么简单。

我先写了个简单的测试程序如下

C/C++ code
#include <stdio.h>int main(void){    enum liquid {OUNCE = 1, CUP = 8, PINT = 16,                 QUART = 32, GALLON = 128};                     enum liquid jar;    jar = -1;        printf("%d\n", jar);    if (jar < 0)    {        printf("less than zero\n");    }        return 0;}


运行的结果是:
-1
从上面的结果来看,枚举类型似乎是用无符号整形来表示的.因为如果是用有符号整形来表示的话, 上面程序运行的结果应该是
-1
less than zero

而如果把程序做一个小小的修改,如下
C/C++ code
#include <stdio.h>int main(void){        /* OUNCE改成了-1 */    enum liquid {OUNCE = -1, CUP = 8, PINT = 16,                 QUART = 32, GALLON = 128};                     enum liquid jar;    jar = -1;        printf("%d\n", jar);    if (jar < 0)    {        printf("less than zero\n");    }        return 0;}


运行的结果是
-1
less than zero
这个结果似乎又说明枚举类型不是用无符号整形来表示的。那到底实际情况是怎么样呢?我推测应该是跟枚举类型的定义有关。
因为在第一段代码中,enum liquid的所有枚举值都是非负数,非负数可以用无符号整形来表示,于是编译器就把enum liquid类型的jar
用无符号整形来表示,然后就得到了上面第一个测试结果。而在第二段代码中, enum liquid的枚举值中包含了-1这个负数, 不能用无符号整形来表示,于是编译器就用有符号
整形来表示jar, 第二个测试结果似乎也证实了这一点。
网上搜了一下,似乎没有对这个问题很好的解释,期待高手的解释。

[解决办法]
不知道为什么,很多人总是去纠结错误的东西
[解决办法]
根据C标准的规定,枚举常量的类型为 int,枚举变量的类型应该与 char、有符号或无符号整型兼容。因此,枚举变量可以接受 char、有符号或无符号整型数,而不限于仅从此枚举类型所定义的枚举常量中取值。由于上述原因,在C语言中无法从语法上保证枚举变量只能在定义的枚举成员中取值,只能由程序员自身保证不使用除枚举成员之外的值。
在第一例中:jar=-1 确确实实是将jar的内存中值变为了-1,但在编译器的记忆中jar只有1,8,16,32,128等值。所以在用if判断时,编译器认为jar的值仍是大于零的。
第二个理所应当就不解释了。

赵老师:
不要纠结各种常量了,这个世界上唯一不变的就是变化。用API WriteProcessMemory还能修改正运行的其它进程的内存里面的所谓常量呢!
[解决办法]
However, converting an integer to an enumerator requires an explicit cast, and the results are not defined if the integer value is outside the range of the defined enumeration.

读书人网 >C语言

热点推荐