目录
一、断言概述
二、基本用法
三、工作原理
四、断言的优点
五、启用和禁用断言
六、性能考虑
七、最佳实践
八、示例代码
一、断言概述
assert.h
头文件定义了宏 assert()
,用于在运行时验证程序是否符合指定条件。如果条件不满足,程序会报错并终止运行。这种机制被称为"断言"(assertion),是程序开发中常用的调试工具。
二、基本用法
assert(p != NULL);
上述代码会在程序执行到该行时,验证变量 p
是否不等于 NULL
。如果条件为真,程序继续执行;如果为假,程序会终止并输出错误信息。
三、工作原理
assert()
宏接受一个表达式作为参数:
-
当表达式为真(返回值非零)时,
assert()
不产生任何作用 -
当表达式为假(返回值为零)时,
assert()
会:-
向标准错误流
stderr
写入错误信息 -
显示未通过的表达式
-
显示包含该表达式的文件名和行号
-
调用
abort()
终止程序执行
-
四、断言的优点
-
自动诊断:自动标识问题所在的文件和行号,便于快速定位错误
-
灵活启用/禁用:通过定义
NDEBUG
宏可以全局启用或禁用断言 -
文档作用:断言可以充当代码注释,明确表达程序员的预期
-
防御性编程:帮助在开发阶段捕获非法条件和逻辑错误
五、启用和禁用断言
在 #include <assert.h>
之前定义 NDEBUG
宏可以禁用所有断言:
#define NDEBUG
#include <assert.h>
这样编译器会忽略文件中的所有 assert()
语句。如需重新启用断言,只需移除或注释掉 NDEBUG
的定义。
六、性能考虑
断言的缺点是会引入额外的运行时检查,可能影响程序性能。因此:
-
Debug 版本:建议启用断言,帮助开发者发现问题
-
Release 版本:通常禁用断言以提高性能
在 Visual Studio 等集成开发环境中,Release 版本会自动优化掉断言代码。
七、最佳实践
-
使用断言检查不应发生的条件,而不是预期的错误情况
-
不要用断言替代正常的错误处理
-
断言表达式不应有副作用(如修改变量值)
-
在关键算法和复杂逻辑处添加断言
-
为函数的前置条件和后置条件添加断言
八、示例代码
#include <stdio.h>
#include <assert.h>int divide(int a, int b) {assert(b != 0 && "Divide by zero"); // 检查除数不为零return a / b;
}int main() {printf("10/2 = %d\n", divide(10, 2));printf("10/0 = %d\n", divide(10, 0)); // 会触发断言失败return 0;
}
当断言失败时,程序会输出类似以下信息: