C语言高级编程技巧:预处理器与宏编程

C语言预处理器是一个强大的文本处理工具,它在编译之前对源代码进行处理。掌握预处理器和宏编程技巧,可以让你的代码更加灵活、可维护和高效。

1. 预处理器基础

1.1 预处理指令概览

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <stdio.h>
#include <stdlib.h>

// 简单宏定义
#define PI 3.14159265359
#define MAX_SIZE 1000
#define SQUARE(x) ((x) * (x))

// 条件编译
#ifdef DEBUG
#define DBG_PRINT(fmt, ...) printf("[DEBUG] " fmt "\n", ##__VA_ARGS__)
#else
#define DBG_PRINT(fmt, ...) // 空宏
#endif

// 字符串化和连接
#define STRINGIFY(x) #x
#define CONCAT(a, b) a##b

void preprocessor_basics() {
printf("=== 预处理器基础演示 ===\n");

// 使用简单宏
printf("PI = %f\n", PI);
printf("MAX_SIZE = %d\n", MAX_SIZE);
printf("SQUARE(5) = %d\n", SQUARE(5));

// 调试宏演示
DBG_PRINT("这是一条调试信息");
DBG_PRINT("变量值: %d", 42);

// 字符串化
printf("STRINGIFY(Hello) = %s\n", STRINGIFY(Hello));
printf("STRINGIFY(123) = %s\n", STRINGIFY(123));

// 标识符连接
int CONCAT(var, 1) = 10;
int CONCAT(var, 2) = 20;
printf("var1 = %d, var2 = %d\n", var1, var2);

printf("\n");
}

int main() {
preprocessor_basics();
return 0;
}

1.2 预定义宏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#include <stdio.h>
#include <time.h>

void predefined_macros_demo() {
printf("=== 预定义宏演示 ===\n");

// 文件和行号信息
printf("当前文件: %s\n", __FILE__);
printf("当前行号: %d\n", __LINE__);
printf("当前函数: %s\n", __func__);

// 编译时间信息
printf("编译日期: %s\n", __DATE__);
printf("编译时间: %s\n", __TIME__);

// 编译器信息
#ifdef __GNUC__
printf("GCC 编译器版本: %d.%d.%d\n",
__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
#endif

#ifdef _MSC_VER
printf("MSVC 编译器版本: %d\n", _MSC_VER);
#endif

// C标准版本
#if __STDC_VERSION__ >= 201112L
printf("C11 或更新标准\n");
#elif __STDC_VERSION__ >= 199901L
printf("C99 标准\n");
#elif __STDC_VERSION__ >= 199409L
printf("C95 标准\n");
#else
printf("C90 标准\n");
#endif

printf("\n");
}

int main() {
predefined_macros_demo();
return 0;
}

2. 高级宏技巧

2.1 可变参数宏

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#include <stdio.h>
#include <stdarg.h>
#include <time.h>

// 日志级别
typedef enum {
LOG_DEBUG,
LOG_INFO,
LOG_WARNING,
LOG_ERROR
} LogLevel;

// 当前日志级别
static LogLevel current_log_level = LOG_INFO;

// 日志级别名称
static const char* log_level_names[] = {
"DEBUG", "INFO", "WARNING", "ERROR"
};

// 获取当前时间字符串
static void get_timestamp(char* buffer, size_t size) {
time_t now = time(NULL);
struct tm* tm_info = localtime(&now);
strftime(buffer, size, "%Y-%m-%d %H:%M:%S", tm_info);
}

// 基础日志函数
void log_message(LogLevel level, const char* file, int line,
const char* func, const char* format, ...) {
if (level < current_log_level) {
return; // 过滤低级别日志
}

char timestamp[32];
get_timestamp(timestamp, sizeof(timestamp));

printf("[%s] [%s] %s:%d in %s(): ",
timestamp, log_level_names[level], file, line, func);

va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);

printf("\n");
}

