C语言枚举(enum)详解:(万字实例详解,从入门到精通)

C语言枚举(enum)详解:从入门到精通

目录

  1. 枚举的基本概念
  2. 枚举的声明和定义
  3. 枚举的使用方法
  4. 枚举的数值特性
  5. 枚举与整型的转换
  6. 枚举在switch语句中的应用
  7. 枚举的高级用法
  8. 枚举与宏定义的比较
  9. 枚举的最佳实践

1. 枚举的基本概念

什么是枚举?

枚举是C语言中一种用户自定义的数据类型,用于定义一组命名的整数常量,使代码更易读和维护。

枚举的特点:

  • 提高代码可读性
  • 类型安全检查
  • 自动数值分配
  • 便于调试

2. 枚举的声明和定义

2.1 基本枚举声明

#include <stdio.h>

// 方法1:先声明枚举类型,再定义变量
enum Color {
    RED,    // 0
    GREEN,  // 1
    BLUE    // 2
};

// 方法2:声明枚举类型的同时定义变量
enum Size {
    SMALL,  // 0
    MEDIUM, // 1
    LARGE   // 2
} shirtSize, pantSize;

// 方法3:匿名枚举
enum {
    JAN = 1,
    FEB,    // 2
    MAR     // 3
};

int main() {
    enum Color myColor = RED;
    shirtSize = MEDIUM;
    
    printf("myColor = %d\n", myColor);
    printf("shirtSize = %d\n", shirtSize);
    printf("JAN = %d, FEB = %d, MAR = %d\n", JAN, FEB, MAR);
    
    return 0;
}

输出:

myColor = 0
shirtSize = 1
JAN = 1, FEB = 2, MAR = 3

2.2 使用typedef简化枚举

#include <stdio.h>

// 使用typedef创建枚举类型别名
typedef enum {
    MONDAY,
    TUESDAY,
    WEDNESDAY,
    THURSDAY,
    FRIDAY,
    SATURDAY,
    SUNDAY
} Weekday;

// 另一个枚举例子
typedef enum {
    FALSE = 0,
    TRUE = 1
} Boolean;

int main() {
    Weekday today = WEDNESDAY;
    Boolean isWeekend = FALSE;
    
    printf("Today is day number: %d\n", today);
    printf("Is weekend? %d\n", isWeekend);
    
    // 可以重新赋值
    today = SATURDAY;
    isWeekend = TRUE;
    
    printf("Now today is day number: %d\n", today);
    printf("Now is weekend? %d\n", isWeekend);
    
    return 0;
}

输出:

Today is day number: 2
Is weekend? 0
Now today is day number: 5
Now is weekend? 1

3. 枚举的使用方法

3.1 枚举作为函数参数和返回值

#include <stdio.h>

// 定义枚举
typedef enum {
    OFF,
    ON,
    AUTO,
    STANDBY
} SystemState;

// 使用枚举作为函数参数
void printSystemState(SystemState state) {
    printf("System state: ");
    switch(state) {
        case OFF:     printf("OFF\n"); break;
        case ON:      printf("ON\n"); break;
        case AUTO:    printf("AUTO\n"); break;
        case STANDBY: printf("STANDBY\n"); break;
        default:      printf("UNKNOWN\n"); break;
    }
}

// 使用枚举作为返回值
SystemState toggleState(SystemState current) {
    switch(current) {
        case OFF: return ON;
        case ON: return OFF;
        case AUTO: return STANDBY;
        case STANDBY: return AUTO;
        default: return OFF;
    }
}

int main() {
    SystemState currentState = OFF;
    
    printf("Initial state:\n");
    printSystemState(currentState);
    
    // 切换状态
    currentState = toggleState(currentState);
    printf("After first toggle:\n");
    printSystemState(currentState);
    
    currentState = toggleState(currentState);
    printf("After second toggle:\n");
    printSystemState(currentState);
    
    return 0;
}

输出:

Initial state:
System state: OFF
After first toggle:
System state: ON
After second toggle:
System state: OFF

3.2 枚举在结构体中的应用

#include <stdio.h>
#include <string.h>

