exit与return
exit(exiitcode):这个表示整个程序终止执行,也就是说在整个程序中,只要调用 exit ,就结束,并且可以返回一个数值给调用这个程序的环境,环境就可以知道这个程序执行的结果。exit为c 的退出函数,声明于stdlib.h中,对于c 其标准的头文件为cstdlib。
return:一般是函数返回的结果,这个结果可以是int类型、short类型、bool类型等所有c 已有的类型和用户自定义的类型,甚至可以规定不返回任何值,直接是void,这个值是返回给调用这个函数的环境。return() 是当前函数返回,当然如果是在主函数main,自然也就结束当前进程了,如果不是,那就是退回上一层调用。在多个进程时,如果有时要检测上进程是否正常退出的,就要用到上个进程的返回值。
也就是说:
exit 这个是返回给调用该"程序"的外界环境
return 这个是返回给调用该"函数"的外界环境
int fun()
{
exit(3); // 函数执行到这里的时候就终止程序并且返回3
return 2; // 如果不添加这句话的话会编译出错,因为fun()函数要求返回int型变量
// 上一行exit(3)并不是"函数的"返回值
}
int main()
{
int i = fun(); // fun()函数还没有执行完就退出程序了,所以i不会被赋予任何值
return 0; // 程序根本就不会执行到这里来
}
exit和return在main中的作用基本相同:return x 和 exit(x) 基本是一个意思。
【补充】exit()就是退出,传入的参数是程序退出时的状态码,0表示正常退出,其他表示非正常退出,一般都用-1,标准c里有exit_success和exit_failure两个宏,用exit(exit_success)可读性比较好一点,这两个宏定义在stdio.h里。。此外,使用exit()时,可以不论main()的返回值类型。
两个问题
问题1:exit的返回值是给谁用的?
每个运行着的程序都是进程,而进程就会有父进程,父进程通常是直接启动你的进程,父进程死亡的进程会被 init 收养,其父进程变为 init,而 init 的父进程是进程 0,进程 0 则是系统启动时启动的第一个进程。exit() 里面的参数,是传递给其父进程的。对父进程来说,你的进程仿佛是一个函数,而函数可以有返回值。所以exit() 的参数是给自己的父进程使用的。通常一个程序的父进程可能是任何进程,因此我们无法预期我们的父进程是否规定必须要有这个返回值,那么我们应当提供这个返回值,以保证不同的父进程的需求得到满足。
问题2:为什么要使用 exit() 函数?
历史原因,虽然现在大多数平台下,直接在 main() 函数里面 return 可以退出程序。但是在某些平台下,在 main() 函数里面 return 会导致程序永远不退出(因为代码已经执行完毕,程序却还没有收到要退出的指令)。换句话说,为了兼容性考虑,在特定的平台下,程序最后一行必须使用 exit() 才能正常退出,这是 exit() 存在的重要价值。
进程终止
c程序的终止分为两种:正常终止和异常终止
【正常终止分为】return、exit、_exit、_exit、pthreade_exit
【异常终止分为】abort、signal、线程响应取消
主要说一下正常终止的前4种,即exit系列函数:
#i nclude /* iso c */
void exit(int status);
void _exit(int status);
#i nclude /* posix */
void _exit(int status);
以上3个函数的区别是:
exit()(或return 0)会调用终止处理程序和用户空间的标准i/o清理程序(如fclose),_exit和_exit不调用而直接由内核接管进行清
理,因此,在main函数中exit(0)等价于return 0。
如何看到exit的值?
如果你的进程为nginx,则执行./nginx后再执行echo $? ,就可以看到你的进程的返回值,也就是exit(x)的x!