13.5 库中包含函数的修改
基于原先为特殊上下文环境开发的函数而建立个人库时,通常建议进行一些修改。库函数应尽可能地通用,所以应该检查所有使用的常量是否能由输入参数代替。任何对于库函数参数的限制都应该小心定义。
在前面的工作中,编写的函数已经可以通过返回一个错误代码、或是显示一条错误消息来处理错误,并且可以返回一个允许继续执行的数值。然而在一些情况下,不允许继续处理会更好一些。例如,一个大型二维数组的操作可能会非常耗费时间,而且在一个包含错误数据的矩阵上耗费时间可能是毫无意义的。类似地,如果用一个负数调用factorial函数,不可能返回一个合法的值。因此可以输出一条消息,然后在程序错误发生的地方终止程序的执行。
C语言的标准库stdlib中的exit函数可以用于上面的这些情况来提前终止执行。用参数1调用exit表示是一些故障导致了退出。使用数值0调用exit表示没有故障,就像从函数main返回0表示函数成功完成一样。exit函数也可以使用预定义的常量EXIT_SUCCESS和EXIT_FAILURE作为返回值。只要包含了标准库stdlib,这两个常量也可以用于return语句。图13-8给出了函数factorial的库的形式,它会在有负数输入时提前终止程序执行。
|
687. /* 688. * Computes n! 689. * n is greater than or equal to zero -- premature exit on negative data 690. */ 691. int 692. factorial(int n) 693. { 694. int i, /* local variables */ 695. product = 1; 696. 697. if (n < 0) { 698. printf("\n***Function factorial reports "); 699. printf("ERROR: %d! is undefined***\n", n); 700. exit(1); 701. } else { 702. /* Compute the product n x (n-1) x (n-2) x ... x 2 x 1 */ 703. for (i = n; i > 1; --i) { 704. product = product * i; 705. } 706. 707. /* Return function result */ 708. return (product); 709. } 710. } |
图13-8 对于负数数据提前退出的函数factorial
下面的语法展示描述了exit函数。
exit函数
语法:exit(返回值);
示例:/*
* Gets next positive number from input
* stream. Returns EOF if end of file
* is encountered. Exits program with error
* message if erroneous input is encountered.
*/
int
get_positive(void)
{
int n, status;
char ch;
for(status=scanf("%d", &n);
status==1 && n<=0;
status=scanf("%d", &n)) {}
if(stauts==0) {
scanf("%c", &ch);
printf("\n***Function get_positive");
printf("reports ERROR in data at");
printf(">>%c<<***\n", ch);
exit(1);
} else if (status==EOF) {
return(status);
} else {
return(n);
}
}
说明:exit调用的执行使得程序可以在其中任何一点终止。返回值用于表示终止是否是由某些类型的故障引起的。返回值为0意味着正常退出。通常应在函数中避免使用
exit(0);
除非是在main中,这是因为将程序的“正常”终止放在其中一个子函数中会使得函数main的可读性降低。
exit(1);
的使用应为终止执行而保留,以防不能进行错误恢复或错误恢复不可用。
练习
自测
1.为什么在库自身的实现文件中#include库的头文件?







