C語言的main函數到底怎麼寫的
來自專欄編程珠璣1 人贊了文章
原創不易,如果覺得文章不錯,歡迎點贊留言
前言
main函數是程序啟動後執行的第一個自定義函數。從開始學習C語言到現在,我們似乎看到了很多個版本的main函數,那麼哪一種才是正確的呢?我們先來看看目前有哪些版本。
main函數版本
第一種,沒有返回值,沒有入參:
main()
在C89標準中,這種寫法是可以接受的,但使用現在的編譯器編譯時,會報告警,並且會將其返回值默認為int。實際上,如果函數沒有顯式聲明返回類型,那麼編譯器會將返回值默認為int。
第二種,返回值為void,沒有入參:
void main()
這種形式的來源不得而知。但是為何這麼多初學者使用?main函數的返回值最終會作為程序的退出狀態,而一旦聲明為void,在程序退出後,想要獲取其退出狀態也就不可以了。因此不建議其返回值為void。
第三種,返回值為int,參數為void:
int main(void)
這是常見的一種寫法。形參為void,表明它在調用的時候不能傳入任何參數,那麼它也就不能獲取命令行參數了。
第四種,返回值為int,沒有參數:
int main()
看起來似乎和第三種沒有什麼區別,但這種形式卻有些許不同。雖然它的聲明沒有入參,實際調用卻可以傳入參數,看下面的例子:
#include<stdio.h>void test();int main() { test(4); return 0; }void test(int a){ printf("%d",a);}
對於上面的程序,我們仍然可以編譯並正常運行,test函數雖然聲明為無入參,但調用時卻是可以傳入任何參數或不傳參數的。
第五種,返回值為int,有兩個入參:
int main(int argc,char *argv[])
這也是最常見的一種寫法。第一個入參為命令行參數個數,第二個入參為命令行參數數組。通常用於實現需要從命令行獲取參數的功能。
第六種,返回值為int,有三個入參:
int main(int argc,char *argv[],char *envp[]
這種和第五種相似,但多了一個參數,用於獲取環境變數,這種形式多源於編譯器的擴展。但全局變數environ可以代替envp的作用,獲取或者設置環境變數可以使用getenv或putenv,因此也沒有必要使用該形式。
沒想到吧,仔細數一數竟然有這麼種寫法?但是真相究竟如何?到底使用哪種呢?
真相大白
C89/C99/C11標準文檔中只提供了兩種main函數的寫法:
int main(void) { /* ... */ }int main(int argc, char *argv[]) { /* ... */ }
也就是說,其他的寫法都是不符合標準的,有的是歷史遺留問題,有的是編譯器擴展,更有的不知從何而來。當然對於帶參數的寫法,其參數名可自定義。另外對於除標準提供的以外的寫法,不同的編譯器有不同的處理策略,有的可能編譯不過,有的可能報警告,但一個「正經」的編譯器是不會對標準提供的形式產生質疑的。
總結
至此,我們已經知道了c語言main函數的寫法,我們來總結一下前面的內容:
- C標準只提供了兩種main的形式,即前面提到的第三種和第五種。
- 為了代碼的通用可移植性,建議採用標準提供的形式。
- 不需要命令行參數可採用第三種,需要命令行參數採用第五種。
- 如果一個函數確定無需傳入任何參數,那麼用void限定是一個不錯的選擇。
- 函數沒有聲明返回值時,編譯器默認其返回值為int。
推薦閱讀:
hello程序是如何被編譯出來的?
一個奇怪的鏈接問題
變長參數探究
推薦閱讀: