C 语言错误处理
更新时间:2026-08-26。本文是
languages/c/主题高手层文档。
本文要回答的问题
- C 没有异常,错误怎么表达和传递?
errno是什么?为什么使用前要清零?- 多文件工程怎么统一错误处理风格?
一、错误表达的三种方式
| 方式 | 例子 | 优点 | 缺点 |
|---|---|---|---|
| 返回值 | return -1 / NULL | 简单直接 | 容易忘检查 |
errno | fopen 失败置 errno | 带错误码 | 线程内全局、易被覆盖 |
| 回调/输出参数 | int *err_out | 灵活 | 啰嗦 |
惯例:函数用返回值表示成败(0 成功 / 非 0 失败码),细节存 errno 或错误码参数。
二、errno 使用要点
errno是线程局部的(现代实现),但调用成功也可能残留旧值——使用前先清零:errno = 0;- 出错后立即检查并记录,别隔了很多调用再查。
- 用
perror("上下文")打印人类可读错误,或用strerror(errno)取字符串。
三、错误传播与清理
深层函数出错要"逐层向上报告",资源还得释放干净。C 的经典模式:
c
if (init_a() < 0) goto fail_a; /* 逐级回滚 */
if (init_b() < 0) goto fail_b;
return 0;
fail_b: cleanup_a();
fail_a: return -1;goto 的"只进不退"错误清理是 C 社区公认模式:每个标签负责"清理已申请的资源",避免泄漏,见 内存泄漏与悬垂指针。
实测:errno 与 goto 清理
c
errno = 0;
FILE *f = fopen("/nonexistent", "r");
if (!f) printf("errno=%d (%s)\n", errno, strerror(errno));实测:
text
errno 演示: errno=2 (No such file or directory)
打开文件失败: No such file or directory ← goto 清理路径的 perror 输出要点:strerror(errno) 把错误码翻译成可读字符串,perror 更是直接打印"上下文 + 错误描述"——这是 C 错误处理的标配工具。
四、与入门层的衔接
- break/continue 与提前退出,见 break 与 continue。
- return 与退出码,见 main 与返回值。
- 多文件工程的错误码约定,见 多文件工程与头文件设计。
一句话总结
C 的错误处理是"返回值报错 + errno 给细节 + goto 做回滚清理"的组合拳:先清 errno、再查返回值、资源逐级回收,错误才不会在深层函数里走丢。
本文已完成填充:示例代码与实测数据已补齐。