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