// 可变参数宏定义
#define LOG_DEBUG(fmt, ...) \
log_message(LOG_DEBUG, __FILE__, __LINE__, __func__, fmt, ##__VA_ARGS__)

#define LOG_INFO(fmt, ...) \
log_message(LOG_INFO, __FILE__, __LINE__, __func__, fmt, ##__VA_ARGS__)

#define LOG_WARNING(fmt, ...) \
log_message(LOG_WARNING, __FILE__, __LINE__, __func__, fmt, ##__VA_ARGS__)

#define LOG_ERROR(fmt, ...) \
log_message(LOG_ERROR, __FILE__, __LINE__, __func__, fmt, ##__VA_ARGS__)

// 断言宏
#define ASSERT(condition, fmt, ...) \
do { \
if (!(condition)) { \
LOG_ERROR("断言失败: " #condition ". " fmt, ##__VA_ARGS__); \
abort(); \
} \
} while(0)

// 性能测量宏
#define BENCHMARK(name, code) \
do { \
clock_t start = clock(); \
code; \
clock_t end = clock(); \
double time_spent = ((double)(end - start)) / CLOCKS_PER_SEC; \
LOG_INFO("性能测试 [%s]: %.6f 秒", name, time_spent); \
} while(0)

void variadic_macros_demo() {
printf("=== 可变参数宏演示 ===\n");

// 设置日志级别
current_log_level = LOG_DEBUG;

// 各种日志级别测试
LOG_DEBUG("这是调试信息");
LOG_INFO("程序启动,版本: %s", "1.0.0");
LOG_WARNING("内存使用率: %d%%", 85);
LOG_ERROR("文件打开失败: %s", "config.txt");

// 断言测试
int value = 42;
ASSERT(value > 0, "值必须为正数,当前值: %d", value);

// 性能测试
BENCHMARK("数组求和", {
int sum = 0;
for (int i = 0; i < 1000000; i++) {
sum += i;
}
printf("求和结果: %d\n", sum);
});

printf("\n");
}

int main() {
variadic_macros_demo();
return 0;
}

2.2 宏的高级应用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 自动变量声明和初始化
#define AUTO_VAR(type, name, value) type name = value
#define AUTO_ARRAY(type, name, size) type name[size] = {0}

// 安全的内存操作宏
#define SAFE_FREE(ptr) \
do { \
if (ptr) { \
free(ptr); \
ptr = NULL; \
} \
} while(0)

#define SAFE_MALLOC(ptr, type, count) \
do { \
ptr = (type*)malloc(sizeof(type) * (count)); \
if (!ptr) { \
fprintf(stderr, "内存分配失败: %s:%d\n", __FILE__, __LINE__); \
exit(EXIT_FAILURE); \
} \
} while(0)

// 数组操作宏
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
#define ARRAY_FOREACH(arr, var) \
for (size_t _i = 0; _i < ARRAY_SIZE(arr) && ((var) = (arr)[_i], 1); _i++)

// 最值宏(类型安全)
#define MAX(a, b) ({ \
typeof(a) _a = (a); \
typeof(b) _b = (b); \
_a > _b ? _a : _b; \
})

#define MIN(a, b) ({ \
typeof(a) _a = (a); \
typeof(b) _b = (b); \
_a < _b ? _a : _b; \
})

// 交换宏
#define SWAP(a, b) \
do { \
typeof(a) temp = (a); \
(a) = (b); \
(b) = temp; \
} while(0)

// 范围检查宏
#define IN_RANGE(value, min, max) ((value) >= (min) && (value) <= (max))

// 结构体字段偏移宏
#define OFFSET_OF(type, member) ((size_t)&((type*)0)->member)

// 容器宏(从成员指针获取结构体指针)
#define CONTAINER_OF(ptr, type, member) \
((type*)((char*)(ptr) - OFFSET_OF(type, member)))

// 测试结构体
typedef struct {
int id;
char name[32];
double score;
} Student;

void advanced_macros_demo() {
printf("=== 高级宏应用演示 ===\n");

// 自动变量声明
AUTO_VAR(int, count, 10);
AUTO_ARRAY(char, buffer, 256);
printf("count = %d, buffer size = %zu\n", count, sizeof(buffer));

// 安全内存操作
int* numbers;
SAFE_MALLOC(numbers, int, 5);
for (int i = 0; i < 5; i++) {
numbers[i] = i * i;
}
printf("动态数组: ");
for (int i = 0; i < 5; i++) {
printf("%d ", numbers[i]);
}
printf("\n");
SAFE_FREE(numbers);

// 数组操作
int arr[] = {3, 1, 4, 1, 5, 9, 2, 6};
printf("数组大小: %zu\n", ARRAY_SIZE(arr));

printf("数组元素: ");
int element;
ARRAY_FOREACH(arr, element) {
printf("%d ", element);
}
printf("\n");

// 最值和交换
int a = 10, b = 20;
printf("a = %d, b = %d\n", a, b);
printf("MAX(a, b) = %d\n", MAX(a, b));
printf("MIN(a, b) = %d\n", MIN(a, b));

SWAP(a, b);
printf("交换后: a = %d, b = %d\n", a, b);

// 范围检查
int score = 85;
printf("分数 %d %s\n", score,
IN_RANGE(score, 0, 100) ? "有效" : "无效");

// 结构体偏移
printf("Student.id 偏移: %zu\n", OFFSET_OF(Student, id));
printf("Student.name 偏移: %zu\n", OFFSET_OF(Student, name));
printf("Student.score 偏移: %zu\n", OFFSET_OF(Student, score));

// 容器宏演示
Student student = {1, "张三", 95.5};
char* name_ptr = student.name;
Student* student_ptr = CONTAINER_OF(name_ptr, Student, name);
printf("通过name指针获取结构体: id=%d, score=%.1f\n",
student_ptr->id, student_ptr->score);

printf("\n");
}

int main() {
advanced_macros_demo();
return 0;
}

3. 条件编译

3.1 平台相关代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#include <stdio.h>

// 平台检测
#if defined(_WIN32) || defined(_WIN64)
#define PLATFORM "Windows"
#define PATH_SEPARATOR '\\'
#include <windows.h>

void platform_sleep(int seconds) {
Sleep(seconds * 1000);
}

void get_platform_info() {
SYSTEM_INFO si;
GetSystemInfo(&si);
printf("处理器数量: %lu\n", si.dwNumberOfProcessors);
}

#elif defined(__linux__)
#define PLATFORM "Linux"
#define PATH_SEPARATOR '/'
#include <unistd.h>
#include <sys/sysinfo.h>

void platform_sleep(int seconds) {
sleep(seconds);
}

void get_platform_info() {
printf("处理器数量: %ld\n", sysconf(_SC_NPROCESSORS_ONLN));
}

#elif defined(__APPLE__)
#define PLATFORM "macOS"
#define PATH_SEPARATOR '/'
#include <unistd.h>
#include <sys/sysctl.h>

void platform_sleep(int seconds) {
sleep(seconds);
}

void get_platform_info() {
int mib[2] = {CTL_HW, HW_NCPU};
int ncpu;
size_t len = sizeof(ncpu);
sysctl(mib, 2, &ncpu, &len, NULL, 0);
printf("处理器数量: %d\n", ncpu);
}

#else
#define PLATFORM "Unknown"
#define PATH_SEPARATOR '/'

void platform_sleep(int seconds) {
// 通用实现或空实现
printf("睡眠 %d 秒(模拟)\n", seconds);
}

void get_platform_info() {
printf("无法获取平台信息\n");
}
#endif

// 编译器相关代码
#ifdef __GNUC__
#define FORCE_INLINE __attribute__((always_inline)) inline
#define PACKED __attribute__((packed))
#define ALIGN(n) __attribute__((aligned(n)))
#elif defined(_MSC_VER)
#define FORCE_INLINE __forceinline
#define PACKED
#define ALIGN(n) __declspec(align(n))
#else
#define FORCE_INLINE inline
#define PACKED
#define ALIGN(n)
#endif

// 使用编译器特定属性的结构体
typedef struct PACKED {
char a;
int b;
char c;
} PackedStruct;

typedef struct {
char a;
int b;
char c;
} ALIGN(16) AlignedStruct;

// 强制内联函数
FORCE_INLINE int fast_multiply(int a, int b) {
return a * b;
}

void conditional_compilation_demo() {
printf("=== 条件编译演示 ===\n");

printf("当前平台: %s\n", PLATFORM);
printf("路径分隔符: '%c'\n", PATH_SEPARATOR);

get_platform_info();

printf("PackedStruct 大小: %zu 字节\n", sizeof(PackedStruct));
printf("AlignedStruct 大小: %zu 字节\n", sizeof(AlignedStruct));

int result = fast_multiply(6, 7);
printf("快速乘法结果: %d\n", result);

printf("\n");
}

int main() {
conditional_compilation_demo();
return 0;
}

3.2 调试和发布版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

// 调试配置
#ifdef DEBUG
#define DEBUG_MODE 1
#define OPTIMIZATION_LEVEL 0
#else
#define DEBUG_MODE 0
#define OPTIMIZATION_LEVEL 2
#endif

// 调试宏
#if DEBUG_MODE
#define DEBUG_PRINT(fmt, ...) \
printf("[DEBUG %s:%d] " fmt "\n", __func__, __LINE__, ##__VA_ARGS__)

#define DEBUG_ASSERT(condition) \
do { \
if (!(condition)) { \
printf("[ASSERT FAILED %s:%d] " #condition "\n", __FILE__, __LINE__); \
abort(); \
} \
} while(0)

#define DEBUG_TRACE() \
printf("[TRACE] 进入函数 %s (文件: %s, 行: %d)\n", __func__, __FILE__, __LINE__)

// 调试版本的内存分配跟踪
static int allocation_count = 0;

void* debug_malloc(size_t size, const char* file, int line) {
void* ptr = malloc(size);
allocation_count++;
printf("[MALLOC %s:%d] 分配 %zu 字节,地址: %p,总分配次数: %d\n",
file, line, size, ptr, allocation_count);
return ptr;
}

void debug_free(void* ptr, const char* file, int line) {
if (ptr) {
allocation_count--;
printf("[FREE %s:%d] 释放地址: %p,剩余分配次数: %d\n",
file, line, ptr, allocation_count);
free(ptr);
}
}

#define malloc(size) debug_malloc(size, __FILE__, __LINE__)
#define free(ptr) debug_free(ptr, __FILE__, __LINE__)

#else
#define DEBUG_PRINT(fmt, ...) // 空宏
#define DEBUG_ASSERT(condition) // 空宏
#define DEBUG_TRACE() // 空宏
#endif

// 性能测试宏
#if DEBUG_MODE
#define PERFORMANCE_TEST(name, code) \
do { \
clock_t start = clock(); \
code; \
clock_t end = clock(); \
double time_spent = ((double)(end - start)) / CLOCKS_PER_SEC; \
printf("[PERF] %s: %.6f 秒\n", name, time_spent); \
} while(0)
#else
#define PERFORMANCE_TEST(name, code) code
#endif

// 版本信息
#define VERSION_MAJOR 1
#define VERSION_MINOR 2
#define VERSION_PATCH 3

#if DEBUG_MODE
#define VERSION_STRING "1.2.3-debug"
#define BUILD_TYPE "Debug"
#else
#define VERSION_STRING "1.2.3-release"
#define BUILD_TYPE "Release"
#endif

// 示例函数
void example_function(int* array, size_t size) {
DEBUG_TRACE();
DEBUG_ASSERT(array != NULL);
DEBUG_ASSERT(size > 0);

DEBUG_PRINT("处理数组,大小: %zu", size);

PERFORMANCE_TEST("数组处理", {
for (size_t i = 0; i < size; i++) {
array[i] = array[i] * 2;
}
});

DEBUG_PRINT("数组处理完成");
}

void debug_release_demo() {
printf("=== 调试和发布版本演示 ===\n");

printf("程序版本: %s\n", VERSION_STRING);
printf("构建类型: %s\n", BUILD_TYPE);
printf("调试模式: %s\n", DEBUG_MODE ? "开启" : "关闭");
printf("优化级别: %d\n", OPTIMIZATION_LEVEL);

// 内存分配测试
int* numbers = (int*)malloc(10 * sizeof(int));
DEBUG_ASSERT(numbers != NULL);

// 初始化数组
for (int i = 0; i < 10; i++) {
numbers[i] = i + 1;
}

DEBUG_PRINT("数组初始化完成");

// 处理数组
example_function(numbers, 10);

// 打印结果
printf("处理后的数组: ");
for (int i = 0; i < 10; i++) {
printf("%d ", numbers[i]);
}
printf("\n");

// 释放内存
free(numbers);

printf("\n");
}

int main() {
debug_release_demo();
return 0;
}

4. 代码生成宏

4.1 数据结构生成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 动态数组生成宏
#define DECLARE_DYNAMIC_ARRAY(type) \
typedef struct { \
type* data; \
size_t size; \
size_t capacity; \
} type##_array_t; \
\
type##_array_t* type##_array_create(size_t initial_capacity) { \
type##_array_t* arr = malloc(sizeof(type##_array_t)); \
if (!arr) return NULL; \
arr->data = malloc(sizeof(type) * initial_capacity); \
if (!arr->data) { \
free(arr); \
return NULL; \
} \
arr->size = 0; \
arr->capacity = initial_capacity; \
return arr; \
} \
\
void type##_array_destroy(type##_array_t* arr) { \
if (arr) { \
free(arr->data); \
free(arr); \
} \
} \
\
int type##_array_push(type##_array_t* arr, type value) { \
if (arr->size >= arr->capacity) { \
size_t new_capacity = arr->capacity * 2; \
type* new_data = realloc(arr->data, sizeof(type) * new_capacity); \
if (!new_data) return 0; \
arr->data = new_data; \
arr->capacity = new_capacity; \
} \
arr->data[arr->size++] = value; \
return 1; \
} \
\
type type##_array_get(type##_array_t* arr, size_t index) { \
return arr->data[index]; \
} \
\
size_t type##_array_size(type##_array_t* arr) { \
return arr->size; \
}

