C语言系统学习系列 - 第7篇
探索C语言的高级特性和现代编程技巧,学会编写高质量、可维护的专业级代码。

前言

经过前面六篇文章的系统学习,您已经掌握了C语言的核心概念和基本技能。现在是时候深入探索C语言的高级特性,学习现代C编程的最佳实践,提升代码质量和开发效率。

现代C语言的发展

C语言并非一成不变,从C89到C99、C11、C18,每个标准都引入了新的特性:

  • C99:变长数组、内联函数、复数类型、布尔类型
  • C11:多线程支持、原子操作、静态断言、匿名结构体
  • C18:主要是错误修正和澄清

本文学习目标:

  • 掌握预处理器的高级用法
  • 学会使用可变参数函数
  • 理解内联函数和编译器优化
  • 掌握现代C语言的新特性
  • 学会代码规范和最佳实践
上一篇:文件操作与数据持久化

一、预处理器高级技巧

(一)宏的高级用法

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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

// 调试宏
#ifdef DEBUG
#define DBG_PRINT(fmt, ...) \
printf("[DEBUG] %s:%d: " fmt, __FILE__, __LINE__, ##__VA_ARGS__)
#else
#define DBG_PRINT(fmt, ...) ((void)0)
#endif

// 性能测试宏
#define BENCHMARK_START(name) \
do { \
printf("开始测试: %s\n", name); \
clock_t start_time = clock();

#define BENCHMARK_END() \
clock_t end_time = clock(); \
double elapsed = ((double)(end_time - start_time)) / CLOCKS_PER_SEC; \
printf("测试完成,耗时: %.4f 秒\n", elapsed); \
} while(0)

// 安全的内存分配宏
#define SAFE_MALLOC(ptr, size, type) \
do { \
(ptr) = (type*)malloc(size); \
if ((ptr) == NULL) { \
fprintf(stderr, "内存分配失败: %s:%d\n", __FILE__, __LINE__); \
exit(EXIT_FAILURE); \
} \
DBG_PRINT("分配内存: %p, 大小: %zu\n", (void*)(ptr), (size_t)(size)); \
} while(0)

#define SAFE_FREE(ptr) \
do { \
if ((ptr) != NULL) { \
DBG_PRINT("释放内存: %p\n", (void*)(ptr)); \
free(ptr); \
(ptr) = NULL; \
} \
} while(0)

// 数组大小宏
#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))

// 最大值和最小值宏(类型安全)
#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 STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)

// 连接宏
#define CONCAT(a, b) a##b
#define CONCAT3(a, b, c) a##b##c

// 版本信息宏
#define VERSION_MAJOR 1
#define VERSION_MINOR 2
#define VERSION_PATCH 3
#define VERSION_STRING TOSTRING(VERSION_MAJOR) "." \
TOSTRING(VERSION_MINOR) "." \
TOSTRING(VERSION_PATCH)

void demonstrate_advanced_macros(void) {
printf("=== 高级宏演示 ===\n");

// 版本信息
printf("程序版本: %s\n", VERSION_STRING);

// 调试信息
DBG_PRINT("这是一条调试信息,数字: %d\n", 42);

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

// 类型安全的最大值最小值
int a = 10, b = 20;
float x = 3.14f, y = 2.71f;
printf("MAX(%d, %d) = %d\n", a, b, MAX(a, b));
printf("MIN(%.2f, %.2f) = %.2f\n", x, y, MIN(x, y));

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

// 安全内存分配
int* ptr;
SAFE_MALLOC(ptr, 10 * sizeof(int), int);

// 使用分配的内存
for (int i = 0; i < 10; i++) {
ptr[i] = i * i;
}

printf("分配的数组内容: ");
for (int i = 0; i < 10; i++) {
printf("%d ", ptr[i]);
}
printf("\n");

SAFE_FREE(ptr);
}

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

// 编译器检测
#ifdef __GNUC__
printf("使用GCC编译器,版本: %d.%d.%d\n",
__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
#elif defined(_MSC_VER)
printf("使用Microsoft Visual C++编译器\n");
#elif defined(__clang__)
printf("使用Clang编译器\n");
#else
printf("未知编译器\n");
#endif

// 操作系统检测
#ifdef _WIN32
printf("运行在Windows系统\n");
#elif defined(__linux__)
printf("运行在Linux系统\n");
#elif defined(__APPLE__)
printf("运行在macOS系统\n");
#else
printf("未知操作系统\n");
#endif

// 架构检测
#ifdef _WIN64
printf("64位Windows\n");
#elif defined(_WIN32)
printf("32位Windows\n");
#elif defined(__x86_64__)
printf("64位x86架构\n");
#elif defined(__i386__)
printf("32位x86架构\n");
#elif defined(__aarch64__)
printf("64位ARM架构\n");
#else
printf("未知架构\n");
#endif

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

int main(void) {
demonstrate_advanced_macros();
demonstrate_conditional_compilation();
return 0;
}

2. X-宏技术

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
#include <stdio.h>
#include <string.h>

// X-宏定义:错误代码
#define ERROR_CODES \
X(SUCCESS, 0, "操作成功") \
X(INVALID_PARAMETER, 1, "无效参数") \
X(OUT_OF_MEMORY, 2, "内存不足") \
X(FILE_NOT_FOUND, 3, "文件未找到") \
X(PERMISSION_DENIED, 4, "权限被拒绝") \
X(NETWORK_ERROR, 5, "网络错误") \
X(TIMEOUT, 6, "操作超时") \
X(UNKNOWN_ERROR, 99, "未知错误")

// 生成枚举
typedef enum {
#define X(name, code, desc) ERROR_##name = code,
ERROR_CODES
#undef X
} ErrorCode;

// 生成错误描述数组
static const char* error_descriptions[] = {
#define X(name, code, desc) [ERROR_##name] = desc,
ERROR_CODES
#undef X
};

// 生成错误名称数组
static const char* error_names[] = {
#define X(name, code, desc) [ERROR_##name] = #name,
ERROR_CODES
#undef X
};

// 获取错误描述
const char* get_error_description(ErrorCode code) {
if (code >= 0 && code < sizeof(error_descriptions) / sizeof(error_descriptions[0])) {
return error_descriptions[code] ? error_descriptions[code] : "未定义错误";
}
return "无效错误代码";
}

// 获取错误名称
const char* get_error_name(ErrorCode code) {
if (code >= 0 && code < sizeof(error_names) / sizeof(error_names[0])) {
return error_names[code] ? error_names[code] : "UNDEFINED";
}
return "INVALID";
}

// X-宏定义:状态机状态
#define STATES \
X(IDLE, "空闲状态") \
X(CONNECTING, "连接中") \
X(CONNECTED, "已连接") \
X(SENDING, "发送中") \
X(RECEIVING, "接收中") \
X(DISCONNECTING, "断开连接中") \
X(ERROR, "错误状态")

// 生成状态枚举
typedef enum {
#define X(name, desc) STATE_##name,
STATES
#undef X
STATE_COUNT
} State;

// 生成状态名称数组
static const char* state_names[] = {
#define X(name, desc) #name,
STATES
#undef X
};

// 生成状态描述数组
static const char* state_descriptions[] = {
#define X(name, desc) desc,
STATES
#undef X
};

// 状态机结构
typedef struct {
State current_state;
State previous_state;
} StateMachine;

// 状态转换
void state_machine_transition(StateMachine* sm, State new_state) {
if (sm != NULL && new_state < STATE_COUNT) {
printf("状态转换: %s -> %s\n",
state_names[sm->current_state],
state_names[new_state]);
sm->previous_state = sm->current_state;
sm->current_state = new_state;
}
}

// 打印状态信息
void print_state_info(const StateMachine* sm) {
if (sm != NULL) {
printf("当前状态: %s (%s)\n",
state_names[sm->current_state],
state_descriptions[sm->current_state]);
printf("前一状态: %s (%s)\n",
state_names[sm->previous_state],
state_descriptions[sm->previous_state]);
}
}

void demonstrate_x_macros(void) {
printf("=== X-宏技术演示 ===\n");

// 错误代码演示
printf("错误代码演示:\n");
ErrorCode errors[] = {ERROR_SUCCESS, ERROR_INVALID_PARAMETER,
ERROR_OUT_OF_MEMORY, ERROR_FILE_NOT_FOUND};

for (int i = 0; i < 4; i++) {
printf("错误 %s (%d): %s\n",
get_error_name(errors[i]),
errors[i],
get_error_description(errors[i]));
}

// 状态机演示
printf("\n状态机演示:\n");
StateMachine sm = {STATE_IDLE, STATE_IDLE};

print_state_info(&sm);

state_machine_transition(&sm, STATE_CONNECTING);
state_machine_transition(&sm, STATE_CONNECTED);
state_machine_transition(&sm, STATE_SENDING);
state_machine_transition(&sm, STATE_ERROR);

print_state_info(&sm);

// 显示所有状态
printf("\n所有可用状态:\n");
for (int i = 0; i < STATE_COUNT; i++) {
printf("%d: %s - %s\n", i, state_names[i], state_descriptions[i]);
}
}

int main(void) {
demonstrate_x_macros();
return 0;
}

(二)可变参数函数

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
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

// 计算多个整数的和
int sum_integers(int count, ...) {
va_list args;
va_start(args, count);

int total = 0;
for (int i = 0; i < count; i++) {
total += va_arg(args, int);
}

va_end(args);
return total;
}

// 计算多个浮点数的平均值
double average_doubles(int count, ...) {
if (count <= 0) return 0.0;

va_list args;
va_start(args, count);

double total = 0.0;
for (int i = 0; i < count; i++) {
total += va_arg(args, double);
}

va_end(args);
return total / count;
}

// 查找多个字符串中的最长字符串
const char* find_longest_string(int count, ...) {
if (count <= 0) return NULL;

va_list args;
va_start(args, count);

const char* longest = va_arg(args, const char*);
size_t max_length = strlen(longest);

for (int i = 1; i < count; i++) {
const char* current = va_arg(args, const char*);
size_t current_length = strlen(current);
if (current_length > max_length) {
longest = current;
max_length = current_length;
}
}

va_end(args);
return longest;
}

// 自定义printf函数(简化版)
void my_printf(const char* format, ...) {
va_list args;
va_start(args, format);

const char* p = format;
while (*p != '\0') {
if (*p == '%' && *(p + 1) != '\0') {
p++; // 跳过%
switch (*p) {
case 'd': {
int value = va_arg(args, int);
printf("%d", value);
break;
}
case 'f': {
double value = va_arg(args, double);
printf("%.2f", value);
break;
}
case 's': {
const char* value = va_arg(args, const char*);
printf("%s", value);
break;
}
case 'c': {
int value = va_arg(args, int); // char被提升为int
printf("%c", value);
break;
}
case '%': {
printf("%%");
break;
}
default:
printf("%%%c", *p); // 未知格式符
break;
}
} else {
printf("%c", *p);
}
p++;
}

va_end(args);
}

// 日志函数
typedef enum {
LOG_DEBUG,
LOG_INFO,
LOG_WARNING,
LOG_ERROR
} LogLevel;

void log_message(LogLevel level, const char* format, ...) {
const char* level_names[] = {"DEBUG", "INFO", "WARNING", "ERROR"};

// 打印日志级别
printf("[%s] ", level_names[level]);

// 处理可变参数
va_list args;
va_start(args, format);
vprintf(format, args); // 使用vprintf处理可变参数
va_end(args);

printf("\n");
}

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

// 整数求和
printf("整数求和:\n");
printf("sum(3, 1, 2, 3) = %d\n", sum_integers(3, 1, 2, 3));
printf("sum(5, 10, 20, 30, 40, 50) = %d\n", sum_integers(5, 10, 20, 30, 40, 50));

// 浮点数平均值
printf("\n浮点数平均值:\n");
printf("average(3, 1.5, 2.5, 3.0) = %.2f\n",
average_doubles(3, 1.5, 2.5, 3.0));
printf("average(4, 10.0, 20.0, 30.0, 40.0) = %.2f\n",
average_doubles(4, 10.0, 20.0, 30.0, 40.0));

// 最长字符串
printf("\n最长字符串:\n");
const char* longest = find_longest_string(4, "hello", "world", "programming", "C");
printf("最长字符串: \"%s\"\n", longest);

// 自定义printf
printf("\n自定义printf演示:\n");
my_printf("整数: %d, 浮点数: %f, 字符串: %s, 字符: %c\n",
42, 3.14159, "Hello", 'A');

// 日志函数
printf("\n日志函数演示:\n");
log_message(LOG_INFO, "程序启动成功");
log_message(LOG_WARNING, "内存使用率达到 %d%%", 85);
log_message(LOG_ERROR, "文件 %s 打开失败,错误代码: %d", "config.txt", 404);
log_message(LOG_DEBUG, "变量值: x=%d, y=%.2f", 10, 3.14);
}

int main(void) {
demonstrate_variadic_functions();
return 0;
}

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
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>

// 参数类型枚举
typedef enum {
ARG_INT,
ARG_DOUBLE,
ARG_STRING,
ARG_CHAR,
ARG_END
} ArgType;

// 参数值联合体
typedef union {
int i;
double d;
const char* s;
char c;
} ArgValue;

// 类型化参数结构
typedef struct {
ArgType type;
ArgValue value;
} TypedArg;

// 类型安全的打印函数
void safe_print(const char* format, ...) {
va_list args;
va_start(args, format);

const char* p = format;
while (*p != '\0') {
if (*p == '%' && *(p + 1) != '\0') {
p++; // 跳过%

// 获取类型信息
ArgType expected_type = va_arg(args, ArgType);

if (expected_type == ARG_END) {
printf("[错误: 参数不足]");
break;
}

switch (*p) {
case 'd':
if (expected_type == ARG_INT) {
int value = va_arg(args, int);
printf("%d", value);
} else {
printf("[类型错误: 期望int]");
}
break;

case 'f':
if (expected_type == ARG_DOUBLE) {
double value = va_arg(args, double);
printf("%.2f", value);
} else {
printf("[类型错误: 期望double]");
}
break;

case 's':
if (expected_type == ARG_STRING) {
const char* value = va_arg(args, const char*);
printf("%s", value);
} else {
printf("[类型错误: 期望string]");
}
break;

case 'c':
if (expected_type == ARG_CHAR) {
int value = va_arg(args, int);
printf("%c", value);
} else {
printf("[类型错误: 期望char]");
}
break;

default:
printf("%%%c", *p);
break;
}
} else {
printf("%c", *p);
}
p++;
}

va_end(args);
}

// 宏简化类型安全调用
#define SAFE_PRINT(format, ...) \
safe_print(format, ##__VA_ARGS__, ARG_END)

#define INT_ARG(x) ARG_INT, (x)
#define DOUBLE_ARG(x) ARG_DOUBLE, (x)
#define STRING_ARG(x) ARG_STRING, (x)
#define CHAR_ARG(x) ARG_CHAR, (x)

// 动态参数数组
typedef struct {
TypedArg* args;
int count;
int capacity;
} ArgArray;

ArgArray* arg_array_create(void) {
ArgArray* arr = malloc(sizeof(ArgArray));
if (arr == NULL) return NULL;

arr->args = NULL;
arr->count = 0;
arr->capacity = 0;

return arr;
}

void arg_array_add_int(ArgArray* arr, int value) {
if (arr == NULL) return;

if (arr->count >= arr->capacity) {
int new_capacity = arr->capacity == 0 ? 4 : arr->capacity * 2;
TypedArg* new_args = realloc(arr->args, new_capacity * sizeof(TypedArg));
if (new_args == NULL) return;

arr->args = new_args;
arr->capacity = new_capacity;
}

arr->args[arr->count].type = ARG_INT;
arr->args[arr->count].value.i = value;
arr->count++;
}

void arg_array_add_double(ArgArray* arr, double value) {
if (arr == NULL) return;

if (arr->count >= arr->capacity) {
int new_capacity = arr->capacity == 0 ? 4 : arr->capacity * 2;
TypedArg* new_args = realloc(arr->args, new_capacity * sizeof(TypedArg));
if (new_args == NULL) return;

arr->args = new_args;
arr->capacity = new_capacity;
}

arr->args[arr->count].type = ARG_DOUBLE;
arr->args[arr->count].value.d = value;
arr->count++;
}

void arg_array_add_string(ArgArray* arr, const char* value) {
if (arr == NULL) return;

if (arr->count >= arr->capacity) {
int new_capacity = arr->capacity == 0 ? 4 : arr->capacity * 2;
TypedArg* new_args = realloc(arr->args, new_capacity * sizeof(TypedArg));
if (new_args == NULL) return;

arr->args = new_args;
arr->capacity = new_capacity;
}

arr->args[arr->count].type = ARG_STRING;
arr->args[arr->count].value.s = value;
arr->count++;
}

void arg_array_print(const ArgArray* arr) {
if (arr == NULL) return;

printf("参数数组 (%d个参数):\n", arr->count);
for (int i = 0; i < arr->count; i++) {
printf(" [%d] ", i);
switch (arr->args[i].type) {
case ARG_INT:
printf("int: %d\n", arr->args[i].value.i);
break;
case ARG_DOUBLE:
printf("double: %.2f\n", arr->args[i].value.d);
break;
case ARG_STRING:
printf("string: \"%s\"\n", arr->args[i].value.s);
break;
case ARG_CHAR:
printf("char: '%c'\n", arr->args[i].value.c);
break;
default:
printf("unknown type\n");
break;
}
}
}

void arg_array_free(ArgArray* arr) {
if (arr != NULL) {
free(arr->args);
free(arr);
}
}

void demonstrate_type_safe_variadic(void) {
printf("=== 类型安全可变参数演示 ===\n");

// 类型安全的打印函数
printf("类型安全打印:\n");
safe_print("整数: %d, 浮点数: %f, 字符串: %s\n",
INT_ARG(42), DOUBLE_ARG(3.14), STRING_ARG("Hello"));

// 类型错误演示
printf("\n类型错误演示:\n");
safe_print("整数: %d, 浮点数: %f\n",
DOUBLE_ARG(3.14), INT_ARG(42)); // 故意颠倒类型

// 动态参数数组
printf("\n动态参数数组演示:\n");
ArgArray* arr = arg_array_create();

arg_array_add_int(arr, 100);
arg_array_add_double(arr, 2.718);
arg_array_add_string(arr, "动态参数");
arg_array_add_int(arr, 200);

arg_array_print(arr);

arg_array_free(arr);
}

int main(void) {
demonstrate_type_safe_variadic();
return 0;
}

二、现代C语言特性

(一)C99和C11新特性

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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <complex.h>

// C99特性:变长数组
void demonstrate_vla(void) {
printf("=== 变长数组演示 ===\n");

int n;
printf("请输入数组大小: ");
scanf("%d", &n);

if (n <= 0 || n > 1000) {
printf("无效的数组大小\n");
return;
}

// 变长数组声明
int vla[n];

// 初始化数组
for (int i = 0; i < n; i++) {
vla[i] = i * i;
}

printf("变长数组内容 (大小: %d):\n", n);
for (int i = 0; i < n; i++) {
printf("%d ", vla[i]);
if ((i + 1) % 10 == 0) printf("\n");
}
if (n % 10 != 0) printf("\n");

// 二维变长数组
printf("\n二维变长数组演示:\n");
int rows = 3, cols = 4;
int matrix[rows][cols];

// 初始化矩阵
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
matrix[i][j] = i * cols + j + 1;
}
}

// 打印矩阵
printf("矩阵 %dx%d:\n", rows, cols);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%3d ", matrix[i][j]);
}
printf("\n");
}
}

