Linux C 中断言assert()使用简介

assert()是一个调试程序时经常使用的宏,在程序运行时它计算括号内的表达式,如果表达式为FALSE (0), 程序将报告错误,并终止执行。如果表达式不为0,则继续执行后面的语句,它的作用是终止程序以免导致严重后果,同时也便于查找错误

所需头文件:#include <assert.h>

报告错误的条件:assert(0);
[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. void assert(     
  2.    int expression     
  3. );    

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

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

示例程序:

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. void *memcpy(void *pvTo, const void *pvFrom, size_t size)  
  2. {  
  3.     assert((pvTo != NULL) && (pvFrom != NULL));   // 使用断言  
  4.     byte *pbTo = (byte *) pvTo;                   // 防止改变pvTo 的地址  
  5.     byte *pbFrom = (byte *) pvFrom;               // 防止改变pvFrom 的地址  
  6.     while(size -- > 0 )  
  7.     *pbTo ++ = *pbFrom ++ ;  
  8.       
  9.     return pvTo;  
  10. }  


assert() 用法总结:

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

如:

[cpp] view plaincopy
在CODE上查看代码片派生到我的代码片
  1. int resetBufferSize(int nNewSize)  
  2. {  
  3.     //功能:改变缓冲区大小,  
  4.     //参数:nNewSize 缓冲区新长度  
  5.     //返回值:缓冲区当前长度  
  6.     //说明:保持原信息内容不变     nNewSize<=0表示清除缓冲区  
  7.     assert(nNewSize >= 0);  
  8.     assert(nNewSize <= MAX_BUFFER_SIZE);  
  9.   ...  
  10. }  

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>


何时需要使用断言

1.可以在预计正常情况下程序不会到达的地方放置断言:ASSERT( FALSE );
2.断言可以用于检查传递给私有方法的参数。(对于公有方法,因为是提供给外部的接口,所以必须在方法中有相应的参数检验才能保证代码的健壮性)
3.使用断言测试方法执行的前置条件和后置条件
4.使用断言检查类的不变状态,确保任何情况下,某个变量的状态必须满足。(如age属性应大于0小于某个合适值)


什么地方不要使用断言

断言语句不是永远会执行,可以屏蔽也可以启用

因此:

1.不要使用断言作为公共方法的参数检查,公共方法的参数永远都要执行
2.断言语句不可以有任何边界效应,不要使用断言语句去修改变量和改变方法的返回值

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/402483.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL中group by的用法

group by即按照给定字段对结果集进行分组&#xff0c;从字面意义上理解就是根据“by”指定的规则对数据进行分组&#xff0c;所谓的分组就是将一个“数据集”划分成若干个“小区域”&#xff0c;然后针对若干个“小区域”进行数据处理。 group by的写法&#xff1a; 1.select 字…

【Mac】tar 打包指定目录并排除某些目录或文件

如题&#xff0c;bash脚本如下&#xff1a; #!/bin/bashDIR$1 # 要打包的目标目录# 排除的目录列表 if [ "$1" "retail" ]; thenarray(logs lib target .idea .mvn) elif [ "$1" "manager" ]; thenarray(.idea update data/log d…

C#写文本文件如何写入回车换行符?

public void WriteLogFile(String input){//指定日志文件的目录string fname "C:\\Inetpub\\wwwroot\\CommonFunction\\upFile " "\\logfile.txt ";//定义文件信息对象FileInfo finfo new FileInfo(fname);//判断文件是否存在以及是否大于2Kif (finfo.E…

Linux C 数据结构---链表(单向链表)

上一篇我们讲到了线性表&#xff0c;线性表就是数据元素都一一对应&#xff0c;除只有唯一的前驱&#xff0c;唯一的后继。 线性表存储结构分为顺序存储、链式存储。 顺序存储的优点&#xff1a; 顺序存储的缺点&#xff1a; 链表就是典型的链式存储&#xff0c;将线性表L &am…

前端学PHP之文件操作(认真读读)

前面的话 在程序运行时&#xff0c;程序本身和数据一般都存在内存中&#xff0c;当程序运行结束后&#xff0c;存放在内存中的数据被释放。如果需要长期保存程序运行所需的原始数据&#xff0c;或程序运行产生的结果&#xff0c;就需要把数据存储在文件或数据库。一般地&#x…

java 定时任务(三):cron表达式

From: https://www.cnblogs.com/sawyerlsy/p/7208321.html 一、完整的cron表达式由7位以空格分隔的时间元素组成&#xff0c;从左到右分别为&#xff1a;秒、分、时、日期、月份、星期几、年份。其中需要注意的有以下几点&#xff1a; 1. spring 4.x 的spring task中只支持前6种…

1.对程序的看法 2013.8.1

一、一个程序或者是一个项目&#xff0c;其实就是 数据库 与 程序 与 界面的集合。做程序主要就是处理它们三个 之间的关系 处理它们的经典模式就是MVC M model 数据库v view 显示 html css javascriptc con 控制器 编程语言 二、一个项目 就是类库与函数的集合 三、类库 ①构…

做值钱的事比赚钱更有意义

艾伦图灵是英国著名的数学家&#xff0c;二战时期&#xff0c;他在军方邀请下进行德国Enigma密码破译工作。Enigma是当时德国使用的一种加密系统&#xff0c;直到今天还被视为史上最可靠的加密系统之一。它由一个装满了复杂而精致元件的盒子构成&#xff0c;包括26个字母键盘、…

我为什么要立刻放弃 React 而使用 Vue?

From: https://baijiahao.baidu.com/s?id1607323518011007619&wfrspider&forpc CSDN 发布时间&#xff1a;18-07-29 19:28 现在&#xff0c;Vue.js 在 Github 上得到的星星数已经超过了 React。这个框架的流行度在不断增长&#xff0c;由于它并没有像 Facebok&#…

本地同时修改2个版本

为什么80%的码农都做不了架构师&#xff1f;>>> 昨天讨论后我又想了想&#xff0c;你主要的需求是想在本地同时修改2个版本&#xff0c;用分支也可以做到&#xff0c;方法如下 上图是库的目录结构&#xff0c;比如Codes上做了个分支b1&#xff0c;想同时在本地编辑…

Linux C 内存管理

提到C语言&#xff0c;我们知道C语言和其他高级语言的最大的区别就是C语言是要操作内存的&#xff01; 我们需要知道——变量&#xff0c;其实是内存地址的一个抽像名字罢了。在静态编译的程序中&#xff0c;所有的变量名都会在编译时被转成内存地址。机器是不知道我们取的名字…

20145315 《信息安全系统设计基础》第14周学习总结

20145315 《信息安全系统设计基础》第14周学习总结 课程内容总结 物理地址和虚拟地址 物理地址&#xff1a;计算机系统的主存被组织成一个由M个连续的字节大小的单元组成的数组。每个字节都有唯一的物理地址。虚拟寻址&#xff1a;使用虚拟寻址时&#xff0c;CPU通过生成一个虚…

Moment.js常见用法总结

From: https://www.jianshu.com/p/9c10543420de Moment.js常见用法总结 Moment.js是一个轻量级的JavaScript时间库&#xff0c;它方便了日常开发中对时间的操作&#xff0c;提高了开发效率。 ​ 日常开发中&#xff0c;通常会对时间进行下面这几个操作&#xff1a;比如获取时间…

CSDN并购博客园遐想

我要打“假想”&#xff0c;打成了“遐想”&#xff0c;不过确实这篇文章属于我个人YY出来的。主要晚上写博客&#xff0c;用live writer发布好多次都不成功&#xff0c;然后用浏览器访问博客园首页&#xff0c;出现了下面画面。估计很多人都很熟悉这个界面&#xff0c;因为阿里…

Linux C 深入分析结构体指针的定义与引用

关于结构体的基础知识&#xff0c;网上书上都一大堆&#xff0c;这里就不赘述了&#xff0c;下面我们要学习的是结构体指针。 介绍结构体指针之前&#xff0c;先给大家看一个小程序&#xff1a; [cpp] view plaincopy #include <stdio.h> #include <string.h> …

20155313 预备作业二

你有什么技能比大多人&#xff08;超过90%以上&#xff09;更好&#xff1f;针对这个技能的获取你有什么成功的经验&#xff1f;与老师博客中的学习经验有什么共通之处&#xff1f; 说到一个比90%的人要强的技能&#xff0c;我一下子很惆怅&#xff0c;说起来&#xff0c;从小家…

react 父子组件之间相互传值

From: https://blog.csdn.net/luzhaopan/article/details/85003362 1、定义父组件 import React, { PureComponent } from react; export default class Father extends PureComponent { render(){ return( <div> …

android 多线程概述

android多线程&#xff0c;一直是一个麻烦的事情&#xff0c;要掌握它的本质&#xff0c;我们需要搞清楚一个问题&#xff0c;linux多线程的本质。 我们这篇文章&#xff0c;来讨论以下的议程&#xff1a; 了解linux的历程&#xff0c;了解android的异步任务机制&#xff0c;了…

Linux 进程间通讯详解一

进程间的通讯 两台主机间的进程通讯 --socket一台主机间的进程通讯 --管道&#xff08;匿名管道&#xff0c;有名管道&#xff09; --System V进程间通信&#xff08;IPC&#xff09;包括System V消息队列&#xff0c;System V信号量&#xff0c;System V共享内存 --socket 进程…

Linux C 函数指针应用---回调函数

&#xff08;这里引用了知乎上一些知友的回答&#xff0c;感觉不错&#xff0c;有助于理解&#xff0c;这里引用作为借鉴&#xff0c;如有冒犯&#xff0c;烦请告知&#xff09; 我们先来回顾一下函数指针&#xff0c;函数指针是专门用来存放函数地址的指针&#xff0c;函数地址…