// 生成不同类型的动态数组
DECLARE_DYNAMIC_ARRAY(int)
DECLARE_DYNAMIC_ARRAY(double)
DECLARE_DYNAMIC_ARRAY(char*)

// 链表生成宏
#define DECLARE_LINKED_LIST(type) \
typedef struct type##_node { \
type data; \
struct type##_node* next; \
} type##_node_t; \
\
typedef struct { \
type##_node_t* head; \
type##_node_t* tail; \
size_t size; \
} type##_list_t; \
\
type##_list_t* type##_list_create(void) { \
type##_list_t* list = malloc(sizeof(type##_list_t)); \
if (!list) return NULL; \
list->head = NULL; \
list->tail = NULL; \
list->size = 0; \
return list; \
} \
\
void type##_list_destroy(type##_list_t* list) { \
if (!list) return; \
type##_node_t* current = list->head; \
while (current) { \
type##_node_t* next = current->next; \
free(current); \
current = next; \
} \
free(list); \
} \
\
int type##_list_append(type##_list_t* list, type value) { \
type##_node_t* node = malloc(sizeof(type##_node_t)); \
if (!node) return 0; \
node->data = value; \
node->next = NULL; \
if (!list->head) { \
list->head = list->tail = node; \
} else { \
list->tail->next = node; \
list->tail = node; \
} \
list->size++; \
return 1; \
} \
\
void type##_list_foreach(type##_list_t* list, void (*func)(type)) { \
type##_node_t* current = list->head; \
while (current) { \
func(current->data); \
current = current->next; \
} \
}

