【在主画面加入捷径】
       
【选择语系】
繁中 简中

[C 语言] 程序设计教学:如何使用枚举 (Enumeration)

【赞助商连结】

    枚举 (enum 或 enumeration) 是另一种复合类型,主要是用在仅有少数值的类型,像是一星期内的日期 (day of week) 或是一年内的月份等。透过枚举,我们可以在程序中定义几个独一无二的符号 (symbol),且该符号享有类型安全。

    声明枚举

    使用 enum 保留字可以声明枚举,如下例:

    enum direction {
        North,
        South,
        East,
        West
    };
    
    int main(void) {
        enum direction dest = East;
        
        return 0;
    }
    

    枚举同样可用 typedef 简化类型名称,如下例:

    // Foreward declaration.
    typedef enum direction Direction;
    
    enum direction {
        North,
        South,
        East,
        West
    };
    
    int main(void) {
        Direction dest = East;
        
        return 0;
    }
    

    由于 C 语言的枚举本身没有前缀,可以自行加入前缀,如下例:

    typedef enum direction Direction;
    
    // Enum with prefix.
    enum direction {
        Direction_North,
        Direction_South,
        Direction_East,
        Direction_West
    };
    
    int main(void) {
        Direction dest = Direction_East;
        
        return 0;
    }
    

    虽然前缀不是强制规定,有些程序设计者偏好此种风格,以减少命名空间冲突。

    有些程序设计者会将枚举用全大写来表示:

    enum direction {
        NORTH,
        SOUTH,
        EAST,
        WEST
    };
    

    这种观点将枚举视为一种常数,这些不是硬性规定,而属个人风格,读者可自由选用。

    枚举 vs. 常数

    我们若不使用枚举,也可以用常数 (constant) 替代,如下例:

    typedef unsigned short Direction;
    
    // Compile time constants.
    #define NORTH 1
    #define SOUTH 2
    #define EAST  3
    #define WESt  4
    
    int main(void) {
        Direction dest = EAST;
        
        return 0;
    }
    

    在这里我们用到基本的前置处理器语法,读者不用太在意其使用细节,将其视为编译期的常数即可。

    常数和枚举的主要差别在于类型安全,前者没有类型安全,如下例:

    typedef unsigned short Direction;
    
    #define NORTH 1
    #define SOUTH 2
    #define EAST  3
    #define WESt  4
    
    int main(void) {
        // Wrongly correct.
        Direction dest = 6;
        
        return 0;
    }
    

    但使用枚举时,就会在编译程序时引发错误:

    typedef enum direction Direction;
    
    enum direction {
        North,
        South,
        East,
        West
    };
    
    int main(void) {
        // Error!
        Direction dest = South_West;
        
        return 0;
    }
    

    枚举是 ANSI C 就有的特性,如果想在程序中使用枚举,不需要刻意使用常数来仿真。

    读取枚举的数字

    一般来说,我们使用枚举时,将其视为一种符号,不会在意其内部的数值;但必要时也可指定枚举的值,如下例:

    #include <assert.h>
    
    enum mode {
        READ = 4,
        WRITE = 2,
        EXEC = 1
    };
    
    int main(void) {
        assert(READ ^ WRITE == 6);
        
        return 0;
    }