版權聲明:本文轉載于公眾號TeachPlus---C語言面試題---main函數
1、下面的代碼能編譯通過嗎?如果能,它有什么潛在的問題嗎?
在絕大多數的編譯器中,該段代碼都是可以編譯通過的,但是可能會報出警告。main()的返回類型應該是“int”而不是“void”。因為“int”返回類型會讓程序返回狀態(tài)值。這點非常重要,特別當程序是作為依賴于程序成功運行的腳本的 一部分運行時。
我們可能在許多地方都會看到這樣的寫法,或者其他多種多樣的寫法,這讓初學者,甚至 一部分老手都會搞不明白main函數到底應該怎么去寫。下面就是幾種常 見的main函數的寫法:
1.
int main()
{
????//do something
????return 0;
}
這是大家最常見的寫法,那么這種寫法好不好呢?
這種寫法會產生歧義,函數main是有參數,還是沒有參數。
你可能覺得很奇怪,它明明是沒有參數的,但編譯器 可不這么認為。
不同編譯器 可能有不同解釋。原因在于要與舊式代碼風格的兼容。如下面的代碼:
int fun()
int main()
{
????//do somethings
????return? 0;
}
int fun(int a,int b)
{
????//do somethings
}
int main()
{
????//do somethings
????return ;
}
int fun(int a,int b)
{
????//do somethings
}
這段代碼編譯完全沒有問題,可是fun函數明明是有參數的.
這種寫法,編譯器只會記住函數的返回類型,并不會檢查函數的參數個數和類型是否匹配。你寫了了這么多,編譯器就只記住intfun() ;
所以,只能通過這種形式main( void ),表明main函數沒有參數
2.
void main()
{
????//do somethings
}
這種寫法的流傳也非常廣泛,因為許多教科書里就是這么寫的, 而且絕大部分編譯器 都能夠正常編譯。
雖然在 一些編譯器中,voidmain可以通過編譯(如vc6)。
并且編譯器 對于你寫的voidmain,在實際編譯的時候還是默認返回一個int.
有些編譯器允許這種形式,但是還沒有任何標準考慮接受它。
C++之 父Bjarne Stroustrup在他的主 頁上的FAQ中明確地表示:
voidmain()的定義從來就不存在于C++或者C。
所以,編譯器不必接受這種形式,并且很多編譯器也不允許這么寫。
我們要考慮程序的可擴展性,養(yǎng)成 一個良好的習慣。
3.
main()
{
????//do somethings
}
這種方法比較罕見,但是現在仍然有很多編譯器支持這種寫法。
這種寫法往往存在于非常老的c語 言版本中。
C90標準允許這種形式,但是C99標準不允許。因此即使你當前的編譯器允許,也不要這么寫.
正本清源
其實在C99標準中,只有以下兩種定義 方式是正確的:
int main(void) /*無參數形式*/
{
????//do somethings
????return 0;
}
int main(int argc, char*argv[]) /*帶參數形勢*/
{
????//do somethings
????return 0;
}
int指明了了main()函數的返回類型,函數名后面的圓括號 一般包含傳遞給函數的信息。void表示沒
有給函數傳遞參數。
main函數可以不帶參數,也可以帶參數,這個參數可以認為是main函數的形式參數。C語言規(guī)定main函數的參數只能有兩個,習慣上這兩個參數寫為argc和argv。因此,main函數的函數頭可寫為:
main (argc,argv)
C語言還規(guī)定argc(第 一個形參)必須是整型變量,argv(第 二個形參)必須是指向字符串的指針數組。加上形參說明后,main函數的函數頭應寫為:
main (int argc,char *argv[])
由于main函數不能被其它函數調用,因此不可能在程序內部取得實際值。那么,在何處把實參值賦予main函數的形參呢?實際上,main函數的參數值是從操作系統(tǒng)命令 行上獲得的。當我們要運行 一個可執(zhí)行文件時,在命令提示符下鍵 入文件名,再輸入實際參數即可把這些實參傳送到main的形參中去。
Linux命令提示符下的 一般形式為:
ubuntu@ubuntu:~$./可執(zhí) 行行 文件名 參數1參數2……;
但是應該特別注意的是,main的兩個形參和命令行中的參數在位置上不是 一 一對應的。因
為,main的形參只有二個, 而命令行中的參數個數原則上未加限制。argc參數表示了了命令行中參
數的個數(注意: 文件名本身也算 一個參數),argc的值是在輸入命令行時由系統(tǒng)按實際參數的個
數 自動賦予的。
例如有命令 行行為:
ubuntu@ubuntu:~$./a.out?? BASIC? foxpro? FORTRAN
由于文件名a.out本身也算 一個參數,所以共有4個參數,因此argc取得的值為4。argv參數是字符串指針數組,其各元素值為命令行中各字符串(參數均按字符串處理理)的首地址。 指針數組的長度
即為參數個數。數組元素初值由系統(tǒng)自動賦予。其表示如下所示:
int main(int argc,char *argv[])
{
????int i = 0;
????for(i = 1 ; i< argc; i++)
????{
????????printf("%s\n",argv[i]);
????}
????return 0;
}
本例是顯示命令行中輸入的參數。如果上例的可執(zhí)行文件名為a.out,因此輸入的命令行為:
ubuntu@ubuntu:~$./a.outBASIC foxpro FORTRAN
則運 行行結果為:
BASIC
foxpro
FORTRAN
該行共有4個參數,執(zhí)行main時,argc的初值即為4。argv的4個元素分為4個字符串的首地址。