乐闻世界logo
搜索文章和话题

C语言

C 语言,是一种通用的、过程式的编程语言,广泛用于系统与应用软件的开发。具有高效、灵活、功能丰富、表达力强和较高的移植性等特点,在程序员中备受青睐。 C 语言是由 UNIX 的研制者丹尼斯·里奇(Dennis Ritchie)和肯·汤普逊(Ken Thompson)于 1970 年研制出的B语言的基础上发展和完善起来的。目前,C 语言编译器普遍存在于各种不同的操作系统中,例如 UNIX、MS-DOS、Microsoft Windows 及 Linux 等。C 语言的设计影响了许多后来的编程语言,例如 C++、Objective-C、Java、C# 等。
C语言
查看更多相关内容
C语言中枚举类型的定义和使用技巧有哪些?C语言中枚举类型的定义和使用技巧有哪些? **枚举类型基础:** 1. **基本定义** ```c enum Color { RED, GREEN, BLUE }; enum Color c = RED; ``` 2. **指定值** ```c enum Status { SUCCESS = 0, ERROR = -1, PENDING = 1, COMPLETED = 2 }; ``` 3. **匿名枚举** ```c enum { MAX_SIZE = 100, BUFFER_SIZE = 1024 }; ``` **高级用法:** 1. **枚举作为位标志** ```c enum FileFlags { READ = 0x01, // 0001 WRITE = 0x02, // 0010 EXECUTE = 0x04, // 0100 APPEND = 0x08 // 1000 }; unsigned int flags = READ | WRITE; if (flags & READ) { printf("Read permission\n"); } ``` 2. **枚举与switch配合** ```c enum Day { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY }; void print_day(enum Day day) { switch (day) { case MONDAY: printf("Monday\n"); break; case TUESDAY: printf("Tuesday\n"); break; default: printf("Other day\n"); } } ``` 3. **枚举类型转换** ```c enum Color { RED, GREEN, BLUE }; // 枚举到整数 int value = RED; // value = 0 // 整数到枚举 enum Color c = (enum Color)1; // GREEN // 枚举大小 printf("Size of enum: %zu\n", sizeof(enum Color)); ``` **最佳实践:** 1. **命名约定** ```c // 使用大写和下划线 enum ErrorCode { ERROR_NONE, ERROR_INVALID_PARAM, ERROR_OUT_OF_MEMORY, ERROR_FILE_NOT_FOUND }; // 或使用前缀 enum SocketType { SOCK_TYPE_STREAM, SOCK_TYPE_DGRAM }; ``` 2. **枚举作为数组索引** ```c enum Month { JAN = 1, FEB, MAR, APR, MAY, JUN, JUL, AUG, SEP, OCT, NOV, DEC }; const char* month_names[] = { "", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" }; printf("%s\n", month_names[JAN]); ``` 3. **枚举与typedef结合** ```c typedef enum { STATE_IDLE, STATE_RUNNING, STATE_PAUSED, STATE_STOPPED } State; State current_state = STATE_IDLE; ``` **注意事项:** 1. **枚举值的连续性** ```c enum Example { A = 1, B = 2, C = 5, // 不连续 D = 6 }; // 不能假设枚举值是连续的 ``` 2. **枚举的范围** ```c enum Small { MIN = 0, MAX = 255 }; // 编译器可能选择更大的类型 // 不能保证只占用1字节 ``` 3. **枚举的前向声明** ```c // C11 支持 enum Color; void process_color(enum Color c); enum Color { RED, GREEN, BLUE }; ``` **实际应用示例:** 1. **状态机实现** ```c typedef enum { STATE_INIT, STATE_CONNECTING, STATE_CONNECTED, STATE_DISCONNECTING, STATE_ERROR } ConnectionState; ConnectionState handle_state(ConnectionState state) { switch (state) { case STATE_INIT: return STATE_CONNECTING; case STATE_CONNECTING: return STATE_CONNECTED; case STATE_CONNECTED: return STATE_DISCONNECTING; default: return STATE_ERROR; } } ``` 2. **配置选项** ```c enum ConfigOption { OPT_DEBUG = 0x01, OPT_VERBOSE = 0x02, OPT_LOG_FILE = 0x04, OPT_DAEMON = 0x08 }; void configure(unsigned int options) { if (options & OPT_DEBUG) { enable_debug(); } if (options & OPT_DAEMON) { run_as_daemon(); } } ``` 3. **错误码定义** ```c enum LibraryError { LIB_OK = 0, LIB_ERR_INVALID_ARG = -1, LIB_ERR_OUT_OF_MEMORY = -2, LIB_ERR_IO = -3, LIB_ERR_TIMEOUT = -4 }; enum LibraryError library_init() { if (!allocate_memory()) { return LIB_ERR_OUT_OF_MEMORY; } return LIB_OK; } ```
服务端 · 2月18日 17:22
C语言中结构体和类的区别及使用场景是什么?C语言中结构体和类的区别及使用场景是什么? **结构体基本概念:** 1. **结构体定义** ```c struct Point { int x; int y; }; struct Point p1 = {10, 20}; struct Point p2 = {.x = 30, .y = 40}; ``` 2. **结构体指针** ```c struct Point *ptr = &p1; ptr->x = 50; ptr->y = 60; ``` **与类的对比:** 1. **数据封装** ```c // C语言结构体 struct Rectangle { int width; int height; }; // C++类 class Rectangle { private: int width; int height; public: Rectangle(int w, int h) : width(w), height(h) {} int area() { return width * height; } }; ``` 2. **方法定义** ```c // C语言:使用函数指针 struct Shape { int (*area)(struct Shape*); int (*perimeter)(struct Shape*); }; int rectangle_area(struct Shape *s) { struct Rectangle *r = (struct Rectangle*)s; return r->width * r->height; } // C++:成员函数 class Shape { public: virtual int area() = 0; virtual int perimeter() = 0; }; ``` 3. **构造和析构** ```c // C语言:手动初始化 struct Point create_point(int x, int y) { struct Point p = {x, y}; return p; } void destroy_point(struct Point *p) { // 手动清理资源 } // C++:自动构造和析构 class Point { public: Point(int x, int y) : x(x), y(y) {} ~Point() {} private: int x, y; }; ``` **使用场景:** 1. **数据结构** ```c struct Node { int data; struct Node *next; }; struct LinkedList { struct Node *head; int size; }; ``` 2. **配置管理** ```c struct Config { char server[256]; int port; int timeout; int max_connections; }; struct Config load_config(const char *filename); ``` 3. **网络协议** ```c struct PacketHeader { unsigned int version : 4; unsigned int type : 4; unsigned int length : 16; unsigned int checksum : 8; }; ``` **高级特性:** 1. **结构体嵌套** ```c struct Address { char street[100]; char city[50]; char country[50]; }; struct Person { char name[50]; int age; struct Address address; }; struct Person person = { .name = "John Doe", .age = 30, .address = { .street = "123 Main St", .city = "New York", .country = "USA" } }; ``` 2. **结构体数组** ```c struct Student { int id; char name[50]; float score; }; struct Student students[100]; students[0].id = 1; strcpy(students[0].name, "Alice"); students[0].score = 95.5; ``` 3. **灵活数组成员** ```c struct String { size_t length; char data[]; // 灵活数组成员 }; struct String *create_string(const char *str) { size_t len = strlen(str); struct String *s = malloc(sizeof(struct String) + len + 1); s->length = len; strcpy(s->data, str); return s; } ``` **最佳实践:** 1. **命名约定** ```c struct Point { int x; int y; }; typedef struct Point Point; Point p1 = {10, 20}; ``` 2. **初始化函数** ```c struct Point point_create(int x, int y) { struct Point p = {x, y}; return p; } struct Point p = point_create(10, 20); ``` 3. **内存管理** ```c struct Point *point_alloc(int x, int y) { struct Point *p = malloc(sizeof(struct Point)); if (p) { p->x = x; p->y = y; } return p; } void point_free(struct Point *p) { free(p); } ``` **注意事项:** 1. **内存对齐** ```c struct Example { char c; // 1字节 + 3字节填充 int i; // 4字节 }; // 总大小: 8字节 ``` 2. **结构体赋值** ```c struct Point p1 = {10, 20}; struct Point p2 = p1; // 浅拷贝 ``` 3. **结构体比较** ```c struct Point p1 = {10, 20}; struct Point p2 = {10, 20}; // 错误:不能直接比较结构体 // if (p1 == p2) { } // 正确:逐个成员比较 if (p1.x == p2.x && p1.y == p2.y) { printf("Equal\n"); } ```
服务端 · 2月18日 17:22
C语言中动态内存管理的完整指南和常见问题是什么?C语言中动态内存管理的完整指南和常见问题是什么? **动态内存分配函数:** 1. **malloc - 分配内存** ```c void *malloc(size_t size); // 分配指定字节数的内存 int *arr = (int*)malloc(10 * sizeof(int)); if (arr == NULL) { fprintf(stderr, "Memory allocation failed\n"); exit(1); } // 使用内存 for (int i = 0; i < 10; i++) { arr[i] = i * i; } // 释放内存 free(arr); ``` 2. **calloc - 分配并初始化** ```c void *calloc(size_t num, size_t size); // 分配并初始化为零 int *arr = (int*)calloc(10, sizeof(int)); // 所有元素自动初始化为0 free(arr); ``` 3. **realloc - 重新分配** ```c void *realloc(void *ptr, size_t size); int *arr = (int*)malloc(5 * sizeof(int)); // 扩展内存 int *new_arr = (int*)realloc(arr, 10 * sizeof(int)); if (new_arr == NULL) { free(arr); // 原内存仍然有效 exit(1); } arr = new_arr; free(arr); ``` 4. **free - 释放内存** ```c void free(void *ptr); int *ptr = (int*)malloc(sizeof(int)); free(ptr); ptr = NULL; // 避免悬空指针 ``` **内存管理最佳实践:** 1. **检查分配结果** ```c void *ptr = malloc(size); if (ptr == NULL) { // 处理内存分配失败 return NULL; } ``` 2. **避免内存泄漏** ```c void function_with_leak() { int *ptr = malloc(sizeof(int)); // 忘记 free(ptr) - 内存泄漏 } void correct_function() { int *ptr = malloc(sizeof(int)); if (ptr) { // 使用内存 free(ptr); } } ``` 3. **防止悬空指针** ```c int *ptr = malloc(sizeof(int)); free(ptr); ptr = NULL; // 避免使用已释放的内存 // 错误示例 *ptr = 10; // 未定义行为 ``` 4. **双重释放防护** ```c int *ptr = malloc(sizeof(int)); free(ptr); ptr = NULL; // 设置为NULL free(ptr); // free(NULL) 是安全的 ``` **常见问题和解决方案:** 1. **内存碎片** ```c // 问题:频繁分配和释放不同大小的内存 for (int i = 0; i < 1000; i++) { void *ptr = malloc(rand() % 1000); free(ptr); } // 解决:使用内存池或固定大小分配 ``` 2. **缓冲区溢出** ```c // 危险 int *arr = malloc(10 * sizeof(int)); arr[10] = 100; // 越界访问 // 安全 int *arr = malloc(10 * sizeof(int)); if (index < 10) { arr[index] = value; } ``` 3. **野指针** ```c int *ptr; // 未初始化 *ptr = 10; // 未定义行为 // 正确做法 int *ptr = NULL; ptr = malloc(sizeof(int)); if (ptr) { *ptr = 10; free(ptr); ptr = NULL; } ``` **高级技巧:** 1. **自定义内存分配器** ```c void* my_malloc(size_t size) { void *ptr = malloc(size); if (ptr) { memset(ptr, 0, size); // 清零 } return ptr; } ``` 2. **内存调试** ```c #ifdef DEBUG void *debug_malloc(size_t size, const char *file, int line) { void *ptr = malloc(size); printf("Allocated %zu bytes at %p (%s:%d)\n", size, ptr, file, line); return ptr; } #define MALLOC(size) debug_malloc(size, __FILE__, __LINE__) #else #define MALLOC(size) malloc(size) #endif ```
服务端 · 2月18日 17:21
C语言中typedef和#define的区别及使用场景是什么?C语言中typedef和#define的区别及使用场景是什么? **核心区别:** 1. **处理阶段** - `#define`: 预处理器阶段,文本替换 - `typedef`: 编译器阶段,类型别名 2. **作用域** - `#define`: 全局作用域,从定义点到文件末尾 - `typedef`: 遵循正常作用域规则 3. **类型检查** - `#define`: 无类型检查,纯文本替换 - `typedef`: 有类型检查,编译器验证 4. **调试支持** - `#define`: 调试时显示原始代码 - `typedef`: 调试时显示别名类型 **使用场景对比:** 1. **类型别名** ```c // typedef - 推荐 typedef unsigned int uint32_t; uint32_t value = 100; // #define - 不推荐 #define uint32_t unsigned int uint32_t value = 100; ``` 2. **函数指针** ```c // typedef - 清晰易读 typedef int (*CompareFunc)(const void*, const void*); CompareFunc compare = my_compare; // #define - 难以理解 #define CompareFunc int (*)(const void*, const void*) CompareFunc compare = my_compare; ``` 3. **结构体** ```c // typedef - 简洁 typedef struct { int x; int y; } Point; Point p1 = {10, 20}; // #define - 不适用 ``` 4. **数组类型** ```c // typedef - 类型安全 typedef int Array10[10]; Array10 arr1, arr2; // #define - 可能导致意外行为 #define Array10 int[10] Array10 arr1, arr2; // 只有arr2是数组 ``` **#define 的优势场景:** 1. **常量定义** ```c #define MAX_SIZE 100 #define PI 3.14159 #define VERSION "1.0.0" ``` 2. **条件编译** ```c #ifdef DEBUG #define LOG(x) printf x #else #define LOG(x) #endif ``` 3. **宏函数** ```c #define SQUARE(x) ((x) * (x)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) ``` **typedef 的优势场景:** 1. **提高代码可读性** ```c typedef unsigned long long ull; typedef struct Node* NodePtr; ``` 2. **跨平台兼容性** ```c #ifdef _WIN64 typedef __int64 intptr_t; #else typedef long intptr_t; #endif ``` 3. **回调函数类型** ```c typedef void (*Callback)(int result); void register_callback(Callback cb); ``` **常见陷阱:** 1. **宏的副作用** ```c #define SQUARE(x) ((x) * (x)) int i = 2; int result = SQUARE(i++); // 未定义行为 ``` 2. **宏的括号问题** ```c #define MUL(a, b) a * b int result = MUL(2 + 3, 4); // 结果是14,不是20 ``` 3. **typedef 不能用于数组初始化** ```c typedef int IntArray[10]; IntArray arr = {1, 2, 3}; // 错误 int arr[10] = {1, 2, 3}; // 正确 ```
服务端 · 2月18日 17:21
C语言中联合体(union)的使用场景和内存布局是什么?C语言中联合体(union)的使用场景和内存布局是什么? **联合体基本概念:** 1. **定义和声明** ```c union Data { int i; float f; char str[20]; }; union Data data; data.i = 10; data.f = 3.14; strcpy(data.str, "Hello"); ``` 2. **内存共享特性** ```c union Example { int value; char bytes[4]; }; union Example ex; ex.value = 0x12345678; // bytes[0] = 0x78 (小端序) // bytes[1] = 0x56 // bytes[2] = 0x34 // bytes[3] = 0x12 ``` **典型使用场景:** 1. **数据类型转换** ```c union FloatInt { float f; unsigned int i; }; float_to_bits(float value) { union FloatInt converter; converter.f = value; return converter.i; } ``` 2. **节省内存空间** ```c // 不使用联合体:占用12字节 struct Message { int type; union { int int_data; float float_data; char char_data[4]; } data; }; // 使用联合体:只占用8字节 union CompactMessage { struct { int type; int data; } int_msg; struct { int type; float data; } float_msg; }; ``` 3. **网络协议解析** ```c union IPHeader { struct { unsigned int version : 4; unsigned int ihl : 4; unsigned int tos : 8; unsigned int total_length : 16; } fields; unsigned int raw; }; ``` 4. **变体数据类型** ```c enum DataType { INT, FLOAT, STRING }; struct Variant { enum DataType type; union { int int_val; float float_val; char *str_val; } value; }; ``` **内存布局分析:** 1. **大小计算** ```c union SizeExample { char c; // 1字节 int i; // 4字节 double d; // 8字节 }; sizeof(union SizeExample); // 8字节(最大成员的大小) ``` 2. **对齐规则** ```c union AlignedExample { char c; int i; double d; }; // 大小为8字节,对齐到8字节边界 ``` **高级应用:** 1. **位域操作** ```c union BitManipulation { unsigned int value; struct { unsigned int bit0 : 1; unsigned int bit1 : 1; unsigned int bit2 : 1; unsigned int rest : 29; } bits; }; union BitManipulation bm; bm.value = 0; bm.bits.bit0 = 1; ``` 2. **类型安全的联合体** ```c struct SafeUnion { enum { INT, FLOAT, STRING } type; union { int int_val; float float_val; char *str_val; } data; }; void print_safe_union(struct SafeUnion *su) { switch (su->type) { case INT: printf("%d\n", su->data.int_val); break; case FLOAT: printf("%f\n", su->data.float_val); break; case STRING: printf("%s\n", su->data.str_val); break; } } ``` **注意事项:** 1. **同时访问问题** ```c union Data { int i; float f; }; union Data d; d.i = 10; d.f = 3.14; // 覆盖了之前的值 // 此时访问 d.i 是未定义行为 ``` 2. **字节序依赖** ```c union EndianTest { int value; char bytes[4]; }; union EndianTest test; test.value = 1; if (test.bytes[0] == 1) { printf("Little Endian\n"); } else { printf("Big Endian\n"); } ``` 3. **初始化** ```c union Data { int i; float f; }; union Data d1 = {10}; // 初始化第一个成员 union Data d2 = {.f = 3.14}; // 指定成员初始化 ```
服务端 · 2月18日 17:21
C语言中字符串处理函数的完整列表和最佳实践是什么?C语言中字符串处理函数的完整列表和最佳实践是什么? **核心字符串函数:** 1. **字符串长度** ```c size_t strlen(const char *str); // 返回字符串长度,不包含终止符 '\0' ``` 2. **字符串复制** ```c char *strcpy(char *dest, const char *src); char *strncpy(char *dest, const char *src, size_t n); // strncpy 不会自动添加 '\0',需要手动处理 ``` 3. **字符串连接** ```c char *strcat(char *dest, const char *src); char *strncat(char *dest, const char *src, size_t n); // 确保目标缓冲区足够大 ``` 4. **字符串比较** ```c int strcmp(const char *s1, const char *s2); int strncmp(const char *s1, const char *s2, size_t n); // 返回值:0表示相等,<0表示s1<s2,>0表示s1>s2 ``` 5. **字符串查找** ```c char *strchr(const char *str, int c); // 查找字符首次出现 char *strrchr(const char *str, int c); // 查找字符最后出现 char *strstr(const char *haystack, const char *needle); // 查找子串 ``` 6. **字符串分割** ```c char *strtok(char *str, const char *delim); // 注意:strtok 会修改原字符串,且不是线程安全的 ``` 7. **安全版本(C11)** ```c errno_t strcpy_s(char *dest, rsize_t destsz, const char *src); errno_t strcat_s(char *dest, rsize_t destsz, const char *src); ``` **最佳实践:** 1. **缓冲区溢出防护** ```c // 不安全 strcpy(dest, src); // 安全方式 strncpy(dest, src, sizeof(dest) - 1); dest[sizeof(dest) - 1] = '\0'; ``` 2. **字符串拼接安全** ```c char buffer[100]; snprintf(buffer, sizeof(buffer), "%s%s", str1, str2); ``` 3. **动态字符串处理** ```c char *safe_strdup(const char *str) { if (!str) return NULL; size_t len = strlen(str) + 1; char *copy = malloc(len); if (copy) memcpy(copy, str, len); return copy; } ``` 4. **字符串格式化** ```c char buffer[256]; int result = snprintf(buffer, sizeof(buffer), "Value: %d", value); if (result < 0 || result >= sizeof(buffer)) { // 处理错误 } ``` **常见陷阱:** - 忘记为 '\0' 预留空间 - 使用未初始化的字符串 - 混淆 strlen 和 sizeof - 忽略函数返回值 - 多次调用 strtok 时的状态问题
服务端 · 2月18日 17:21
C语言中预处理器指令的完整列表和使用场景有哪些?C语言中预处理器指令的完整列表和使用场景有哪些? **核心预处理器指令:** 1. **文件包含 #include** ```c #include <stdio.h> // 系统头文件 #include "myheader.h" // 用户头文件 // 条件包含 #if defined(USE_FEATURE) #include "feature.h" #endif ``` 2. **宏定义 #define** ```c // 简单宏 #define PI 3.14159 #define MAX_SIZE 100 // 带参数的宏 #define SQUARE(x) ((x) * (x)) #define MIN(a, b) ((a) < (b) ? (a) : (b)) // 字符串化 #define STR(x) #x #define PRINT_VAR(var) printf(#var " = %d\n", var) // 连接 #define CONCAT(a, b) a##b ``` 3. **条件编译** ```c #if defined(UNIX) #include <unistd.h> #elif defined(WINDOWS) #include <windows.h> #else #error "Unsupported platform" #endif #ifdef DEBUG #define LOG(x) printf x #else #define LOG(x) #endif ``` 4. **错误和警告** ```c #if SIZE < 0 #error "Size must be positive" #endif #if !defined(VERSION) #warning "VERSION not defined, using default" #define VERSION "1.0" #endif ``` 5. **行控制 #line** ```c #line 100 "custom.c" // 错误信息将显示为 custom.c:100 ``` 6. **编译指示 #pragma** ```c #pragma once // 防止重复包含 #pragma pack(1) // 内存对齐 #pragma warning(disable:4996) // 禁用警告 ``` 7. **取消定义 #undef** ```c #define TEMP 100 #undef TEMP ``` **高级应用场景:** 1. **跨平台兼容性** ```c #if defined(_WIN32) || defined(_WIN64) #define PATH_SEPARATOR '\\' #else #define PATH_SEPARATOR '/' #endif ``` 2. **调试和日志** ```c #ifdef DEBUG #define DEBUG_PRINT(fmt, ...) printf(fmt, ##__VA_ARGS__) #else #define DEBUG_PRINT(fmt, ...) #endif ``` 3. **版本控制** ```c #define VERSION_MAJOR 2 #define VERSION_MINOR 5 #define VERSION_STRING "2.5" ``` **注意事项:** - 宏没有类型检查 - 宏展开可能导致意外的副作用 - 优先使用 const 和 inline 函数替代宏
服务端 · 2月18日 17:21
C语言中预定义宏和条件编译的完整用法是什么?C语言中预定义宏和条件编译的完整用法是什么? **预定义宏:** 1. **标准预定义宏** ```c void print_predefined_macros() { printf("File: %s\n", __FILE__); printf("Line: %d\n", __LINE__); printf("Date: %s\n", __DATE__); printf("Time: %s\n", __TIME__); printf("Function: %s\n", __func__); #ifdef __STDC_VERSION__ printf("C Standard: %ld\n", __STDC_VERSION__); #endif } ``` 2. **编译器特定宏** ```c void compiler_specific_code() { #ifdef __GNUC__ printf("GCC compiler\n"); #elif defined(__clang__) printf("Clang compiler\n"); #elif defined(_MSC_VER) printf("MSVC compiler\n"); #endif } ``` 3. **平台检测** ```c void platform_specific_code() { #ifdef _WIN32 printf("Windows platform\n"); #elif defined(__linux__) printf("Linux platform\n"); #elif defined(__APPLE__) printf("macOS platform\n"); #endif } ``` **条件编译:** 1. **基本条件编译** ```c #ifdef DEBUG #define LOG(x) printf x #else #define LOG(x) #endif void function() { LOG(("Debug message\n")); } ``` 2. **多重条件** ```c #if defined(UNIX) && !defined(DEBUG) #define OPTIMIZED_CODE #endif #if VERSION >= 2 #include "new_features.h" #else #include "legacy_features.h" #endif ``` 3. **错误和警告** ```c #if SIZE < 0 #error "Size must be positive" #endif #if !defined(VERSION) #warning "VERSION not defined, using default" #define VERSION "1.0" #endif ``` **高级用法:** 1. **宏字符串化** ```c #define STRINGIFY(x) #x #define TOSTRING(x) STRINGIFY(x) printf("Line: %s\n", TOSTRING(__LINE__)); ``` 2. **宏连接** ```c #define CONCAT(a, b) a##b int CONCAT(var, 1) = 10; // var1 ``` 3. **可变参数宏** ```c #define LOG(fmt, ...) printf("[LOG] " fmt "\n", ##__VA_ARGS__) LOG("Value: %d", 42); LOG("Simple message"); ``` **实际应用:** 1. **调试宏** ```c #ifdef DEBUG #define DEBUG_PRINT(fmt, ...) \ printf("[DEBUG %s:%d] " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__) #else #define DEBUG_PRINT(fmt, ...) #endif void example_function() { DEBUG_PRINT("Processing data: %d", 100); } ``` 2. **版本控制** ```c #define VERSION_MAJOR 2 #define VERSION_MINOR 5 #define VERSION_PATCH 1 #define VERSION_STRING \ TOSTRING(VERSION_MAJOR) "." \ TOSTRING(VERSION_MINOR) "." \ TOSTRING(VERSION_PATCH) printf("Version: %s\n", VERSION_STRING); ``` 3. **跨平台代码** ```c #ifdef _WIN32 #define PATH_SEPARATOR '\\' #define PATH_SEPARATOR_STR "\\" #else #define PATH_SEPARATOR '/' #define PATH_SEPARATOR_STR "/" #endif void join_path(char *dest, const char *dir, const char *file) { sprintf(dest, "%s%s%s", dir, PATH_SEPARATOR_STR, file); } ``` 4. **功能开关** ```c #define FEATURE_A_ENABLED 1 #define FEATURE_B_ENABLED 0 void process_data() { #if FEATURE_A_ENABLED feature_a_process(); #endif #if FEATURE_B_ENABLED feature_b_process(); #endif } ``` **最佳实践:** 1. **头文件保护** ```c #ifndef HEADER_H #define HEADER_H // 头文件内容 #endif ``` 2. **一次性包含** ```c #pragma once // 头文件内容 ``` 3. **宏作用域控制** ```c #undef TEMP_MACRO #define TEMP_MACRO(x) (x * 2) int result = TEMP_MACRO(5); #undef TEMP_MACRO ``` **注意事项:** 1. **宏的副作用** ```c #define SQUARE(x) ((x) * (x)) int i = 2; int result = SQUARE(i++); // 未定义行为 ``` 2. **宏的括号** ```c #define MUL(a, b) ((a) * (b)) int result = MUL(2 + 3, 4); // 正确: (2 + 3) * 4 = 20 ``` 3. **条件编译的嵌套** ```c #ifdef DEBUG #ifdef VERBOSE #define LOG(x) printf x #else #define LOG(x) #endif #else #define LOG(x) #endif ```
服务端 · 2月18日 17:21