十年網(wǎng)站開(kāi)發(fā)經(jīng)驗(yàn) + 多家企業(yè)客戶 + 靠譜的建站團(tuán)隊(duì)
量身定制 + 運(yùn)營(yíng)維護(hù)+專業(yè)推廣+無(wú)憂售后,網(wǎng)站問(wèn)題一站解決
main函數(shù)可以不帶參數(shù),也可以帶參數(shù),這個(gè)參數(shù)可以認(rèn)為是 main函數(shù)的形式參數(shù)。
創(chuàng)新互聯(lián)專業(yè)為企業(yè)提供梓潼網(wǎng)站建設(shè)、梓潼做網(wǎng)站、梓潼網(wǎng)站設(shè)計(jì)、梓潼網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁(yè)設(shè)計(jì)與制作、梓潼企業(yè)網(wǎng)站模板建站服務(wù),10多年梓潼做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
C語(yǔ)言規(guī)定main函數(shù)的參數(shù)只能有兩個(gè),還規(guī)定argc(第一個(gè)形參)必須是整型變量,argv( 第二個(gè)形參)必須是指向字符串的指針數(shù)組。加上形參說(shuō)明后,main函數(shù)的函數(shù)頭應(yīng)寫為:
int main (int argc,char *argv[])
由于main函數(shù)不能被其它函數(shù)調(diào)用,因此不可能在程序內(nèi)部取得實(shí)際值。那么,在何處把實(shí)參值賦予main函數(shù)的形參呢? 實(shí)際上,main函數(shù)的參數(shù)值是從操作系統(tǒng)命令行上獲得的。當(dāng)我們要運(yùn)行一個(gè)可執(zhí)行文件時(shí),在DOS提示符下鍵入文件名,再輸入實(shí)際參數(shù)即可把這些實(shí)參傳送到main的形參中去。
DOS提示符下命令行的一般形式為:
C:\可執(zhí)行文件名 參數(shù) 參數(shù)……
不知道函數(shù)調(diào)用原理的話,很難說(shuō)得清楚的。粗略的說(shuō)在C中函數(shù)其實(shí)是分成三個(gè)部分,分別是聲明、實(shí)現(xiàn)和使用。聲明就是告訴C有這么個(gè)函數(shù),實(shí)現(xiàn)就是這個(gè)函數(shù)的完整代碼,使用則是調(diào)用這個(gè)函數(shù)幫你做運(yùn)算或者是做事情。為了讓函數(shù)能做更多的事情,就需要一種方法能向函數(shù)傳遞性息,最可靠、最方便的方法就是參數(shù)傳遞,C就是這樣做的。參數(shù)傳遞也不是簡(jiǎn)單的一件事情,首先在調(diào)用者和被調(diào)用者之間得有個(gè)約定,大家約定好了參數(shù)放什么地方,如何使用,這個(gè)就稱為調(diào)用約定?,F(xiàn)在我們回過(guò)頭來(lái)看什么叫實(shí)參和形參。由上面的敘述可以看到,函數(shù)其實(shí)有一定的獨(dú)立性的,參數(shù)是在調(diào)用約定下放在指定地方供函數(shù)使用的,在我們實(shí)現(xiàn)函數(shù)的時(shí)候,實(shí)際的參數(shù)是什么我們還不知道,但我們知道有多少參數(shù),分別是什么數(shù)據(jù)類型的和放在什么地方(順序),這個(gè)是由調(diào)用約定來(lái)保證的。我們知道的這些就是形式的或者說(shuō)是邏輯的,我們?cè)趯?shí)現(xiàn)函數(shù)(編寫函數(shù)體)的時(shí)候需要給他們命名,以便使用,這些在函數(shù)實(shí)現(xiàn)的時(shí)候命名的形式上的參數(shù)就是形式參數(shù),簡(jiǎn)稱形參。而在實(shí)際調(diào)用發(fā)生的時(shí)候,調(diào)用者會(huì)將實(shí)際的參數(shù)放在約定好了的地方,這個(gè)實(shí)際參數(shù)簡(jiǎn)稱實(shí)參。函數(shù)被運(yùn)行的時(shí)候?qū)崊⒑托螀⑿纬闪艘灰粚?duì)應(yīng),對(duì)形參的操作就變成了對(duì)實(shí)參的操作。
對(duì)調(diào)用約定還有需要說(shuō)明的就是,現(xiàn)在常用的調(diào)用約定都是傳值的,也就是說(shuō)只是傳遞了一個(gè)副本,這樣做的結(jié)果就是你對(duì)形參的操作不會(huì)被傳遞出來(lái)。
是否可以解決您的問(wèn)題?
C語(yǔ)言中沒(méi)有參數(shù)默認(rèn)值的概念,但其實(shí)可以利用宏來(lái)模擬參數(shù)默認(rèn)值;
我們之前介紹過(guò)可變參數(shù)宏與逗號(hào)運(yùn)算符,將兩者相結(jié)合的話可以定義出以下形式的宏:
示例:
輸出:
舉個(gè)栗子,比如計(jì)算a+b的值的函數(shù)
#includestdio.h
int?plus(int?a,int?b)
{
int?c?=?a+b;//2.此處定義的c無(wú)法被主函數(shù)直接調(diào)用,因?yàn)閏為局部變量
return?c;//3.要返回計(jì)算結(jié)果,只能用return語(yǔ)句
}
int?main()
{
int?i=5,j=7;
int?ans?=?plus(i,j);//1.該過(guò)程中,首先將i,j作為參數(shù)(與上面的plus函數(shù)說(shuō)明(m,n)一一對(duì)應(yīng))傳遞給plus函數(shù)。
printf("%d",ans);
}
數(shù)組元素就是下標(biāo)變量,它與普通變量并無(wú)區(qū)別。 因此它作為函數(shù)實(shí)參使用與普通變量是完全相同的,在發(fā)生函數(shù)調(diào)用時(shí),把作為實(shí)參的數(shù)組元素的值傳送給形參,實(shí)現(xiàn)單向的值傳送?!纠?-4】說(shuō)明了這種情況。
【例8-7】判別一個(gè)整數(shù)數(shù)組中各元素的值,若大于0 則輸出該值,若小于等于0則輸出0值。編程如下:#include stdio.hvoid nzp(int v){ if(v0) printf("%d ",v); else printf("%d ",0);}int main(void){ int a[5],i; printf("input 5 numbers\n"); for(i=0;i5;i++){ scanf("%d",a[i]); nzp(a[i]); } return 0;}
本程序中首先定義一個(gè)無(wú)返回值函數(shù)nzp,并說(shuō)明其形參v為整型變量。在函數(shù)體中根據(jù)v值輸出相應(yīng)的結(jié)果。在main函數(shù)中用一個(gè)for語(yǔ)句輸入數(shù)組各元素,每輸入一個(gè)就以該元素作實(shí)參調(diào)用一次nzp函數(shù),即把a(bǔ)[i]的值傳送給形參v,供nzp函數(shù)使用。
數(shù)組名作為函數(shù)參數(shù)
用數(shù)組名作函數(shù)參數(shù)與用數(shù)組元素作實(shí)參有幾點(diǎn)不同。
1) 用數(shù)組元素作實(shí)參時(shí),只要數(shù)組類型和函數(shù)的形參變量的類型一致,那么作為下標(biāo)變量的數(shù)組元素的類型也和函數(shù)形參變量的類型是一致的。因此,并不要求函數(shù)的形參也是下標(biāo)變量。換句話說(shuō),對(duì)數(shù)組元素的處理是按普通變量對(duì)待的。用數(shù)組名作函數(shù)參數(shù)時(shí),則要求形參和相對(duì)應(yīng)的實(shí)參都必須是類型相同的數(shù)組,都必須有明確的數(shù)組說(shuō)明。當(dāng)形參和實(shí)參二者不一致時(shí),即會(huì)發(fā)生錯(cuò)誤。
2) 在普通變量或下標(biāo)變量作函數(shù)參數(shù)時(shí),形參變量和實(shí)參變量是由編譯系統(tǒng)分配的兩個(gè)不同的內(nèi)存單元。在函數(shù)調(diào)用時(shí)發(fā)生的值傳送是把實(shí)參變量的值賦予形參變量。在用數(shù)組名作函數(shù)參數(shù)時(shí),不是進(jìn)行值的傳送,即不是把實(shí)參數(shù)組的每一個(gè)元素的值都賦予形參數(shù)組的各個(gè)元素。因?yàn)閷?shí)際上形參數(shù)組并不存在,編譯系統(tǒng)不為形參數(shù)組分配內(nèi)存。那么,數(shù)據(jù)的傳送是如何實(shí)現(xiàn)的呢?在我們?cè)榻B過(guò),數(shù)組名就是數(shù)組的首地址。因此在數(shù)組名作函數(shù)參數(shù)時(shí)所進(jìn)行的傳送只是地址的傳送,也就是說(shuō)把實(shí)參數(shù)組的首地址賦予形參數(shù)組名。形參數(shù)組名取得該首地址之后,也就等于有了實(shí)在的數(shù)組。實(shí)際上是形參數(shù)組和實(shí)參數(shù)組為同一數(shù)組,共同擁有一段內(nèi)存空間。
上圖說(shuō)明了這種情形。圖中設(shè)a為實(shí)參數(shù)組,類型為整型。a占有以2000為首地址的一塊內(nèi)存區(qū)。b為形參數(shù)組名。當(dāng)發(fā)生函數(shù)調(diào)用時(shí),進(jìn)行地址傳送,把實(shí)參數(shù)組a的首地址傳送給形參數(shù)組名b,于是b也取得該地址2000。于是a,b兩數(shù)組共同占有以2000為首地址的一段連續(xù)內(nèi)存單元。從圖中還可以看出a和b下標(biāo)相同的元素實(shí)際上也占相同的兩個(gè)內(nèi)存單元(整型數(shù)組每個(gè)元素占二字節(jié))。例如a[0]和b[0]都占用2000和2001單元,當(dāng)然a[0]等于b[0]。類推則有a[i]等于b[i]。
【例8-8】數(shù)組a中存放了一個(gè)學(xué)生5門課程的成績(jī),求平均成績(jī)。#include stdio.hfloat aver(float a[5]){ int i; float av,s=a[0]; for(i=1;i5;i++) s=s+a[i]; av=s/5; return av;}int main(void){ float sco[5],av; int i; printf("\ninput 5 scores:\n"); for(i=0;i5;i++) scanf("%f",sco[i]); av=aver(sco); printf("average score is %5.2f",av); return 0;}
本程序首先定義了一個(gè)實(shí)型函數(shù)aver,有一個(gè)形參為實(shí)型數(shù)組a,長(zhǎng)度為5。在函數(shù)aver中,把各元素值相加求出平均值,返回給主函數(shù)。主函數(shù)main 中首先完成數(shù)組sco的輸入,然后以sco作為實(shí)參調(diào)用aver函數(shù),函數(shù)返回值送av,最后輸出av值。 從運(yùn)行情況可以看出,程序?qū)崿F(xiàn)了所要求的功能。
3) 前面已經(jīng)討論過(guò),在變量作函數(shù)參數(shù)時(shí),所進(jìn)行的值傳送是單向的。即只能從實(shí)參傳向形參,不能從形參傳回實(shí)參。形參的初值和實(shí)參相同,而形參的值發(fā)生改變后,實(shí)參并不變化,兩者的終值是不同的。而當(dāng)用數(shù)組名作函數(shù)參數(shù)時(shí),情況則不同。由于實(shí)際上形參和實(shí)參為同一數(shù)組,因此當(dāng)形參數(shù)組發(fā)生變化時(shí),實(shí)參數(shù)組也隨之變化。當(dāng)然這種情況不能理解為發(fā)生了“雙向”的值傳遞。但從實(shí)際情況來(lái)看,調(diào)用函數(shù)之后實(shí)參數(shù)組的值將由于形參數(shù)組值的變化而變化。為了說(shuō)明這種情況,把【例5.4】改為【例5.6】的形式。
【例8-9】題目同【例8.7】。改用數(shù)組名作函數(shù)參數(shù)。#include stdio.hvoid nzp(int a[5]){ int i; printf("\nvalues of array a are:\n"); for(i=0;i5;i++){ if(a[i]0) a[i]=0; printf("%d ",a[i]); }}int main(void){ int b[5],i; printf("\ninput 5 numbers:\n"); for(i=0;i5;i++) scanf("%d",b[i]); printf("initial values of array b are:\n"); for(i=0;i5;i++) printf("%d ",b[i]); nzp(b); printf("\nlast values of array b are:\n"); for(i=0;i5;i++) printf("%d ",b[i]); return 0;}
本程序中函數(shù)nzp的形參為整數(shù)組a,長(zhǎng)度為5。主函數(shù)中實(shí)參數(shù)組b也為整型,長(zhǎng)度也為5。在主函數(shù)中首先輸入數(shù)組b的值,然后輸出數(shù)組b的初始值。然后以數(shù)組名b為實(shí)參調(diào)用nzp函數(shù)。在nzp中,按要求把負(fù)值單元清0,并輸出形參數(shù)組a的值。 返回主函數(shù)之后,再次輸出數(shù)組b的值。從運(yùn)行結(jié)果可以看出,數(shù)組b的初值和終值是不同的,數(shù)組b的終值和數(shù)組a是相同的。這說(shuō)明實(shí)參形參為同一數(shù)組,它們的值同時(shí)得以改變。
用數(shù)組名作為函數(shù)參數(shù)時(shí)還應(yīng)注意以下幾點(diǎn):
①形參數(shù)組和實(shí)參數(shù)組的類型必須一致,否則將引起錯(cuò)誤。
②形參數(shù)組和實(shí)參數(shù)組的長(zhǎng)度可以不相同,因?yàn)樵谡{(diào)用時(shí),只傳送首地址而不檢查形參數(shù)組的長(zhǎng)度。當(dāng)形參數(shù)組的長(zhǎng)度與實(shí)參數(shù)組不一致時(shí),雖不至于出現(xiàn)語(yǔ)法錯(cuò)誤(編譯能通過(guò)),但程序執(zhí)行結(jié)果將與實(shí)際不符,這是應(yīng)予以注意的。
【例8.10】如把例8.9修改如下:#include stdio.hvoid nzp(int a[8]){ int i; printf("\nvalues of array aare:\n"); for(i=0;i8;i++){ if(a[i]0)a[i]=0; printf("%d ",a[i]); }}int main(void){ int b[5],i; printf("\ninput 5 numbers:\n"); for(i=0;i5;i++) scanf("%d",b[i]); printf("initial values of array b are:\n"); for(i=0;i5;i++) printf("%d ",b[i]); nzp(b); printf("\nlast values of array b are:\n"); for(i=0;i5;i++) printf("%d ",b[i]); return 0;}
本程序與【例8.9】程序比,nzp函數(shù)的形參數(shù)組長(zhǎng)度改為8,函數(shù)體中,for語(yǔ)句的循環(huán)條件也改為i8。因此,形參數(shù)組a和實(shí)參數(shù)組b的長(zhǎng)度不一致。編譯能夠通過(guò),但從結(jié)果看,數(shù)組a的元素a[5]、a[6]、a[7]顯然是無(wú)意義的。
③在函數(shù)形參表中,允許不給出形參數(shù)組的長(zhǎng)度,或用一個(gè)變量來(lái)表示數(shù)組元素的個(gè)數(shù)。例如,可以寫為:
void nzp(int a[])
或?qū)憺?/p>
void nzp( int a[], int n )
其中形參數(shù)組a沒(méi)有給出長(zhǎng)度,而由n值動(dòng)態(tài)地表示數(shù)組的長(zhǎng)度。n的值由主調(diào)函數(shù)的實(shí)參進(jìn)行傳送。由此,【例8-10】又可改為【例8-11】的形式。
【例8-11】復(fù)制純文本新窗口
#include stdio.hvoid nzp(int a[],int n){ int i; printf("\nvalues of array a are:\n"); for(i=0;in;i++){ if(a[i]0) a[i]=0; printf("%d ",a[i]); }}int main(void){ int b[5],i; printf("\ninput 5 numbers:\n"); for(i=0;i5;i++) scanf("%d",b[i]); printf("initial values of array b are:\n"); for(i=0;i5;i++) printf("%d ",b[i]); nzp(b,5); printf("\nlast values of array b are:\n"); for(i=0;i5;i++) printf("%d ",b[i]); return 0;}