// 生成链表
DECLARE_LINKED_LIST(int)
DECLARE_LINKED_LIST(double)

// 打印函数
void print_int(int value) {
printf("%d ", value);
}

void print_double(double value) {
printf("%.2f ", value);
}

void data_structure_generation_demo() {
printf("=== 数据结构生成演示 ===\n");

// 测试整数动态数组
printf("\n整数动态数组测试:\n");
int_array_t* int_arr = int_array_create(5);

for (int i = 1; i <= 10; i++) {
int_array_push(int_arr, i * i);
}

printf("数组大小: %zu\n", int_array_size(int_arr));
printf("数组内容: ");
for (size_t i = 0; i < int_array_size(int_arr); i++) {
printf("%d ", int_array_get(int_arr, i));
}
printf("\n");

int_array_destroy(int_arr);

// 测试双精度动态数组
printf("\n双精度动态数组测试:\n");
double_array_t* double_arr = double_array_create(3);

double_array_push(double_arr, 3.14);
double_array_push(double_arr, 2.71);
double_array_push(double_arr, 1.41);
double_array_push(double_arr, 1.73);

printf("数组大小: %zu\n", double_array_size(double_arr));
printf("数组内容: ");
for (size_t i = 0; i < double_array_size(double_arr); i++) {
printf("%.2f ", double_array_get(double_arr, i));
}
printf("\n");

double_array_destroy(double_arr);

// 测试整数链表
printf("\n整数链表测试:\n");
int_list_t* int_list = int_list_create();

for (int i = 1; i <= 5; i++) {
int_list_append(int_list, i * 10);
}

printf("链表内容: ");
int_list_foreach(int_list, print_int);
printf("\n");

int_list_destroy(int_list);

// 测试双精度链表
printf("\n双精度链表测试:\n");
double_list_t* double_list = double_list_create();

double_list_append(double_list, 1.1);
double_list_append(double_list, 2.2);
double_list_append(double_list, 3.3);

printf("链表内容: ");
double_list_foreach(double_list, print_double);
printf("\n");

double_list_destroy(double_list);

printf("\n");
}