// 定义多个枚举
typedef enum {
    ENGINE_OFF,
    ENGINE_IDLE,
    ENGINE_RUNNING,
    ENGINE_OVERHEAT
} EngineStatus;

typedef enum {
    GEAR_PARK,
    GEAR_REVERSE,
    GEAR_NEUTRAL,
    GEAR_DRIVE
} TransmissionGear;

typedef enum {
    FUEL_LOW,
    FUEL_MEDIUM,
    FUEL_HIGH,
    FUEL_FULL
} FuelLevel;

// 结构体中使用枚举
struct Car {
    char model[50];
    EngineStatus engine;
    TransmissionGear gear;
    FuelLevel fuel;
    int speed;
};

void printCarStatus(struct Car *car) {
    printf("Car Model: %s\n", car->model);
    
    printf("Engine: ");
    switch(car->engine) {
        case ENGINE_OFF: printf("OFF"); break;
        case ENGINE_IDLE: printf("IDLE"); break;
        case ENGINE_RUNNING: printf("RUNNING"); break;
        case ENGINE_OVERHEAT: printf("OVERHEAT"); break;
    }
    
    printf(" | Gear: ");
    switch(car->gear) {
        case GEAR_PARK: printf("PARK"); break;
        case GEAR_REVERSE: printf("REVERSE"); break;
        case GEAR_NEUTRAL: printf("NEUTRAL"); break;
        case GEAR_DRIVE: printf("DRIVE"); break;
    }
    
    printf(" | Fuel: ");
    switch(car->fuel) {
        case FUEL_LOW: printf("LOW"); break;
        case FUEL_MEDIUM: printf("MEDIUM"); break;
        case FUEL_HIGH: printf("HIGH"); break;
        case FUEL_FULL: printf("FULL"); break;
    }
    
    printf(" | Speed: %d km/h\n", car->speed);
}

int main() {
    struct Car myCar;
    strcpy(myCar.model, "Toyota Camry");
    myCar.engine = ENGINE_RUNNING;
    myCar.gear = GEAR_DRIVE;
    myCar.fuel = FUEL_HIGH;
    myCar.speed = 60;
    
    printCarStatus(&myCar);
    
    // 模拟状态变化
    myCar.gear = GEAR_NEUTRAL;
    myCar.speed = 0;
    myCar.fuel = FUEL_MEDIUM;
    
    printf("\nAfter stopping:\n");
    printCarStatus(&myCar);
    
    return 0;
}

输出:

Car Model: Toyota Camry
Engine: RUNNING | Gear: DRIVE | Fuel: HIGH | Speed: 60 km/h

After stopping:
Car Model: Toyota Camry
Engine: RUNNING | Gear: NEUTRAL | Fuel: MEDIUM | Speed: 0 km/h

4. 枚举的数值特性

4.1 枚举的自动数值分配

#include <stdio.h>

int main() {
    // 枚举默认从0开始自动递增
    enum AutoValues {
        FIRST,   // 0
        SECOND,  // 1
        THIRD,   // 2
        FOURTH   // 3
    };
    
    // 可以手动设置起始值
    enum WithStart {
        START = 10,
        NEXT,    // 11
        AFTER    // 12
    };
    
    // 可以部分手动设置
    enum Mixed {
        APPLE = 5,
        BANANA,   // 6
        CHERRY = 10,
        DATE,     // 11
        EGGPLANT  // 12
    };
    
    // 可以有重复值
    enum Duplicates {
        ZERO = 0,
        FALSE = 0,
        ONE = 1,
        TRUE = 1
    };
    
    printf("AutoValues: %d, %d, %d, %d\n", FIRST, SECOND, THIRD, FOURTH);
    printf("WithStart: %d, %d, %d\n", START, NEXT, AFTER);
    printf("Mixed: %d, %d, %d, %d, %d\n", APPLE, BANANA, CHERRY, DATE, EGGPLANT);
    printf("Duplicates: ZERO=%d, FALSE=%d, ONE=%d, TRUE=%d\n", 
           ZERO, FALSE, ONE, TRUE);
    
    return 0;
}

输出:

