理解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語句,它也只不過是個宏定義而已。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM