? ? ? ? main 函数的返回值叫做进程的退出码。当进程成功退出的时候,我们一般用0来表示。进程失败的时候一般用非零来表示。我们使用不同的数字来表示进程退出时不同的失败原因。
????????我们查看系统的有多少退出码以及其含义时需要用到strerror()? 他的头文件和用法如下。
????????通过一下代码来查看系统有多少退出码
#include<stdio.h>
#include<unistd.h>
#include<errno.h>
#include<string.h>
int main()
{
int i = 0;
for(i;i<200;i++)
{
printf("%d:,%s\n",i,strerror(i));
}
return 0;
}
? ? ? ? 我们可以看到系统大概有134个退出码,每个退出码都有其自己的含义。由于太长只列举出来前几个。
?????????echo $?? 查看最近一个进程的退出状态,查看到的是0 表示的就是成功。
? ? ? ? 同时我们还可以自己设置进程退出码以及它的含义。
enum{
success=0,
open_err,
malloc_err
};
const char* errorTodesc(int code)
{
switch(code)
{
case success:
return "sucesss";
case open_err:
return "open_fail";
case malloc_err:
return "malloc_fail";
dafault:
return "unknow error";
}
}
int main()
{
int code = malloc_err;
printf("%s\n",errorTodesc(code));
return malloc_err;
}
? ? ? ?除了进程退出,还有函数退出。?main函数退出表示进程结束,而函数退出仅仅表示函数调用完毕。函数也是有返回值的。调用函数一般我们通常想看到两种结果,第一函数执行结果 成功,或者失败。第二函数的执行情况,如打开一个文件,如果成功会返回一个文件指针,如果失败就会返回NULL。如:
????????打印出错误码,并且打印出错误原因。?
? ? ? ? 通过以上我们列举的情况可以说明进程退出有三种情况
? ? ? ? 1.程序执行完,结果是正确的。
? ? ? ? 2.程序执行完,结果是错误的。
? ? ? ? 3.程序没执行完,程序就出现错误,结果无意义!!!
? ? ? ? 综上所述,只有当程序执行完的时候,结果才有意义。
? ? ? ? 进程出现退出是进程收到了异常的信号,每个信号都有不同的编号,每个编号都有自己的异常原因。
? ? ? ? 我们可以通过kill -l 查看有哪些信号:
? ? ? ? 我们这次主要了解 8 号 和 11号信号,8号信号相当与代码除0?,而十一号信号相当于对野指针进行解引用。
exit:
? ? ? ? exit是终止进程 其中status:是进程退出时候的退出码。
? ? ? ? 代码演示:
? ? ? ?该进程只跑1秒就退出。
????????并且退出码显示为3。
? ? ? ? 同时,如果在while循环中调用一个函数,并且调用exit() 那么进程也会同样退出的。如下:
????????
????????说明exit 是终止整个进程,在任意地方调用都是终止进程。
_exit 与 exit
????????
????????他们两个的功能是一模一样的,exit是c语言给我们提供的接口,而_exit是linux系统给我们提供的接口,那么二者有什么区别呢?
? ? ? ? 看代码:
? ? ? ? 程序停止了3秒然后hello linux ,hello gm 才被打印到屏幕上。
????????_exit 并没有把hello linux ,hello gm 打印到屏幕上,
????????这是因为_exit 没有刷新缓冲去,而exit刷新了缓冲区,这也是他们的区别。
那么exit 和_exit 是什么关系呢。
? ? ? ? exit 和 _exit 都是终止进程的,在整个系统中只有操作系统能够有权限来终止进程。
? ? ? ? 而_exit是系统调用接口,exit是c语言提供的库函数,库函数是不能终止进程的,只有操作系统提供的系统调用才能够终止进程,那么他们的关系就比较明确了。
? ? ? ? 就是exit在底层封装了_exit ,同时exit 中又添加了刷新缓冲区的功能。
? ? ? ? 为什么语言层面要进行封装呢?
? ? ? ? 第一:提高了语言的跨平台性。window系统,和Linux系统给我们提供的退出进程的接口肯定是不一样的(比如:函数名,函数参数,函数返回值)。所以Linux下的退出进程函数,在Windo ws下注定是跑不了的,造成代码的可移植性较差。所以c语言把系统调用接口在底层进行封装,在上层直接给一个exit函数。在Linux下使用Linux系统的调用接口给exit,在windows下使用windo ws的系统调用接口给exit,这样做在底层屏蔽了系统之间的差异,提高了可移植性、跨平台性。比如Java的虚拟机,python的命令行解释器,c/c++的库,都是为了解决跨平台而提出的解决方案。他们都会提供exit的功能,底层也封装了不同系统的系统调用接口。
? ? ? ? 第二:提高代码的可读性,降低程序员使用的门槛。