这几个函数都在头文件#include <stdlib.h>中声明。exit、_Exit与abort函数使程序终止,控制并不返回到这些函数的调用者。
exit()函数
void exit(intstate);
exit()函数用于在程序执行的过程中随时结束程序,exit的參数state是返回给操作系统,返回0表示程序正常结束,非0表示程序非正常结束。
main函数结束时也会隐式地调用exit函数。
exit函数执行时首先会执行由atexit()函数登记的函数,然后会做一些自身的清理工作,同一时候刷新全部输出流、关闭全部打开的流、删除过标准I/O函数tmpfile()创建的暂时文件、控制返回宿主环境,提供状态值。
依照很多系统中的习惯,state值为0表示终止程序成功,用非0值表示异常终止。
标准C语言中数值0和宏EXIT_SCCESS的值表示终止成功,宏EXIT_FAILURE的值表示终止不成功,其它值的含义由实现定义。从函数main返回一个整数值相当于用这个值调用exit函数。
_Exit()函数
void _Exit(int status); //C99
函数_Exit与exit函数不同之处在于既不调用atexit注冊的退出处理器。也不调用singal注冊的信号处理器。
是否进行其它清理操作由实现定义,如关闭全部打开的数据流。
_Exit是C99添加的,传统上有些实现用名为_exit的函数提供类似功能。
atexit()函数
intatexit(void(*func)(void));
非常多时候我们须要在程序退出的时候做一些诸如释放资源的操作,但程序退出的方式有非常多种,比方main()函数执行结束、在程序的某个地方用exit()结束程序、用户通过Ctrl+C或Ctrl+break操作来终止程序等等。因此须要有一种与程序退出方式无关的方法来进行程序退出时的必要处理。方法就是用atexit()函数来注冊程序正常终止时要被调用的函数。
atexit()函数的參数是一个函数指针,函数指针指向一个没有參数也没有返回值的函数。atexit()的函数原型是:int atexit (void (*)(void));
在一个程序中最多能够用atexit()注冊32个处理函数,这些处理函数的调用顺序与其注冊的顺序相反,也即最先注冊的最后调用,最后注冊的最先调用。
注冊函数不能引用不论什么不是自定义的存储类为auto或 register的对象(比如通过指针引用)。
函数注冊几次就会在此时调用几次。
以下是一段代码演示样例:
#include <stdlib.h>
#include<iostream.h>
void terminateTest()
{
cout<<"程序正在结束..."<<endl;
}
int main(void)
{
// 注冊退出处理函数
atexit(terminateTest);
cout<<"the end ofmain()"<<endl;
return 0;
}
程序的执行结果为:
the end of main()
程序正在结束...
这些函数都是在main结束以后才被调用的。atexit仅仅是注冊他们。使得他们在main结束以后被调用,看名字就能够看出来。
atexit这个玩意超实用,能够依照你预设的顺序摧毁全局变量(类),比如有个log类,你在其他的全局类里也有可能调用到Log类写日志。
所以log类必须最后被析构。假如没有规定析构顺序,那么程序在退出时将有可能首先析构log类,那么其他的全局类在此时将无法正确写日志。
abort()函数
void abort(void);
abort函数使程序异常终止,不调用向atexit注冊的函数。abort是否引起清理操作由实现定义。向宿主系统返回的状态值也由实现定义,但应表示为“不成功”。
在标准C语言和很多传统实现中,调用abort转换成能够捕获的特殊信号(标准C语言中为SIGABRT)。
假设信号被忽略或处理器返回,则标准C语言实现仍然终止程序,而其它实现可能使abort函数返回调用者。断言失败也会调用abort。