AutoValues: 0, 1, 2, 3
WithStart: 10, 11, 12
Mixed: 5, 6, 10, 11, 12
Duplicates: ZERO=0, FALSE=0, ONE=1, TRUE=1

4.2 枚举的数值运算

#include <stdio.h>

typedef enum {
    LOW = 1,
    MEDIUM = 5,
    HIGH = 10,
    MAX = 100
} PriorityLevel;

int main() {
    PriorityLevel p1 = MEDIUM;
    PriorityLevel p2 = HIGH;
    
    printf("Enum numerical operations:\n");
    printf("p1 = %d, p2 = %d\n", p1, p2);
    printf("p1 + p2 = %d\n", p1 + p2);
    printf("p2 - p1 = %d\n", p2 - p1);
    printf("p1 * 2 = %d\n", p1 * 2);
    printf("p2 / 2 = %d\n", p2 / 2);
    
    // 比较操作
    printf("\nComparison operations:\n");
    printf("p1 < p2: %d\n", p1 < p2);
    printf("p1 == MEDIUM: %d\n", p1 == MEDIUM);
    printf("p2 >= HIGH: %d\n", p2 >= HIGH);
    
    // 枚举数值范围
    printf("\nEnum value ranges:\n");
    printf("Size of PriorityLevel: %zu bytes\n", sizeof(PriorityLevel));
    printf("From LOW(%d) to MAX(%d)\n", LOW, MAX);
    
    return 0;
}

输出:

Enum numerical operations:
p1 = 5, p2 = 10
p1 + p2 = 15
p2 - p1 = 5
p1 * 2 = 10
p2 / 2 = 5

Comparison operations:
p1 < p2: 1
p1 == MEDIUM: 1
p2 >= HIGH: 1

Enum value ranges:
Size of PriorityLevel: 4 bytes
From LOW(1) to MAX(100)

5. 枚举与整型的转换

5.1 隐式和显式转换

#include <stdio.h>

typedef enum {
    RED = 1,
    GREEN = 2,
    BLUE = 4
} Color;

int main() {
    Color c = GREEN;
    int integer_value;
    Color from_int;
    
    printf("Original enum value: %d\n", c);
    
    // 枚举到整型的隐式转换
    integer_value = c;
    printf("Implicit conversion to int: %d\n", integer_value);
    
    // 整型到枚举的隐式转换(可能有警告)
    from_int = 4;  // BLUE
    printf("Implicit conversion from int: %d\n", from_int);
    
    // 显式转换
    from_int = (Color)2;  // GREEN
    printf("Explicit conversion from int: %d\n", from_int);
    
    // 超出枚举定义范围的转换
    from_int = (Color)99;
    printf("Out-of-range conversion: %d\n", from_int);
    
    // 使用枚举进行位运算
    printf("\nBitwise operations with enums:\n");
    Color mixed = (Color)(RED | BLUE);
    printf("RED | BLUE = %d\n", mixed);
    printf("Is RED in mixed? %d\n", (mixed & RED) == RED);
    printf("Is GREEN in mixed? %d\n", (mixed & GREEN) == GREEN);
    
    return 0;
}

输出:

Original enum value: 2
Implicit conversion to int: 2
Implicit conversion from int: 4
Explicit conversion from int: 2
Out-of-range conversion: 99

Bitwise operations with enums:
RED | BLUE = 5
Is RED in mixed? 1
Is GREEN in mixed? 0

6. 枚举在switch语句中的应用

6.1 完整的switch示例

#include <stdio.h>

typedef enum {
    CMD_UNKNOWN = 0,
    CMD_START,
    CMD_STOP,
    CMD_PAUSE,
    CMD_RESUME,
    CMD_STATUS,
    CMD_EXIT
} Command;

const char* commandToString(Command cmd) {
    switch(cmd) {
        case CMD_START:   return "START";
        case CMD_STOP:    return "STOP";
        case CMD_PAUSE:   return "PAUSE";
        case CMD_RESUME:  return "RESUME";
        case CMD_STATUS:  return "STATUS";
        case CMD_EXIT:    return "EXIT";
        case CMD_UNKNOWN: 
        default:          return "UNKNOWN";
    }
}

void executeCommand(Command cmd) {
    printf("Executing command: %s -> ", commandToString(cmd));
    
    switch(cmd) {
        case CMD_START:
            printf("System starting...\n");
            break;
        case CMD_STOP:
            printf("System stopping...\n");
            break;
        case CMD_PAUSE:
            printf("System pausing...\n");
            break;
        case CMD_RESUME:
            printf("System resuming...\n");
            break;
        case CMD_STATUS:
            printf("System status: Running\n");
            break;
        case CMD_EXIT:
            printf("Exiting system...\n");
            break;
        default:
            printf("Invalid command!\n");
            break;
    }
}

int main() {
    Command commands[] = {CMD_START, CMD_STATUS, CMD_PAUSE, CMD_RESUME, CMD_STOP, CMD_EXIT, CMD_UNKNOWN};
    int num_commands = sizeof(commands) / sizeof(commands[0]);
    
    printf("Command Execution Sequence:\n");
    printf("==========================\n");
    
    for(int i = 0; i < num_commands; i++) {
        executeCommand(commands[i]);
    }
    
    return 0;
}

输出:

Command Execution Sequence:
==========================
Executing command: START -> System starting...
Executing command: STATUS -> System status: Running
Executing command: PAUSE -> System pausing...
Executing command: RESUME -> System resuming...
Executing command: STOP -> System stopping...
Executing command: EXIT -> Exiting system...
Executing command: UNKNOWN -> Invalid command!

7. 枚举的高级用法

7.1 枚举与字符串的映射

#include <stdio.h>
#include <string.h>

typedef enum {
    ERROR_NONE = 0,
    ERROR_FILE_NOT_FOUND,
    ERROR_PERMISSION_DENIED,
    ERROR_OUT_OF_MEMORY,
    ERROR_NETWORK_FAILURE,
    ERROR_INVALID_INPUT,
    ERROR_UNKNOWN
} ErrorCode;

// 错误码到字符串的映射结构
struct ErrorInfo {
    ErrorCode code;
    const char* name;
    const char* description;
};

// 错误信息表
const struct ErrorInfo errorTable[] = {
    {ERROR_NONE, "NONE", "No error occurred"},
    {ERROR_FILE_NOT_FOUND, "FILE_NOT_FOUND", "The specified file was not found"},
    {ERROR_PERMISSION_DENIED, "PERMISSION_DENIED", "Insufficient permissions"},
    {ERROR_OUT_OF_MEMORY, "OUT_OF_MEMORY", "Insufficient memory available"},
    {ERROR_NETWORK_FAILURE, "NETWORK_FAILURE", "Network connection failed"},
    {ERROR_INVALID_INPUT, "INVALID_INPUT", "The input provided was invalid"},
    {ERROR_UNKNOWN, "UNKNOWN", "An unknown error occurred"}
};

const char* errorCodeToString(ErrorCode code) {
    for(int i = 0; i < sizeof(errorTable)/sizeof(errorTable[0]); i++) {
        if(errorTable[i].code == code) {
            return errorTable[i].name;
        }
    }
    return "INVALID_ERROR_CODE";
}

const char* errorCodeToDescription(ErrorCode code) {
    for(int i = 0; i < sizeof(errorTable)/sizeof(errorTable[0]); i++) {
        if(errorTable[i].code == code) {
            return errorTable[i].description;
        }
    }
    return "Invalid error code";
}

void printErrorInfo(ErrorCode code) {
    printf("Error %d: %s - %s\n", 
           code, errorCodeToString(code), errorCodeToDescription(code));
}

int main() {
    printf("Error Information Table:\n");
    printf("=======================\n");
    
    for(ErrorCode code = ERROR_NONE; code <= ERROR_UNKNOWN; code++) {
        printErrorInfo(code);
    }
    
    return 0;
}

输出:

Error Information Table:
=======================
Error 0: NONE - No error occurred
Error 1: FILE_NOT_FOUND - The specified file was not found
Error 2: PERMISSION_DENIED - Insufficient permissions
Error 3: OUT_OF_MEMORY - Insufficient memory available
Error 4: NETWORK_FAILURE - Network connection failed
Error 5: INVALID_INPUT - The input provided was invalid
Error 6: UNKNOWN - An unknown error occurred

