永发信息网

C语言异常处理

答案:2  悬赏:60  手机版
解决时间 2021-04-21 10:37

我想知道C语言或C++自带的异常类型有哪些?

比如说,throw bad_alloc

最佳答案


bad_alloc:new分配失败
bad_cast:dynamic_cast失败
bad_typeid:typeif参数为空
logic_error:逻辑错误
ios_base::failure:IO错误
runtime_error:运行时错误
bad_exception:未知错误

赋值不成功可以用runtime_error,你也可以自己继承一个异常类过来,自定义异常信息
全部回答

一、前言

Visual C++提供了对C语言、C++语言及MFC的支持,因而其涉及到的异常(exception)处理也包含了这三种类型,即C语言、C++语言和MFC的异常处理。除此之外,微软对C和C++的异常处理进行了扩展,提出了结构化异常处理(SEH)的概念,它支持C和C++(与之相比,MFC异常处理仅支持C++)。   一个典型的异常处理包含如下几个步骤:   (1)程序执行时发生错误;   (2)以一个异常对象(最简单的是一个整数)记录错误的原因及相关信息;   (3)程序检测到这个错误(读取异常对象);   (4)程序决定如何处理错误;   (5)进行错误处理,并在此后恢复/终止程序的执行。   C、C++、MFC及SEH在这几个步骤中表现出了不同的特点。下面将对这四种异常处理进行介绍,并对它们进行对比分析。 以下代码调试平台为Visual C++6.0,操作系统为Windows XP,所有程序均调试通过。   许多的学员对异常处理视而不见,程序里很少考虑异常情况。一部分人甚至根本就不考虑,以为程序总是能以正确的途径运行。譬如我们有的学员调用fopen打开一个文件后,立马就开始进行读写操作,根本就不考虑文件是否正常打开了。这种习惯一定要改掉,纵使你再不愿意!这是软件健壮性的需要!异常处理不是浪费时间!

二、C语言的异常处理

1 异常终止   标准C库提供了abort()和exit()两个函数,它们可以强行终止程序的运行,其声明处于头文件中。这两个函数本身不能检测异常,但在C程序发生异常后经常使用这两个函数进行程序终止。下面的这个例子描述了exit()的行为:

CODE: #include <stdio.h> #include <stdlib.h> int main(void) {  exit(EXIT_SUCCESS);  printf("程序不会执行到这里\n");  return 0; }

在这个例子中,main函数一开始就执行了exit函数(此函数原型为void exit(int)),因此,程序不会输出"程序不会执行到这里"。程序中的exit(EXIT_SUCCESS)表示程序正常结束,与之对应的exit(EXIT_FAILURE)表示程序执行错误,只能强行终止。EXIT_SUCCESS、EXIT_FAILURE分别定义为0和1。

  对于exit函数,我们可以利用atexit函数为exit事件"挂接"另外的函数,这种"挂接"有点类似Windows编程中的"钩子"(Hook)。譬如:

CODE: #include <stdio.h> #include <stdlib.h> static void atExitFunc(void) {  printf("atexit挂接的函数\n"); } int main(void) {  atexit(atExitFunc);  exit(EXIT_SUCCESS);  printf("程序不会执行到这里\n");  return 0; }

程序输出"atexit挂接的函数"后即终止。来看下面的程序,我们不调用exit函数,看看atexit挂接的函数会否执行:

CODE: #include <stdio.h> #include <stdlib.h> static void atExitFunc(void) {  printf("atexit挂接的函数\n"); } int main(void) {  atexit(atExitFunc);  //exit(EXIT_SUCCESS);  printf("不调用exit函数\n");  return 0; }

程序输出:   不调用exit函数   atexit挂接的函数   这说明,即便是我们不调用exit函数,当程序本身退出时,atexit挂接的函数仍然会被执行。   atexit可以被多次执行,并挂接多个函数,这些函数的执行顺序为后挂接的先执行,例如:

CODE: #include <stdio.h> #include <stdlib.h> static void atExitFunc1(void) {  printf("atexit挂接的函数1\n"); } static void atExitFunc2(void) {  printf("atexit挂接的函数2\n"); } static void atExitFunc3(void) {  printf("atexit挂接的函数3\n"); } int main(void) {  atexit(atExitFunc1);  atexit(atExitFunc2);  atexit(atExitFunc3);  return 0; }   输出的结果是:    atexit挂接的函数3    atexit挂接的函数2    atexit挂接的函数1

  在Visual C++中,如果以abort函数(此函数不带参数,原型为void abort(void))终止程序,则会在debug模式运行时弹警告对话框。 2 断言(assert) assert宏在C语言程序的调试中发挥着重要的作用,它用于检测不会发生的情况,表明一旦发生了这样的情况,程序就实际上执行错误了,例如strcpy函数:

