C++异常处理机制全解

合集下载

C 或Java中的异常处理机制的简单原理和应用

C  或Java中的异常处理机制的简单原理和应用
如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overridi
ng)。子类的对象使用这个方法时,将调用子类中的定义,对它而言,父类中的定义如同被
“屏蔽”了。如果在一个类中定义了多个同名的方法,它们或有不同的参数个数或有不同 的参数类型,则称为方法的重载(Overloading)。Overloaded的方法是可以改变返回值的类
当JAVA程序违反了JAVA的语义规则时,JAVA虚拟机就会将发生的错误表示为一个异常。违
反语义规则包括2种情况。一种是JAVA类库内置的语义检查。例如数组下标越界,会引发In
dexOutOfBoundsException;访问null的对象时会引发NullPointerException。另一种情况
sleep():使一个正在运行的线程处于睡眠状态,是一个静态方法,调用此方法要捕捉Inte
rruptedException异常。
notify():唤醒一个处于等待状态的线程,注意的是在调用此方法的时候,并不能确切的唤
醒某一个等待状态的线程,而是由JVM确定唤醒哪个线程,而且不是按优先级。
13,Anonymous Inner Class (匿名内部类) 是否可以extends(继承)其它类,是否可以im
plements(实现)interface(接口)?
匿名的内部类是没有名字的内部类。不能extends(继承) 其它类,但一个内部类可以
作为一个接口,由另一个内部类实现。
两个对象,一个是“xyx”,一个是指向“xyx”的引用对象s。
20,Math.round(11.5)等於多少? Math.round(-11.5)等於多少?
Math.round(11.5)返回(long)12,Math.round(-11.5)返回(long)-11;

C语言错误处理方法

C语言错误处理方法

C语言错误处理方法在编写C语言程序时,错误是不可避免的。

错误可能导致程序崩溃、功能异常或数据丢失。

为了提高程序的稳定性和可靠性,我们需要采取适当的错误处理方法。

本文将介绍一些常见的C语言错误处理方法,帮助读者更好地应对程序中的错误。

一、错误码和返回值在C语言中,常用的错误处理方法是通过错误码和返回值的方式。

当函数执行出错时,它会返回一个特定的错误码或者错误标志。

我们可以通过检查返回值来确定函数是否执行成功,如果返回一个非零值,则表示出现了错误。

例如,在文件操作中,函数fopen用于打开文件,如果打开失败,它会返回一个空指针NULL。

我们可以通过检查返回值是否为NULL来判断文件是否成功打开。

类似地,malloc函数在动态分配内存时,如果失败,会返回一个NULL指针。

对于返回一个整数值的函数,通常约定返回0表示函数执行成功,非零值表示函数执行出错。

可以定义一系列错误码来表示不同类型的错误,比如1表示文件打开失败,2表示内存分配失败等等。

二、错误处理函数除了返回错误码外,我们还可以通过定义错误处理函数来处理错误。

当函数执行出错时,它会调用相应的错误处理函数来处理错误。

错误处理函数可以采取各种措施,比如输出错误信息、记录日志、恢复程序状态等。

例如,在文件操作中,我们可以定义一个错误处理函数,在文件打开失败时输出错误信息,告知用户无法打开指定文件,并且提供相应的解决方案。

通过这种方式,我们可以提高程序的友好性和对用户的提示。

三、异常处理机制除了常规的错误处理方法,C语言还允许使用异常处理机制来应对程序中的错误。

异常处理机制可以在出现异常时,跳转到一个特定的异常处理代码块中执行,从而避免程序崩溃或数据丢失。

异常处理机制通常使用try-catch语句来实现。

try块中包含可能抛出异常的代码,catch块用于捕捉并处理异常。

如果try块中的代码出现异常,程序会立即跳转到最近的catch块中执行相应的异常处理代码。

C语言异常处理

C语言异常处理

11 scanf("%lf",&a); 12 printf("请输入第二个数字:");
13 scanf("%lf",&b);
14 if(0==b)
//如果除数为 0 终止程序 ,并挂接到模拟异常捕获的注册函