7.2 枚举的位标志用法

#include <stdio.h>

// 使用枚举定义位标志
typedef enum {
    PERMISSION_NONE    = 0,
    PERMISSION_READ    = 1 << 0,  // 1
    PERMISSION_WRITE   = 1 << 1,  // 2
    PERMISSION_EXECUTE = 1 << 2,  // 4
    PERMISSION_DELETE  = 1 << 3,  // 8
    PERMISSION_ALL     = PERMISSION_READ | PERMISSION_WRITE | 
                         PERMISSION_EXECUTE | PERMISSION_DELETE  // 15
} FilePermissions;

// 权限检查函数
int hasPermission(int userPermissions, FilePermissions required) {
    return (userPermissions & required) == required;
}

void printPermissions(int permissions) {
    printf("Permissions: ");
    if(permissions == PERMISSION_NONE) {
        printf("NONE");
    } else {
        if(hasPermission(permissions, PERMISSION_READ)) printf("READ ");
        if(hasPermission(permissions, PERMISSION_WRITE)) printf("WRITE ");
        if(hasPermission(permissions, PERMISSION_EXECUTE)) printf("EXECUTE ");
        if(hasPermission(permissions, PERMISSION_DELETE)) printf("DELETE");
    }
    printf(" (0x%02X)\n", permissions);
}

int main() {
    // 不同的权限组合
    int user1 = PERMISSION_READ | PERMISSION_EXECUTE;  // 1 + 4 = 5
    int user2 = PERMISSION_WRITE | PERMISSION_DELETE;  // 2 + 8 = 10
    int admin = PERMISSION_ALL;  // 15
    int guest = PERMISSION_NONE; // 0
    
    printf("User Permission Tests:\n");
    printf("=====================\n");
    
    printPermissions(user1);
    printPermissions(user2);
    printPermissions(admin);
    printPermissions(guest);
    
    printf("\nPermission Checks for User1:\n");
    printf("Can read? %s\n", hasPermission(user1, PERMISSION_READ) ? "YES" : "NO");
    printf("Can write? %s\n", hasPermission(user1, PERMISSION_WRITE) ? "YES" : "NO");
    printf("Can delete? %s\n", hasPermission(user1, PERMISSION_DELETE) ? "YES" : "NO");
    
    // 添加权限
    user1 |= PERMISSION_WRITE;
    printf("\nAfter adding WRITE permission to User1:\n");
    printPermissions(user1);
    printf("Can write now? %s\n", hasPermission(user1, PERMISSION_WRITE) ? "YES" : "NO");
    
    // 移除权限
    user1 &= ~PERMISSION_EXECUTE;
    printf("\nAfter removing EXECUTE permission from User1:\n");
    printPermissions(user1);
    printf("Can execute now? %s\n", hasPermission(user1, PERMISSION_EXECUTE) ? "YES" : "NO");
    
    return 0;
}

输出:

User Permission Tests:
=====================
Permissions: READ EXECUTE (0x05)
Permissions: WRITE DELETE (0x0A)
Permissions: READ WRITE EXECUTE DELETE (0x0F)
Permissions: NONE (0x00)

Permission Checks for User1:
Can read? YES
Can write? NO
Can delete? NO

After adding WRITE permission to User1:
Permissions: READ WRITE EXECUTE (0x07)
Can write now? YES

After removing EXECUTE permission from User1:
Permissions: READ WRITE (0x03)
Can execute now? NO

8. 枚举与宏定义的比较

8.1 枚举vs宏定义

#include <stdio.h>

// 使用宏定义常量
#define STATUS_OFF 0
#define STATUS_ON 1
#define STATUS_STANDBY 2

// 使用枚举定义常量
typedef enum {
    MODE_OFF,
    MODE_ON,
    MODE_STANDBY
} OperationMode;

// 混合使用:枚举作为基础,宏作为扩展
typedef enum {
    BASE_RED,
    BASE_GREEN,
    BASE_BLUE
} BaseColors;