int main() {
data_structure_generation_demo();
return 0;
}

4.2 属性和方法生成

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 属性生成宏(getter/setter)
#define DECLARE_PROPERTY(type, name) \
type _##name; \
type get_##name(void) { \
return _##name; \
} \
void set_##name(type value) { \
_##name = value; \
}

// 带验证的属性生成宏
#define DECLARE_VALIDATED_PROPERTY(type, name, validator) \
type _##name; \
type get_##name(void) { \
return _##name; \
} \
int set_##name(type value) { \
if (validator(value)) { \
_##name = value; \
return 1; \
} \
return 0; \
}

// 枚举到字符串转换生成宏
#define DECLARE_ENUM_TO_STRING(enum_name, ...) \
const char* enum_name##_to_string(enum_name value) { \
static const char* names[] = {__VA_ARGS__}; \
static const size_t count = sizeof(names) / sizeof(names[0]); \
if (value >= 0 && value < count) { \
return names[value]; \
} \
return "UNKNOWN"; \
}

// 比较函数生成宏
#define DECLARE_COMPARE_FUNCTION(type, name) \
int compare_##name(const void* a, const void* b) { \
type va = *(const type*)a; \
type vb = *(const type*)b; \
if (va < vb) return -1; \
if (va > vb) return 1; \
return 0; \
}

