函数 assert() 是干啥的 包含在哪个库中

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了函数 assert() 是干啥的 包含在哪个库中相关的知识,希望对你有一定的参考价值。

断言assert是仅在Debug版本起作用的宏,它用于检查“不应该”发生的情况。以下是一个内存复制程序,在运行过程中,如果assert的参数为假,那么程序就会中止(一般地还会出现提示对话,说明在什么地方引发了assert)。

断言assert是宏,不是函数,不存在包含在哪个库中的问题。

assert不是一个仓促拼凑起来的宏,为了不在程序的Debug版本和Release版本引起差别,assert不应该产生任何副作用。所以assert不是函数,而是宏。程序员可以把assert看成一个在任何系统状态下都可以安全使用的无害测试手段。 

扩展资料

以下是使用断言的几个原则: 

1)使用断言捕捉不应该发生的非法情况。不要混淆非法情况与错误情况之间的区别,后者是必然存在的并且是一定要作出处理的。 

2)使用断言对函数的参数进行确认。 

3)在编写函数时,要进行反复的考查,并且自问:“我打算做哪些假定?”一旦确定了的假定,就要使用断言对假定进行检查。 

4)一般教科书都鼓励程序员们进行防错性的程序设计,但要记住这种编程风格会隐瞒错误。当进行防错性编程时,如果“不可能发生”的事情的确发生了,则要使用断言进行报警。

参考资料:百度百科——assert

参考技术A 断言assert是一个宏,该宏在<assert>中,,当使用assert时候,给他个参数,即一个判读为真的表达式。预处理器产生测试该断言的代码,如果断言不为真,则发出一个错误信息告诉断言是什么以及它失败一会,程序会终止。
我们一般可以用在判断某件操作是否成功上。
摘录林锐博士高质量编程一书中相关内容。

~~~~~~~~~~~~~~~~~~~~~~~~
程序一般分为Debug版本和Release版本,Debug版本用于内部调试,Release版本发行给用户使用。
断言assert是仅在Debug版本起作用的宏,它用于检查“不应该”发生的情况。以下是一个内存复制程序,在运行过程中,如果assert的参数为假,那么程序就会中止(一般地还会出现提示对话,说明在什么地方引发了assert)。
//复制不重叠的内存块
void memcpy(void *pvTo, void *pvFrom, size_t size)

void *pbTo = (byte *) pvTo;
void *pbFrom = (byte *) pvFrom;
assert( pvTo != NULL && pvFrom != NULL );
while(size - - > 0 )
*pbTo + + = *pbFrom + + ;
return (pvTo);

assert不是一个仓促拼凑起来的宏,为了不在程序的Debug版本和Release版本引起差别,assert不应该产生任何副作用。所以assert不是函数,而是宏。程序员可以把assert看成一个在任何系统状态下都可以安全使用的无害测试手段。
以下是使用断言的几个原则:
1)使用断言捕捉不应该发生的非法情况。不要混淆非法情况与错误情况之间的区别,后者是必然存在的并且是一定要作出处理的。
2)使用断言对函数的参数进行确认。
3)在编写函数时,要进行反复的考查,并且自问:“我打算做哪些假定?”一旦确定了的假定,就要使用断言对假定进行检查。
4)一般教科书都鼓励程序员们进行防错性的程序设计,但要记住这种编程风格会隐瞒错误。当进行防错性编程时,如果“不可能发生”的事情的确发生了,则要使用断言进行报警。本回答被提问者和网友采纳
参考技术B 函数名: assert
功 能: 测试一个条件并可能使程序终止
用 法: void assert(int test);
程序例:
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
struct ITEM
int key;
int value;
;
/* add item to list, make sure list is not null */
void additem(struct ITEM *itemptr)
assert(itemptr != NULL);
/* add item to list */

int main(void)

additem(NULL);
return 0;

assert() 函数用法
assert宏的原型定义在<assert.h>中,其作用是如果它的条件返回错误,则终止程序执行,原型定义:
#include <assert.h>
void assert( int expression );
assert的作用是先计算表达式 expression ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,
然后通过调用 abort 来终止程序运行。
请看下面的程序清单badptr.c:
#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;