15 {
16
17 atexit(Exception);
18 exit(EXIT_FAILURE);
第三个版本:version3
在 Stack 里面添加一个类 class Stack_error,让 Underflow 和 Overflow 都继承它:
1 template<class T>class Stack{
printf("相除的结果是: %.2lf\n",result); } else printf("试图除以一个为 0 的数字\n");
return 0; }
四 总结:
除了以上几种方法之外,另外还有使用信号量等等方法进行异常处理。当然在实际 开发中每个人都有各种调式的技巧,而且这文章并不是说明异常处理一定要这样做, 这只是对一般做法的一些总结,也不要乱使用异常处理,如果弄的不好就严重影响 了程序的效率和结构,就像设计模式一样,不能胡乱使用。
C 语言异常处理。
三 C 语言中的异常处理
在 C 语言中异常处理一般有这么几种方式:
1.使用标准 C 库提供了 abort()和 exit()两个函数,它们可以强行终止程序的运 行,其声明处于<stdlib.h>头文件中。 2.使用 assert(断言)宏调用,位于头文件<assert.h>中,当程序出错时,就会 引发一个 abort()。 3.使用 errno 全局变量,由 C 运行时库函数提供,位于头文件<errno.h>中。 4.使用 goto 语句,当出错时跳转。 5.使用 setjmp,longjmp 进行异常处理。 接下来,我们就依次对这几种方式来看看到底是怎么做的: 我们仍旧以前面处理除数为 0 的异常为例子。 1.使用 exit()函数进行异常终止:

c语言常见问题及解决方法

c语言常见问题及解决方法

c语言常见问题及解决方法
一、C语言常见问题及解决方法
1、程序编译错误,原因及解决方法
(1)语法错误:检查程序中出现的缩进、分号、圆括号、大括号的位置,以及程序中变量的定义,保证程序的语法正确。

(2)类型错误:检查程序中关系运算符两边操作数的类型是否匹配,以及变量的使用是否正确,保证每一步运算的类型正确。

(3)变量未声明:检查变量在程序中是否已经声明,声明后才能正确使用。

2、程序运行错误,原因及解决方法
(1)程序中存在逻辑错误:检查程序中的流程是否按设计要求正确,以及程序输出结果是否正确。

(2)程序中存在数据错误:检查程序中的数据是否正确,数据输入、输出以及运算结果都要求正确。

(3)程序运行错误:检查程序中的函数调用是否正确,注意函数的参数和返回值的类型要求。

3、程序编译成功却无法执行,原因及解决方法
这可能是程序出现了语法错误,编译器无法判断,所以编译成功,但是在执行时系统无法识别出程序的命令。

可以通过重新编写程序,查找错误语句的方式查找程序错误,并根据提示修改程序,以解决此问题。

c++异常处理机制和常用方法

c++异常处理机制和常用方法

c++异常处理机制和常用方法C++ 异常处理机制是一种处理程序错误的标准方法,它允许程序员在程序出现异常情况时进行处理。

异常处理机制通过抛出异常、捕获异常、传递异常三个步骤来实现。

1. 抛出异常当程序出现异常情况时,可以使用 `throw` 关键字来抛出一个异常。

例如:```throw std::runtime_error("Something went wrong!");```这里抛出了一个 `std::runtime_error` 类型的异常,其中包含了一个字符串描述信息。

2. 捕获异常当程序抛出异常后,可以使用 `try-catch` 块来处理异常。

例如:```try {// some code that may throw an exception} catch (const std::exception& e) {std::cerr << "Exception caught: " << e.what() << std::endl; }```这里使用 `try` 关键字开始一个代码块,该代码块可能会抛出异常。

如果抛出异常,则 `catch` 块中的代码将被执行。

`catch` 块中的参数指定了要捕获的异常类型,这里使用了 `conststd::exception&` 表示捕获所有继承自 `std::exception` 的异常。

`e.what()` 方法返回异常描述信息。

3. 传递异常当一个函数抛出异常时,它可以选择不处理该异常并将其传递给调用该函数的代码。

例如:```void foo() {throw std::runtime_error("Something went wrong!");}int main() {try {foo();} catch (const std::exception& e) {std::cerr << "Exception caught: " << e.what() << std::endl; }}```这里 `foo()` 函数抛出了一个异常,但它没有在函数中处理该异常。

C语言异常处理异常的产生传递和捕获

C语言异常处理异常的产生传递和捕获

C语言异常处理异常的产生传递和捕获C语言异常处理:异常的产生、传递和捕获异常处理是编程中非常重要的一个概念,当程序发生非预期的错误或异常时,异常处理机制可以帮助我们优雅地管理这些异常并避免程序崩溃。