// 示例:使用属性生成宏
struct Person {
DECLARE_PROPERTY(int, age)
DECLARE_PROPERTY(char*, name)
};

// 验证函数
int validate_age(int age) {
return age >= 0 && age <= 150;
}

int validate_score(double score) {
return score >= 0.0 && score <= 100.0;
}

// 带验证的属性
struct Student {
DECLARE_VALIDATED_PROPERTY(int, age, validate_age)
DECLARE_VALIDATED_PROPERTY(double, score, validate_score)
};

// 枚举定义
typedef enum {
COLOR_RED,
COLOR_GREEN,
COLOR_BLUE,
COLOR_YELLOW,
COLOR_PURPLE
} Color;

// 生成枚举到字符串转换函数
DECLARE_ENUM_TO_STRING(Color, "RED", "GREEN", "BLUE", "YELLOW", "PURPLE")

// 生成比较函数
DECLARE_COMPARE_FUNCTION(int, int)
DECLARE_COMPARE_FUNCTION(double, double)

// 序列化宏
#define DECLARE_SERIALIZATION(type, format_spec) \
void serialize_##type(type value, char* buffer, size_t size) { \
snprintf(buffer, size, format_spec, value); \
} \
type deserialize_##type(const char* str) { \
type value; \
sscanf(str, format_spec, &value); \
return value; \
}

// 生成序列化函数
DECLARE_SERIALIZATION(int, "%d")
DECLARE_SERIALIZATION(double, "%lf")