[root@localhost error_process]# gcc badptr.c
[root@localhost error_process]# ./a.out
a.out: badptr.c:14: main: Assertion `fp' failed.
已放弃
使用assert的缺点是,频繁的调用会极大的影响程序的性能,增加额外的开销。
在调试结束后,可以通过在包含#include <assert.h>的语句之前插入 #define NDEBUG 来禁用assert调用,示例代码如下:
#include <stdio.h>
#define NDEBUG
#include <assert.h>
用法总结与注意事项:
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不能代替条件过滤
注意:当对于浮点数:
#include<assert.h>
// float pi=3.14;
// assert(pi=3.14); //
float pi=3.14f;
assert (pi=3.14f);
---------------------------------------------------------
在switch语句中总是要有default子句来显示信息(Assert)。
int number = SomeMethod();
switch(number)

case 1:
Trace.WriteLine("Case 1:");
break;
case 2:
Trace.WriteLine("Case 2:");
break;
default :
Debug.Assert(false);
break;

MATLAB 文件夹前面的+和@是干啥的 命名空间与函数的重载

前言

当你打开MATLAB的toolbox文件夹时(工具箱存储路径),会发现里面文件夹名称前会有一些奇奇怪怪的符号:

???这里面的+@是干啥的???

为了探究这个问题,我们建立了一个具有如下目录的文件夹:

当前文件夹──@cell──dispTest.m
        |
        ├──@double──dispTest.m
        |
        ├──+test1──+test2──test.m
        |       |
        |       └──test.m
        |
        └──untitled.m      

命名空间:路径函数(目录结构体)

如果想要代码整洁条理,很多情况会把一些同一类的工具函数放在一个单独的文件夹里,即你要调用的函数在当前文件夹内的一个文件夹中,想在当前文件夹直接调用这个函数是做不到的,要咋办?

很多人会选择直接addpath,但这样的话那些工具函数就不止该项目可以调用,其他位置的其他项目也能调用,这样有可能导致命名冲突。

那么一个很简单的方法就是将装工具函数的文件夹命名为+fordername的形式,就是前面有个+的形式,实际上就是文件夹路径作为命名空间。

对于我们前面提出的目录的以下部分:

当前文件夹──+test1──+test2──test.m
        |       |
        |       └──test.m
        |
        └──untitled.m   

我想要在untitled.m中调用+test1文件夹中的test.m,就可以直接通过以下代码调用:

test1.test()

当然像目录所示,+test1文件夹里还有个带加号的+test2文件夹,我们想要调用那个文件夹里的
test.m,就可以通过如下方式:

test1.test2.test()

这种调用格式非常像是在调用结构体里的函数,这也是我将其称为目录结构体的原因。

函数的重载

当然接下来就要讲目录的这部分是啥:

当前文件夹──@cell──dispTest.m
        |
        ├──@double──dispTest.m
        |
        └──untitled.m      

很像是C++中的函数的重载哈,两个@classname的文件夹中右两个名字完全相同的函数。

注意这里说的是@加上类名称的格式,可以是MATLAB自带的类,也可以是自己定义的类函数,我们这里就设置了元胞类和双精度类命名的文件夹。

这么设置有啥用呢?这样设置后,比如我再调用dispTest.m函数的时候,如果输入变量是元胞数组,那么就会调用@cell文件夹里的该函数,如果输入变量是双精度类型,那么就会调用@double文件夹里的函数。

也就是说以下的两种写法,用的是不同函数:

dispTest(1)

dispTest(1)

结语

大概就是这个样子,对于+可以想做结构体,对于@可以想做重载,本人不同文件夹里的函数定义是这样的:

+test1\\test.m

function test
disp('欢迎关注slandarer forder1')
end 

+test1+test2\\test.m

function test
disp('欢迎关注slandarer forder2')
end 

@cell\\dispTest.m

function dispTest(coe)
disp('is cell') 
end  

@double\\dispTest.m

function dispTest(coe)
disp('is double') 
end  

因此在untitled.m中运行如下代码,效果如下:

test1.test()

test1.test2.test()

dispTest(1)

dispTest(1)

欢迎关注slandarer forder1
欢迎关注slandarer forder2
is double
is cell

以上是关于函数 assert() 是干啥的 包含在哪个库中的主要内容,如果未能解决你的问题,请参考以下文章

iOS 中 NSParameterAssert 是干啥的之官方解释翻译篇

C函数后面多加两条下划线是干啥的?

Python类中的self到底是干啥的

c语言中math.h和dos.h是干啥的

Python类中的self到底是干啥的

Python类中的self到底是干啥的