linux c中return 與exit的區別
1.
return 是c語言中的關鍵字,而exit是linux中的系統呼叫。
return是表示函式的返回,而exit是程序的終止。
如果return 或者exit出現在main函式中,兩者的作用是一樣。
如果return出現在子程式中表示返回,而exit出現在子程序中表示終止子程序。
2.
通常情況:exit(0)表示程式正常, exit(1)/exit(-1)表示程式異常退出,exit(2)表示表示系統找不到指定的檔案。用Error lookup可以檢視
exit()結束當前程序/當前程式/,在整個程式中,只要呼叫exit就結束(當前程序或者在main時候為整個程式)
return()是當前函式返回,當然如果是在主函式
exit(1)表示程序非正常退出. 返回1;
exit(0)表示程序正常退出. 返回0.
程序環境與程序控制(1): 程序的開始與終止
exit(int n)其實就是直接退出程式,因為預設的標準程式入口為 int main(int argc, char** argv),返回值是int型的。一般在shell下面,執行一個程式,然後使用命令echo $?就能得到該程式的返回值,也就是退出值,在main()裡面,你可以用return n,也能夠直接用
理論上exit可以返回小於256的任何整數。返回的不同數值主要是給呼叫者作不同處理的。
單獨的程序是返回給作業系統的。如果是多程序,是返回給父程序的。父程序裡面呼叫waitpid()等函式得到子程序退出的狀態,以便作不同處理。根據相應的返回值來讓呼叫者作出相應的處理.總的說來,exit()就是當前程序把控制權返回給呼叫該程式的程式,括號裡的是返回值,告訴呼叫程式該程式的執行狀態
1. 程序的開始:
C程式是從main函式開始執行, 原型如下:
int main(int argc, char *argv[]);
通常main
如果main的返回值為void或者無, 某些編譯器會給出警告, 此時main的返回值通常是0.(看我blog下面關於return函式的介紹就知道,事實上main函式是沒有void main()這樣的宣告的,一定要在main的結束有返回值,需要返回什麼型別的值,就返回這個型別的值。通常為int型的0值表示成功返回)
關於main的命令列引數不做過多解釋, 以下面的程式展示一下:
- #include <stdio.h>
- int main(int argc, char *argv[])
- {
- int i;
- for (i = 0; i < argc; i++)
- printf("argv[%d]: %s/n", i, argv[i]);
- return 0;
- }
2. 程序終止:
C程式的終止分為兩種: 正常終止和異常終止.
正常終止分為: return, exit, _exit, _Exit, pthreade_exit
異常中指分為: abort, SIGNAL, 執行緒響應取消
主要說一下正常終止的前4種, 即exit系列函式.
#include <stdlib.h> /* ISO C */
void exit(int status);
void _Exit(int status);
#include <unistd.h> /* POSIX */
void _exit(int status);
以上3個函式的區別是:
exit()(或return 0)會呼叫終止處理程式和使用者空間的標準I/O清理程式(如fclose), _exit和_Exit不呼叫而直接由核心接管進行清理.因此, 在main函式中exit(0)等價於return 0.
_exit()函式的作用最為簡單:直接使程序停止執行,清除其使用的記憶體空間,並銷燬其在核心中的各種資料結構;exit()函式則在這些基礎上作了一些包裝,在執行退出之前加了若干道工序,也是因為這個原因,有些人認為exit已經不能算是純粹的系統呼叫。
exit()函式與_exit()函式最大的區別就在於exit()函式在呼叫exit系統呼叫之前要檢查檔案的開啟情況,把檔案緩衝區中的內容寫回檔案,就是圖中的“清理I/O緩衝”一項。
在Linux 的標準函式庫中,有一套稱作“高階I/O”的函式,我們熟知的printf()、fopen()、fread()、fwrite()都在此列,它們也被稱作“緩衝I/O(buffered I/O)”,其特徵是對應每一個開啟的檔案,在記憶體中都有一片緩衝區,每次讀檔案時,會多讀出若干條記錄,這樣下次讀檔案時就可以直接從記憶體的緩衝區中讀取,每次寫檔案的時候,也僅僅是寫入記憶體中的緩衝區,等滿足了一定的條件(達到一定數量,或遇到特定字元,如換行符/n和檔案結束符EOF),再將緩衝區中的內容一次性寫入檔案,這樣就大大增加了檔案讀寫的速度,但也為我們程式設計帶來了一點點麻煩。如果有一些資料,我們認為已經寫入了檔案,實際上因為沒有滿足特定的條件,它們還只是儲存在緩衝區內,這時我們用_exit()函式直接將程序關閉,緩衝區中的資料就會丟失,反之,如果想保證資料的完整性,就一定要使用exit()函式。
請看以下例程:
/* exit2.c */
#include<stdlib.h>
- int main()
- {
- printf("output begin/n");
- printf("content in buffer");
- exit(0);
- }
編譯並執行:
$gcc exit2.c -o exit2
$./exit2
output begin
content in buffer
/* _exit1.c */
- #include<unistd.h>
- int main()
- }
- printf("output begin/n");
- printf("content in buffer");
- _exit(0);
- }
編譯並執行:
$gcc _exit1.c -o _exit1
$./_exit1
output begin
3. atexit終止處理程式:
ISO C規定, 一個程序最對可登記32個終止處理函式, 這些函式由exit按登記相反的順序自動呼叫. 如果同一函式登記多次, 也會被呼叫多次.
原型如下:
#include <stdlib.h>
int atexit(void (*func)(void));
其中引數是一個函式指標, 指向終止處理函式, 該函式無參無返回值. atexit函式本身成功呼叫後返回0.
以下面的程式為例:
- #include <stdlib.h>
- staticvoid myexit1()
- {
- printf("first exit handler/n");
- }
- staticvoid myexit2()
- {
- printf("second exit handler/n");
- }
- int main()
- {
- if (atexit(my_exit2) != 0)
- printf("can't register my_exit2/n");
- if (atexit(my_exit1) != 0)
- printf("can't register my_exit1/n");
- if (atexit(my_exit1) != 0)
- printf("can't register my_exit1/n");
- printf("main is done/n");
- return 0;
- }
執行結果:
$ ./a.out
main is done
first exit handler
first exit handler
second exit handler執行結果:
注意上面的結果,可以發現這些函式由exit按登記相反的順序自動呼叫(先myexit1後myexit2). 如果同一函式登記多次, 也會被呼叫多次(如這裡的myexit1).而這些處理函式都是在程式推出的時候利用atexit函式呼叫了這些處理函式。但是如果用_exit()退出程式,則它不關閉任何檔案,不清除任何緩衝器、也不呼叫任何終止函式!
return函式exit函式區別
1,exit用於在程式執行的過程中隨時結束程式,exit的引數是返回給OS的。main函式結束時也會隱式地呼叫exit函式。exit函式執行時首先會執行由atexit()函式登記的函式,然後會做一些自身的清理工作,同時重新整理所有輸出流、關閉所有開啟的流並且關閉通過標準I/O函式tmpfile()建立的臨時檔案。exit是結束一個程序,它將刪除程序使用的記憶體空間,同時把錯誤資訊返回父程序,而return是返回函式值並退出函式
2,return是語言級別的,它表示了呼叫堆疊的返回;而exit是系統呼叫級別的,它表示了一個程序的結束。
3,exit函式是退出應用程式,並將應用程式的一個狀態返回給OS,這個狀態標識了應用程式的一些執行資訊。
4,和機器和作業系統有關一般是 0 為正常退出 非0 為非正常退出
5,void exit(int status);
6,atexit()函式的引數是一個函式指標,函式指標指向一個沒有引數也沒有返回值的函式。atexit()的函式原型是:int atexit (void (*)(void));在一個程式中最多可以用atexit()註冊32個處理函式,這些處理函式的呼叫順序與其註冊的順序相反,也即最先註冊的最後呼叫,最後註冊的最先呼叫。
一般程式執行到 main() 的結束就完成了, 如果想在程式結束時做一些事情, 可以嘗試著用這個函式.
example:
- void f1(void)
- {
- printf("exit f1/n");
- }
- void f2(void)
- {
- printf("exit f2/n");
- }
- int main()
- {
- atexit(f1);
- atexit(f2);
- printf("exit main/n");
- return 0;
- }