CODE: char *strcpy(char *strDest, const char *strSrc) {  char *address = strDest;  assert((strDest != NULL) && (strSrc != NULL));  while ((*strDest++ = *strSrc++) != ’\0’)   ;  return address; }

  其中包含断言assert( (strDest != NULL) && (strSrc != NULL) ),它的意思是源和目的字符串的地址都不能为空,一旦为空,程序实际上就执行错误了,会引发一个abort。   assert宏的定义为:

CODE: #ifdef NDEBUG #define assert(exp) ((void)0) #else #ifdef __cplusplus extern "C" {  #endif  _CRTIMP void __cdecl _assert(void *, void *, unsigned);  #ifdef __cplusplus } #endif #define assert(exp) (void)( (exp) || (_assert(#exp, __FILE__, __LINE__), 0) ) #endif

  如果程序不在debug模式下,assert宏实际上什么都不做;而在debug模式下,实际上是对_assert()函数的调用,此函数将输出发生错误的文件名、代码行、条件表达式。例如下列程序:

CODE: #include <stdio.h> #include <stdlib.h> #include <assert.h> char * myStrcpy( char *strDest, const char *strSrc ) {  char *address = strDest;  assert( (strDest != NULL) && (strSrc != NULL) );  while( (*strDest++ = *strSrc++) != ’\0’ );   return address; } int main(void) {  myStrcpy(NULL,NULL);  return 0; }

  在此程序中,为了避免我们的strcpy与C库中的strcpy重名,将其改为myStrcpy。 失败的断言也会弹出对话框,这是因为_assert()函数中也调用了abort()函数。   一定要记住的是assert本质上是一个宏,而不是一个函数,因而不能把带有副作用的表达式放入assert的"参数"中。 3 errno errno在C程序中是一个全局变量,这个变量由C运行时库函数设置,用户程序需要在程序发生异常时检测之。C运行库中主要在math.h和stdio.h头文件声明的函数中使用了errno,前者用于检测数学运算的合法性,后者用于检测I/O操作中(主要是文件)的错误,例如:

CODE: #include <errno.h> #include <math.h> #include <stdio.h> int main(void) {  errno = 0;  if (NULL == fopen("d:\\1.txt", "rb"))  {   printf("%d", errno);  }  else  {   printf("%d", errno);  }  return 0; }

  在此程序中,如果文件打开失败(fopen返回NULL),证明发生了异常。我们读取error可以获知错误的原因,如果D盘根目录下不存在"1.txt"文件,将输出2,表示文件不存在;在文件存在并正确打开的情况下,将执行到else语句,输出0,证明errno没有被设置。   Visual C++提供了两种版本的C运行时库。-个版本供单线程应用程序调用,另一个版本供多线程应用程序调用。多线程运行时库与单线程运行时库的一个重大差别就是对于类似errno的全局变量,每个线程单独设置了一个。因此,对于多线程的程序,我们应该使用多线程C运行时库,才能获得正确的error值。   另外,在使用errno之前,我们最好将其设置为0,即执行errno = 0的赋值语句。 4 其它   除了上述异常处理方式外,在C语言中还支持非局部跳转(使用setjmp和longjmp)、信号(使用signal、raise)、返回错误值或回传错误值给参数等方式进行一定能力的异常处理,但是其使用不如上面所介绍方式常用,我们不必过细研究。   从以上分析可知,C语言的异常处理是简单而不全面的。与C++的异常处理比起来,C语言异常处理相形见绌,它就像一个新生的雏婴。

参考

http://hi.baidu.com/wukongafei/blog/item/d4f9e9a2d25fcfa8caefd064.html

我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
时间长了,是不是感情都会变质???
在上海哪里有玩桌游的地方???
剪不简单怎么去啊,有知道地址的么
关于DNF装备被盗找回。。
DNF索喃可以卖多少钱
这是什么内存
谁有shinee唱的boys on top的mp3?
烽火战国怎么打据点?
我装了个驱动 然后再桌面点右键就老出现这个
盐城英皇国标舞会所在什么地方?
鸿发大理石石材地址在哪,我要去那里办事
U盘打不开,怎么办啊?
金羽杰羽绒服地址有知道的么?有点事想过去
PASCAL书籍推荐
快乐女声写真集在杭州书店有卖么
推荐资讯
空间播放器怎么弄呢?
云和县食品药品监督管理局(旧)在什么地方啊,
我一笑眼角有好多皱纹我现在才二十一岁
问道里怎么接不起元宝商人任务?
阳合·汽车租赁华林店在什么地方啊,我要过去
E语言如何实现导入一个TXT文件到一个编辑框
网上卖东西,都是正品吗?
美德能用憔悴形容吗
谁知道怎么批量下载百度音乐盒里的歌曲
DNF为什么登陆到选择频道时退出游戏?
花冠群芳专卖店这个地址在什么地方,我要处理
用阿斯匹林怎么美白啊?
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?