IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C++浅谈【异常处理】 -> 正文阅读

[C++知识库]C++浅谈【异常处理】

异常处理

什么是异常处理

在程序中可能会出现各种各样的异常,比如出现了错误,常见错误主要分为语法错误和编译错误,有的错误编译器是可以检查出来的,有的错误编译器检查不出来,;又比如违背正常情况,比如要求输入小写字母,但是实际输入大写的或者数字等,这种错误编译器一般不会检查出来。

在设计程序之前,应当分析各种可能出现的异常情况,并设定相应的识别、处理方式,这就是异常处理的任务

比如如果某个数除以0,这就是一个异常,要根据除数为0的这种异常情况进行一个判断和处理(比如报错并结束程序)

当然,也可以通过断言等方式来处理一些错误,当assert中的判别式结果为false的时候,就直接异常退出程序

C++中如何实现异常处理

C++的异常处理机制是由三个部分组成的:检查(try)、抛出(throw)、捕捉(catch)

"异常情况“是设计者人为认定判定的:如果想要检查一段代码,在这个代码段里面出现了我们不想要的异常情况,就需要抛出”这是一个异常情况“的信号,然后由相应的捕捉代码进行捕捉,一旦捕捉到抛出的异常,就会进入到用来处理这个异常的代码。

跟assert相比,异常处理机制显然更为温和,不会直接断死代码直接退出程序

throw语句

形式:

throw 表达式

throw关键字抛出的表达式是什么样的数据由设计者自己定,可以是常规的变量,也可以是一串字符,也可以是自定义的变量

throw的关键在于表达式的结果的类型,而不是表达式的具体的值,但还是会将表达式作为“异常信号/信息”(异常)整个抛出去,包括值

一旦throw抛出异常,就会在进行异常处理之后,立即跳出throw所在的函数,回到上一级函数(比如main函数)

try-catch结构

try关键字负责划定需要检查的代码区域,在区域内的代码段会接受检查,try和被检查的代码段被合称为try块

catch关键字用于接收throw抛出的异常,并针对异常进行相应处理,catch和被检查的代码段被合称为catch块

形式:

try
{	
	被检查的代码段
}catch(异常信息类型 变量名·一般情况下不写变量名·){
	处理异常的代码段
}

注意

  1. 如果throw的表达式是类的话,可以不用单独实例化出一个对象,直接使用匿名对象,因为有的时候会定义一些空类来专门作为异常信息用,没必要为了异常信息实例化一个对象
class outofsize{};//这是一个空类,专门用来当异常信息的
......
throw outofsize();//使用的outofsize的匿名对象,格式是"类名"+"()"
try
{}
catch(outofsize)
{}
  1. 被检查的代码段必须放在try里,否则不起作用

  2. try-catch结构是一个整体,catch块必须紧跟try块,catch不能脱离try单独使用,且两者之间不能夹杂其他语句;但是try块是可以单独使用的,即只检查不处理,catch块在另一个函数里面

  3. 花括号不能省略

  4. 由于一段代码中可能存在多种错误情况,所以允许一个try块后面接多个catch块,以便匹配不同的异常信息

try
{}
catch()
{}
catch()
{}
//以上省略了内容,主要体现结构
  1. catch也只检查异常信息的类型,而不检查异常信息的值,根据异常信息的类型匹配相应的catch块,无论doule类型的值是多少,都只会匹配catch(double);所以一般的catch写法括号内只有异常信息类型
catch( double )
{}

这里发现,在函数的定义的时候也可以只写类型,不写变量,因为参数从左到右依次传入函数

? catch括号内还有另一种写法,即除了指定类型之外还指定变量名

catch(double d)
{
	cout << d << endl;
}

? 这样catch在捕捉异常信息的时候,除了捕捉变量类型,还会捕捉变量的值,这样就可以在catch中使用这个值(当然,是拷贝的)

  1. 如果catch括号内没有写变量类型,而是写了catch(…),这表示这个catch块可以接受任何类型的异常信息

  2. throw语句和try-catch块在同一个函数中,也可以不在同一个函数中。throw抛出异常信息之后,会先在本函数内让catch捕捉,如果本函数没有try-catch或者没有可以匹配的catch,则跳出本函数到上一个函数,直到找到最近的可匹配的catch

  3. 某些情况下,throw后面可以不加表达式,比如如果在catch块里有throw,则catch里的throw会将catch捕捉到的catch外的throw抛出的异常原样抛出,表示“本级函数的catch不处理这个异常,给上一级的catch块处理”

catch(int)
{				//其他语句
    throw;		//将以捕获的异常信息再次原样抛出
}
  1. 如果throw抛出的异常到最后都没有catch与之匹配,系统会调用一个系统函数terminate终止程序进行

几个例子

#include<iostream>
#include<cmath>

using namespace std;

double triangle(double,double,double);

int main()
{
  double a,b,c;
  cin>>a>>b>>c;
  try
  {
      while(a>0&&b>0&&a>0)
      {
          cout<<triangle(a,b,c)<<endl;		//try里包含了要被检查的函数
          cin>>a>>b>>c;
         }
     }catch(double)
  {
      cout << "a=" << a << ",b=" << b << ",c=" << c << ",that is not a triangle" <<endl;
     }
  cout<< "end" <<endl;
  return 0;
}

double triangle(double a,double b,double c)
{	
  double s = ( a+b+c )/2;
  if( a + b <= c || b + c <= a || a + c <= b )
      throw a;
  return sqrt( s + (s-a) * (s-b) * (s-c) );	//如果在上面的throw中抛出了异常信息,则直接跳到上一级函数,这一行代码就不会生效
}
#include <iostream>
using namespace std;

double division(int a, int b)
{
	if( b == 0 )
	{
		throw "Division by zero condition!";		//表达式的类型本质是上是字符串,也就是char指针
	}
	return (a/b);
}

int main ()
{
	int x = 50;
	int y = 0;
	double z = 0;

	try 
 {
		 z = division(x, y);
		cout << z << endl;	
	}catch (const char* msg)			 	//既有变量类型又有变量名,就可以在下面使用捕捉到的异常信息
	{
		cerr << msg << endl;
	}

	return 0;
}
#include<iostream>
#define SIZE 10
using namespace std;

class outOfSize {};//这里定义了一个空outOfSize类,只用作异常信号,不用与其他作用
class illegalType {};//同上

void addWord(int&, char*, char);

int main()
{
 char a[SIZE];
 char b;
 int x = 0;

 try
 {
     while (1)
     {
         cout << "Please keyonte a~z"<<endl;
         cin >> b;
         addWord(x, a, b);
     }
 }
 catch (outOfSize)
 {
     cout << "Outofsize!" << endl;
 }
 catch (illegalType)
 {
     cout << "IllegalType!" << endl;
 }
 return 0;
}

void addWord(int& x, char* a, char b)
{
 if (x >= SIZE)
     throw outOfSize();//抛出的是outOfSize类的匿名对象
 if (b < 'a' || b>'z')
     throw illegalType();
 a[x] = b;
 x++;
}

结束

That’s all, thanks for reading!💐

  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-09-13 10:54:41  更:2022-09-13 10:57:50 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/19 14:16:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码