理解C语言中的花式退出

代码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...\n", __FUNCTION__);
 8 }
 9 
10 //简单输出fun2被调用的提示信息
11 void fun2(void){
12     printf("[%s] is called...\n", __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()函数中没有\n,也就是只输出,不刷新
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...\n", __FUNCTION__);
 8 }
 9 
10 //简单输出fun2被调用的提示信息
11 void fun2(void){
12     printf("[%s] is called...\n", __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()函数中添加\n,也就是既输出,又刷新                               
23     printf("abcdef\n");
24 
25     //_exit()是一种退出,这种退出不处理退出函数,也不刷新IO
26     _exit(0);
27 }
复制代码

结果是:

abcdef

表明_exit(0)只负责退出,而刷新IO只能靠\n解决了

接下来: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...\n", __FUNCTION__);
 8 }
 9 
10 //简单输出fun2被调用的提示信息
11 void fun2(void){
12     printf("[%s] is called...\n", __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()函数中没有\n,也就是只输出,不刷新                               
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...\n", __FUNCTION__);
 8 }
 9 
10 //简单输出fun2被调用的提示信息
11 void fun2(void){
12     printf("[%s] is called...\n", __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()函数中没有\n,也就是只输出,不刷新                               
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...\n", __FUNCTION__);
 8 }
 9 
10 //简单输出fun2被调用的提示信息
11 void fun2(void){
12     printf("[%s] is called...\n", __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()函数中有\n,也就是不但输出,而且刷新                             
23     printf("abcdef\n");
24 
25     //exit()是这种退出,不但处理退出函数,同时刷新IO
26     exit(0);
27 }
复制代码

结果为:

abcdef
[fun2] is called...
[fun1] is called...

很明显可以看出,exit()完成了IO的刷新,\n完成了换行,终于实现了我们需要的结果,其实这里的exit(0)完全等价于我们的return 0语句,它也只不过是个宏定义而已。

posted @   叕叒双又  阅读(363)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示