C语言 异常处理

 (*^-^ *)

没有rethrow哟
异常处理的方向:由下向上,异常超脱于函数机制,决定了其对函数的跨越式回跳
函数调用的方向:由上到下

异常处理语句

在这里插入图片描述
⚫将可能抛出异常的程序段嵌在try块之中。控制通过正常的顺序执
行到达try语句,然后执行try块内的保护段。
⚫ 如果在保护段执行期间没有引起异常,那么跟在try块后的catch子
句就不执行。程序从try块后跟随的最后一个catch子句后面的语句
继续执行下去。
⚫ catch子句按其在try块后出现的顺序被检查。匹配的catch子句将
捕获并处理异常(或继续抛掷异常)。
⚫ 可以只有try块而无catch块
表达式可以是对象或整数
catch语句:
当没有指定的异常信息的类型时,可以使用省略号
catch(…) {cout<<“OK”<<endl;}
e.g.除0异常

#include<iostream>
using namespace std;
double divide(double x, double y) 
{
	if (y == 0)
	{
		throw x;//数据被传递到catch语句中
	}
	return x / y;
}
int main()
{
	try
	{
		cout << "6/2=" << divide(6, 2) << endl;
		cout << "8/0=" << divide(8, 0) << endl;//数据在函数中被传递到catch语句中,后面try块中的语句不再执行
		cout << "7/1=" << divide(7, 1) << endl;//抛出之后的语句不再执行
	}
	catch (double x)
	{
		cout <<x<< " is divided by 0" << endl;
	}
	cout << "operator finish" << endl;//catch语句块执行完成后,后面的语句按照顺序依然执行
}

在这里插入图片描述
修改,若果想要异常语句之后的语句能够继续执行:

try
{ cout<<"5/2="<<Div(5,2)<<endl; }
catch(int)
{ cout<<"except of deviding zero.\n"; }
try//异常之后在catch之后,可以继续执行
{ cout<<"8/0="<<Div(8,0)<<endl; }
catch(int)
{ cout<<"except of deviding zero.\n"; }
try
{ cout<<"7/1="<<Div(7,1)<<endl;}
catch(int)
{ cout<<"except of deviding zero.\n"; }

e.g.文件打不开异常

#include <fstream>
#include <iostream>
using namespace std;
int main () { 
ifstream source (“a.txt”); //打开文件
char line[128];
try {
if (source.fail()) 
throw “a.txt” ;
}
catch (char * s) {
cout << "error opening the file " << s << endl; 
exit(1);
}
while ( !source.eof()) //注意判断文件输入结束的语句
{ 
source.getline (line, sizeof(line)) ;//getline需要写清读入的字节长度
cout << line << endl ; 
} 
source.close() ; 
return 0; }

异常接口声明

函数事先声明可能抛出的异常,声明之后函数可以抛出的异常类型将受到限制,没有声明就可以抛出任何类型的异常,但如果throw的表达式为空,就说明函数不抛掷任何类型的异常。
在这里插入图片描述

异常处理的构造与析构

在这里插入图片描述
在这里插入图片描述

e.g.try 语句块中有类的对象

先构造局部对象,如果有错误,在throw之前将这个局部对象析构

#include <iostream>
using namespace std;
void MyFunc(void);
class Expt
{ 
public:
Expt() { cout << "cons for Expt" << endl; }
	~Expt() { cout << "des for Expt" << endl; }
const char * ShowReason() const
{ return "Expt类异常。"; }
};class Demo
{ public:
Demo();
~Demo();
};
Demo::Demo()
{
cout<<"构造 Demo."<<endl;
}
Demo::~Demo()
{
cout<<"析构 Demo."<<endl;
}
void MyFunc()
{ Demo D;
cout<<"在MyFunc()中抛掷Expt类异常。"<<endl;
throw Expt();
}
17int main()
{ cout<<"在main函数中。"<<endl;
try
{ cout<<"在try块中,调用MyFunc()。" <<endl;
MyFunc();
}
catch( Expt E )
{ cout<<"在catch异常处理程序中。“;
cout<<endl;
cout<<"捕获到Expt类型异常:";
cout<<E.ShowReason()<<endl;
}
catch( char *str )
{ cout<<"捕获到其它的异常:"<<str<<endl; }
cout<<"回到main函数。从这里恢复执行。" <<endl;
return 0;
}

输出:
在main函数中。
在try块中,调用MyFunc()。
构造 Demo.
在MyFunc()中抛掷Expt类异常。
cons for Expt 在throw时局部变量不析构掉
析构 Demo.
在catch异常处理程序中。
捕获到Expt类型异常:Expt类异常。
des for Expt 执行完catch语句才进行析构
des for Expt
回到main函数。从这里恢复执行。

标准程序库的异常类

exception 标准程序库异常类的公共基类
logic_error 可以被预先检测到的异常
runtime_error难以被预先检测到的异常
在这里插入图片描述
在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值