// 使用变长数组的函数
double calculate_average(int n, double arr[n]) {
double sum = 0.0;
for (int i = 0; i < n; i++) {
sum += arr[i];
}
return sum / n;
}

void matrix_multiply(int n, int m, int p,
double a[n][m], double b[m][p], double result[n][p]) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < p; j++) {
result[i][j] = 0.0;
for (int k = 0; k < m; k++) {
result[i][j] += a[i][k] * b[k][j];
}
}
}
}

// C99特性:复合字面量
void demonstrate_compound_literals(void) {
printf("\n=== 复合字面量演示 ===\n");

// 数组复合字面量
int* ptr = (int[]){1, 2, 3, 4, 5};
printf("数组复合字面量: ");
for (int i = 0; i < 5; i++) {
printf("%d ", ptr[i]);
}
printf("\n");

// 结构体复合字面量
typedef struct {
int x, y;
char name[20];
} Point;

Point p = (Point){.x = 10, .y = 20, .name = "原点"};
printf("结构体复合字面量: (%d, %d) - %s\n", p.x, p.y, p.name);

// 函数参数中使用复合字面量
double avg = calculate_average(5, (double[]){1.5, 2.5, 3.5, 4.5, 5.5});
printf("平均值: %.2f\n", avg);

// 矩阵乘法演示
printf("\n矩阵乘法演示:\n");
double a[2][3] = {{1, 2, 3}, {4, 5, 6}};
double b[3][2] = {{1, 2}, {3, 4}, {5, 6}};
double result[2][2];

matrix_multiply(2, 3, 2, a, b, result);

printf("矩阵A (2x3):\n");
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 3; j++) {
printf("%.0f ", a[i][j]);
}
printf("\n");
}

