错误处理

说实话这一章节看的云里雾里, 而且目前也没有能用到它的场景. 先记下来, 以后用的时候方便查看.

编写无错程序的方法有两种,但只有第三种写程序的方法才行得通.

<assert.h>: 诊断

void assert(scalar express);
  • assert是一个按照函数的使用方法设计的宏.
  • 需要传入一个(正常情况一定为真的)表达式.
  • 表达式返回结果为真时,什么也不做.
  • 表达式返回结果为假时,assert会向stderr写一条消息,并用abort函数终止程序.

<errno.h>: 错误

errno变量

声明了一个int型的errno变量(/宏). 某些函数出错会在erron中存储一个正整数错误码. 可以通过判断erron是否为0来判断函数是否出错.

errno = 0; // 需要先将errno重置为0
y = sqrt(x);
if(errno!=0){
    fprintf(stderr,"sqrt error; program terminated.\n");
}

相关宏

宏名 含义
EDOM 定义域错误
ERANGE 取值范围错误
EILSEQ(C99) 特定头(尤其是wchar.h)中库函数发生了编码错误

perror函数和strerror函数

函数原型 头文件
void perror(const char *s); 来自<stdio.h>
char *strerror(int errnum); 来自<string.h>

perror

void perror(const char *s);

perror()打印一条错误信息(打印在stderr中).

打印的格式如下:

perror中的参数: 出错信息\n

出错信息取决于errno变量中的值.

strerror

char *strerror(int errnum);

strerror()需要传入一个错误码,可以选择传入errno变量,也可以自己传入一些错误码(如EDOM).

他的返回值是一个指针. 这个指针指向一个字符串, 字符串中存着关于这个错误码的描述.

puts(strerror(EDOM));

上面这个代码会打印:

Numberical argument out of domain

<signal.h>: 信号处理

信号宏

宏名 含义
SIGABRT 异常终止(可能由于调用abort导致)
SIGFPE 在算数运算中发生错误(可能是除以0或者溢出了)
SIGILL 无效指令
SIGINT 中断
SIGSEGV 无效内存访问
SIGTERM 终止请求

这里的信号宏不一定都有意义,至少能支持其中的一部分.

signal函数

使用方法

signal(信号宏,函数指针);

当出现<信号宏>信号时,函数指针指向的函数就会被自动调用(相当于给指定信号安装了信号处理装置). 如:

signal(SIGINT,handler);

SIGINT信号出现时,执行handler函数.

关于信号处理函数的三个要点:

  • 信号处理函数需要是void返回值,且必须有一个int型参数.
  • 信号的编码会被当做参数传给信号处理函数.
  • 除非信号是调用abort或者raise函数发出的, 信号处理函数不应该调用库函数或者操作静态变量.

signal函数的返回值

signal函数返回值是一个函数指针,指向前一个(指定信号的)信号处理函数. 一般不怎么用他.

预定义的信号处理函数

  • SIG_DFL: 默认
  • SIG_IGN: 忽略

还有一个长得很像喜好处理函数的宏, SIG_ERR. 实际上这个宏是用来检测安装信号处理函数时是否发生了错误.如:

if(signal(SIGINT,handler) == SIG_ERR){
    perror("signal(SIGINT,handler) failed");
    ...
}

raise函数

主动产生信号. 失败返回0, 成功返回非0值.

int raise(int sig);

无论信号从哪里产生,他都会被最近安装的该信号的处理函数捕获.

<setjmp.h>: 非局部跳转

goto语句可以跳转到他所在函数的某一位置. 但是不能离开这个函数. 但<setjmp.h>可以从一个函数跳转到另一个函数中, 不需要返回.

setjump()

设置跳转点

int setjmp(jmp_buf environment)
  • environment -- 这是一个类型为 jmp_buf 的用于存储环境信息的对象。

longjmp()

跳转

void longjmp(jmp_buf environment, int value)
最后修改:2023 年 04 月 28 日
如果觉得我的文章对你有用,请随意赞赏