在C语言中,异常可以通过一些特定的语言特性来处理,包括异常的产生、传递和捕获。

本文将深入探讨这些方面的内容。

1. 异常的产生异常在程序中表示一个特定的问题或错误情况,它可以由多种原因产生,例如除零错误、空指针引用、数组越界等。

当这些异常发生时,程序会中断执行并跳转到异常处理代码。

2. 异常的传递异常的传递指的是将异常从一个代码块传递到另一个代码块的过程。

在C语言中,当异常发生时,程序会从发生异常的地方跳转到离它最近的异常处理代码块。

如果该异常处理代码块无法处理该异常,它将继续传递异常到更高层的代码块,直到找到一个能够处理异常的地方。

3. 异常的捕获异常的捕获指的是编写特定的代码来处理异常并进行相应的操作。

在C语言中,我们可以使用try-catch语句来捕获异常,并在catch块中编写处理异常的代码。

如果异常被捕获并处理,程序将继续执行异常处理代码块后面的代码;否则,异常将继续传递到更高层的代码块。

在C语言中,异常处理机制并不是内置的,我们通常需要使用一些额外的库或编写自定义的函数来实现异常处理。

以下是一个简单的示例,演示了异常处理的过程:```c#include <stdio.h>#include <setjmp.h>jmp_buf exception;void divide(int a, int b) {if (b == 0) {longjmp(exception, 1); // 抛出异常}printf("结果: %d\n", a / b);}int main() {int x, y;printf("请输入两个整数:");scanf("%d %d", &x, &y);if (setjmp(exception) == 0) { // 设置异常处理点divide(x, y);} else {printf("除数不能为0!\n");}return 0;}```在上面的示例中,我们使用了setjmp和longjmp函数来实现异常处理。

c语言异常处理机制

c语言异常处理机制

c语言异常处理机制C语言异常处理机制异常处理是计算机编程中的重要概念,它允许程序在出现错误或异常情况时进行适当的处理,以保证程序的稳定性和可靠性。

在C语言中,异常处理机制主要通过错误码和异常处理函数来实现。

本文将详细介绍C语言异常处理机制的原理和使用方法。

一、错误码在C语言中,错误码是用来表示程序执行过程中出现错误的一种机制。

当程序执行过程中发生错误时,相应的错误码会被设置为一个特定的值,以便程序能够根据错误码来进行相应的处理。

C语言中常用的错误码包括0表示成功,其他非零值表示不同的错误类型。

例如,当打开一个文件失败时,C语言会将errno变量设置为一个非零值,以表示文件打开失败的错误码。

程序可以通过检查errno 的值来确定文件是否成功打开,并根据具体情况进行相应的处理。

二、异常处理函数异常处理函数是一种特殊的函数,用于处理程序执行过程中出现的异常情况。

在C语言中,异常处理函数通常使用setjmp和longjmp函数来实现。

setjmp函数用于设置一个跳转点,而longjmp函数则用于跳转到之前设置的跳转点,并传递一个特定的值作为异常处理的结果。

异常处理函数的使用方法如下:1. 使用setjmp函数设置一个跳转点,将跳转点保存在一个jmp_buf类型的变量中。

2. 在程序执行过程中,如果发生异常情况,调用longjmp函数跳转到之前设置的跳转点,并传递一个特定的值作为异常处理的结果。

3. 在异常处理函数中,根据传递的异常处理结果进行相应的处理,例如输出错误信息、关闭文件等。

异常处理函数的优点是可以在程序的任何地方进行异常处理,并且可以跳过一些中间步骤,直接跳转到异常处理的代码段。

这样可以提高程序的执行效率,并且使程序的结构更加清晰。

三、异常处理的应用异常处理在实际的程序开发中有着广泛的应用。

它可以用于处理各种类型的异常情况,例如文件打开失败、内存分配失败、网络连接中断等。

通过合理地使用异常处理机制,可以使程序在出现异常情况时能够进行适当的处理,从而提高程序的稳定性和可靠性。

C语言中的错误处理和异常处理技术

C语言中的错误处理和异常处理技术

C语言中的错误处理和异常处理技术在C语言编程中,错误处理和异常处理是非常重要的技术。

