代码test_Exit.c
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 5 //简单输出fun1被调用的提示信息 6 void fun1(void){ 7 printf("[%s] is called... ", __FUNCTION__); 8 } 9 10 //简单输出fun2被调用的提示信息 11 void fun2(void){ 12 printf("[%s] is called... ", __FUNCTION__); 13 } 14 15 int main(int argc, char **argv) 16 { 17 //表示在要在函数退出前进行函数的调用 18 atexit(fun1); 19 //调用顺序为LIFO方式,也就是说先执行第20行,再执行第18行 20 atexit(fun2); 21 22 //printf()函数中没有 ,也就是只输出,不刷新 23 printf("abcdef"); 24 25 //_exit()是一种退出,这种退出不处理退出函数,也不刷新IO 26 _exit(0); 27 }
程序很简单,不多说明
结果是:
对,你没有看错,就是什么也没有,什么也没有了。虽然调用了printf()函数输出了字符串,但是函数退出前没有刷新IO,所有字符串并没有被输出。
接下来testN_exit.c,将23行改为:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 5 //简单输出fun1被调用的提示信息 6 void fun1(void){ 7 printf("[%s] is called... ", __FUNCTION__); 8 } 9 10 //简单输出fun2被调用的提示信息 11 void fun2(void){ 12 printf("[%s] is called... ", __FUNCTION__); 13 } 14 15 int main(int argc, char **argv) 16 { 17 //表示在要在函数退出前进行函数的调用 18 atexit(fun1); 19 //调用顺序为LIFO方式,也就是说先执行第20行,再执行第18行 20 atexit(fun2); 21 22 //printf()函数中添加 ,也就是既输出,又刷新 23 printf("abcdef "); 24 25 //_exit()是一种退出,这种退出不处理退出函数,也不刷新IO 26 _exit(0); 27 }
结果是:
abcdef
表明_exit(0)只负责退出,而刷新IO只能靠 解决了
接下来:testExit.c
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 5 //简单输出fun1被调用的提示信息 6 void fun1(void){ 7 printf("[%s] is called... ", __FUNCTION__); 8 } 9 10 //简单输出fun2被调用的提示信息 11 void fun2(void){ 12 printf("[%s] is called... ", __FUNCTION__); 13 } 14 15 int main(int argc, char **argv) 16 { 17 //表示在要在函数退出前进行函数的调用 18 atexit(fun1); 19 //调用顺序为LIFO方式,也就是说先执行第20行,再执行第18行 20 atexit(fun2); 21 22 //printf()函数中没有 ,也就是只输出,不刷新 23 printf("abcdef"); 24 25 //_exit()是一种退出,这种退出不处理退出函数,也不刷新IO 26 exit(0); 27 }
相较test_Exit.c只是把_exit()换成了exit(),代码:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 5 //简单输出fun1被调用的提示信息 6 void fun1(void){ 7 printf("[%s] is called... ", __FUNCTION__); 8 } 9 10 //简单输出fun2被调用的提示信息 11 void fun2(void){ 12 printf("[%s] is called... ", __FUNCTION__); 13 } 14 15 int main(int argc, char **argv) 16 { 17 //表示在要在函数退出前进行函数的调用 18 atexit(fun1); 19 //调用顺序为LIFO方式,也就是说先执行第20行,再执行第18行 20 atexit(fun2); 21 22 //printf()函数中没有 ,也就是只输出,不刷新 23 printf("abcdef"); 24 25 //exit()这种退出,不但处理退出函数,而且刷新IO 26 exit(0); 27 }
结果:
abcdef[fun2] is called... [fun1] is called...
就会发现,exit()函数不但完成了刷新IO的任务,同时也完成函数退出前的所有任务,调用atexit()函数是按照栈的方式调用的,但是还是有点缺陷的。
下面testNExit.c为:
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <unistd.h> 4 5 //简单输出fun1被调用的提示信息 6 void fun1(void){ 7 printf("[%s] is called... ", __FUNCTION__); 8 } 9 10 //简单输出fun2被调用的提示信息 11 void fun2(void){ 12 printf("[%s] is called... ", __FUNCTION__); 13 } 14 15 int main(int argc, char **argv) 16 { 17 //表示在要在函数退出前进行函数的调用 18 atexit(fun1); 19 //调用顺序为LIFO方式,也就是说先执行第20行,再执行第18行 20 atexit(fun2); 21 22 //printf()函数中有 ,也就是不但输出,而且刷新 23 printf("abcdef "); 24 25 //exit()是这种退出,不但处理退出函数,同时刷新IO 26 exit(0); 27 }
结果为:
abcdef [fun2] is called... [fun1] is called...
很明显可以看出,exit()完成了IO的刷新, 完成了换行,终于实现了我们需要的结果,其实这里的exit(0)完全等价于我们的return 0语句,它也只不过是个宏定义而已。