1.概述

断言是对某种假设条件进行检查(可理解为若条件成立则无动作,否则应报告),它可以快速发现并定位软件问题,同时对系统错误进行自动报警。断言可以对在系统中隐藏很深,用其它手段极难发现的问题进行定位,从而缩短软件问题定位时间,提高系统的可测性。实际应用时,可根据具体情况灵活地设计断言。

2.标准断言机制

原型定义
#include <assert.h>
void assert( int expression_r_r_r );

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

3.实战演练

请看下面的程序

#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
int main( void )
{
FILE *fp; fp = fopen( "test.txt", "w" );//以可写的方式打开一个文件,如果不存在就创建一个同名文件
assert( fp ); //所以这里不会出错
fclose( fp ); fp = fopen( "noexitfile.txt", "r" );//以只读的方式打开一个文件,如果不存在就打开失败
assert( fp ); //所以这里出错
fclose( fp ); //程序永远都执行不到这里来
return 0;
}

  

4.小结

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不能代替条件过滤

6)注意事项:

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

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

②ASSERT只有在Debug版本中才有效,如果编译为Release版本则被忽略掉。(在C中,ASSERT是宏而不是函数),使用ASSERT“断言”容易在debug时输出程序错误所在。
   而assert()的功能类似,它是ANSI C标准中规定的函数,它与ASSERT的一个重要区别是可以用在Release版本中。

参考文章推荐:华为软件编程规范

C语言断言的更多相关文章

  1. C语言-断言

    1 作用: 断言常做语言处理的高级形式,自动处理软件隐藏很深其且它手段不易发现的错误,快速进行异常定位.同时这也是软件单元测试必须的技术. 2 使用范围: 2.1放在函数入口对入口参数进行合法性检查( ...

  2. C语言 断言 总结

    转载: http://wenda.so.com/q/1378817559065638?src=140 assert宏的原型定义在<assert.h>中,其作用是如果它的条件返回错误,则终止 ...

  3. 让我们一起Go(十三)

    前言: 上篇,我们了解了Go语言接口的一些知识,在这篇中,我们将继续聊聊接口这东西. Go语言空接口 Go语言中定义一个空接口,也就是没有任何函数需要实现的接口就是一个空接口,作为一个空接口,因为对象 ...

  4. NSAssert和NSParameterAssert

    2016.05.05 18:34* 字数 861 阅读 5127评论 0喜欢 17 https://www.jianshu.com/p/3072e174554f NSAssert和NSParamete ...

  5. GO语言总结(5)——类型转换和类型断言

    上一篇博客介绍了Go语言的数组和切片——GO语言总结(4)——映射(Map),本篇博客介绍Go语言的类型转换和类型断言 由于Go语言不允许隐式类型转换.而类型转换和类型断言的本质,就是把一个类型转换到 ...

  6. c语言静态断言-定义自己的静态断言

    c语言里面可以自己定义静态断言,更加方便的调试代码. 使用静态断言 #include<stdio.h> #include<stdlib.h> #include<asser ...

  7. c语言静态断言

    在php中可以通过xdebug来显示详细的错误信息,可以细化到哪个文件哪行代码引起的报错.在C语言里面也可以通过静态断言(assert)来使得调试代码更加方便.关于断言,可以作为一种很强大的调试方式或 ...

  8. 编程精粹--编写高质量C语言代码(3):自己设计并使用断言(二)

    接着上一遍文章<<编程精粹--编写高质量C语言代码(2):自己设计并使用断言(一)>>,继续学习怎样自己设计并使用断言,来更加easy,更加不费力地自己主动寻找出程序中的错误. ...

  9. go语言笔记——是c开发的 lex yacc进行词法和语法分析,go不支持函数和运算符重载,不支持类型继承,也不支持断言,还有泛型

    从 Go 1.0.3 版本开始,不再使用 8g,8l 之类的指令进行程序的构建,取而代之的是统一的 go build 和 go install 等命令,而这些指令会自动调用相关的编译器或链接器. 如果 ...

随机推荐

  1. CentOS6.4 安装 mongo-connector

    mongo-connector在python2.6.6版本下安装不成功,官方测试2.7,3.3正常 需要升级python2.7 具体步骤: 安装开发工具包: yum groupinstall &quo ...

  2. JavaScript中创建字典对象(dictionary)实例

    这篇文章主要介绍了JavaScript中创建字典对象(dictionary)实例,本文直接给出了实现的源码,并给出了使用示例,需要的朋友可以参考下 对于JavaScript来说,其自身的Array对象 ...

  3. BZOJ 4036 [HAOI2015] Set 解题报告

    首先我们不能一位一位的考虑,为什么呢? 你想想,你如果一位一位地考虑的话,那么最后就只有 $n$ 个数字,然而他给了你 $2^n$ 个数字,怎么看都不对劲呀.(我是因为这样子弄没过样例才明白的) 所以 ...

  4. 如何通过 OAuth 2.0 使 iOS Apps 集成 LinkedIn 登录功能?

    社交网络早已成为人们日常生活的一部分.其实,社交网络也是编程生活的一部分,大多数 App 必须通过某种方式与社交网络交互,传送或接收与用户相关的数据.大多数情况下,用户需要登录某种社交网络,授权 Ap ...

  5. 其实,前面倒腾那么多,只是为了想玩SPRING BOOT

    嘿嘿,,曲线达到.. 看来看来很多国内的速成,都不爽. 官方教程最体贴~~~:) http://docs.spring.io/spring-boot/docs/current/reference/ht ...

  6. android listview判断是否滑动到顶部还是底部

    listView.setOnScrollListener(new AbsListView.OnScrollListener() { @Override public void onScrollStat ...

  7. Maven for Myeclipse的一个常见错误 Project configuration is not up-to-date with pom.xml

    使用Myeclipse开发Maven项目时,经常会发现一个错误提示: Description Resource Path Location Type Project configuration is ...

  8. 【无聊放个模板系列】POJ 1274 (匈牙利)

    #include<cstdio> #include<cstdlib> #include<cstring> #include<iostream> #inc ...

  9. 使用intellij idea搭建MAVEN+springmvc+mybatis框架

    原文:使用intellij idea搭建MAVEN+springmvc+mybatis框架 1.首先使用idea创建一个maven项目 2.接着配置pom.xml,以下为我的配置 <projec ...

  10. POJ1068——Parencodings

    Parencodings Description Let S = s1 s2...s2n be a well-formed string of parentheses. S can be encode ...