【VS开发】Return与Exit的区别
1. exit用于結(jié)束正在運行的整個程序,它將參數(shù)返回給OS,把控制權(quán)交給操作系統(tǒng);而return 是退出當(dāng)前函數(shù),返回函數(shù)值,把控制權(quán)交給調(diào)用函數(shù)。
2. exit是系統(tǒng)調(diào)用級別,它表示一個進(jìn)程的結(jié)束;而return 是語言級別的,它表示調(diào)用堆棧的返回。
3. 在main函數(shù)結(jié)束時,會隱式地調(diào)用exit函數(shù),所以一般程序執(zhí)行到main()結(jié)尾時,則結(jié)束主進(jìn)程。exit將刪除進(jìn)程使用的內(nèi)存空間,同時把錯誤信息返回給父進(jìn)程。
4. void exit(int status); 一般status為0,表示正常退出,非0表示非正常退出。
1、exit函數(shù)和return函數(shù)的主要區(qū)別是:
1)exit用于在程序運行的過程中隨時結(jié)束程序,其參數(shù)是返回給OS的。也可以這么講:exit函數(shù)是退出應(yīng)用程序,并將應(yīng)用程序的一個狀態(tài)返回給OS,這個狀態(tài)標(biāo)識了應(yīng)用程序的一些運行信息。
main函數(shù)結(jié)束時也會隱式地調(diào)用exit函數(shù),exit函數(shù)運行時首先會執(zhí)行由atexit()函數(shù)登記的函數(shù),然后會做一些自身的清理工作,同時刷新所有輸出流、關(guān)閉所有打開的流并且關(guān)閉通過標(biāo)準(zhǔn)I/O函數(shù)tmpfile()創(chuàng)建的臨時文件。
exit是系統(tǒng)調(diào)用級別的,它表示了一個進(jìn)程的結(jié)束,它將刪除進(jìn)程使用的內(nèi)存空間,同時把錯誤信息返回父進(jìn)程。通常情況:exit(0)表示程序正常, exit(1)和exit(-1)表示程序異常退出,exit(2)表示系統(tǒng)找不到指定的文件。在整個程序中,只要調(diào)用exit就結(jié)束。
?
2)return是語言級別的,它表示了調(diào)用堆棧的返回;return是返回函數(shù)值并退出函數(shù),通常0為正常退出,非0為非正常退出,請注意,如果是在主函數(shù)main, 自然也就結(jié)束當(dāng)前進(jìn)程了(也就是說,在main()里面,你可以用return n,也能夠直接用exit(n)來做),如果不是在main函數(shù)中,那就是退回上一層調(diào)用。在多個進(jìn)程時,如果有時要檢測上個進(jìn)程是否正常退出,就要用到上個進(jìn)程的返回值。
?
2、進(jìn)程環(huán)境與進(jìn)程控制
exit(int n)其實就是直接退出程序,因為默認(rèn)的標(biāo)準(zhǔn)程序入口為 int main(int argc, char** argv),返回值是int型的。一般在shell下面,運行一個程序,然后使用命令echo $?就能得到該程序的返回值,也就是退出值。
理論上exit可以返回小于256的任何整數(shù),返回的不同數(shù)值主要是給調(diào)用者作不同處理的。
對于單獨的進(jìn)程exit的返回值是返回給操作系統(tǒng)的,但如果是多進(jìn)程,則是返回給父進(jìn)程的。父進(jìn)程里面調(diào)用waitpid()等函數(shù)得到子進(jìn)程退出的狀態(tài),以便作不同處理。根據(jù)相應(yīng)的返回值來讓調(diào)用者作出相應(yīng)的處理。
總的說來,exit()就是當(dāng)前進(jìn)程把其控制權(quán)返回給調(diào)用該子程序的主程序, 括號里的是返回值,告訴調(diào)用程序該程序的運行狀態(tài)。
?
1)進(jìn)程的開始:
C程序是從main函數(shù)開始執(zhí)行, 原型如下: int main(int argc, char *argv[]); 通常main的返回值是int型, 正確返回0。?
2)進(jìn)程終止:?
C程序的終止分為兩種: 正常終止和異常終止。正常終止分為: return, exit, _exit, _Exit, pthreade_exit。異常中指分為: abort, SIGNAL, 線程響應(yīng)取消。
主要說一下正常終止的前4種, 即exit系列函數(shù).
#include <stdlib.h>??
void exit(int status);
void _Exit(int status);
?
#include <unistd.h>??
void _exit(int status);
以上3個函數(shù)的區(qū)別是: exit()(或return 0)會調(diào)用終止處理程序和用戶空間的標(biāo)準(zhǔn)I/O清理程序(如fclose), _exit和_Exit不調(diào)用而直接由內(nèi)核接管進(jìn)行清理。因此, 在main函數(shù)中exit(0)等價于return 0.
?
3)atexit終止處理程序:
ISO C規(guī)定, 一個進(jìn)程最多可登記32個終止處理函數(shù), 這些函數(shù)由exit按登記相反的順序自動調(diào)用。如果同一函數(shù)登記多次, 也會被調(diào)用多次。
?
原型如下:?
#include <stdlib.h>
int atexit(void (*func)(void));
?
其中參數(shù)是一個函數(shù)指針, 指向終止處理函數(shù), 該函數(shù)無參無返回值。atexit函數(shù)本身成功調(diào)用后返回0。
?
以下面的程序為例:
?
#include <stdlib.h>?
static void myexit1()
{
???? printf("first exit handler\n");
}?
static void myexit2()
{
???? printf("second exit handler\n");
}?
int main()
{
???? atexit(my_exit2);
?? ??atexit(my_exit1);
atexit(my_exit1);
???? printf("main is done\n");
???? return 0;
}
?
運行結(jié)果:
$ ./a.out
main is done
first exit handler
first exit handler
second exit handler
? ? 注意上面的結(jié)果,可以發(fā)現(xiàn)這些函數(shù)由exit按登記相反的順序自動調(diào)用(先myexit1后myexit2)。如果同一函數(shù)登記多次, 也會被調(diào)用多次(如這里的myexit1)。而這些處理函數(shù)都是在程序退出的時候利用atexit函數(shù)調(diào)用了這些處理函數(shù)。但是如果用_exit()退出程序,則它不關(guān)閉任何文件,不清除任何緩沖器、也不調(diào)用任何終止函數(shù)!
exit函數(shù)在頭文件stdlib.h中。
exit(0):正常運行程序并退出程序;
exit(1):非正常運行導(dǎo)致退出程序;
return():返回函數(shù),若在main主函數(shù)中,則會退出函數(shù)并返回一值,可以寫為return(0),或return 0。
詳細(xì)說:
??1. return返回函數(shù)值,是關(guān)鍵字;exit是一個函數(shù)。
? 2. return是語言級別的,它表示了調(diào)用堆棧的返回;而exit是系統(tǒng)調(diào)用級別的,它表示了一個進(jìn)程的結(jié)束。
? 3. return是函數(shù)的退出(返回);exit是進(jìn)程的退出。
? 4. return是C語言提供的,exit是操作系統(tǒng)提供的(或者函數(shù)庫中給出的)。
? 5. return用于結(jié)束一個函數(shù)的執(zhí)行,將函數(shù)的執(zhí)行信息傳出個其他調(diào)用函數(shù)使用;exit函數(shù)是退出應(yīng)用程序,刪除進(jìn)程使用的內(nèi)存空間,并將應(yīng)用程序的一個狀態(tài)返回給OS,這個狀態(tài)標(biāo)識了應(yīng)用程序的一些運行信息,這個信息和機(jī)器和操作系統(tǒng)有關(guān),一般是?0 為正常退出,非0 為非正常退出。
? 6. 非主函數(shù)中調(diào)用return和exit效果很明顯,但是在main函數(shù)中調(diào)用return和exit的現(xiàn)象就很模糊,多數(shù)情況下現(xiàn)象都是一致的。
?下面是幾個例子:
1.
| #include <unistd.h> #include <stdio.h> #include <stdlib.h> ?? int?main(void) { pid_t pid; int?count=0; ?? pid=vfork(); if(pid==0) { printf("child: count=%d\n",count); printf("child: getpid=%d\n",getpid()); count=1; printf("child: count=%d\n",count); // return 0;//會出現(xiàn)段錯誤 exit(0);?//ok } else { printf("\nfather: pid=%d\n",pid); printf("father: count=%d\n",count); } return(0); } |
?
運行結(jié)果
?| [root@localhost part1_linux]# gcc fork2.c? [root@localhost part1_linux]# ./a.out? child: count=0 child: getpid=9911 child: count=1 ?? father: pid=9911 father: count=1 |
運行結(jié)果說明:vfrok時父、子進(jìn)程共享數(shù)據(jù)段,fork時是進(jìn)行拷貝。如果,vfork子進(jìn)程中,使用return返回時,出現(xiàn)段錯誤,結(jié)果如下:
?| [root@localhost part1_linux]# gcc fork2.c? [root@localhost part1_linux]# ./a.out? child: count=0 child: getpid=10864 child: count=1 ?? father: pid=10864 father: count=0 段錯誤 |
| #include <stdio.h> #include <sys/types.h> #include <unistd.h> ?? int?main() { ????int?i=0; ????pid_t pid; ????printf("還沒創(chuàng)建子進(jìn)程\n"); ????i++; ????pid = fork(); ????if(pid==-1) ????{ ???? printf("fork error!\n"); ????} ????else?if(pid==0) ????{ ???? i++; ???? printf("我是子進(jìn)程,id%d\n",getpid()); ? printf("我的父親是id:%d\n",getppid()); printf("-----i=%d-----\n",i); ????} ????else ????{ ???? i++; ???? printf("我是父進(jìn)程,id:%d\n",getpid()); ???? printf("-----i=%d-----\n",i); ????} ????exit(0); } |
| #include <stdio.h> #include <sys/types.h> #include <unistd.h> ?? int?main() { int?i=0; pid_t pid; printf("還沒創(chuàng)建子進(jìn)程\n"); i++; pid = vfork(); if(pid==-1) { printf("fork error!\n"); } else?if(pid==0) { i++; printf("我是子進(jìn)程,id%d\n",getpid()); printf("我的父親是id:%d\n",getppid()); printf("-----i=%d-----\n",i); } else { i++; printf("我是父進(jìn)程,id:%d\n",getpid()); printf("-----i=%d-----\n",i); } return(0); |
轉(zhuǎn)載于:https://www.cnblogs.com/huty/p/8518849.html
總結(jié)
以上是生活随笔為你收集整理的【VS开发】Return与Exit的区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: bs4_2
- 下一篇: JVM原理和性能调优