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. 常见的仿Flash图片轮播效果

    现在基本在很多网站上都能看到轮播效果,虽然有点烂大街的赶脚,但是这个效果确实很好看,很时尚,今天分享下代码相对较少的轮播框架,望采纳 . ①向左滑动: 思路: 将几个图片用分别用几个 li 包住,并且 ...

  2. 引用外部CSS的link和import方式的分析与比较

    很多网页中的 CSS 链接与引用是这样写的: <style type="text/css" media="screen"> @import url( ...

  3. jquery下拉列表选中项改变时获取新选项的属性值

    $("#textSel").change(funtion(){ var selVal=$(this).val(); var selText=$("#textSel opt ...

  4. PAT-乙级-1021. 个位数统计 (15)

    1021. 个位数统计 (15) 时间限制 100 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 CHEN, Yue 给定一个k位整数N = dk-1 ...

  5. Android 显示大图片

    主要的代码如下: BitmapFactory.Options options = new BitmapFactory.Options(); //图片解析配置 options.inJustDecodeB ...

  6. IText 生成横向的doc文档

    IText生成doc文档需要三个包:iTextAsian.jar,iText-rtf-2.1.4.jar,iText-2.1.4.jar 亲测无误,代码如下: import com.lowagie.t ...

  7. 钣金的折弯成型工艺(Press Braking)

    钣金的折弯成型:金属板材的弯曲和成型是在弯板机上进行的,将要成型的板材放置在弯板机上,用升降杠杆将制动片提起,工件滑动到适当的位置,然后将制动片降低到要成型的板材上,通过对弯板机上的弯曲杠杆施力而实现 ...

  8. P94、面试题12:打印1到最大的n位数

    题目:输入数字n,按顺序打印出从1最大的n位十进制数.比如输入3,则打印出1,2,3一直到最大的3位数999. 思路:先把字符串中的每一个数字都初始化为‘0’,然后每一次为字符串表示的数字加1,再打印 ...

  9. node.js模块之fs文件系统

    fs 模块是文件操作的封装,它提供了文件的读取.写入.更名.删除.遍历目录.链接等 POSIX 文件系统操作.与其他模块不同的是,fs 模块中所有的操作都提供了异步的和同步的两个版本, 例如读取文件内 ...

  10. 超实用的PHP代码片段

    一.查看邮件是否已被阅读 当你在发送邮件时,你或许很想知道该邮件是否被对方已阅读.这里有段非常有趣的代码片段能够显示对方IP地址记录阅读的实际日期和时间. 1 2 3 4 5 6 7 8 9 10 1 ...