在程序运行过程中,可能会出现各种意外情况,如输入错误、文件打开失败、内存分配失败等,处理这些异常情况可以提高程序的健壮性和可靠性。

在C语言中,有几种常见的错误处理和异常处理技术:1. 返回值检查:在调用函数时,经常会返回一个特定的值来表示函数执行的结果。

程序员可以检查返回值来判断函数是否运行成功,并据此做出相应的处理。

例如,当调用文件读写函数时,可以检查返回值是否为NULL来判断文件是否打开成功。

2. 错误码:有些函数在执行过程中会返回一个错误码,表示出现了何种错误。

程序员可以根据该错误码来分析问题所在,并采取相应的措施。

例如,标准函数库中的errno变量就是用来存储错误码的。

3. 异常处理:C语言并没有内建的异常处理机制,但可以通过setjmp和longjmp函数来实现简单的异常处理。

setjmp函数设置一个跳转点,然后程序在执行过程中发生异常时,可以使用longjmp函数跳转到之前设置的跳转点,从而实现异常处理。

4. 信号处理:在Unix/Linux系统中,程序可以通过信号处理机制来处理异常情况。

可以使用signal函数注册一个信号处理函数,当接收到相应的信号时,程序将调用该函数来处理异常。

常见的信号包括SIGSEGV(段错误)、SIGFPE(浮点异常)等。

5. 强制类型转换:有时候程序需要进行类型转换操作,但会出现类型不匹配的情况,造成编译或运行错误。

在这种情况下,程序员可以使用强制类型转换来解决问题,通过将数据强制转换为目标类型来消除警告或错误。

总的来说,良好的错误处理和异常处理是一个程序的重要组成部分,可以帮助程序更加健壮地运行。

程序员需要在编写代码的过程中考虑可能出现的各种异常情况,采取相应的措施来处理这些异常,以确保程序的稳定性和可靠性。

通过合理的错误处理和异常处理,可以提高代码的质量和可维护性,为软件开发工作带来很大的便利。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