printf("矩阵B (3x2):\n");
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 2; j++) {
printf("%.0f ", b[i][j]);
}
printf("\n");
}

printf("结果矩阵 (2x2):\n");
for (int i = 0; i < 2; i++) {
for (int j = 0; j < 2; j++) {
printf("%.0f ", result[i][j]);
}
printf("\n");
}
}

// C99特性:复数类型
void demonstrate_complex_numbers(void) {
printf("\n=== 复数类型演示 ===\n");

// 复数声明和初始化
double complex z1 = 3.0 + 4.0 * I;
double complex z2 = 1.0 - 2.0 * I;

printf("z1 = %.1f + %.1fi\n", creal(z1), cimag(z1));
printf("z2 = %.1f + %.1fi\n", creal(z2), cimag(z2));

// 复数运算
double complex sum = z1 + z2;
double complex diff = z1 - z2;
double complex product = z1 * z2;
double complex quotient = z1 / z2;

printf("\n复数运算:\n");
printf("z1 + z2 = %.1f + %.1fi\n", creal(sum), cimag(sum));
printf("z1 - z2 = %.1f + %.1fi\n", creal(diff), cimag(diff));
printf("z1 * z2 = %.1f + %.1fi\n", creal(product), cimag(product));
printf("z1 / z2 = %.2f + %.2fi\n", creal(quotient), cimag(quotient));

// 复数函数
double magnitude = cabs(z1);
double phase = carg(z1);
double complex conjugate = conj(z1);

printf("\n复数函数:\n");
printf("|z1| = %.2f\n", magnitude);
printf("arg(z1) = %.2f 弧度\n", phase);
printf("conj(z1) = %.1f + %.1fi\n", creal(conjugate), cimag(conjugate));
}

