void main和int main

最近在論壇上看到有不少網(wǎng)友的程序中,main函數(shù)都寫(xiě)成void main(),而不是int main()。那么,到底哪個(gè)是正確的,或至少是推薦使用的呢?這篇文章本來(lái)是自己想寫(xiě)的,但有些概念不是很清楚,于是在網(wǎng)上搜索了一下,發(fā)現(xiàn)了moon網(wǎng)友的一篇非常好的文章,對(duì)很多模糊不清的概念都講解的非常清楚,值得學(xué)習(xí)和借鑒,特轉(zhuǎn)載過(guò)來(lái),一起學(xué)習(xí)。全文如下:

main函數(shù)的返回值大家注意了嗎,也許有人會(huì)說(shuō)可以沒(méi)有返回值,如果你深入到程序的CRT啟動(dòng)代碼,你會(huì)發(fā)現(xiàn)....

    __initenv = envp;
    mainret = main(argc, argv, envp);
    if ( !managedapp )
       exit(mainret);
    if (has_cctor == 0)
       cexit();

按照新的C99標(biāo)準(zhǔn),即使函數(shù)本身沒(méi)有定義返回值,編譯器也會(huì)加上,以返回給激發(fā)程序,運(yùn)行狀態(tài)。很多人甚至市面上的一些書(shū)籍,都使用了void main( ) ,其實(shí)這是錯(cuò)誤的。C/C++ 中從來(lái)沒(méi)有定義過(guò)void main( ) 。C++ 之父 Bjarne Stroustrup 在他的主頁(yè)上的 FAQ 中明確地寫(xiě)著 The definition void main( ) { /* ... * / } is not and never has been C++, nor has it even been C. ( void main( ) 從來(lái)就不存在于 C++ 或者 C )。下面我分別說(shuō)一下 C 和 C++ 標(biāo)準(zhǔn)中對(duì) main 函數(shù)的定義。
“The C programming Language(《C 程序設(shè)計(jì)語(yǔ)言》)用的就是 main( )?!?-- 這是因?yàn)榈谝话娴腃語(yǔ)言只有一種類(lèi)型,那就是int,沒(méi)有char,沒(méi)有l(wèi)ong,沒(méi)有 float,…………既然只有一種類(lèi)型,那么就可以不寫(xiě),后來(lái)的改進(jìn)版為了兼容以前的代碼于是規(guī)定:不明確標(biāo)明返回值的,默認(rèn)返回值為int,也就是說(shuō) main()等同于int main(),而不是等同于void main()。在C99中,標(biāo)準(zhǔn)要求編譯器至少給 main() 這種用法來(lái)個(gè)警告。
(1) C語(yǔ)言中
在 C89 中,main( ) 是可以接受的。 Brian W. Kernighan 和 Dennis M. Ritchie 的經(jīng)典巨著 The C programming Language 2e(《C 程序設(shè)計(jì)語(yǔ)言第二版》)用的就是 main( )。不過(guò)在最新的 C99 標(biāo)準(zhǔn)中,只有以下兩種定義方式是正確的:

    int main( void ) 
    int main( int argc, char *argv[] ) 

(參考資料:ISO/IEC 9899:1999 (E) Programming languages — C 5.1.2.2.1 Program startup)
當(dāng)然,我們也可以做一點(diǎn)小小的改動(dòng)。例如:char *argv[] 可以寫(xiě)成 char **argv;argv 和 argc 可以改成別的變量名(如 intval 和 charval),不過(guò)一定要符合變量的命名規(guī)則。
如果不需要從命令行中獲取參數(shù),請(qǐng)用int main(void) ;否則請(qǐng)用int main( int argc, char *argv[] ) 。
main 函數(shù)的返回值類(lèi)型必須是 int ,這樣返回值才能傳遞給程序的激活者(如操作系統(tǒng))。
如果 main 函數(shù)的最后沒(méi)有寫(xiě) return 語(yǔ)句的話,C99 規(guī)定編譯器要自動(dòng)在生成的目標(biāo)文件中(如 exe 文件)加入return 0; ,表示程序正常退出。不過(guò),我還是建議你最好在main函數(shù)的最后加上return 語(yǔ)句,雖然沒(méi)有這個(gè)必要,但這是一個(gè)好的習(xí)慣。注意,vc6不會(huì)在目標(biāo)文件中加入return 0; ,大概是因?yàn)?vc6 是 98 年的產(chǎn)品,所以才不支持這個(gè)特性。現(xiàn)在明白我為什么建議你最好加上 return 語(yǔ)句了吧!不過(guò),gcc3.2(Linux 下的 C 編譯器)會(huì)在生成的目標(biāo)文件中加入 return 0; 。
(2) C++語(yǔ)言中
C++98 中定義了如下兩種 main 函數(shù)的定義方式:

    int main( )
    int main( int argc, char *argv[] ) 
   (參考資料:ISO/IEC 14882(1998-9-01)Programming languages — C++ 3.6 Start and termination) 
    int main( ) 等同于 C99 中的 int main( void ) ;int main( int argc, char *argv[] ) 的用法也和 C99 中定義的一樣。同樣,main 函數(shù)的返回值類(lèi)型也必須是int。如果main函數(shù)的末尾沒(méi)寫(xiě)return語(yǔ)句,C++98 規(guī)定編譯器要自動(dòng)在生成的目標(biāo)文件中加入 return 0; 。同樣,vc6 也不支持這個(gè)特性,但是 g++3.2(Linux 下的 C++ 編譯器)支持。 
   (3) 關(guān)于 void main 
    在 C 和 C++ 中,不接收任何參數(shù)也不返回任何信息的函數(shù)原型為“void foo(void);”??赡苷且?yàn)檫@個(gè),所以很多人都誤認(rèn)為如果不需要程序返回值時(shí)可以把 main函數(shù)定義成void main(void) 。然而這是錯(cuò)誤的!main 函數(shù)的返回值應(yīng)該定義為 int 類(lèi)型,C 和 C++ 標(biāo)準(zhǔn)中都是這樣規(guī)定的。雖然在一些編譯器中,void main 可以通過(guò)編譯(如 vc6),但并非所有編譯器都支持 void main ,因?yàn)闃?biāo)準(zhǔn)中從來(lái)沒(méi)有定義過(guò) void main 。g++3.2 中如果 main 函數(shù)的返回值不是 int 類(lèi)型,就根本通不過(guò)編譯。而 gcc3.2 則會(huì)發(fā)出警告。所以,如果你想你的程序擁有很好的可移植性,請(qǐng)一定要用 int main。 
    總而言之:
    void main 主函數(shù)沒(méi)有返回值,main 默認(rèn)為int 型,即 int main(), 返回整數(shù)。注意,新標(biāo)準(zhǔn)不允許使用默認(rèn)返回值,即int不能省,而且對(duì)應(yīng)main函數(shù)不再支持void型返回值,因此為了使程序有很好的移植性,強(qiáng)烈建議使用:
    int main()
    { 
        return 0; /* 新標(biāo)準(zhǔn)主函數(shù)的返回值這條語(yǔ)句可以省略 */  
    } 
    返回值的作用:
    main函數(shù)的返回值用于說(shuō)明程序的退出狀態(tài)。如果返回0,則代表程序正常退出;返回其它數(shù)字的含義則由系統(tǒng)決定。通常,返回非零代表程序異常退出。下面我們?cè)趙inxp環(huán)境下做一個(gè)小實(shí)驗(yàn)。首先編譯下面的程序:
    int main( void )
    {
        return 0;
    }
    然后打開(kāi)附件里的“命令提示符”,在命令行里運(yùn)行剛才編譯好的可執(zhí)行文件,然后輸入“echo%ERRORLEVEL%”,回車(chē),就可以看到程序的返回值為0。假設(shè)剛才編譯好的文件是a.exe,如果輸入“a && dir”,則會(huì)列出當(dāng)前目錄下的文件夾和文件。但是如果改成“return -1”,或者別的非0值,重新編譯后輸入“a && dir”,則dir不會(huì)執(zhí)行。因?yàn)?amp;&的含義是:如果&&前面的程序正常退出,則繼續(xù)執(zhí)行&&后面的程序,否則不執(zhí)行。也就是說(shuō),利用程序的返回值,我們可以控制要不要執(zhí)行下一個(gè)程序。這就是int main的好處。如果你有興趣,也可以把main函數(shù)的返回值類(lèi)型改成非int類(lèi)型(如float),重新編譯后執(zhí)行“a && dir”,看看會(huì)出現(xiàn)什么情況,想想為什么會(huì)出現(xiàn)那樣的情況。順便提一下,如果輸入a || dir的話,則表示如果a異常退出,則執(zhí)行dir。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開(kāi)發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見(jiàn)模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,654評(píng)論 19 139
  • 題目類(lèi)型 a.C++與C差異(1-18) 1.C和C++中struct有什么區(qū)別? C沒(méi)有Protection行為...
    阿面a閱讀 7,894評(píng)論 0 10
  • 第1章 第一個(gè)C程序第2章 C語(yǔ)言基礎(chǔ)第3章 變量和數(shù)據(jù)類(lèi)型第4章 順序結(jié)構(gòu)程序設(shè)計(jì)第5章 條件結(jié)構(gòu)程序設(shè)計(jì)第6章...
    小獅子365閱讀 10,874評(píng)論 3 71
  • 1、c語(yǔ)言的函數(shù)有以下特點(diǎn): (1)才源程序由函數(shù)組成,一個(gè)主函數(shù)main()+若干其他函數(shù) C程序中的函數(shù)類(lèi)似文...
    滕王閣序閱讀 1,526評(píng)論 0 6
  • 今天和孩子復(fù)習(xí)象棋課上的內(nèi)容,因?yàn)樗浟瞬襟E讓我很是生氣,他說(shuō)肚子不舒服,跑去上廁所,突然我就想到了,呼吸。讓自...
    Andy媽媽閱讀 318評(píng)論 0 0

友情鏈接更多精彩內(nèi)容