函數(shù)的定義
函數(shù)的定義如下:
類型 函數(shù)名(形式參數(shù))
{
代碼塊
}
代碼塊包含了局部變量的聲明和函數(shù)調(diào)用所要執(zhí)行的語(yǔ)句。
return語(yǔ)句
return 語(yǔ)句的語(yǔ)法如下:
return expression;
??當(dāng)執(zhí)行流執(zhí)行到return語(yǔ)句時(shí)函數(shù)被返回到被調(diào)用的地方,return語(yǔ)句允許在任何地方返回,并不要一定在函數(shù)的末尾。
??表達(dá)式expression是可選的,如果函數(shù)不需要向調(diào)用程序返回一個(gè)值,就可以被省略,這種沒(méi)有返回值的函數(shù)可以在聲明的時(shí)候?qū)⑵浜瘮?shù)的類型置為void。
??真函數(shù)是從內(nèi)部表達(dá)式調(diào)用的,它必須返回一個(gè)值,用于表達(dá)式的求值,這類函數(shù)的return語(yǔ)句必須包含一個(gè)表達(dá)式,通常函數(shù)的類型就是表達(dá)式的類型。
只有當(dāng)編譯器可以通過(guò)通常的算數(shù)轉(zhuǎn)化把表達(dá)式的類型轉(zhuǎn)化為正確的類型時(shí),才允許返回值的類型與函數(shù)的類型不一致
函數(shù)的聲明
??如果沒(méi)有函數(shù)的聲明信息,編譯器便假定這個(gè)函數(shù)的調(diào)用時(shí)的參數(shù)類型和數(shù)量是正確的,它同時(shí)假定函數(shù)的返回值類型是整型。
原型
??向編譯器提供一些關(guān)于函數(shù)的信息顯然是很安全的,我們可以通過(guò)兩種方法來(lái)實(shí)現(xiàn):
- 如果同一源文件的前面已經(jīng)出現(xiàn)過(guò)該函數(shù)的定義,編譯器會(huì)記住它的參數(shù)數(shù)量和類型,以及函數(shù)的返回值類型。接著編譯器會(huì)檢查該函數(shù)的后續(xù)調(diào)用,確保它們是正確的。
- 向編譯器提供函數(shù)的原型,使用原型最安全的方法是把原型置于一個(gè)單獨(dú)的文件,當(dāng)其它文件需要原型時(shí),就使用#include指令包含改文件。
??原型的定義如下:
int *find_int(int key,int array[],int len);
??函數(shù)原型的使用如下:
#include "func.h"
void a()
{
func(&a,b);
}
文件func.h包含了函數(shù)func的聲明
int func(int *value,int len);
函數(shù)的原型同時(shí)也被#include包含到定義函數(shù)的文件中,編譯器就可以確認(rèn)函數(shù)的定義與函數(shù)的原型必須匹配。
??區(qū)分函數(shù)原型和函數(shù)定義的是后面那個(gè)分號(hào)(;)。
函數(shù)的缺省認(rèn)定
??當(dāng)函數(shù)調(diào)用一個(gè)無(wú)法見到原型的韓束時(shí),編譯器認(rèn)為該函數(shù)返回一個(gè)整型值。對(duì)于那些并不是返回值為整型值的函數(shù)調(diào)用,這可能引起錯(cuò)誤。
值的類型并不是值得內(nèi)在本質(zhì)(固有屬性),而是取決于它使用的方式。
函數(shù)的參數(shù)
兩個(gè)概念:
1.傳值調(diào)用:傳遞給被調(diào)用函數(shù)的是實(shí)參的一份拷貝,函數(shù)可以放心的修改這個(gè)拷貝值,而不用擔(dān)心會(huì)修改調(diào)用程序?qū)嶋H傳遞給它的參數(shù)。
2.傳址調(diào)用:傳遞給被調(diào)用函數(shù)的是指針的一份拷貝,假如傳遞的是數(shù)組名,并且在函數(shù)中使用下標(biāo)引用該數(shù)組的值,那么在函數(shù)中對(duì)數(shù)組元素的修改其實(shí)修改的是調(diào)用程序中的數(shù)組元素,數(shù)組并不會(huì)復(fù)制。
數(shù)組參數(shù)的這種行為似乎與傳值調(diào)用相悖,其實(shí)不然,數(shù)組名其實(shí)就是一個(gè)指針,傳遞函數(shù)的就是該指針的一份拷貝,下標(biāo)應(yīng)用也是間接訪問(wèn)的一種,所以這份拷貝進(jìn)行間接訪問(wèn)操作訪問(wèn)的是原先的數(shù)組。
總結(jié)
- 傳遞給函數(shù)的標(biāo)量都是傳值調(diào)用;
- 傳遞給函數(shù)的數(shù)組參數(shù)在行為上就像他們是通過(guò)傳址調(diào)用一樣。
可變參數(shù)列表
??讓一個(gè)函數(shù)在不同的時(shí)刻接受不同數(shù)目的參數(shù)。
stdarg宏
??可變參數(shù)列表是通過(guò)宏來(lái)實(shí)現(xiàn)的,這些宏位于stdarg.h,這個(gè)頭文件聲明了一個(gè)類型va_list和三個(gè)宏——va_start,va_arg,va_end。
??可變參數(shù)列表實(shí)現(xiàn)的步驟
- 用類型va_list聲明一個(gè)變量var_arg,它用于訪問(wèn)參數(shù)列表的未定部分;
- var_arg變量用va_start來(lái)初始化,它的第一個(gè)參數(shù)是va_list變量,第二個(gè)參數(shù)是省略號(hào)前最后一個(gè)有名字的參數(shù),初始化過(guò)程把var_arg變量設(shè)置為指向可變參數(shù)部分的第一個(gè)參數(shù);
- 用va_arg訪問(wèn)參數(shù),這個(gè)宏接受兩個(gè)參數(shù),va_list變量和參數(shù)列表中下一個(gè)參數(shù)的類型;
- 當(dāng)訪問(wèn)完參數(shù)后,調(diào)用va_end;
實(shí)例演示:求平均數(shù)
#include<stdarg.h>
float average(int n_values,...)
{
valist var_arg; //聲明va_list類型的變量
int count;
float sum = 0;
/*
*準(zhǔn)備訪問(wèn)可變參數(shù)
*/
va_start(var_arg,n_values);
/*
*添加自可變量列表
*/
for(count = 0;count < n_values;count++ )
{
sum += va_arg(var_arg,int);
}
va_end(var_arg);
return sum / n_values;
}