int main(void) {
demonstrate_vla();
demonstrate_compound_literals();
demonstrate_complex_numbers();
return 0;
}

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
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>

// C99特性:内联函数
static inline int max(int a, int b) {
return (a > b) ? a : b;
}

static inline int min(int a, int b) {
return (a < b) ? a : b;
}

static inline double square(double x) {
return x * x;
}

static inline bool is_power_of_two(unsigned int n) {
return n != 0 && (n & (n - 1)) == 0;
}

// 内联函数用于位操作
static inline unsigned int set_bit(unsigned int value, int bit) {
return value | (1U << bit);
}

static inline unsigned int clear_bit(unsigned int value, int bit) {
return value & ~(1U << bit);
}

static inline bool test_bit(unsigned int value, int bit) {
return (value & (1U << bit)) != 0;
}

static inline unsigned int toggle_bit(unsigned int value, int bit) {
return value ^ (1U << bit);
}

// C11特性:静态断言
_Static_assert(sizeof(int) >= 4, "int类型必须至少4字节");
_Static_assert(sizeof(void*) == sizeof(size_t), "指针大小必须等于size_t");

// 结构体对齐检查
struct TestStruct {
char c;
int i;
double d;
};

_Static_assert(sizeof(struct TestStruct) >= sizeof(char) + sizeof(int) + sizeof(double),
"结构体大小异常");

