跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
C 语言断言库
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
{{Note|本文介绍的是C标准库中的断言机制,如需了解其他编程语言的断言实现,请查阅相关文档。}} = C语言断言库(assert.h)= '''断言(Assertion)'''是C语言标准库(assert.h)提供的调试辅助工具,用于在程序运行时验证假设条件是否成立。当断言条件为假时,程序会立即终止并输出错误信息,帮助开发者快速定位逻辑错误。 == 核心概念 == 断言基于一个简单哲学:'''"如果代码正确运行,这个条件必须为真"'''。它不同于错误处理机制(如errno或异常),而是专门用于捕获'''程序员的逻辑错误'''。 === 工作原理 === <mermaid> graph LR A[程序执行] --> B{断言条件为真?} B -->|是| C[继续执行] B -->|否| D[输出错误信息并终止] </mermaid> == 标准库接口 == assert.h只提供一个宏: ```c void assert(int expression); ``` == 基础用法示例 == <syntaxhighlight lang="c"> #include <stdio.h> #include <assert.h> void calculate_sqrt(double x) { // 前置条件断言 assert(x >= 0.0 && "输入不能为负数"); double result = /* 平方根计算 */; // 后置条件断言 assert(result * result - x < 0.0001 && "计算结果精度不足"); } int main() { calculate_sqrt(4.0); // 正常执行 calculate_sqrt(-1.0); // 触发断言 return 0; } </syntaxhighlight> 输出示例(当x=-1时): ```text assertion_fail.c:5: calculate_sqrt: Assertion `x >= 0.0 && "输入不能为负数"' failed. Aborted (core dumped) ``` == 关键特性 == === 编译控制 === 通过定义NDEBUG宏可禁用所有断言: ```c #define NDEBUG // 必须放在#include <assert.h>之前 #include <assert.h> ``` === 错误信息组成 === 断言失败时会输出: 1. 源文件名 2. 行号 3. 函数名(C99起) 4. 失败的表达式 == 进阶应用 == === 防御性编程 === ```c #include <assert.h> void process_buffer(char *buf, size_t size) { assert(buf != NULL); assert(size > 0 && size <= MAX_BUFFER_SIZE); // 处理逻辑 } ``` === 不变式检查 === ```c struct Account { double balance; // 其他字段... }; void transfer(struct Account *a, struct Account *b, double amount) { assert(a != NULL && b != NULL); assert(amount > 0); double old_total = a->balance + b->balance; // 转账操作... // 验证不变式 assert(fabs((a->balance + b->balance) - old_total) < 1e-6); } ``` == 最佳实践 == {| class="wikitable" |- ! 场景 !! 推荐做法 !! 不推荐做法 |- | 参数验证 | 对关键参数使用断言 | 用断言替代所有错误检查 |- | 资源检查 | 结合常规错误处理 | <code>assert(fopen() != NULL)</code> |- | 发布版本 | 通过NDEBUG禁用 | 保留断言影响性能 |} == 数学表达 == 断言可形式化为: <math> assert(P) = \begin{cases} \text{继续执行} & \text{当 } P = \text{真} \\ \text{终止程序} & \text{当 } P = \text{假} \end{cases} </math> == 常见误区 == 1. '''副作用问题''':断言表达式不应产生副作用 ```c assert(x++ > 0); // 错误!发布模式下行为不同 ``` 2. '''性能敏感路径''':避免在热点代码中使用复杂断言 3. '''用户输入验证''':断言不是用来检查用户输入的,应使用常规错误检查 == 扩展思考 == === 自定义断言 === 可定义增强版断言宏: ```c #define STRONG_ASSERT(expr) \ do { \ if (!(expr)) { \ fprintf(stderr, "[%s] Critical failure at %s:%d\n", \ __TIMESTAMP__, __FILE__, __LINE__); \ abort(); \ } \ } while(0) ``` === 静态断言(C11)=== C11引入编译期断言: ```c static_assert(sizeof(int) == 4, "int必须是32位"); ``` {{Warning|断言不能替代正常的错误处理机制,它只是开发阶段的辅助工具}} == 总结 == 断言是C程序员重要的调试工具: * 优点:快速暴露逻辑错误,自带详细上下文信息 * 限制:仅适用于开发阶段,需通过NDEBUG控制 * 适用场景:不变式检查、前置/后置条件验证、不可能到达的代码路径 通过合理使用断言,可以显著提高代码的健壮性和可维护性。 [[Category:编程语言]] [[Category:C]] [[Category:C 语言标准库]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)
该页面使用的模板:
模板:Mbox
(
编辑
)
模板:Note
(
编辑
)
模板:Warning
(
编辑
)
模块:Arguments
(
编辑
)
模块:Message box
(
编辑
)
模块:Message box/ambox.css
(
编辑
)
模块:Message box/configuration
(
编辑
)
模块:Yesno
(
编辑
)