C++中的atexit函数和exit函数

一、exit()函数
函数声明:void exit(int state);
exit()函数用于在程序运行的过程中随时结束程序,exit的参数state是返回给操作系统,返回0表示程序正常结束,非0表示程序非正常结束。main函数结束时也会隐式地调用exit函数。exit函数运行时首先会执行由atexit()函数登记的函数,然后会做一些自身的清理工作,同时刷新所有输出流、关闭所有打开的流并且关闭通过标准I/O函数tmpfile()创建的临时文件。


二、atexit()函数
函数声明:int atexit(void (*func)(void)); 
很多时候我们需要在程序退出的时候做一些诸如释放资源的操作,但程序退出的方式有很多种,比如main()函数运行结束、在程序的某个地方用exit()结束程序、用户通过Ctrl+C或Ctrl+break操作来终止程序等等,因此需要有一种与程序退出方式无关的方法来进行程序退出时的必要处理。方法就是用atexit()函数来注册程序正常终止时要被调用的函数。
atexit()函数的参数是一个函数指针,函数指针指向一个没有参数也没有返回值的函数。atexit()的函数原型是:int atexit (void (*)(void));在一个程序中最多可以用atexit()注册32个处理函数,这些处理函数的调用顺序与其注册的顺序相反也即最先注册的最后调用,最后注册的最先调用

    我们通常认为C语言的起始函数是main函数,实质上一个程序的启动函数并不一定是main函数,这个可以采用链接器来设置,但是gcc(GNU Compiler Collection)中默认main就是C语言的入口函数,在main函数启动之前,内核会调用一个特殊的启动例程,这个启动例程从内核中取得命令行参数值和环境变量值,为调用main函数做好准备,因此对应程序而言main函数并不是起始,但是对应C 语言而言,main函数就是入口地址,其他的链接器帮助我们完成,实际上mian函数的执行是使用了exec函数,这是一个函数族,这也是内核执行一个程序的唯一方法,这在进程控制部分将进行分析。
     在exit函数的介绍中我们知道,exit()和_exit()以及_Exit()函数的本质区别是是否立即进入内核,_exit()以及_Exit()函数都是在调用后立即进入内核,而不会执行一些清理处理,但是exit()则会执行一些清理处理,这也是为什么会存在atexit()函数的原因,因为exit()函数需要执行清理处理,需要执行一系列的操作,这些终止处理函数实际上就是完成各种所谓的清除操作的实际执行体。atexit函数的定义也给了程序员一种运用exit执行一些清除操作的方法,比如有一些程序需要额外的操作,具体的清除操作可以采用这种方法对特殊操作进行清除等。
    有一道关于在main函数退出之后,是否还可以执行程序的问题,这时候就要使用到前面提到的atexit函数。
     #include<stdlib.h>
     int atexit(void(*func)(void));
  具体检测代码如下:
  1. #include <stdlib.h>
  2. int atexit(void(*function)(void));
  3. #include <stdio.h>
  4. #include <iostream>
  5. using namespace std;
  6. void fn1(void),fn2(void),fn3(void),fn4(void);
  7. int main(void)
  8. {
  9. atexit(fn1);
  10. atexit(fn2);
  11. atexit(fn3);
  12. atexit(fn4);
  13. cout<< "This is executed first."<< endl;
  14. }
  15. void fn1()
  16. {
  17. cout<< "next."<< endl;
  18. }
  19. void fn2()
  20. {
  21. cout<< "executed "<< endl;
  22. }
  23. void fn3()
  24. {
  25. cout<< "is "<< endl;
  26. }
  27. void fn4()
  28. {
  29. cout<< "This "<< endl;
  30. }

    其中,atexit的参数是一个函数地址,当调用此函数时无须传递任何参数,该函数也不能返回值,atexit函数称为终止处理程序注册程序,注册完成以后,当函数终止是exit()函数会主动的调用前面注册的各个函数。
运行结果如下:
由上图可知,exit函数调用这些函数的顺序和这些函数登记的顺序是相反的,这是因为最先注册的最后调用,最后注册的最先调用相当于一个堆栈的运行情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值