// 数组大小检查
#define BUFFER_SIZE 1024
char buffer[BUFFER_SIZE];
_Static_assert(BUFFER_SIZE >= 512, "缓冲区大小必须至少512字节");

void demonstrate_inline_functions(void) {
printf("=== 内联函数演示 ===\n");

// 基本内联函数
int a = 15, b = 23;
printf("max(%d, %d) = %d\n", a, b, max(a, b));
printf("min(%d, %d) = %d\n", a, b, min(a, b));

double x = 3.5;
printf("square(%.1f) = %.2f\n", x, square(x));

// 2的幂检查
printf("\n2的幂检查:\n");
unsigned int numbers[] = {1, 2, 3, 4, 8, 15, 16, 32, 33, 64};
int count = sizeof(numbers) / sizeof(numbers[0]);

for (int i = 0; i < count; i++) {
printf("%u %s 2的幂\n", numbers[i],
is_power_of_two(numbers[i]) ? "是" : "不是");
}

// 位操作演示
printf("\n位操作演示:\n");
unsigned int value = 0;

printf("初始值: 0x%08X (%u)\n", value, value);

value = set_bit(value, 3);
printf("设置第3位: 0x%08X (%u)\n", value, value);

value = set_bit(value, 7);
printf("设置第7位: 0x%08X (%u)\n", value, value);

printf("测试第3位: %s\n", test_bit(value, 3) ? "已设置" : "未设置");
printf("测试第5位: %s\n", test_bit(value, 5) ? "已设置" : "未设置");

value = toggle_bit(value, 3);
printf("切换第3位: 0x%08X (%u)\n", value, value);

value = clear_bit(value, 7);
printf("清除第7位: 0x%08X (%u)\n", value, value);
}

