Z
ZHANK
高级技巧

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 函数代替宏