C 语言最佳实践
安全编码、缓冲区溢出防御、编码规范、常见陷阱总结
C 语言最佳实践
C 语言的自由是把双刃剑——灵活性巨大,但错误也更容易。好的习惯让 C 代码安全、可靠、可维护。
学完本章你将: 掌握安全编码原则、缓冲区溢出防御、编码规范、常见陷阱。
缓冲区溢出 —— 头号敌人
c
// ❌ 危险模式
char buf[10];
strcpy(buf, longString); // 溢出
gets(buf); // 永远不要用
scanf("%s", buf); // 溢出
sprintf(buf, "%s", src); // 溢出
// ✅ 安全模式
strncpy(buf, src, sizeof(buf) - 1);
buf[sizeof(buf) - 1] = '\0';
fgets(buf, sizeof(buf), stdin);
snprintf(buf, sizeof(buf), "%s", src);
内存管理原则
c
// 1. 配对原则
int *p = malloc(n * sizeof(int));
// ... 使用 ...
free(p);
// 每个 malloc 都要有对应的 free
// 2. 释放后置 NULL
free(p);
p = NULL;
// 3. 检查返回值
p = malloc(...);
if (p == NULL) { /* 处理错误 */ }
编码规范
c
// ✅ 推荐的 C 代码风格
#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 1024
// 函数命名:小写 + 下划线
int calculate_total(int *data, size_t len) {
if (data == NULL || len == 0) {
return 0; // 防御性编程
}
int total = 0;
for (size_t i = 0; i < len; i++) {
total += data[i];
}
return total;
}
int main(void) {
// 变量声明在函数开头(兼容 C89)
int data[] = {1, 2, 3, 4, 5};
int result;
result = calculate_total(data, 5);
printf("总和:%d\n", result);
return 0;
}
常见陷阱速查表
| 陷阱 | 正确做法 |
|---|---|
| `=` 和 `==` 混淆 | 常量放左边:`if (0 == x)` |
| 数组越界 | 用 sizeof 算边界,用安全函数 |
| 未初始化变量 | 声明时初始化:`int x = 0;` |
| 忘记 free | 写 malloc 时立刻写 free |
| 指针未检查 NULL | `if (p == NULL) return;` |
| gets/strcpy | 用 fgets/strncpy/snprintf |
| 宏副作用 | 用 static inline 函数代替宏 |