void property_method_generation_demo() {
printf("=== 属性和方法生成演示 ===\n");

// 测试基本属性
printf("\n基本属性测试:\n");
set_age(25);
set_name("张三");
printf("年龄: %d\n", get_age());
printf("姓名: %s\n", get_name());

// 测试带验证的属性
printf("\n带验证的属性测试:\n");
if (set_age(30)) {
printf("设置年龄成功: %d\n", get_age());
} else {
printf("设置年龄失败\n");
}

if (set_age(200)) {
printf("设置年龄成功: %d\n", get_age());
} else {
printf("设置年龄失败(年龄无效)\n");
}

if (set_score(95.5)) {
printf("设置分数成功: %.1f\n", get_score());
} else {
printf("设置分数失败\n");
}

if (set_score(150.0)) {
printf("设置分数成功: %.1f\n", get_score());
} else {
printf("设置分数失败(分数无效)\n");
}

// 测试枚举到字符串转换
printf("\n枚举到字符串转换测试:\n");
for (int i = 0; i < 6; i++) {
printf("Color %d: %s\n", i, Color_to_string((Color)i));
}

// 测试比较函数
printf("\n比较函数测试:\n");
int arr[] = {5, 2, 8, 1, 9, 3};
size_t arr_size = sizeof(arr) / sizeof(arr[0]);

printf("排序前: ");
for (size_t i = 0; i < arr_size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

qsort(arr, arr_size, sizeof(int), compare_int);

printf("排序后: ");
for (size_t i = 0; i < arr_size; i++) {
printf("%d ", arr[i]);
}
printf("\n");

// 测试序列化
printf("\n序列化测试:\n");
char buffer[64];

serialize_int(42, buffer, sizeof(buffer));
printf("序列化整数: %s\n", buffer);
int restored_int = deserialize_int(buffer);
printf("反序列化整数: %d\n", restored_int);

serialize_double(3.14159, buffer, sizeof(buffer));
printf("序列化浮点数: %s\n", buffer);
double restored_double = deserialize_double(buffer);
printf("反序列化浮点数: %.5f\n", restored_double);

printf("\n");
}

int main() {
property_method_generation_demo();
return 0;
}

5. 宏编程最佳实践

5.1 宏的安全使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <stdio.h>
#include <stdlib.h>

// 错误的宏定义示例
#define BAD_MAX(a, b) a > b ? a : b
#define BAD_SQUARE(x) x * x
#define BAD_ABS(x) x < 0 ? -x : x

// 正确的宏定义示例
#define SAFE_MAX(a, b) ((a) > (b) ? (a) : (b))
#define SAFE_SQUARE(x) ((x) * (x))
#define SAFE_ABS(x) ((x) < 0 ? -(x) : (x))

// 更安全的宏(避免副作用)
#define SAFER_MAX(a, b) ({ \
typeof(a) _a = (a); \
typeof(b) _b = (b); \
_a > _b ? _a : _b; \
})

#define SAFER_SQUARE(x) ({ \
typeof(x) _x = (x); \
_x * _x; \
})

// 多语句宏的正确写法
#define SAFE_MULTI_STATEMENT(x) \
do { \
printf("Processing: %d\n", x); \
x = x * 2; \
printf("Result: %d\n", x); \
} while(0)

// 错误的多语句宏
#define BAD_MULTI_STATEMENT(x) \
printf("Processing: %d\n", x); \
x = x * 2; \
printf("Result: %d\n", x)

void macro_safety_demo() {
printf("=== 宏安全使用演示 ===\n");

// 演示优先级问题
printf("\n优先级问题演示:\n");
int a = 3, b = 5;

// 错误的宏可能产生意外结果
printf("BAD_MAX(2 + 3, 4): %d (期望: 5, 实际可能不对)\n", BAD_MAX(2 + 3, 4));
printf("SAFE_MAX(2 + 3, 4): %d (正确)\n", SAFE_MAX(2 + 3, 4));

// 演示副作用问题
printf("\n副作用问题演示:\n");
int x = 5;
printf("x = %d\n", x);

// 错误的宏会多次计算参数
printf("BAD_SQUARE(++x): %d, x = %d (x被多次递增)\n", BAD_SQUARE(++x), x);

x = 5; // 重置
printf("SAFER_SQUARE(++x): %d, x = %d (x只递增一次)\n", SAFER_SQUARE(++x), x);

// 演示多语句宏的问题
printf("\n多语句宏演示:\n");
int value = 10;

// 安全的多语句宏
if (value > 5)
SAFE_MULTI_STATEMENT(value);

printf("最终值: %d\n", value);

printf("\n");
}

