C++ Assert()断言机制原理以及使用方法

发布时间 - 2026-01-10 22:24:54    点击率:

MSDN原文如是说:

Evaluates an expression and, when the result is false, prints a diagnostic message and aborts the program.

(判断一个表达式,如果结果为假,输出诊断消息并中止程序。)

void assert(  
  int expression  
); 

参数:Expression (including pointers) that evaluates to nonzero or 0.(表达式【包括指针】是非零或零)

原理:assert的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。

MSDN示例程序

// crt_assert.c 
// compile with: /c 
#include <stdio.h> 
#include <assert.h> 
#include <string.h> 
 
void analyze_string( char *string );  // Prototype 
 
int main( void ) 
{ 
  char test1[] = "abc", *test2 = NULL, test3[] = ""; 
 
  printf ( "Analyzing string '%s'\n", test1 ); fflush( stdout ); 
  analyze_string( test1 ); 
  printf ( "Analyzing string '%s'\n", test2 ); fflush( stdout ); 
  analyze_string( test2 ); 
  printf ( "Analyzing string '%s'\n", test3 ); fflush( stdout ); 
  analyze_string( test3 ); 
} 
 
// Tests a string to see if it is NULL,  
// empty, or longer than 0 characters. 
void analyze_string( char * string ) 
{ 
  assert( string != NULL );    // Cannot be NULL 
  assert( *string != '\0' );    // Cannot be empty 
  assert( strlen( string ) > 2 ); // Length must exceed 2 
} 

输出结果

Analyzing string 'abc' 
Analyzing string '(null)' 
Assertion failed: string != NULL, file assert.cpp, line 25 
 
abnormal program termination 

用法总结:

1) 在函数开始处检验传入参数的合法性

如:

int resetBufferSize(int nNewSize)
{
 //功能:改变缓冲区大小,
 //参数:nNewSize 缓冲区新长度
//返回值:缓冲区当前长度
//说明:保持原信息内容不变   nNewSize<=0表示清除缓冲区
assert(nNewSize >= 0);
assert(nNewSize <= MAX_BUFFER_SIZE);

 ...
}

2) 每个assert只检验一个条件,因为同时检验多个条件时,如果断言失败,无法直观的判断是哪个条件失败

不好:  assert(nOffset>=0 && nOffset+nSize<=m_nInfomationSize);

好:  assert(nOffset >= 0);
       assert(nOffset+nSize <= m_nInfomationSize);


3) 不能使用改变环境的语句,因为assert只在DEBUG个生效,如果这么做,会使用程序在真正运行时遇到问题


错误: assert(i++ < 100)

这是因为如果出错,比如在执行之前i=100,那么这条语句就不会执行,那么i++这条命令就没有执行。

正确: assert(i < 100);
         i++;

4) assert和后面的语句应空一行,以形成逻辑和视觉上的一致感

5) 有的地方,assert不能代替条件过滤

ASSERT只有在Debug版本中才有效,如果编译为Release版本则被忽略掉。(在C中,ASSERT是宏而不是函数),使用ASSERT“断言”容易在debug时输出程序错误所在。

而assert()的功能类似,它是ANSI C标准中规定的函数,它与ASSERT的一个重要区别是可以用在Release版本中。

使用assert的缺点是,频繁的调用会极大的影响程序的性能,增加额外的开销。

在调试结束后,可以通过在包含#include <assert.h>的语句之前插入 #define NDEBUG 来禁用assert调用,示例代码如下:

#include <stdio.h>
#define NDEBUG
#include <assert.h>

加入#define NDEBUG之后,上文第一个例子输出结果为:

Analyzing string 'abc' 
Analyzing string '(null)' 
Analyzing string '' 

在面试中经常用到的一个题目:

已知memcpy的函数为: void* memcpy(void *dest , const void* src , size_t count)其中dest是目的指针,src是源指针。不调用c++/c的memcpy库函数,请编写memcpy。

void* memcpy(void *dst, const void *src, size_t count)   
{   
  //安全检查 
  assert( (dst != NULL) && (src != NULL) );   
 
  unsigned char *pdst = (unsigned char *)dst;   
  const unsigned char *psrc = (const unsigned char *)src;   
 
  //防止内存重复 
  assert(!(psrc<=pdst && pdst<psrc+count));   
  assert(!(pdst<=psrc && psrc<pdst+count));   
 
  while(count--)   
  {   
    *pdst = *psrc;   
    pdst++;   
    psrc++;   
  }   
  return dst;   
}  

