函数exit()


函数原型:

 wKiom1diskGxc9mDAAAHqscUHgo576.png   

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

  exit() 结束当前进程/当前程序/,在整个程序中,只要调用 exit ,就结束;

 exit(1)表示进程非正常退出. 返回 1给操作系统;

 exit(0)表示进程正常退出. 返回 0给操作系统.

exit()和return的区别:

按照ANSI C,在最初调用的main()中使用return和exit()的效果相同。

但要注意这里所说的是"最初调用"。如果main()在一个递归程序中,exit()仍然会终止程序;但return将控制权移交给递归的前一级,直到最初的那一级,此时return才会终止程序。return和exit()的另一个区别在于,即使在除main()之外的函数中调用exit(),它也将终止程序。

函数_exit() 和 _Exit()--终止调用进程

函数原型:

wKiom1djTBWSlCJsAAA3TR58eq8199.png

函数描述和返回值:

wKioL1djUQOgWeGNAAB1319SLfI699.png

从中可以解读道_Exit() is equivalent to _exit().(功能相同) 

exit与_exit的区别

头文件:

exit:#include<stdlib.h>

_exit:#include<unistd.h>

_exit()函数:直接使进程停止运行,清除其使用的内存空间,并销毁其在内核中的各种数据结构;

exit()函数则在这些基础上作了一些包装,在执行退出之前加了若干道工序。

exit()函数与_exit()函数最大的区别就在于 exit()函数在调用 exit 系统调用之前要检查文件的打开情况,把文件缓冲区中的内容写回文件。

atexit()函数--注册程序正常终止时要被调用的函数

    按照ISO C的规定,一个进程可以登记多达32个函数,这些函数将由exit自动调用,通常这32个函数被称为终止处理程序,并调用atexit函数来登记这些函数。

    在程序退出时经常需要做一些诸如释放资源的操作,但程序退出的方式有很多种。因此需要一种与程序退出方式无关的方法来进行程序退出时的必要处理。atexit()函数用来注册程序正常终止时要被调用的函数。      


下面看一下atexit()函数的原型:

wKiom1djTXGyYAYLAAAuZX26PM8330.png

函数描述和返回值:

wKioL1djVdrTak5bAADbvDRTnog507.png

    atexit的参数是一个函数指针,当调用此函数时无须传递任何参数,该函数也不能返回值,atexit函数称为终止处理程序注册程序,注册完成以后,当函数终止时exit函数会主动的调用前面注册的各个函数,但是exit函数调用这些函数的顺序与这些函数登记的顺序是相反的,我认为这实质上是参数压栈造成的,参数由于压栈顺序而先入后出。同时如果一个函数被多次登记,那么该函数也将多次的执行。


代码段:

#include<stdio.h>
#include<atdlib.h>

void fun1(void)
{
    printf("fun1\n");
}

void fun2(void)
{
    printf("fun2\n");
}

void fun3(void)
{
    printf("fun3\n");
}

int main()
{
    atexit(fun1);
    atexit(fun2);
    atexit(fun3);
    
    printf("main\n");
}

程序运行结果输出是:

wKioL1dipGvA2xqnAAAkh2cp7v8009.png

    这些函数都是在main结束以后才被调用的。atexit只是注册他们,使得他们在main结束以后被调用,看名字就可以看出来。