int main() {
macro_safety_demo();
return 0;
}

5.2 宏调试技巧

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <stdio.h>
#include <stdlib.h>

// 宏展开调试
#define DEBUG_MACRO_EXPANSION 1

#if DEBUG_MACRO_EXPANSION
#define TRACE_MACRO(name) printf("宏展开: %s\n", #name)
#else
#define TRACE_MACRO(name)
#endif

// 复杂宏的分步调试
#define COMPLEX_CALCULATION(a, b, c) \
({ \
TRACE_MACRO(COMPLEX_CALCULATION); \
typeof(a) _a = (a); \
typeof(b) _b = (b); \
typeof(c) _c = (c); \
printf(" 参数: a=%d, b=%d, c=%d\n", (int)_a, (int)_b, (int)_c); \
typeof(a) _temp1 = _a * _b; \
printf(" 中间结果1: %d * %d = %d\n", (int)_a, (int)_b, (int)_temp1); \
typeof(a) _temp2 = _temp1 + _c; \
printf(" 中间结果2: %d + %d = %d\n", (int)_temp1, (int)_c, (int)_temp2); \
typeof(a) _result = _temp2 * 2; \
printf(" 最终结果: %d * 2 = %d\n", (int)_temp2, (int)_result); \
_result; \
})

// 宏参数类型检查
#define TYPE_CHECK_ADD(a, b) \
({ \
_Static_assert(sizeof(a) == sizeof(b), "参数类型大小必须相同"); \
(a) + (b); \
})

// 宏使用计数器
static int macro_call_count = 0;

#define COUNTED_MACRO(x) \
({ \
macro_call_count++; \
printf("宏调用次数: %d\n", macro_call_count); \
(x) * (x); \
})

void macro_debugging_demo() {
printf("=== 宏调试技巧演示 ===\n");

// 复杂宏调试
printf("\n复杂宏调试:\n");
int result = COMPLEX_CALCULATION(3, 4, 5);
printf("最终返回值: %d\n", result);

// 类型检查
printf("\n类型检查演示:\n");
int a = 10, b = 20;
printf("TYPE_CHECK_ADD(%d, %d) = %d\n", a, b, TYPE_CHECK_ADD(a, b));

// 宏调用计数
printf("\n宏调用计数演示:\n");
for (int i = 1; i <= 3; i++) {
int squared = COUNTED_MACRO(i);
printf("COUNTED_MACRO(%d) = %d\n", i, squared);
}

printf("\n");
}

int main() {
macro_debugging_demo();
return 0;
}

总结

C语言预处理器和宏编程是强大的工具,但需要谨慎使用:

优势:

  1. 代码复用:减少重复代码,提高开发效率
  2. 条件编译:支持多平台、多配置的代码管理
  3. 代码生成:自动生成重复性的数据结构和函数
  4. 性能优化:内联展开,避免函数调用开销
  5. 调试支持:提供丰富的调试和日志功能

注意事项:

  1. 副作用:避免宏参数被多次求值
  2. 优先级:正确使用括号确保运算优先级
  3. 类型安全:使用typeof或模板技术提高类型安全性
  4. 调试困难:宏展开后难以调试,需要合理的调试策略
  5. 可读性:复杂宏可能降低代码可读性

最佳实践:

  1. 简单宏使用大写命名
  2. 复杂宏参数要加括号
  3. 多语句宏使用do-while(0)包装
  4. 使用typeof避免副作用
  5. 提供充分的文档和示例
  6. 在调试版本中添加宏展开跟踪

掌握这些技巧,你将能够充分利用C语言预处理器的强大功能,编写出更加灵活和高效的代码。

版权所有,如有侵权请联系我