以上这篇C++ Assert()断言机制原理以及使用方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。


# c  # assert  # 断言  # C++ 中assert()函数用法总结  # 详解C++编程中断言static_assert的使用  # C++ assert()函数用法案例详解  # C/C++ assert()函数用法案例总结  # C++之assert推荐用法及注意事项  # 这条  # 给大家  # 第一个  # 多个  # 它是  # 可以通过  # 希望能  # 只在  # 一个重要  # 如是说  # 这么做  # 这篇  # 用在  # 这是因为  # 如在  # 即为  # 小编  # 它与  # 值为  # 大家多多 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: Claude怎样写结构化提示词_Claude结构化提示词写法【教程】  七夕网站制作视频,七夕大促活动怎么报名?  简历没回改:利用AI润色让你的文字更专业  Android中AutoCompleteTextView自动提示  Laravel数据库迁移怎么用_Laravel Migration管理数据库结构的正确姿势  Laravel如何为API生成Swagger或OpenAPI文档  奇安信“盘古石”团队突破 iOS 26.1 提权  敲碗10年!Mac系列传将迎来「触控与联网」双革新  Python面向对象测试方法_mock解析【教程】  网站制作大概多少钱一个,做一个平台网站大概多少钱?  香港服务器选型指南:免备案配置与高效建站方案解析  在线制作视频网站免费,都有哪些好的动漫网站?  网站制作免费,什么网站能看正片电影?  怎样使用JSON进行数据交换_它有什么限制  北京专业网站制作设计师招聘,北京白云观官方网站?  详解CentOS6.5 安装 MySQL5.1.71的方法  如何在IIS中配置站点IP、端口及主机头?  微信小程序 require机制详解及实例代码  如何在HTML表单中获取用户输入并结合JavaScript动态控制复利计算循环  JS去除重复并统计数量的实现方法  如何续费美橙建站之星域名及服务?  北京的网站制作公司有哪些,哪个视频网站最好?  Laravel的辅助函数有哪些_Laravel常用Helpers函数提高开发效率  如何自定义建站之星模板颜色并下载新样式?  Laravel如何集成微信支付SDK_Laravel使用yansongda-pay实现扫码支付【实战】  Laravel怎么使用Intervention Image库处理图片上传和缩放  Laravel如何保护应用免受CSRF攻击?(原理和示例)  html5如何设置样式_HTML5样式设置方法与CSS应用技巧【教程】  大连网站制作费用,大连新青年网站,五年四班里的视频怎样下载啊?  打开php文件提示内存不足_怎么调整php内存限制【解决方案】  Laravel Vite是做什么的_Laravel前端资源打包工具Vite配置与使用  Laravel如何使用Gate和Policy进行权限控制_Laravel权限判定与策略规则配置  WordPress 子目录安装中正确处理脚本路径的完整指南  如何用y主机助手快速搭建网站?  Laravel如何生成PDF或Excel文件_Laravel文档导出工具与使用教程  Laravel怎么为数据库表字段添加索引以优化查询  Laravel用户密码怎么加密_Laravel Hash门面使用教程  夸克浏览器网页跳转延迟怎么办 夸克浏览器跳转优化  网站制作软件有哪些,制图软件有哪些?  怎么制作网站设计模板图片,有电商商品详情页面的免费模板素材网站推荐吗?  最好的网站制作公司,网购哪个网站口碑最好,推荐几个?谢谢?  Laravel如何与Inertia.js和Vue/React构建现代单页应用  利用python获取某年中每个月的第一天和最后一天  西安市网站制作公司,哪个相亲网站比较好?西安比较好的相亲网站?  如何快速生成高效建站系统源代码?  西安专业网站制作公司有哪些,陕西省建行官方网站?  如何用虚拟主机快速搭建网站?详细步骤解析  php打包exe后无法访问网络共享_共享权限设置方法【教程】  如何在IIS7中新建站点?详细步骤解析  香港服务器租用费用高吗?如何避免常见误区?