// 运行时断言演示
void demonstrate_assertions(void) {
printf("\n=== 断言演示 ===\n");

int array[] = {1, 2, 3, 4, 5};
int size = sizeof(array) / sizeof(array[0]);

// 运行时断言
assert(size > 0); // 确保数组不为空
printf("数组大小: %d (断言通过)\n", size);

// 函数参数检查
int index = 2;
assert(index >= 0 && index < size); // 边界检查
printf("array[%d] = %d (边界检查通过)\n", index, array[index]);

// 指针检查
int* ptr = array;
assert(ptr != NULL); // 空指针检查
printf("指针有效,值: %d\n", *ptr);

printf("所有断言检查通过\n");

// 注意:以下断言会导致程序终止(已注释)
// assert(size == 10); // 这会失败并终止程序
}

// 编译时计算(使用内联函数)
static inline int factorial_compile_time(int n) {
return (n <= 1) ? 1 : n * factorial_compile_time(n - 1);
}

// 使用宏进行编译时计算
#define FACTORIAL_5 (5 * 4 * 3 * 2 * 1)

void demonstrate_compile_time_computation(void) {
printf("\n=== 编译时计算演示 ===\n");

// 编译时常量
const int fact5_macro = FACTORIAL_5;
printf("5! (宏计算) = %d\n", fact5_macro);

// 内联函数(可能在编译时优化)
printf("5! (内联函数) = %d\n", factorial_compile_time(5));

// 静态断言验证编译时计算
_Static_assert(FACTORIAL_5 == 120, "5!应该等于120");
printf("编译时计算验证通过\n");
}

int main(void) {
printf("静态断言检查通过,程序开始执行\n\n");

demonstrate_inline_functions();
demonstrate_assertions();
demonstrate_compile_time_computation();

return 0;
}

三、代码质量与最佳实践

(一)错误处理和防御性编程

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
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <stdbool.h>

// 错误代码定义
typedef enum {
RESULT_SUCCESS = 0,
RESULT_NULL_POINTER,
RESULT_INVALID_PARAMETER,
RESULT_OUT_OF_MEMORY,
RESULT_BUFFER_TOO_SMALL,
RESULT_FILE_ERROR,
RESULT_UNKNOWN_ERROR
} ResultCode;

// 结果结构体
typedef struct {
ResultCode code;
const char* message;
int line;
const char* file;
} Result;

// 创建结果的宏
#define RESULT_OK() \
((Result){RESULT_SUCCESS, "操作成功", __LINE__, __FILE__})

#define RESULT_ERROR(code, msg) \
((Result){code, msg, __LINE__, __FILE__})

// 检查结果的宏
#define CHECK_RESULT(result) \
do { \
if ((result).code != RESULT_SUCCESS) { \
fprintf(stderr, "错误 [%s:%d]: %s\n", \
(result).file, (result).line, (result).message); \
return result; \
} \
} while(0)

// 安全的字符串复制函数
Result safe_strcpy(char* dest, size_t dest_size, const char* src) {
// 参数验证
if (dest == NULL) {
return RESULT_ERROR(RESULT_NULL_POINTER, "目标指针为空");
}
if (src == NULL) {
return RESULT_ERROR(RESULT_NULL_POINTER, "源指针为空");
}
if (dest_size == 0) {
return RESULT_ERROR(RESULT_INVALID_PARAMETER, "目标缓冲区大小为0");
}

size_t src_len = strlen(src);
if (src_len >= dest_size) {
return RESULT_ERROR(RESULT_BUFFER_TOO_SMALL, "目标缓冲区太小");
}

strcpy(dest, src);
return RESULT_OK();
}

// 安全的整数除法
Result safe_divide(int dividend, int divisor, int* result) {
if (result == NULL) {
return RESULT_ERROR(RESULT_NULL_POINTER, "结果指针为空");
}

if (divisor == 0) {
return RESULT_ERROR(RESULT_INVALID_PARAMETER, "除数不能为零");
}

// 检查整数溢出
if (dividend == INT_MIN && divisor == -1) {
return RESULT_ERROR(RESULT_INVALID_PARAMETER, "整数溢出");
}

*result = dividend / divisor;
return RESULT_OK();
}

// 安全的内存分配
Result safe_malloc(void** ptr, size_t size) {
if (ptr == NULL) {
return RESULT_ERROR(RESULT_NULL_POINTER, "指针参数为空");
}

if (size == 0) {
return RESULT_ERROR(RESULT_INVALID_PARAMETER, "分配大小为0");
}

*ptr = malloc(size);
if (*ptr == NULL) {
return RESULT_ERROR(RESULT_OUT_OF_MEMORY, "内存分配失败");
}

return RESULT_OK();
}

// 安全的文件读取
Result safe_read_file(const char* filename, char** content, size_t* size) {
if (filename == NULL || content == NULL || size == NULL) {
return RESULT_ERROR(RESULT_NULL_POINTER, "参数指针为空");
}

FILE* file = fopen(filename, "r");
if (file == NULL) {
char error_msg[256];
snprintf(error_msg, sizeof(error_msg), "无法打开文件: %s", strerror(errno));
return RESULT_ERROR(RESULT_FILE_ERROR, error_msg);
}

// 获取文件大小
fseek(file, 0, SEEK_END);
long file_size = ftell(file);
fseek(file, 0, SEEK_SET);

if (file_size < 0) {
fclose(file);
return RESULT_ERROR(RESULT_FILE_ERROR, "无法获取文件大小");
}

// 分配内存
char* buffer = malloc(file_size + 1);
if (buffer == NULL) {
fclose(file);
return RESULT_ERROR(RESULT_OUT_OF_MEMORY, "内存分配失败");
}

// 读取文件
size_t bytes_read = fread(buffer, 1, file_size, file);
if (bytes_read != (size_t)file_size) {
free(buffer);
fclose(file);
return RESULT_ERROR(RESULT_FILE_ERROR, "文件读取失败");
}

buffer[file_size] = '\0';
fclose(file);

*content = buffer;
*size = file_size;

return RESULT_OK();
}

