zoukankan      html  css  js  c++  java
  • 理解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...
    ", __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语句,它也只不过是个宏定义而已。

    人就像是被蒙着眼推磨的驴子,生活就像一条鞭子;当鞭子抽到你背上时,你就只能一直往前走,虽然连你也不知道要走到什么时候为止,便一直这么坚持着。
  • 相关阅读:
    mybatis映射文件配置-1对多
    启动服务器加载spring.xml:web.xml配置
    spring-mybatis.xml配置文件
    json转换器映射文件配置
    Restful levels
    事务隔离级别「脏读、不可重复读、幻读」
    Java CDI
    session和Cookie的介绍和应用
    java RE Validation常用
    hello2 source Analysis
  • 原文地址:https://www.cnblogs.com/guochaoxxl/p/15194607.html
Copyright © 2011-2022 走看看