#define EXTENDED_YELLOW (BASE_GREEN + BASE_RED)
#define EXTENDED_CYAN (BASE_GREEN + BASE_BLUE)
#define EXTENDED_MAGENTA (BASE_RED + BASE_BLUE)

int main() {
    printf("Comparison: Macros vs Enums\n");
    printf("===========================\n");
    
    // 使用宏
    printf("Using macros:\n");
    printf("STATUS_OFF = %d\n", STATUS_OFF);
    printf("STATUS_ON = %d\n", STATUS_ON);
    printf("STATUS_STANDBY = %d\n", STATUS_STANDBY);
    
    // 使用枚举
    OperationMode mode = MODE_ON;
    printf("\nUsing enums:\n");
    printf("MODE_OFF = %d\n", MODE_OFF);
    printf("MODE_ON = %d\n", MODE_ON);
    printf("MODE_STANDBY = %d\n", MODE_STANDBY);
    printf("Current mode value: %d\n", mode);
    
    // 枚举的类型安全性(在编译时检查)
    // mode = 5; // 可能产生警告,但不会错误
    // int invalid_mode = MODE_OFF + MODE_ON; // 允许,因为枚举本质是整数
    
    printf("\nExtended colors (mixed approach):\n");
    printf("BASE_RED = %d\n", BASE_RED);
    printf("BASE_GREEN = %d\n", BASE_GREEN);
    printf("BASE_BLUE = %d\n", BASE_BLUE);
    printf("EXTENDED_YELLOW = %d\n", EXTENDED_YELLOW);
    printf("EXTENDED_CYAN = %d\n", EXTENDED_CYAN);
    printf("EXTENDED_MAGENTA = %d\n", EXTENDED_MAGENTA);
    
    // 枚举的大小信息
    printf("\nSize information:\n");
    printf("sizeof(OperationMode) = %zu bytes\n", sizeof(OperationMode));
    printf("sizeof(int) = %zu bytes\n", sizeof(int));
    
    return 0;
}

输出:

Comparison: Macros vs Enums
===========================
Using macros:
STATUS_OFF = 0
STATUS_ON = 1
STATUS_STANDBY = 2

Using enums:
MODE_OFF = 0
MODE_ON = 1
MODE_STANDBY = 2
Current mode value: 1

Extended colors (mixed approach):
BASE_RED = 0
BASE_GREEN = 1
BASE_BLUE = 2
EXTENDED_YELLOW = 1
EXTENDED_CYAN = 3
EXTENDED_MAGENTA = 2

Size information:
sizeof(OperationMode) = 4 bytes
sizeof(int) = 4 bytes

9. 枚举的最佳实践

9.1 完整项目示例

#include <stdio.h>
#include <string.h>

// 完整的日志系统使用枚举
typedef enum {
    LOG_TRACE = 0,
    LOG_DEBUG = 1,
    LOG_INFO = 2,
    LOG_WARN = 3,
    LOG_ERROR = 4,
    LOG_FATAL = 5
} LogLevel;

typedef enum {
    OUTPUT_CONSOLE,
    OUTPUT_FILE,
    OUTPUT_NETWORK,
    OUTPUT_ALL
} OutputTarget;

struct LoggerConfig {
    LogLevel level;
    OutputTarget target;
    const char* filename;
};

const char* logLevelToString(LogLevel level) {
    static const char* strings[] = {"TRACE", "DEBUG", "INFO", "WARN", "ERROR", "FATAL"};
    return strings[level];
}

const char* outputTargetToString(OutputTarget target) {
    static const char* strings[] = {"CONSOLE", "FILE", "NETWORK", "ALL"};
    return strings[target];
}

void logMessage(struct LoggerConfig* config, LogLevel level, const char* message) {
    // 只记录达到配置级别的消息
    if(level >= config->level) {
        const char* targetStr = "";
        
        switch(config->target) {
            case OUTPUT_CONSOLE:
                targetStr = "[CONSOLE]";
                break;
            case OUTPUT_FILE:
                targetStr = "[FILE]";
                break;
            case OUTPUT_NETWORK:
                targetStr = "[NETWORK]";
                break;
            case OUTPUT_ALL:
                targetStr = "[ALL]";
                break;
        }
        
        printf("%s %s: %s\n", targetStr, logLevelToString(level), message);
    }
}

