C 语言程序的错误处理是需要程序员自己来解决的,而面向对象类语言如Java、C++、Python都是用异常机制来处理错误。
如果返回值是 int 类型,并且返回的数据是非负数,一般使用 -1 代表出错,然后非负数代表正确的返回值。
如果返回值是 int 类型,但返回的数据有可能是负数,用指针接收返回数据,也就是将其中一个参数作为输出返回,用返回值 0 代表成功,返回 -1 代表出错。
如果返回值是指针,一般用 NULL 代表出错,非空代表正确。
如果不需要考虑错误处理,返回值用 void 即可。简单总结这几种情况,以上几种情况属于一般情况,当然也可能会有特列。
打印传入的字符串 对应上述第 4 种情况,不需要返回值,一般不会出错,不需要考虑错误处理。
判断传入的字符串是否正确 判断传入的字符串是否是 error,如果是返回 ok,不是的话报错。对应上述第 3 种情况,如果不是返回 NULL。
返回 1-10 随机数 返回 1-10 随机数,如果随机数是 5,返回 -1 代表出错,若不是则返回 1-10 的随机数。
比较两个整数的大小 比较两个整数的大小,返回最大值,如果相等则报错。对应上述第 2 种情况,返回值可能是负数,不能直接返回 -1 来表示错误,需要增加指针参数来接收最大值的返回。
当然文中举例都非常简单,主要是想说明 C 语言程序中我们要关注错误的处理,这样有助于对程序的错误的快速排查。当然错误的时候不止可以返回 -1,如果系统比较复杂,可以设置多种错误码来区分程序中的各类错误,最好每个错误码都对应具体的错误原因。
C语言中,系统预先设定了一些错误,每种错误都由错误编号和错误信息组成。每个错误编号对应一种错误信息。
errno 外部全局变量,提供了错误编号,需要先出错,再用errno,函数出错会改变 errno 的值,但成功不会改值,也不会清零。所以它不能用于判断是否出错,errno 直接拿来使用即可,不过程序中需要加头文件 error.h。
strerror 函数通过错误编号得到错误信息,完成从错误编号到错误信息的转换,与 errno 没有直接的关系,是否产生错误都可以使用它。
printf("%s\n", strerror(errno);
perror 函数打印错误信息并自动换行,这个函数经常使用,参数是附加的信息,能更好的帮助程序员定位错误。
perror("open file error: ");
// 前提是打开文件出错
perror 函数是找 errno,打印 errno 对应的错误信息,先发生错误而后才能使用。errno 针对大多数函数有效,但也有一些函数不能使用 errno 作为错误记录,比如线程函数,因为线程出错会将之前的错误覆盖,导致不能够准确判断出具体错误。