C++异常处理机制全解▌异常处理(Exception handling)●返回一个错误码进行异常处理(C语言):例:bool func(float a, float b, float& c){if(b==0){return false;}c=a/b;return true;}int main(){float a=10;float b=0;float c=0;bool result=func(a, b, c);if(!result){cout<<"The func fails!"<<endl;return 0;}else{cout<<"The func succeeds!"<<endl;}//func1();//func2();return 0;}●try-throw-catch语句(C++);例:void func(float a, float b, float& c){if(b==0){ //如果b为0,则抛出字符串“Divided by zero!”;throw "Divided by zero"; //throw出来的东西可以是任何类型,甚至可以是类的对象;}c=a/b;}int main(){float a=10;float b=0;float c=0;try{ //测试条件;func(a, b, c);//func1();//func2();}catch(const char* str){ //捕获异常信息;cout<<str<<endl;}//func4();return 0;}★try:诊断异常代码;例:try{//可能出现异常的情况}☆可能出现异常的三种情况:①可执行语句;②一个函数调用;③一个函数调用另一个函数;★throw:抛出错误信息;例:if(分母==0){throw 参数(只有一个,可以是任何类型,甚至是一个对象)}★catch:捕获异常信息;例:catch(参数类型参数){ //只能有一个参数,这里的形参可以被省略,但是省略后不能输出异常信息,依然可以捕获;cout<<参数<<endl;}☆☆☆如果throw抛出了异常,异常类型如果与catch块后面的类型匹配,catch块内的代码将会被执行,在try语句后面可以有多个catch块,程序会寻找第一个相匹配的catch块,实行catch块的语句代码,然后跳到最后一个catch块的下一行代码,如果没有匹配的catch块,则异常返回上一层try-catch语句,如果没有相应的catch发现,程序将会终结。

★catch块不能访问try块里面定义的临时变量。

★try-throw-catch的三种写法:例://1void func(){float x, num, den;... //initialize num and dentry{ //把操作放到try块里面,不良的写法;if(den==0){throw "Divided by zero";}x=num/den;}//...}//2float divide(float a, float b){ //在函数体中实现操作,推荐写法;if(b==0){throw "divided by zero";}return a/b;}void func(){float x, num, den;//initialize num and dentry{x=divide(num, den);}catch(const char* error){cout<<error;}//...}//3float divide(float a, float b){if(b==0){throw "divided by zero";}return a/b;}float middle(float a, float b){ //嵌套写法,推荐写法;return divide(a, b);}void func(){float x, num, den;//initialize num and dentry{x=middle(num, den);}catch(char* error){cout<<error;}//...}▌再次抛出一个异常:例:#include<iostream>using namespace std;float divide(int a, int b){if(b==0){throw "divided by zero";}return float(a)/float(b);}float middle(int a, int b){try{return divide(a, b);}catch(const char* str){cout<<"Caught by function middle."<<endl;throw str;}}void func(int d){float x;int num=100;int den=d;//initialize num and dentry{x=middle(num, den);}catch(const char* error){cout<<error<<endl;}}int main(){int i=1;cin>>i;func(i);return 0;}▌catch块命令:★通用格式:catch(...) //这里的三个点表示可以捕获任何异常;{//...}☆由于没有参数在上面,所以不能使用这些异常信息。

☆如果有一个catch块比另一个catch块更通用,则通用的catch块放在后面。

例:class Base;class Derived : public Base;Base b;Derived d;func(){throw "First exception"; //抛出一个字符串;throw d; //抛出一个子类对象;}try{func();}catch(const char* str){}catch(const int a){}catch(const Derived& d) //捕获子类对象;//catch(const Base& b) //可以捕获,子类对象可以当基类对象来使(公有继承);..catch(...){}☆catch块捕获一个对象时,catch块一般是子类放前面,基类放后面。

▌▲栈展开(Stack unwinding):★定义:如果一个函数里产生异常,那么这个函数将会被终结,并且本地变量(栈上的变量)会被释放。

但是如果有指针且动态分配了内存,那么栈上的指针将会被释放,而指针指向的堆内存没有被释放,这时会发生内存泄漏。

在这种情况下,为了避免内存泄漏,必须把指针抛给它的上一层调用者,让它来释放这块堆内存。

我们可以把这个指针封装到一个错误消息类里面去,然后抛出这个类的对象(构造函数构造的临时对象),为了避免临时对象的生成,我们在catch块里用这个类的引用做参数。

例:func(){int a=5; //在栈上声明的;int b=8; //在栈上声明的;char* p=new char[100] //p在栈上,p指向的内存在堆上;//throw "exception"; //会发生内存泄漏;......}▲为了避免内存泄露,我们需要将指针抛出。

我们把指针封装在一个错误类里面,然后把对象抛出,为了避免拷贝构造,我们传一个对象的引用。

例:☆☆☆#include<iostream>using namespace stdclass Error_message{public:char* message;int* arrayptr;Error_message(char* str, int* p):message(str),arrayptr(p){}};void f(){int* a=new int[10];int i=0;if(i==0){throw Error_message("error", a); //throw "error"(抛出一个构造函数构造出来的临时对象); }delete [] a; //已经throw了,这里的delete无作用;}void g(){try{f();}catch(Error_message& m){delete [] m.arrayptr; //通过构造函数删除指针在堆上分配的空间;cout<<m.message<<endl;}catch(const char* str){cout<<str<<endl;}}int main(){g();return 0;}▌不捕获异常(Uncaught exception):★定义:如果一个异常没有被catch住,或者没有写catch块,这种情况就叫不捕获异常。

如果一个异常没有被捕获住,则会终结(terminate)函数。

例:func(){int* p=new char[100000000000000];if(p==NULL){throw "exception"; //此处终结函数;}delete p;}void my_clear(){cout<<"OK,clear!"<<endl;}//terminate()set_terminate(my_clear); //调用set_terminate()捕获异常;int main(){func();}▲terminate()...(缓冲区)[set_terminate()]...-->abort()【terminate()调用abort()进行终结,我们在缓冲区(在里面调用set_terminate)来解决异常。

】☆void set_terminate( void(*)() ) //set_terminate()原型。

void(*)()是一个函数指针,这个函数叫回调函数。

例:#include<iostream>#include<exception> //包含set_terminate()的头文件;using namespace std;void my_terminate(){cout<<"Uncaught exception.\n";}float divide(int x, int y){if(y==0){throw "divide by zero";}return float(x)/float(y);}int main(){set_terminate(my_terminate);cout<<divide(1, 0);return 0;}▌异常指定:★定义:可以对抛出的异常进行指定(字符串、对象等等),throw语句不能抛出指定以外的东西。

相关文档
最新文档