void printConfig(struct LoggerConfig* config) {
    printf("Logger Configuration:\n");
    printf("  Level: %s (%d)\n", logLevelToString(config->level), config->level);
    printf("  Target: %s (%d)\n", outputTargetToString(config->target), config->target);
    if(config->filename) {
        printf("  Filename: %s\n", config->filename);
    }
    printf("\n");
}

int main() {
    // 创建不同的日志配置
    struct LoggerConfig consoleConfig = {LOG_INFO, OUTPUT_CONSOLE, NULL};
    struct LoggerConfig fileConfig = {LOG_DEBUG, OUTPUT_FILE, "app.log"};
    struct LoggerConfig verboseConfig = {LOG_TRACE, OUTPUT_ALL, NULL};
    
    printf("Logging System Demo\n");
    printf("===================\n\n");
    
    // 测试不同配置
    printf("Testing Console Config (INFO level):\n");
    printConfig(&consoleConfig);
    
    logMessage(&consoleConfig, LOG_TRACE, "This is a trace message");
    logMessage(&consoleConfig, LOG_DEBUG, "This is a debug message");
    logMessage(&consoleConfig, LOG_INFO, "This is an info message");
    logMessage(&consoleConfig, LOG_ERROR, "This is an error message");
    
    printf("\nTesting Verbose Config (TRACE level):\n");
    printConfig(&verboseConfig);
    
    logMessage(&verboseConfig, LOG_TRACE, "This is a trace message");
    logMessage(&verboseConfig, LOG_DEBUG, "This is a debug message");
    logMessage(&verboseConfig, LOG_INFO, "This is an info message");
    
    // 枚举的迭代使用
    printf("\nAll Log Levels:\n");
    for(LogLevel level = LOG_TRACE; level <= LOG_FATAL; level++) {
        printf("  %s (%d)\n", logLevelToString(level), level);
    }
    
    printf("\nAll Output Targets:\n");
    for(OutputTarget target = OUTPUT_CONSOLE; target <= OUTPUT_ALL; target++) {
        printf("  %s (%d)\n", outputTargetToString(target), target);
    }
    
    return 0;
}

输出:

Logging System Demo
===================

Testing Console Config (INFO level):
Logger Configuration:
  Level: INFO (2)
  Target: CONSOLE (0)

[CONSOLE] INFO: This is an info message
[CONSOLE] ERROR: This is an error message

Testing Verbose Config (TRACE level):
Logger Configuration:
  Level: TRACE (0)
  Target: ALL (3)

[ALL] TRACE: This is a trace message
[ALL] DEBUG: This is a debug message
[ALL] INFO: This is an info message

All Log Levels:
  TRACE (0)
  DEBUG (1)
  INFO (2)
  WARN (3)
  ERROR (4)
  FATAL (5)

All Output Targets:
  CONSOLE (0)
  FILE (1)
  NETWORK (2)
  ALL (3)

总结

关键知识点回顾:

  1. 枚举声明:三种声明方式,推荐使用typedef
  2. 数值特性:自动递增,可手动设置,支持位运算
  3. 类型转换:与整型互相转换,注意范围检查
  4. 应用场景:状态机、错误码、配置选项、权限系统
  5. 优势:代码可读性、类型安全、便于维护

枚举vs宏定义:

特性枚举宏定义
类型安全较好
调试支持好(可见符号)差(预处理替换)
作用域遵循C作用域规则全局
自动赋值支持不支持
性能与整数相同与整数相同

最佳实践:

  1. 使用typedef创建有意义的类型名
  2. 为枚举值使用清晰的前缀避免命名冲突
  3. 利用枚举提高switch语句的可读性
  4. 对于位标志使用移位操作定义枚举值
  5. 提供枚举到字符串的转换函数便于调试
  6. 在API中使用枚举而不是裸整数

掌握枚举的使用可以显著提高C代码的质量和可维护性!

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值