assert函数和捕获异常
assert函数:
C语言和C++都有一个专为调试而准备的工具函数,就是 assert()函数。 这个函数是在C语言的 assert.h 库文件里定义的,所以包含到C++程序里我们用以下语句:
#include <cassert>
assert()函数需要有一个参数,它将测试这个输入参数的真 or 假状态。 如果为真,Do nothing,继续往下执行! 如果为假,中断执行!
看下边演示:test.cpp
#include <cassert> int main()
{
int i = 20;
assert( i == 65 ); return 0;
}
结果:
test.cpp, line 6 This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
请按任意键继续. . .
演示中,我们看到 assert()函数可以帮助我们调试程序。 我们可以利用它在某个程序里的关键假设不成立时立刻停止该程序的执行并报错,从而避免发生更严重的问题。 另外,除了结合 assert()函数,在程序的开发、测试阶段,我们还可以使用大量的 cout 语句来报告在程序里正在发生的事情。
用户体验与程序猿体验:
对运行时错误的处理分为两种情况:
- 一种与程序猿有关,在开发、测试和调试程序的过程中,程序猿需要尽可能详细的信息来查找和纠正各种潜在的运行时错误。
- 另一种情况与最终用户有关,在使用一个程序的过程中,错误处理应该把用户的感受摆在第一位!
在理想的情况下,程序发布之前,它里边的所有错误都应该被发现和改正过来。只可惜这是几乎不可能的,就连微软这样的大公司也做不出这样的保证!最为一条原则:最终用户看到的错误信息应该既专业又清晰,不能轻易中断程序,不能充满技术细节。
捕获异常:
同样为了对付潜在的编程错误(尤其是运行时的错误),捕获异常是一种完全不同的办法。 简单地说,异常(exception)就是与预期不相符合的反常现象。 基本使用思路:
- 安排一些C++代码(try语句)去尝试某件事 —— 尤其是那些可能会失败的事(比如打开一个文件或申请一些内存)
- 如果发生问题,就抛出一个异常(throw语句)
- 再安排一些代码(catch语句)去捕获这个异常并进行相应的处理。
捕获异常的基本语法如下:
try
{
// Do something.
// Throw an exception on error.
}
catch
{
// Do whatever.
}
Pay attention!每条 try 语句至少要有一条配对的 catch 语句。必须定义 catch 语句以便让它接收一个特定类型的参数。
C++还允许我们定义多条 catch 语句,让每条 catch 语句分别对应着一种可能的异常类型:
catch(int e){ … }
catch(bool e){ … }
catch(…){ … }
最后一条 catch 语句可以捕获任何类型的异常。
在程序里,我们可以用 throw 保留字来抛出一个异常:throw 1; 在某个 try 语句块里执行过 throw 语句,它后面的所有语句(截止到这个 try 语句块末尾)将永远不会被执行。 与使用一个条件语句或 return 语句相比,采用异常处理机制的好处是它可以把程序的正常功能和逻辑与出错处理部分清晰地划分开而不是让它们混杂在一起。
如何让函数抛出异常:
你可以在定义一个函数时明确地表明你想让它抛出一个异常,为了表明你想让它抛出哪种类型的异常,可以使用如下所示语法:
type functionName(arguments) throw(type);
如果没有使用这种语法来定义函数,就意味着函数可以抛出任意类型的异常。 注:有些编译器不支持这种语法,则可省略 throw(type) 部分。
#include <iostream>
#include <climits> unsigned long returnFactorial(unsigned short num) throw (const char *);
//在 returnFactorial函数内可能会抛出字符串类型的异常 int main()
{
unsigned short num = 0; std::cout << "请输入一个整数: ";
while( !(std::cin>>num) || (num<1) )
{
std::cin.clear(); // 清除状态
std::cin.ignore(100, '\n'); // 清除缓冲区
std::cout << "请输入一个整数:";
}
std::cin.ignore(100, '\n'); try
{
unsigned long factorial = returnFactorial(num);
std::cout << num << "的阶乘值是: " << factorial;
}
catch(const char *e)
{
std::cout << e;
} return 0;
} unsigned long returnFactorial(unsigned short num) throw (const char *)
{
unsigned long sum = 1;
unsigned long max = ULONG_MAX; for( int i=1; i <= num; i++ )
{
sum *= i;
max /= i;
} if( max < 1 )
{
throw "悲催。。。该基数太大,无法在该计算机计算求出阶乘值。\n";
}
else
{
return sum;
}
}
TIPS:
- 如何使用异常是一个很容易引起争论的话题。有些程序员使用异常来处理几乎所有的错误,但C++的创始人Bjarne Stroustrup(BS君)觉得它们正在被滥用。 所以使用异常的基本原则是:应该只用它们来处理确实可能不正常的情况。
- 作为一条原则,在构造器和析构器里不应该使用异常。一位非常有经验的程序猿在这些方法里成功地使用了异常是有可能的,但稍有不慎就会导致严重的问题。
- 如果 try 语句块无法找到一个与之匹配的 catch 语句块,它抛出的异常将中止程序的执行。
- 在C++标准库里有个名为 exception 的文件,该文件声明了一个 exception 的基类。可以用这个基类来创建个人的子类以管理异常。 有经验的程序猿常常这么做,而如此抛出和捕获的是 exception 类或其子类的对象。
- 如果你打算使用对象作为异常,请记住这样一个原则:以”值传递”方式抛出对象,以”引用传递”方式捕获对象。
assert函数和捕获异常的更多相关文章
- assert()函数用法总结
assert()函数用法总结 assert宏的原型定义在<assert.h>中,其作用是如果它的条件返回错误,则终止程序执行,原型定义: #include <assert.h> ...
- 【php】assert函数的用法
[php]assert函数的用法 http://www.douban.com/note/217557007/ 2012-06-01 10:32:37 assert这个函数在php语言中是用来判断一 ...
- python中assert()函数的使用
关于assert()函数的使用,主要参考博客https://blog.csdn.net/qq_37119902/article/details/79637578 assert函数主要是用来声明某个函数 ...
- 解决用try except 捕获assert函数产生的AssertionError异常时,导致断言失败的用例在测试报告中通过的问题
在使用Python3做自动化测试过程中可能会遇到,assert函数不加try except,就可以正常在报告里体现用例不通过,加上变成通过. 这是因为在使用try except 时,捕获了asser ...
- assert函数的用法
assert这个函数在php语言中是用来判断一个表达式是否成立.返回true or false; 例如: <?php $s = 123; assert("is_int($s)" ...
- iOS exit(),abort(),assert()函数区别
iOS exit(),abort(),assert()函数区别 exit() 退出程序 abort() 停止程序, assert()检查里面的参数如果为nil抛出异常:
- assert函数应用
目录 1 assert概念 2 assert作用 3 assert用法 3.1 检测调用者传过来的指针参数是否正常 3.2 判断某个变量的范围 3.3 assert只检验一个地方 3.4 不能使用改变 ...
- 【C/C++】assert()函数用法总结
assert()函数用法总结 assert宏的原型定义在<assert.h>中,其作用是如果它的条件返回错误,则终止程序执行,原型定义: #include <assert.h> ...
- [XCTF嘉年华体验赛](web)web2 assert函数
0x00 题目分析 浏览一遍页面,在about页面,获得如下信息 访问 .git/ ,页面存在. 使用githack扒下来.得到源码,进行代码审计. 分析得到: 1.flag在flag页面,要看源码才 ...
随机推荐
- 关于element-ui表格样式设置的方法cell-class-name
关于element-ui表格使用的一些方法 最近在用Vue.js和elment-ui做一个后台管理项目,不得不说element功能非常强大,提供了许多组件,基本可以满足一些基础的开发了.因为我做的后台 ...
- 转 RMAN-20005: target database name is ambiguous
发生的这个错误的由于: 在RMAN CATALOG中,register了一个name叫test的数据库,后来这个库被我搞坏了.就重建了一个test的数据库,名称没有更改,又重新register到RMA ...
- leetcode 437. 路径总和 III
题目描述: 给定一个二叉树,它的每个结点都存放着一个整数值. 找出路径和等于给定数值的路径总数. 路径不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点). 二 ...
- tcp/ip 性能优化问题的思考学习
首先要看TCP/IP协议,涉及到四层:链路层,网络层,传输层,应用层. 其中以太网(Ethernet)的数据帧在链路层 IP包在网络层 TCP或UDP包在传输层 TCP或UDP中的数据(Data)在 ...
- impdp参数TABLE_EXISTS_ACTION
[转自:http://space.itpub.net/519536/viewspace-631445] 当使用IMPDP完成数据库导入时,如遇到表已存在时,Oracle提供给我们如下四种处理方式:a. ...
- 彻底理解和解决移动WEB开发中CLICK点透问题
在移动WEB开发中,有时候可能会出现点透问题,本文将围绕这个TAP点透问题,详细的讲述到底什么是点透,为什么会出现点透,如何避免出现点透,如果不可避免的出现了,如何解决解决移动WEB开发中CLICK点 ...
- 数据库mysql基础语言--各模式的含义
1. 欢迎信息 欢迎来到 MySQL 镜像.命令以 ; 或 g 结束.你的 MySQL 连接编号为 2.服务器版本:5.1.47-社区 MySQL 社区服务器(GPL) 版权(C)2000.2010, ...
- [转]jQuery实现图片轮播效果,jQuery实现焦点新闻
本文转自:http://blog.csdn.net/tsyj810883979/article/details/8986157 效果图: 实现代码: <!DOCTYPE html> < ...
- Intellij IDEA 14 自动生成 serialVersionUID
1. Preferences > Editor > Inspections > Java > Serialization issues > Serializable c ...
- React.js 小书 Lesson4 - 前端组件化(三):抽象出公共组件类
作者:胡子大哈 原文链接:http://huziketang.com/books/react/lesson4 转载请注明出处,保留原文链接和作者信息. 为了让代码更灵活,可以写更多的组件,我们把这种模 ...