异常处理C中没有异常,所以我们可以通过函数返回值来判断错误类型。但有时希望错误能在顶层统一处理,让代码更简洁。其实首先想到的可能是goto语句,但是goto不能跳转到另一个函数的某个标号,但是C提供了另外两个函数来完成这个任务:setjmp和longjmp。函数原型#includeintsetjmp(jmp_bufenv);voidlongjmp(jmp_bufenv,intval);示例第一次调用setjmp将返回0,并将此处函数的上下文保存在jmp_buf结构中。当调用longjmp函数时,jmp_buf从setjmp函数保存的context中恢复,然后程序跳转到setjmp,setjmp再次返回。如果longjmp设置的val为0,setjmp返回1,否则返回val。#include/*printf,scanf*/#include/*exit*/#include/*jmp_buf,setjmp,longjmp*/main(){jmp_bufenv;整数值;val=setjmp(env);if(val){fprintf(stderr,"发生错误%d",val);退出(瓦尔);}/*代码在这里*/longjmp(env,101);/*发出错误信号*/return0;}C中的宏(macro)是由#define定义的符号。在编译和预处理时,所有出现在程序中的“宏名”都将被替换的字符串所定义。一般形式:#definemacro-nameString宏可以分为两类:带参数和不带参数。//不带参数#definePI3.1415926//带参数#defineMULTIPLY(x,y)(x)*(y)宏用得好,可以使C程序更加简洁合理。实际异常#include#includestaticjmp_bufex_buf__;#defineTRYswitch(setjmp(ex_buf__)){case0:#defineCATCH(x)break;案例x:#defineETRY中断;}#defineTHROW(x)longjmp(ex_buf__,x)#defineFOO_EXCEPTION(1)#defineBAR_EXCEPTION(2)#defineBAZ_EXCEPTION(3)voiddosomething(){printf("我正在做某事!\n");抛出(BAR_EXCEPTION);printf("我联系不上\n");}intmain(intargc,char**argv){TRY{dosomething();}CATCH(FOO_EXCEPTION){printf("GotFoo!\n");}CATCH(BAR_EXCEPTION){printf("GotBar!\n");}CATCH(BAZ_EXCEPTION){printf("GotBaz!\n");}埃特里;printf("一切结束\n");返回0;}