当我们敲代码时,我们都知道,程序出现bug是很正常的,有些比较简单的错误,或者有些强大编译工具,在编译的时候能够将我们的错误直接寻找出来,然后告诉你某某行出现了错误,你直接去该地方,但是如果你写的程序,在编译时并没有出现错误,由于一些未考虑到的地方,和一些运行时,错误的输入,就如以下情况
例如: 1、做除法的时候除数为 0; 2、用户输入年龄时输入了一个负数; 3、用 new 运算符动态分配空间时,空间不够导致无法分配; 4、访问数组元素时,下标越界;打开文件读取时,文件不存在。
在这些情况下,虽然我们能通过编译,但是,运行的时候,我们可以发现,我们的程序会莫名其妙的强行停止,没有任何的信息和提示,出错点有这么多,我们如何才能知道到底出现的是什么错误呢?如何才能在程序g掉的时候,在最后一刻给我们发送一个信息告诉我们错在哪儿呢?
这个时候,我们创造出异常处理机制来帮我们解决这个问题。
正如其名,所谓异常就是在应用程序正常执行过程中发生了不正常的运行。
简单来理解,就是我们写一段代码,在发生一些可预测的异常,甚至或者不可预测的异常时执行我们想要它做的代码,可以是反馈给我们错误信息,可以是修复,使得程序继续正常运行等操作。
说到异常,我们必须要分辨一下,我们平常所说的异常和中断的区别。
中断,由外部硬件设备或异步事件产生。
异常由程序的内部事件产生,异常可以分为故障,陷阱,和终止。
栈展开的实现
C++ 引入了异常处理机制。其基本思想是:函数 A 在执行过程中发现异常时可以不加处理,而只是“拋出一个异常”给 A 的调用者,假定为函数 B。 拋出异常而不加处理会导致函数 A 立即中止,在这种情况下,函数 B 可以选择捕获 A 拋出的异常进行处理,也可以选择置之不理。如果置之不理,这个异常就会被拋给 B 的调用者,以此类推。 如果一层层的函数都不处理异常,异常最终会被拋给最外层的 main 函数。main 函数应该处理异常。如果main函数也不处理异常,那么程序就会立即异常地中止
栈展开 Q:简述一下“栈展开”的过程?A:栈展开的就是指匹配catch子句的过程。具体匹配过程如下:1)当程序抛出一个异常或者在try块中检测到异常时就会停止执行当前的调用链,开始寻找与异常匹配的catch子句。2)当在try块中出现一个throw语句或者在try块中调用了可能出现异常的函数时,首先检查与该try块匹配的catch语句(一个try可能对应多个catch),逐个检查,直到找到匹配的即停止寻找,进入该catch执行处理异常的程序。(注意,匹配不代表最佳匹配,所以最佳的匹配要放在catch的最前端)。3)如果执行过程2)还是没有找到匹配的catch,且当前try嵌套在外部的try块中,则程序就会在外部的try块中查找,直到找到匹配的为止。4)如果执行过程3)还是没有找到匹配的catch语句,则退出当前调用的函数,继续在退出为止的函数的其他函数中寻找,以此类推。5)如果最终执行完上述步骤后还是没有找到匹配的catch,则就是说异常得不到处理(没有被捕获),程序会调用标准库函数terminate终止函数的执行。
通过写代码,我们能对异常处理有一个更直观的认识。