首页 > 编程语言 >C++ Assert()断言机制原理以及使用

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

时间:2022-12-19 17:37:59浏览次数:47  
标签:assert char 断言 void C++ Assert Analyzing NULL string

机器学习以及人工智能的学习需要扎实的数学功底才能走的更远,爬的更高,所以打好数学基础是关键,但无论工作学习都没有充足的时间去拿着书本一个字一个字的去学习了,这里我建议大家找几个比较靠谱入门的机器学习或者人工智能学习平台,一定要系统全面的去学习才能有效果,不要半途而废, 在此推荐一个我看过的小白人工智能入门教程,零基础教程,简单通俗易懂,风趣幽默,由浅及深,点击这里可以直达:人工智能入门基础教程,  关注公众号:木石说(mushiwords)

MSDN原文如是说:

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

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

void assert( 
int expression
);

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
}
// 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

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 ''

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;
}
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;
}

 


 

 

 

标签:assert,char,断言,void,C++,Assert,Analyzing,NULL,string
From: https://blog.51cto.com/u_15917617/5953247

相关文章

  • 零宽断言&正则表达式
    #正则表达式​​http://blog.51cto.com/hmtk520/2074219​​元字符代码说明.匹配除换行符之外的所有字符\w匹配字母或数字或中文或下划线\s匹配任意的空白符\d匹配数字\b匹......
  • 【C++入门】(三)循环结构
    一.while循环循环版的if语句。if语句是判断一次,如果条件成立,则执行后面的语句while是每次判断,如果成立,则执行循环体中的语句,否则停止#include<iostream>using......
  • C++ Primer Plus第三章(操作数据)笔记
    简单变量程序为了将信息储存在计算机中,程序必须记录3个基本属性:信息将储存在哪要存储什么值存储什么类型的信息我们可以利用代码来看看程序到底做了什么:intbrainc......
  • 为什么C++永不过时?
    Linus曾说过:“C++是一门很恐怖的语言,而比它更恐怖的是很多不合格的程序员在使用着它!”这足以说明C++有多难!不过,你也要明白。难度越高意味着含金量与竞争力越高,越能把你和别......
  • 指针都没搞懂,还能算得上 C++ 老司机?
    在工业界,有这样一个规律:“但凡能用其他语言的都不会用C++,只能用C++的必然用C++。”但是,C++的学习和项目开发都比较困难。一个有经验的老手也经常搞出野指针,内存泄露等bug,包......
  • Eclipse下载安装和JDK下载安装(环境配置)及下载C++插件CDT
    一、什么是JDKJDK是Java语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA......
  • [C++] VS Code 中导入MYSQL (包含使用gcc,g++)
    首先安装Gcc1.下载链接:https://sourceforge.net/projects/mingw-w64/files/备用网盘: https://pan.baidu.com/s/1trdQtDO6XqmfCbZHc1IDzQ?pwd=nwh5 2.添加环境变......
  • C++数学与算法系列之排列和组合
    1.前言本文将聊聊排列和组合,排列组合是组合学最基本的概念,在程序运用中也至关重要。排列问题:指从给定个数的元素中取出指定个数的元素进行排序。组合问题:指从给定个......
  • 连号区间数【第四届蓝桥杯省赛C++B组,第四届蓝桥杯省赛JAVAB组】
    连号区间数小明这些天一直在思考这样一个奇怪而有趣的问题:在\(1∼N\)的某个排列中有多少个连号区间呢?这里所说的连号区间的定义是:如果区间\([L,R]\)里的所有元素(即......
  • c++中输出小数
    首先需要有#include<iomanip>这个头文件,因为它是输出输出流的格式控制#include<iomanip>//用于调用setprecision(n)1doublesum=10;2cout<<setiosflags(ios......