// 数组处理函数
Result process_array(int* array, size_t size, int (*processor)(int)) {
if (array == NULL) {
return RESULT_ERROR(RESULT_NULL_POINTER, "数组指针为空");
}
if (processor == NULL) {
return RESULT_ERROR(RESULT_NULL_POINTER, "处理函数指针为空");
}
if (size == 0) {
return RESULT_ERROR(RESULT_INVALID_PARAMETER, "数组大小为0");
}

for (size_t i = 0; i < size; i++) {
array[i] = processor(array[i]);
}

return RESULT_OK();
}

// 示例处理函数
int double_value(int x) {
return x * 2;
}

int square_value(int x) {
return x * x;
}

void demonstrate_error_handling(void) {
printf("=== 错误处理演示 ===\n");

// 字符串复制测试
char buffer[20];
Result result;

printf("1. 安全字符串复制测试:\n");
result = safe_strcpy(buffer, sizeof(buffer), "Hello, World!");
if (result.code == RESULT_SUCCESS) {
printf("复制成功: %s\n", buffer);
} else {
printf("复制失败: %s\n", result.message);
}

// 缓冲区太小的情况
result = safe_strcpy(buffer, sizeof(buffer), "这是一个非常长的字符串,超过了缓冲区的大小");
if (result.code != RESULT_SUCCESS) {
printf("预期错误: %s\n", result.message);
}

// 除法测试
printf("\n2. 安全除法测试:\n");
int div_result;
result = safe_divide(10, 3, &div_result);
if (result.code == RESULT_SUCCESS) {
printf("10 / 3 = %d\n", div_result);
}

result = safe_divide(10, 0, &div_result);
if (result.code != RESULT_SUCCESS) {
printf("预期错误: %s\n", result.message);
}

// 内存分配测试
printf("\n3. 安全内存分配测试:\n");
void* ptr;
result = safe_malloc(&ptr, 100);
if (result.code == RESULT_SUCCESS) {
printf("内存分配成功: %p\n", ptr);
free(ptr);
}

// 数组处理测试
printf("\n4. 数组处理测试:\n");
int numbers[] = {1, 2, 3, 4, 5};
size_t count = sizeof(numbers) / sizeof(numbers[0]);

printf("原始数组: ");
for (size_t i = 0; i < count; i++) {
printf("%d ", numbers[i]);
}
printf("\n");

result = process_array(numbers, count, double_value);
if (result.code == RESULT_SUCCESS) {
printf("翻倍后: ");
for (size_t i = 0; i < count; i++) {
printf("%d ", numbers[i]);
}
printf("\n");
}
}

int main(void) {
demonstrate_error_handling();
return 0;
}

四、总结与下一步

(一)本文重点回顾

通过本文的深入学习,您已经掌握了:

预处理器高级技巧:

  • 复杂宏的编写和调试技巧
  • X-宏技术的应用
  • 条件编译和平台适配

可变参数函数:

  • 标准可变参数的使用
  • 类型安全的可变参数设计
  • 动态参数处理技术

现代C语言特性:

  • C99/C11新特性的应用
  • 内联函数和编译器优化
  • 静态断言和编译时检查

代码质量提升:

  • 错误处理的最佳实践
  • 防御性编程技巧
  • 代码规范和可维护性

(二)编程最佳实践

  1. 错误处理:始终检查函数返回值和边界条件
  2. 内存管理:合理使用动态内存,避免泄漏
  3. 代码规范:保持一致的命名和格式风格
  4. 文档注释:为复杂函数和数据结构添加详细注释
  5. 测试驱动:编写测试用例验证代码正确性
下一篇:项目实战

参考资料:

  • 《C程序设计语言》(第2版)- Brian W. Kernighan & Dennis M. Ritchie
  • 《C专家编程》- Peter van der Linden
  • 《高质量C/C++编程指南》- 林锐
  • 《现代C语言程序设计》- K. N. King
  • ISO/IEC 9899:2018 - C语言国际标准
  • GCC手册:https://gcc.gnu.org/onlinedocs/