4.1 函數(shù)說(shuō)明與返回值
當(dāng)一個(gè)函數(shù)沒(méi)有明確說(shuō)明類型時(shí), C語(yǔ)言的編譯程序自動(dòng)將整型( i n t)作為這個(gè)函數(shù)的缺省類型,缺省類型適用于很大一部分函數(shù)。當(dāng)有必要返回其它類型數(shù)據(jù)時(shí),需要分兩步處理:
首先,必須給函數(shù)以明確的類型說(shuō)明符;
其次,函數(shù)類型的說(shuō)明必須處于對(duì)它的首次調(diào)用之前。只有這樣,C編譯程序才能為返回非整型的值的函數(shù)生成正確代碼。
4.1.1 函數(shù)的類型說(shuō)明
可將函數(shù)說(shuō)明為返回任何一種合法的C語(yǔ)言數(shù)據(jù)類型。
類型說(shuō)明符告訴編譯程序它返回什么類型的數(shù)據(jù)。這個(gè)信息對(duì)于程序能否正確運(yùn)行關(guān)系極大,因?yàn)椴煌臄?shù)據(jù)有不同的長(zhǎng)度和內(nèi)部表示。
返回非整型數(shù)據(jù)的函數(shù)被使用之前,必須把它的類型向程序的其余部分說(shuō)明。若不這樣做,C語(yǔ)言的編譯程序就認(rèn)為函數(shù)是返回整型數(shù)據(jù)的函數(shù),調(diào)用點(diǎn)又在函數(shù)類型說(shuō)明之前,編譯程序就會(huì)對(duì)調(diào)用生成錯(cuò)誤代碼。為了防止上述問(wèn)題的出現(xiàn),必須使用一個(gè)特別的說(shuō)明語(yǔ)句。
[例4 - 1 ]
float sum( ); / *函數(shù)說(shuō)明* /
main( )
{
float first,s e c o n d ;
first =123.23;
second = 99.09;
printf ("%f",sum (first,s e c o n d ) );
}
float sum (a,b ) / * 函數(shù)定義* /
float a,b;
{
return a+b;
}
第一個(gè)函數(shù)的類型說(shuō)明sum( )函數(shù)返回浮點(diǎn)類型的數(shù)據(jù)。這個(gè)說(shuō)明使編譯程序能夠?qū)um( )的調(diào)用產(chǎn)生正確代碼。
函數(shù)類型說(shuō)明語(yǔ)句的一般形式是:
type_specifier function_name ( ) ;
即使函數(shù)使用形參,也不要將其寫入說(shuō)明句。若未使用類型說(shuō)明語(yǔ)句,函數(shù)返回的數(shù)據(jù)類型可能與調(diào)用者所要求的不一致,其結(jié)果是難以預(yù)料的。如果兩者同處于一個(gè)文件中,編譯程序可以發(fā)現(xiàn)該錯(cuò)誤并停止編譯。如果不在同一個(gè)文件中,編譯程序無(wú)法發(fā)現(xiàn)這種錯(cuò)誤。類型檢查僅在編譯中進(jìn)行,鏈接和運(yùn)行時(shí)均不檢查。因此,必須十分細(xì)心以確保絕不發(fā)生上述錯(cuò)誤。當(dāng)被說(shuō)明為整型的函數(shù)返回字符時(shí),這個(gè)字符值被轉(zhuǎn)換為整數(shù)。因?yàn)镃語(yǔ)言以不加說(shuō)明的方式進(jìn)行字符型與整型之間的數(shù)據(jù)轉(zhuǎn)換,因而多數(shù)情況下,返回字符值的函數(shù)并不是說(shuō)明為返回字符值,而是由函數(shù)的這種字符型向整型的缺省類型轉(zhuǎn)換隱含實(shí)現(xiàn)的。
4.1.2 返回語(yǔ)句
返回語(yǔ)句return有兩個(gè)重要用途。第一,它使得內(nèi)含它的那個(gè)函數(shù)立即退出,也就是使程序返回到調(diào)用語(yǔ)句處繼續(xù)進(jìn)行。第二,它可以用來(lái)回送一個(gè)數(shù)值。本章將說(shuō)明這兩個(gè)用途。
1. 從函數(shù)返回
函數(shù)可以用兩種方法停止運(yùn)行并返回到調(diào)用程序。第一種是在執(zhí)行完函數(shù)的最后一個(gè)語(yǔ)句之后,從概念上講,是遇到了函數(shù)的結(jié)束符“ }”(當(dāng)然這個(gè)花括號(hào)實(shí)際上并不會(huì)出現(xiàn)在目標(biāo)碼中,但我們可以這樣理解)。例如,下面的函數(shù)在屏幕上顯示一個(gè)字符串。
[例4 - 2 ]
pr_reverse ()
{
char s[80]; / *定義一個(gè)字符數(shù)組* /
scanf("%s",s); / *輸入一個(gè)字符串,其長(zhǎng)度不超過(guò)7 9個(gè)字符* /
printf("%s\n",s);
}
一旦字串顯示完畢,函數(shù)就沒(méi)事可做了,這時(shí)它返回到被調(diào)用處。
在實(shí)際情況中,沒(méi)有多少函數(shù)是以這種缺省方式終止運(yùn)行的。因?yàn)橛袝r(shí)必須送回一個(gè)值,大多數(shù)函數(shù)用return語(yǔ)句終止運(yùn)行,有時(shí)在函數(shù)中設(shè)立了多個(gè)終止點(diǎn)以簡(jiǎn)化函數(shù)、提高效率。切記,一個(gè)函數(shù)可以有多個(gè)返回語(yǔ)句。如下所示,函數(shù)在s1、s2相等時(shí)返回1,不相等時(shí)返回- 1。
[例4 - 3 ]
find_char(s1,s2)
char s1,s2;
{
if(s1 == s2)
return 1;
else
return -1;
}
2. 返回值
所有的函數(shù),除了空值類型外,都返回一個(gè)數(shù)值(切記,空值是A N S I建議標(biāo)準(zhǔn)所做的擴(kuò)展,也許并不適合讀者手頭的C編譯程序)。該數(shù)值由返回語(yǔ)句確定。無(wú)返回語(yǔ)句時(shí),返回值是0。這就意味著,只要函數(shù)沒(méi)有被說(shuō)明為空值,它就可以用在任何有效的C語(yǔ)言表達(dá)式中作為操作數(shù)。這樣下面的表達(dá)式都是合法的C語(yǔ)言表達(dá)式。
x = power(y);
if(max (x,y) >100) printf("greater");
當(dāng)一個(gè)函數(shù)沒(méi)有明確說(shuō)明類型時(shí), C語(yǔ)言的編譯程序自動(dòng)將整型( i n t)作為這個(gè)函數(shù)的缺省類型,缺省類型適用于很大一部分函數(shù)。當(dāng)有必要返回其它類型數(shù)據(jù)時(shí),需要分兩步處理:
首先,必須給函數(shù)以明確的類型說(shuō)明符;
其次,函數(shù)類型的說(shuō)明必須處于對(duì)它的首次調(diào)用之前。只有這樣,C編譯程序才能為返回非整型的值的函數(shù)生成正確代碼。
4.1.1 函數(shù)的類型說(shuō)明
可將函數(shù)說(shuō)明為返回任何一種合法的C語(yǔ)言數(shù)據(jù)類型。
類型說(shuō)明符告訴編譯程序它返回什么類型的數(shù)據(jù)。這個(gè)信息對(duì)于程序能否正確運(yùn)行關(guān)系極大,因?yàn)椴煌臄?shù)據(jù)有不同的長(zhǎng)度和內(nèi)部表示。
返回非整型數(shù)據(jù)的函數(shù)被使用之前,必須把它的類型向程序的其余部分說(shuō)明。若不這樣做,C語(yǔ)言的編譯程序就認(rèn)為函數(shù)是返回整型數(shù)據(jù)的函數(shù),調(diào)用點(diǎn)又在函數(shù)類型說(shuō)明之前,編譯程序就會(huì)對(duì)調(diào)用生成錯(cuò)誤代碼。為了防止上述問(wèn)題的出現(xiàn),必須使用一個(gè)特別的說(shuō)明語(yǔ)句。
[例4 - 1 ]
float sum( ); / *函數(shù)說(shuō)明* /
main( )
{
float first,s e c o n d ;
first =123.23;
second = 99.09;
printf ("%f",sum (first,s e c o n d ) );
}
float sum (a,b ) / * 函數(shù)定義* /
float a,b;
{
return a+b;
}
第一個(gè)函數(shù)的類型說(shuō)明sum( )函數(shù)返回浮點(diǎn)類型的數(shù)據(jù)。這個(gè)說(shuō)明使編譯程序能夠?qū)um( )的調(diào)用產(chǎn)生正確代碼。
函數(shù)類型說(shuō)明語(yǔ)句的一般形式是:
type_specifier function_name ( ) ;
即使函數(shù)使用形參,也不要將其寫入說(shuō)明句。若未使用類型說(shuō)明語(yǔ)句,函數(shù)返回的數(shù)據(jù)類型可能與調(diào)用者所要求的不一致,其結(jié)果是難以預(yù)料的。如果兩者同處于一個(gè)文件中,編譯程序可以發(fā)現(xiàn)該錯(cuò)誤并停止編譯。如果不在同一個(gè)文件中,編譯程序無(wú)法發(fā)現(xiàn)這種錯(cuò)誤。類型檢查僅在編譯中進(jìn)行,鏈接和運(yùn)行時(shí)均不檢查。因此,必須十分細(xì)心以確保絕不發(fā)生上述錯(cuò)誤。當(dāng)被說(shuō)明為整型的函數(shù)返回字符時(shí),這個(gè)字符值被轉(zhuǎn)換為整數(shù)。因?yàn)镃語(yǔ)言以不加說(shuō)明的方式進(jìn)行字符型與整型之間的數(shù)據(jù)轉(zhuǎn)換,因而多數(shù)情況下,返回字符值的函數(shù)并不是說(shuō)明為返回字符值,而是由函數(shù)的這種字符型向整型的缺省類型轉(zhuǎn)換隱含實(shí)現(xiàn)的。
4.1.2 返回語(yǔ)句
返回語(yǔ)句return有兩個(gè)重要用途。第一,它使得內(nèi)含它的那個(gè)函數(shù)立即退出,也就是使程序返回到調(diào)用語(yǔ)句處繼續(xù)進(jìn)行。第二,它可以用來(lái)回送一個(gè)數(shù)值。本章將說(shuō)明這兩個(gè)用途。
1. 從函數(shù)返回
函數(shù)可以用兩種方法停止運(yùn)行并返回到調(diào)用程序。第一種是在執(zhí)行完函數(shù)的最后一個(gè)語(yǔ)句之后,從概念上講,是遇到了函數(shù)的結(jié)束符“ }”(當(dāng)然這個(gè)花括號(hào)實(shí)際上并不會(huì)出現(xiàn)在目標(biāo)碼中,但我們可以這樣理解)。例如,下面的函數(shù)在屏幕上顯示一個(gè)字符串。
[例4 - 2 ]
pr_reverse ()
{
char s[80]; / *定義一個(gè)字符數(shù)組* /
scanf("%s",s); / *輸入一個(gè)字符串,其長(zhǎng)度不超過(guò)7 9個(gè)字符* /
printf("%s\n",s);
}
一旦字串顯示完畢,函數(shù)就沒(méi)事可做了,這時(shí)它返回到被調(diào)用處。
在實(shí)際情況中,沒(méi)有多少函數(shù)是以這種缺省方式終止運(yùn)行的。因?yàn)橛袝r(shí)必須送回一個(gè)值,大多數(shù)函數(shù)用return語(yǔ)句終止運(yùn)行,有時(shí)在函數(shù)中設(shè)立了多個(gè)終止點(diǎn)以簡(jiǎn)化函數(shù)、提高效率。切記,一個(gè)函數(shù)可以有多個(gè)返回語(yǔ)句。如下所示,函數(shù)在s1、s2相等時(shí)返回1,不相等時(shí)返回- 1。
[例4 - 3 ]
find_char(s1,s2)
char s1,s2;
{
if(s1 == s2)
return 1;
else
return -1;
}
2. 返回值
所有的函數(shù),除了空值類型外,都返回一個(gè)數(shù)值(切記,空值是A N S I建議標(biāo)準(zhǔn)所做的擴(kuò)展,也許并不適合讀者手頭的C編譯程序)。該數(shù)值由返回語(yǔ)句確定。無(wú)返回語(yǔ)句時(shí),返回值是0。這就意味著,只要函數(shù)沒(méi)有被說(shuō)明為空值,它就可以用在任何有效的C語(yǔ)言表達(dá)式中作為操作數(shù)。這樣下面的表達(dá)式都是合法的C語(yǔ)言表達(dá)式。
x = power(y);
if(max (x,y) >100) printf("greater");