user-0 提问: 《The C programming Language》中的一个困惑

回复:
user: user-1
content: 引用 7 楼 swgshj 的回复:引用Enumerations provide a convenient way to associate constant values with names, an alternative to #define with the advantage that the values can be generated for you. Although variables of enum types may be declared, compilers need not check that what you store in such a variable is a valid value for the enumeration. Nevertheless, enumeration variables offer the chance of checking and so are often better than #defines. In addition, a debugger may be able to print values of enumeration variables in their symbolic form. 上面是英文原文，我理解作者的意思是： 虽然枚举变量不提供枚举值的合法性检查，但是提供了（枚举）类型的检查的可能（取决于编译器如何设计），这比#define也是有优势的。 你说的“枚举变量”和“枚举类型的变量”应该是一回事。  补充一下，下面的例子可以看出，枚举类型提供了一定的检查，但是跟int类型类似（但不完全一样），也是存在一些隐式类型转换的，在符合编译器的隐式类型转换时，不会产生编译失败。                                                                 1,5           Top #include <stdio.h>  typedef enum month { JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC  }MON;  typedef struct {     int a;     int b; }STest;  void foo(MON mon) {     printf("Month=%d\n", mon);     return; }  int main() {     MON e_month;     int i_month = 1000;     float f_month = 1.11;     double d_month = 2.22;     char *p_month = "hello";     STest s_test = {0};      e_month = JAN;      //OK     e_month = 100;      //OK     foo(i_month);       //OK      e_month = i_month;  //OK          i_month = f_month;  //OK, no warning     e_month = f_month;  //OK, no warning          i_month = d_month;  //OK, no warning     e_month = d_month;  //OK, no warning      i_month = p_month;  //warning: assignment makes integer from pointer without a cast     e_month = p_month;  //error: incompatible types when assigning to type 'MON' from type 'char *'      i_month = s_test;   //error: incompatible types when assigning to type 'int' from type 'STest'     e_month = s_test;   //error: incompatible types when assigning to type 'MON' from type 'STest'      return 0; }   编译报错： [pc@server ~/c]$ gcc -Wall enum.c enum.c: In function 'main': enum.c:39: warning: assignment makes integer from pointer without a cast enum.c:40: error: incompatible types when assigning to type 'MON' from type 'char *' enum.c:42: error: incompatible types when assigning to type 'int' from type 'STest' enum.c:43: error: incompatible types when assigning to type 'MON' from type 'STest' [pc@server ~/c]$  GCC版本：  $ gcc -v Using built-in specs. Target: x86_64-redhat-linux Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch_32=i686 --build=x86_64-redhat-linux Thread model: posix gcc version 4.4.7 20120313 (Red Hat 4.4.7-3) (GCC)

user: user-1
content: 引用Enumerations provide a convenient way to associate constant values with names, an alternative to #define with the advantage that the values can be generated for you. Although variables of enum types may be declared, compilers need not check that what you store in such a variable is a valid value for the enumeration. Nevertheless, enumeration variables offer the chance of checking and so are often better than #defines. In addition, a debugger may be able to print values of enumeration variables in their symbolic form. 上面是英文原文，我理解作者的意思是： 虽然枚举变量不提供枚举值的合法性检查，但是提供了（枚举）类型的检查的可能（取决于编译器如何设计），这比#define也是有优势的。 你说的“枚举变量”和“枚举类型的变量”应该是一回事。

user: user-2
content: 引用 3 楼 moyac 的回复:enum WEEKDAY{Monday, Tuesday, Wednesday}; enum WEEKDAY w; 称enum WEEKDAY为枚举类型，称w为枚举变量，称Monday等为枚举值（好像也有叫枚举常量的）。 如果是这样的话，是不是说，枚举变量w的值是{0， 1 ，2}啊 是的

user: user-3
content: 特意下个英文版的去看了下原话， 原话的大意是：编译器不需要检查你存放在枚举变量里面的值是否在枚举类型的值的范围内，但是编译器提供了检查的机会（这里说的检查应该是指类型的检查）。而且你可以在调试的时候输出枚举变量的值

user: user-4
content: 那个例子不好， 强制类型转换（）跳过了类型检查。

user: user-4
content: 枚举有类型检查， 类型更安全， 这是好事。