小学生学C++编程语法知识(C++异常处理(Exception)入门)
魔法城堡里的警报器——C++异常处理(Exception)入门
一、故事开始:程序王国的危险按钮
1、在程序王国里,小Q是一名魔法程序员。
一天,国王交给他一个任务:
"请写一个计算除法的程序!"
小Q很快写出了程序:
cout << 10 / 2;运行!
5成功!
2、可是国王又说:
"如果有人输入0呢?"
例如:
cout << 10 / 0;3、这时候……
程序王国突然响起了警报!
轰!! 程序崩溃!4、因为:
任何数字都不能除以0!
所以程序出现了严重错误。
二、有没有办法提前报警?
1、现实生活中:
电影院失火怎么办?
有:
火警报警器
灭火器
安全出口
2、程序也是一样。
如果发生危险,
不要让程序直接崩溃,
而是:
先发现危险,再进行处理。
这就是——
异常处理(Exception)
Exception
意思就是:
程序运行过程中发生了意外。
3、例如:
除以0
文件打不开
数组越界(有些情况)
内存不足
这些都叫:
异常(Exception)
三、异常处理三兄弟
1、C++异常处理只有三个关键词。
try throw catch就像消防队一样。
2、第一位:try
(1)意思:
"这里可能发生危险,请盯着。"
(2)例如:
try { cout << 10 / x; }(3)try里面放:
可能发生错误的代码。
3、第二位:throw
(1)意思:
"危险!危险!快报警!"
(2)例如:
throw "Zero Error";程序立即停止当前工作。
跳出去找救援人员。
4、第三位:catch
(1)意思:
"收到报警,我来处理。"
(2)例如:
catch(const char* msg) { cout << msg; }catch负责接住异常。
(3)所以:
throw ↓ catchthrow抛出去
catch接住
(4)是不是像扔球一样?
throw ○ catch \o/四、完整流程
1、例如:
try { if(y==0) throw "Zero Error"; cout<<x/y; } catch(const char* msg) { cout<<msg; }2、整个流程:
进入try ↓ y是不是0? ↓ 不是 ↓ 继续运行 ↓ 结束 ------------------- 如果是0 ↓ throw ↓ 跳出try ↓ 进入catch ↓ 输出错误信息五、GESP真题讲解
1、题目:
try { int x = 10, y = 0; if (y == 0) throw "Zero Error"; cout << x / y; } catch (int e) { cout << "Error Code: " << e; } catch (const char* msg) { cout << "Caught: " << msg; }问输出什么?
2、第一步
x=10 y=03、第二步
执行:
if(y==0)成立。
于是:
throw "Zero Error";4、这里抛出的是什么?
注意!
"Zero Error"是字符串。
类型:
const char*不是int!
5、第三步
程序开始寻找:
有没有能接住
const char*的catch。
(1)第一个:
catch(int e)接不了。
继续找。
(2)第二个:
catch(const char* msg)完全匹配!
进入。
执行:
cout<<"Caught: "<<msg;msg就是:
Zero Error所以输出:
Caught: Zero Error六、如果没有catch呢?
1、例如:
try { throw "Error"; }没有:
catch(...)那么:
程序直接结束。
2、程序会发现:
"有人把异常扔出来了(throw),但是没有任何人接(catch)!"
(1)于是程序会调用一个系统函数:
std::terminate()程序就在这里结束了。
(2)很多编译器会看到类似的信息:
terminate called after throwing an instance of ...或者
terminate called after throwing ...不同编译器提示略有不同。
3、这算不算"程序崩溃"?
(1)它并不是程序因为内存错误、野指针等原因"崩溃"(Crash)。
而是:
程序因为未处理的异常(Unhandled Exception),被系统终止(Terminate)了。
(2)也就是说:
throw ↓ 没有任何catch ↓ std::terminate() ↓ 程序结束(3)所以,准确的说法应该是:
程序因为异常没有被处理而终止运行。
七、GESP真题讲解
1、题目:
int divi(int a,int b) { if(b==0) throw 0; return a/b; } int main() { try { cout<<divi(10,0); } catch(const char* msg) { cout<<"A"; } catch(int) { cout<<"B"; } }(1)第一步
进入:
divi(10,0)b=0
于是:
throw 0;注意:
抛出的是什么?
0它是什么类型?
int不是字符串。
(2)开始找catch。
第一个:
catch(const char*)接不了。
第二个:
catch(int)成功!
(3)执行:
cout<<"B";输出:
B八、GESP真题讲解
1、程序:
int divide(int a,int b) { if(b==0) throw "Division by zero"; return a/b; } int main() { int result=0; try { result=divide(10,0); cout<<"A"; } catch(const char* msg) { cout<<"B"; result=-1; } cout<<result; }2、第一步
执行:
divide(10,0)b=0
于是:
throw "Division by zero";3、注意,一旦throw发生。
后面的:
cout<<"A";不会执行!!
很多同学最容易错这里。
程序已经跳出try。
4、进入:
catch(const char*)输出:
B然后:
result=-1;最后:
cout<<result;输出:
-1所以最终:
B-1答案:
B
九、为什么 throw 后面的代码不执行?
1、例如:
cout<<"开始"; throw 1; cout<<"结束";很多同学以为:
开始 结束其实不是。
2、执行到:
throw程序立刻跳走。
所以:
开始结束。
后面的全部跳过。
3、可以理解成:
throw ↓ 立刻跳到catch十、异常处理完整模板
最经典写法:
try { //可能发生危险 } catch(int x) { //处理int异常 } catch(const char* msg) { //处理字符串异常 }如果可能抛出多种异常,就可以写多个catch。
十一、万能接收器
1、如果不知道会抛出什么类型。
可以写:
catch(...) { cout<<"发生未知错误"; }三个点:
...表示:
什么异常都接!
2、例如:
try { throw 3.14; } catch(...) { cout<<"万能接收"; }输出:
万能接收十二、异常处理流程图
程序开始 │ ▼ try │ ▼ 有没有异常? │ │ 没有 有 │ │ ▼ ▼ 继续执行 throw │ │ ▼ ▼ 结束 找catch │ 找到?──────┐ │ │ 是 否 │ │ ▼ ▼ 执行catch 程序终止 │ ▼ 继续执行后面的代码十三、记忆口诀
try 看守危险区,throw 报警抛出去,catch 接住来处理,程序安全不崩溃。
十四、课堂练习
第一题
try { throw 5; } catch(int x) { cout<<x; }输出?
答案:
5第二题
try { throw "Hello"; } catch(int) { cout<<"A"; } catch(const char* s) { cout<<s; }输出?
答案:
Hello第三题
try { cout<<"A"; throw 10; cout<<"B"; } catch(int) { cout<<"C"; }输出?
分析:
输出
Athrow 10后立即跳转"B"不会执行进入
catch(int)输出C
答案:
AC第四题
try { throw "Error"; } catch(...) { cout<<"OK"; }输出?
答案:
OK十五、本课总结
今天我们认识了 C++ 的异常处理机制,它就像程序里的“安全警报系统”。
要记住三个关键词:
| 关键字 | 作用 | 可以理解成 |
|---|---|---|
try | 放可能出错的代码 | 安全监控区 |
throw | 抛出异常 | 拉响警报 |
catch | 捕获并处理异常 | 消防员 |
同时牢记四个重要规律:
throw抛出的数据类型,要与catch的类型匹配。执行到
throw后,try中后面的代码不会继续执行。如果没有匹配的
catch,程序通常会终止。catch(...)可以捕获任何类型的异常,是一个“万能接收器”。
对于 GESP 考试而言,最常见的考点就是:
判断
throw抛出的类型;判断哪个
catch能成功接住异常;理解
throw后代码是否继续执行;判断程序最终的输出结果。
只要掌握了这几条规律,这类题目就能快速、准确地完成。
