C語(yǔ)言中函數(shù)的聲明、定義及使用的入門教程
對(duì)函數(shù)的“定義”和“聲明”不是一回事。函數(shù)的定義是指對(duì)函數(shù)功能的確立,包括指定函數(shù)名,函數(shù)值類型、形參及其類型以及函數(shù)體等,它是一個(gè)完整的、獨(dú)立的函數(shù)單位。而函數(shù)的聲明的作用則是把函數(shù)的名字,函數(shù)類型以及形參的類型、個(gè)數(shù)和順序通知編譯系統(tǒng),以便在調(diào)用該函數(shù)時(shí)進(jìn)行對(duì)照檢查(例如,函數(shù)名是否正確,實(shí)參與形參的類型和個(gè)數(shù)是否一致),它不包括函數(shù)體?!T浩強(qiáng) ,《C程序設(shè)計(jì)》(第四版),清華大學(xué)出版社,2010年6月,p182
這段論述包含了許多概念性錯(cuò)誤,這些概念錯(cuò)誤在許多C語(yǔ)言書中都同樣普遍存在。為了說(shuō)明這些錯(cuò)誤,首先來(lái)回顧一下C語(yǔ)言演變和發(fā)展的一些情況。
最早,C語(yǔ)言的代碼可以這樣寫:
main()
{
printf("hello,world!\n");
}
注意,這段代碼對(duì)標(biāo)識(shí)符printf沒有進(jìn)行任何說(shuō)明。這是因?yàn)閜rintf()函數(shù)的返回值為int類型。當(dāng)時(shí)的C語(yǔ)言規(guī)定,對(duì)于沒有任何說(shuō)明的函數(shù)名,編譯器會(huì)默認(rèn)為返回值為int類型,因此對(duì)這樣的函數(shù)名可以不做任何說(shuō)明。那個(gè)時(shí)期的C語(yǔ)言,很多情況下int可以不寫。例如main()函數(shù)返回值的類型為int就可以不寫。
但是需要特別說(shuō)明的是,這種“省勁”的寫法已經(jīng)過(guò)時(shí),從C90標(biāo)準(zhǔn)起,這種寫法就步入了被逐步拋棄的過(guò)程(盡管當(dāng)時(shí)還沒有完全立即廢止)。C99廢除了隱式函數(shù)聲明法則(remove implicit function declaration),另外,省略main()前面的int也已經(jīng)不再容許了。
在C語(yǔ)言早期,盡管有時(shí)不需要對(duì)函數(shù)名進(jìn)行說(shuō)明,但有些情況下對(duì)函數(shù)名進(jìn)行說(shuō)明還是必須的,比如:
double sqrt();
int main()
{
printf("%f\n" , sqrt(9.) );
}
這是因?yàn)楹瘮?shù)sqrt()返回值的類型不是int類型而是double類型,編譯器編譯時(shí)需要知道sqrt(9.)這個(gè)表達(dá)式的類型。
不難注意到這種對(duì)函數(shù)名的說(shuō)明非常簡(jiǎn)單,這是最早期的一種函數(shù)類型說(shuō)明的形式。這種說(shuō)明只著重說(shuō)明函數(shù)名是一個(gè)函數(shù)及其返回值類型,如果程序員在調(diào)用函數(shù)時(shí)存在參數(shù)類型或個(gè)數(shù)方面的錯(cuò)誤編譯器是無(wú)法察覺的,因?yàn)楹瘮?shù)類型說(shuō)明中“()”內(nèi)沒有任何信息。
這種辦法只說(shuō)明了函數(shù)名與()進(jìn)行運(yùn)算的結(jié)果也就是函數(shù)返回值的數(shù)據(jù)類型,無(wú)法進(jìn)一步檢查參數(shù)方面的錯(cuò)誤是這種寫法的不足之處。
如果不寫函數(shù)類型說(shuō)明,也可以把函數(shù)定義寫在函數(shù)調(diào)用之前:
double square ( double x)
{
return x * x ;
}
int main(void)
{
printf("%f\n" , square(3.) );
return 0;
}
這表明函數(shù)定義也具有對(duì)函數(shù)名的類型加以說(shuō)明的效果,因此從這個(gè)意義上來(lái)說(shuō),函數(shù)定義也是一種對(duì)函數(shù)類型的說(shuō)明。這種辦法可以檢查出函數(shù)調(diào)用時(shí)在參數(shù)個(gè)數(shù)和類型方面的錯(cuò)誤。
但是,用這種辦法說(shuō)明函數(shù)名并不好,因?yàn)檫@樣做在編程時(shí)還需要考慮應(yīng)該把哪個(gè)函數(shù)定義寫在前面,哪個(gè)寫在后面的問(wèn)題。假如函數(shù)A調(diào)用函數(shù)B,函數(shù)B調(diào)用函數(shù)C,函數(shù)C又調(diào)用函數(shù)A,究竟如何安排函數(shù)定義的順序就會(huì)讓人感到無(wú)所適從。此外這種辦法也不利于代碼的組織,在由多個(gè)源文件組成的源程序時(shí),這種寫法就更會(huì)捉襟見肘、漏洞百出。因此,在1990年,C標(biāo)準(zhǔn)借鑒C++語(yǔ)言規(guī)定了一種新的說(shuō)明函數(shù)名的方法,這就是函數(shù)原型(Function Propotype)式說(shuō)明函數(shù)類型的方法:
double square ( double ); //或 double square ( double x)
int main(void)
{
printf("%f\n" , square(3.) );
return 0;
}
double square ( double x)
{
return x * x ;
}
使用這種辦法,不但可以檢查函數(shù)調(diào)用時(shí)參數(shù)類型和個(gè)數(shù)方面的錯(cuò)誤,同時(shí)解決了源代碼的組織問(wèn)題,因?yàn)槌绦騿T不必再考慮該把哪個(gè)函數(shù)寫在前面、哪個(gè)寫在后面這種無(wú)聊的問(wèn)題了。這種辦法全面地說(shuō)明了函數(shù)名的數(shù)據(jù)類型。此外要說(shuō)明的是,把形參及其數(shù)據(jù)類型寫在“()”內(nèi)形式的函數(shù)定義也屬于函數(shù)原型(Function Propotype)的范疇。
由此可見,古老的、不對(duì)參數(shù)進(jìn)行任何說(shuō)明的函數(shù)類型說(shuō)明方式、函數(shù)定義以及函數(shù)原型式的函數(shù)類型說(shuō)明方式都具有說(shuō)明函數(shù)名意義的效用。從這個(gè)意義上講它們都是函數(shù)聲明。在C語(yǔ)言中,聲明(Declaration)這個(gè)詞的本義就是指定標(biāo)識(shí)符的意義和性質(zhì)(A declaration specifies the interpretation and attributes of a set of identifiers.),某個(gè)標(biāo)識(shí)符的定義(Definition)同時(shí)也是這個(gè)標(biāo)志符的“聲明”(Declaration)。函數(shù)定義(Function definition)則意指包括函數(shù)體。(A definition of an identifier is a declaration for that identifier that: ……for a function, includes the function body;)。函數(shù)原型則特指包括說(shuō)明參數(shù)類型的函數(shù)聲明,它同樣包含用這種方式寫出的函數(shù)定義。
現(xiàn)在回過(guò)頭來(lái)看樣本中的第一句話:“對(duì)函數(shù)的“定義”和“聲明”不是一回事”。由于函數(shù)定義本身就是一種函數(shù)聲明,怎么可以說(shuō)它們不是一回事呢?這句話的邏輯就如同說(shuō)“男人”和“人”不是一回事。你可以說(shuō)男人和女人不是一回事,因?yàn)樗麄儧]有交集。但沒法說(shuō)男人和人不是一回事,因?yàn)槟腥耸侨说淖蛹腥司褪侨说囊环N,怎么可以說(shuō)男人和人不是一回事呢?
那么,不帶函數(shù)體的函數(shù)聲明應(yīng)該如何稱呼呢?在C語(yǔ)言中,它們叫被做“函數(shù)類型聲明”(Function type declaration)。函數(shù)類型聲明最主要的特點(diǎn)是聲明了函數(shù)名是一個(gè)函數(shù)及其返回值的類型,如果也聲明了參數(shù)的類型,則是函數(shù)原型式的函數(shù)類型聲明。
樣本中的“而函數(shù)的聲明的作用則是把函數(shù)的名字,函數(shù)類型以及形參的類型、個(gè)數(shù)和順序通知編譯系統(tǒng),以便在調(diào)用該函數(shù)時(shí)進(jìn)行對(duì)照檢查(例如,函數(shù)名是否正確,實(shí)參與形參的類型和個(gè)數(shù)是否一致),它不包括函數(shù)體”這句話同樣不通。其主要錯(cuò)誤是它混淆了“函數(shù)原型式類型聲明”與“函數(shù)聲明”這兩個(gè)概念,前一個(gè)概念只是后一個(gè)概念的子集。函數(shù)聲明中不但包含“函數(shù)類型聲明”,也包含“函數(shù)定義”和老式的“函數(shù)類型聲明”。由于函數(shù)定義本身就是一種函數(shù)聲明,所以無(wú)法斷定函數(shù)的聲明是否包括函數(shù)體;而且老式的函數(shù)類型聲明(例如double sqrt();)也屬于函數(shù)聲明,這種函數(shù)聲明并不檢查參數(shù)類型及個(gè)數(shù)方面的錯(cuò)誤。此外函數(shù)聲明也并沒有檢查“函數(shù)名”正確與否的功能。
這段文字中的“函數(shù)類型”這個(gè)概念也有錯(cuò)誤,函數(shù)類型所描述的不但包括函數(shù)返回值類型,也可能一并描述參數(shù)的個(gè)數(shù)和類型(如果是函數(shù)原型),因此不能與“形參的類型、個(gè)數(shù)”相提并論。
現(xiàn)代的C語(yǔ)言的函數(shù)定義和函數(shù)類型聲明都采用函數(shù)原型式的風(fēng)格,C99把舊的非原型形式視為過(guò)時(shí),這意味著非原型形式以后可能被禁止。
main()函數(shù)
在各種C語(yǔ)言書上,能看到各式各樣main()函數(shù)的寫法,簡(jiǎn)直令人無(wú)所適從,這是這么回事?原因主要有兩個(gè):一個(gè)是隨著C語(yǔ)言的發(fā)展和演化,main()函數(shù)的寫法也在不斷變化;另外,某些書籍寫法不規(guī)范或誤導(dǎo)的現(xiàn)象也同時(shí)存在。
最初main()函數(shù)的寫法非常簡(jiǎn)潔,那個(gè)時(shí)候的C程序員哪怕一個(gè)字符似乎都不肯多寫。不知道是因?yàn)楫?dāng)時(shí)鍵盤質(zhì)量不好還是因?yàn)榫庉嬈魈愀獾木壒?,那個(gè)時(shí)代的C程序員似乎驚人地一致崇尚“簡(jiǎn)約”——甚至可以說(shuō)是“至簡(jiǎn)”。
main()
{
printf("hello,world\n");
}
這就是main()函數(shù)最古老的寫法,K&R在他們的經(jīng)典名著《The C Programming Language》中的第一個(gè)C語(yǔ)言源程序(1978)。這種寫法是那個(gè)時(shí)代的主流。
簡(jiǎn)直和裸體差不多,連#include<stdio.h>也沒有么?在《The C Programming Language》的第一版中確實(shí)沒有。那個(gè)時(shí)代的C語(yǔ)言,返回值類型為int的函數(shù)不用聲明。不過(guò)在該書的第二版(1988)中這個(gè)程序被改成了:
#include <stdio.h>
main()
{
printf("hello,world\n");
}
返回值類型為int的函數(shù)不用聲明的規(guī)則改變了嗎?規(guī)則沒有改變。改變了的是觀念,人們已經(jīng)不再傾向于代碼的“至簡(jiǎn)”,而開始傾向于在代碼中交代清楚每一個(gè)標(biāo)識(shí)符的來(lái)龍去脈。從C89開始倡導(dǎo)在函數(shù)調(diào)用之前一定要有函數(shù)聲明,但并沒有強(qiáng)求,而在C99這已經(jīng)是強(qiáng)制性的要求了。由于《The C Programming Language》第二版正值A(chǔ)NSI C標(biāo)準(zhǔn)頒布(1989)前夕出版,所以這種變化也應(yīng)該視為ANSI C標(biāo)準(zhǔn)的傾向性以及K&R對(duì)新標(biāo)準(zhǔn)的認(rèn)同。盡管這個(gè)例子沒有完全反映出來(lái)這種認(rèn)同。
為什么說(shuō)沒有完全反映出來(lái)這種認(rèn)同呢?因?yàn)檫@個(gè)main()的定義并沒有按照函數(shù)原型(Function prototype)的方式來(lái)寫,C90中規(guī)定不帶參數(shù)的main()函數(shù)應(yīng)該這樣寫:
int main(void) { /*. . .*/}
但同時(shí)規(guī)定那個(gè)int可以省略。C90把()內(nèi)不寫任何內(nèi)容視為過(guò)時(shí)的寫法,盡管C90無(wú)奈地容忍了它(The use of function declarators with empty parentheses (not prototype-format parameter type declarators) is an obsolescent feature.)。
為什么要容忍?因?yàn)橛性S多老式的代碼還在用。
如果以C99的標(biāo)準(zhǔn)看這個(gè)main()寫得如何呢?C99不容許省略int。但同樣只把()內(nèi)不寫任何內(nèi)容視為過(guò)時(shí),而沒有完全禁止,可見習(xí)慣力量的頑固。
那又為什么說(shuō)K&R對(duì)新標(biāo)準(zhǔn)的認(rèn)同呢?《The C Programming Language》第二版中的其他函數(shù)定義和函數(shù)類型聲明基本上都改成了函數(shù)原型風(fēng)格。比如,在講解main()函數(shù)的參數(shù)時(shí),K&R把原來(lái)的main()函數(shù)
#include <stdio.h>
main(argc,argv)
int argc;char *argv[];
{
/*…… */
return 0;
}
改成了:
#include <stdio.h>
main(int argc, char *argv[])
{
/*…… */
return 0;
}
前一個(gè)寫法今天已經(jīng)差不多絕跡,后一個(gè)main()以今天的眼光來(lái)看有些奇怪,main()的參數(shù)是用函數(shù)原型風(fēng)格寫的,但卻沒有寫main()返回值的類型,給人有點(diǎn)半新半舊的感覺。盡管不能說(shuō)它違背C90(因?yàn)镃90容許不寫main()前面的int),但如果寫上了返回值的類型int,就同時(shí)滿足現(xiàn)代C99標(biāo)準(zhǔn)的要求了。
這里出現(xiàn)的“return 0;”是怎么回事?這在現(xiàn)代C語(yǔ)言中已經(jīng)是司空見慣了,它返回給操作系統(tǒng)一個(gè)值以表明程序是在何種狀態(tài)下結(jié)束的。但在另一段代碼中,K&R似乎又走得太遠(yuǎn):
#include <stdio.h>
main(int argc,char *argv[])
{
int found = 0 ;
/*……計(jì)算found的值 */
return found;
}
這個(gè)實(shí)在有些“標(biāo)新立異”,居然把計(jì)算結(jié)果返回給了操作系統(tǒng),頗有突破常規(guī)之嫌。
那前面幾個(gè)沒有“return 0;”的main()函數(shù)會(huì)怎么樣?按照C90標(biāo)準(zhǔn),會(huì)返回一個(gè)不確定的int類型的值,如果確實(shí)不關(guān)心這個(gè)返回值是多少,不寫確實(shí)可以。但C99卻要求編譯器在編譯的時(shí)候幫忙給補(bǔ)上這個(gè)“return 0;”,C99在必須寫int這個(gè)問(wèn)題上沒有遷就懶人,但在這里卻對(duì)偷懶的做法給予了遷就。 問(wèn):如果確實(shí)不關(guān)心main()函數(shù)的返回值,把main()的返回值定義為void類型如何?我看到許多書上都這樣寫的。
#include <stdio.h>
void main()
{
printf("This is a C program.\n");
}
這在C99之前是一種野路子寫法,究竟從哪里冒出來(lái)的,無(wú)據(jù)可考。但前幾年的主流教科書中這種寫法很常見。K&R(C語(yǔ)言的發(fā)明者)沒有這樣寫過(guò),C90國(guó)際標(biāo)準(zhǔn)也不承認(rèn)這種寫法。Bjarne Stroustrup(C++語(yǔ)言的創(chuàng)始人)在他的關(guān)于C++的FAQ中,在回答是否可以寫“void main()”時(shí)憤怒地回答說(shuō)這種寫法在C++和C中都不曾有過(guò)。事實(shí)上,很多C語(yǔ)言專家都認(rèn)為“void main()”非常邪惡。
因此,在C99之前,這是不符合標(biāo)準(zhǔn)的寫法。盡管這段代碼的功能似乎是輸出“This is a C program.”,但其實(shí)卻不是一個(gè)“C program”。
但是有時(shí)這樣寫并沒有產(chǎn)生錯(cuò)誤啊?首先,C語(yǔ)言的錯(cuò)誤不一定反應(yīng)在編譯、鏈接或運(yùn)行過(guò)程中。你輸出一個(gè)垃圾值也可能一路通過(guò)編譯、鏈接或運(yùn)行,但這不說(shuō)明你的代碼沒有錯(cuò)誤,更不能說(shuō)明這樣的代碼正確、有意義。其次,這樣的寫法在有些編譯器下程序會(huì)產(chǎn)生崩潰或得到警告。這說(shuō)明這種寫法至少不普遍性適用的??梢哉f(shuō),如果不是C99標(biāo)準(zhǔn),這種寫法根本沒有立錐之地。
C99給了這種寫法以立足之地么?從某種意義上也許可以這樣理解。因?yàn)镵&R沒承認(rèn)過(guò)這種寫法,C90根本不承認(rèn)這種寫法,C99雖然沒有正式承認(rèn)這種寫法,但為這種寫法留了一個(gè)后門:“It shall be defined ……or in some other implementation-defined manner”。這意思就是說(shuō),如果編譯器明確聲稱允許void main()這種寫法的話,那么C99不再象C90那樣簡(jiǎn)單認(rèn)為這種寫法違背C標(biāo)準(zhǔn)。
但是不管怎么說(shuō),這種寫法最多是某些編譯器的一種“方言土語(yǔ)”,如果沒有特殊理由,比如僅僅是工作在某個(gè)特殊環(huán)境,且僅僅使用特定的編譯器而根本不考慮程序的可移植性,為什么不寫普遍適用的形式呢?
既然很多C語(yǔ)言專家都認(rèn)為“void main()”非常邪惡,C99為什么包容這種寫法呢?很難確定C99是否就是打算專門想把這種寫法也“收容”在標(biāo)準(zhǔn)之列。因?yàn)槌藇oid main(),還有另外一些main()函數(shù)的寫法被C90排除在標(biāo)準(zhǔn)之外了。而現(xiàn)在,這些寫法在理論上也具備了符合C99標(biāo)準(zhǔn)的可能性。
還有什么樣的main()函數(shù)?很多編譯器都支持下面的main()的寫法:
int main(int argc, char *argv[], char *env[])
{
/* */
return 0;
}
居然有3個(gè)形參,那個(gè)env是做什么用的?那個(gè)參數(shù)可以使程序獲得環(huán)境變量。
什么叫環(huán)境變量?簡(jiǎn)單地講可以理解為操作系統(tǒng)記錄的一些數(shù)據(jù),比如計(jì)算機(jī)的名字,操作系統(tǒng)放在哪里等等。應(yīng)用程序在運(yùn)行時(shí)可能要用到這些信息,這時(shí)可以通過(guò)env這個(gè)參數(shù)來(lái)獲得。
如果編譯器不支持main()的第三個(gè)參數(shù)怎么辦?標(biāo)準(zhǔn)庫(kù)函數(shù)也可以達(dá)到同樣的目的。
#include <stdlib.h> char *getenv(const char *name);
是否可以說(shuō)void main()和int main(int argc, char *argv[], char *env[])也符合C99標(biāo)準(zhǔn)呢?恐怕還不能這么說(shuō),現(xiàn)在只是不能說(shuō)這兩種寫法一定不符合C99標(biāo)準(zhǔn)。但這兩種寫法不符合C90標(biāo)準(zhǔn)是確定的,這兩種寫法的可移植性很差也是確定無(wú)疑的。C99標(biāo)準(zhǔn)在這里寫的很模糊,沒有進(jìn)一步界定“implementation-defined manner”的含義。除非編譯器聲明遵守C99標(biāo)準(zhǔn),且容許這兩種寫法,否則斷言這兩種寫法符合C99標(biāo)準(zhǔn)屬于空穴來(lái)風(fēng)。
有人說(shuō)“C99建議把main函數(shù)指定為int型”,這種說(shuō)法對(duì)嗎?顯然不對(duì)。因?yàn)镃99并非絕對(duì)不包容返回值非int類型的main()。正確的說(shuō)法是,C90要求main()函數(shù)的返回值一定得是int型。但C90容許不寫那個(gè)int,而C99則要求必須寫上這個(gè)“int”。
下面這種風(fēng)格如何?
#include <stdio.h>
int main()
{
printf("This is a C program.\n");
return 0;
}
這個(gè)寫法有點(diǎn)不倫不類。返回值的類型int寫了,這個(gè)和C89的倡導(dǎo)或C99的要求一致,但是()里面什么都不寫,又與標(biāo)準(zhǔn)的所倡導(dǎo)的風(fēng)格不符,所以說(shuō)不倫不類。這種寫法目前的標(biāo)準(zhǔn)依然容許,但屬于標(biāo)準(zhǔn)目前尚能容忍的但即將過(guò)時(shí)的(obsolescent)寫法,被拋棄只是早晚的問(wèn)題。這種寫法就如同古代的函數(shù)形參的寫法一樣:
main(argc,argv)
int argc;char *argv[];
{
/*…… */
return 0;
}
都屬于歷史的垃圾。
見過(guò)在main()的函數(shù)體的“}”之前前寫一句getch();,這個(gè)是怎么回事?這個(gè)是時(shí)代的產(chǎn)物。在PC從DOS時(shí)代轉(zhuǎn)變?yōu)閃indows時(shí)代的過(guò)程中,DOS時(shí)代開發(fā)的IDE(主要是TC)無(wú)法在運(yùn)行程序后顯示輸出結(jié)果,為了在運(yùn)行后從容仔細(xì)地觀察一下運(yùn)行結(jié)果再返回IED界面,加上了這么一句,人為地延長(zhǎng)程序運(yùn)行時(shí)間(因?yàn)間etch()會(huì)等待用戶輸入一個(gè)字符)。但這與main()本身的結(jié)構(gòu)無(wú)關(guān)。這條語(yǔ)句不具備普遍意義,只是將就過(guò)時(shí)的IDE的一種權(quán)宜之計(jì)而已。所謂不具備普遍意義是指,第一,真正的程序往往不需要這條語(yǔ)句,就是說(shuō)這條語(yǔ)句與程序功能無(wú)關(guān);第二,getch()這個(gè)函數(shù)并不是標(biāo)準(zhǔn)函數(shù),只有個(gè)別的編譯器才支持它,在其他編譯器上寫這條語(yǔ)句,很可能行不通。
為什么不用getchar()這個(gè)標(biāo)準(zhǔn)庫(kù)函數(shù)呢?getchar()的功能和getch()有點(diǎn)區(qū)別,前者會(huì)在標(biāo)準(zhǔn)輸出設(shè)備上顯示用戶鍵入的字符,這顯得很不利索,而后者則不會(huì)顯示用戶所鍵入的字符,更接近“Press Any Key to continue……”的效果。
有的代碼在main()函數(shù)結(jié)束前寫system("PAUSE");,是否也是這個(gè)意思?是的。這也是一種人工制造的“請(qǐng)按任意鍵繼續(xù). . .”,與程序功能結(jié)構(gòu)無(wú)關(guān),只是為了方便地觀察輸出結(jié)果。但是這種寫法比調(diào)用getch()要好,因?yàn)閟ystem()函數(shù)是標(biāo)準(zhǔn)庫(kù)函數(shù),各個(gè)編譯器都提供支持。
有一種說(shuō)法,“在最新的C99標(biāo)準(zhǔn)中,只有以下兩種定義方式是正確的:”
int main( void )
{
/* */
return 0;
}
和
int main( int argc, char *argv[] )
{
/* */
return 0;
}
這種說(shuō)法對(duì)嗎?
這種說(shuō)法顯然不對(duì)。但可以確認(rèn)的是這兩種定義方式一定正確。不但在C99來(lái)說(shuō)是正確的,以C89來(lái)說(shuō)也是正確的。
還有一種寫法:
int main( void )
{
return EXIT_SUCCESS;
}
那個(gè)EXIT_SUCCESS是怎么回事?
return EXIT_SUCCESS;是與return 0;等價(jià)的一種文雅的寫法。EXIT_SUCCESS是在stdlib.h中定義了的符號(hào)常量,返回這個(gè)值表示程序任務(wù)完成后程序退出。在stdlib.h定義的另一個(gè)符號(hào)常量EXIT_FAILURE,通常用于程序無(wú)法完成任務(wù)而退出。
實(shí)在太眼花繚亂了,需要記住這么多嗎?顯然沒必要。很多東西都是歷史原因遺留下的垃圾。
如果學(xué)習(xí)C語(yǔ)言,應(yīng)該記住或使用哪種呢?顯然是:
int main( void )
{
/* */
return 0;
}
和
int main( int argc, char *argv[] )
{
/* */
return 0;
}
第一,他們普遍適用,不存在可移植性的問(wèn)題;
第二,就目前看,他們不存在任何過(guò)時(shí)或即將過(guò)時(shí)的成分。當(dāng)然,如果喜歡文雅,不寫return 0;而寫EXIT_SUCCESS也可以。 順便說(shuō)一句,有的學(xué)習(xí)者記不住帶參數(shù)main()函數(shù)兩個(gè)形參的名字。其實(shí)這兩個(gè)形參的名字也可以自己取,不一定用那兩個(gè)名字,只要記住類型就可以了。第二個(gè)參數(shù)的類型也可以是char **,這和原來(lái)的是等價(jià)的。
上一篇:對(duì)C語(yǔ)言編程標(biāo)準(zhǔn)以及聲明的基本理解
欄 目:C語(yǔ)言
本文標(biāo)題:C語(yǔ)言中函數(shù)的聲明、定義及使用的入門教程
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/2628.html
您可能感興趣的文章
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用函數(shù)刪除字符
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)式函數(shù)庫(kù)
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)數(shù)怎么表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫分段 用c語(yǔ)言表示分段函數(shù)
- 04-02c語(yǔ)言編寫函數(shù)冒泡排序 c語(yǔ)言冒泡排序法函數(shù)
- 04-02c語(yǔ)言沒有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段函數(shù)
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎么打出三角函數(shù)的值
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求階乘


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問(wèn)題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語(yǔ)言函數(shù)調(diào)用后清空內(nèi)存 c語(yǔ)言調(diào)用
- 04-02func函數(shù)+在C語(yǔ)言 func函數(shù)在c語(yǔ)言中
- 04-02c語(yǔ)言的正則匹配函數(shù) c語(yǔ)言正則表達(dá)
- 04-02c語(yǔ)言用函數(shù)寫分段 用c語(yǔ)言表示分段
- 04-02c語(yǔ)言中對(duì)數(shù)函數(shù)的表達(dá)式 c語(yǔ)言中對(duì)
- 04-02c語(yǔ)言編寫函數(shù)冒泡排序 c語(yǔ)言冒泡排
- 04-02c語(yǔ)言沒有round函數(shù) round c語(yǔ)言
- 04-02c語(yǔ)言分段函數(shù)怎么求 用c語(yǔ)言求分段
- 04-02C語(yǔ)言中怎么打出三角函數(shù) c語(yǔ)言中怎
- 04-02c語(yǔ)言調(diào)用函數(shù)求fibo C語(yǔ)言調(diào)用函數(shù)求
隨機(jī)閱讀
- 04-02jquery與jsp,用jquery
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 01-10delphi制作wav文件的方法
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載


