4.3 函數(shù)的調(diào)用與參數(shù)
如果一個(gè)函數(shù)要使用參數(shù),它就必須定義接受參數(shù)值的變量。
4.3.1 形式參數(shù)與實(shí)際參數(shù)
函數(shù)定義時(shí)填入的參數(shù)我們稱之為形式參數(shù),簡(jiǎn)稱形參,它們同函數(shù)內(nèi)部的局部變量作用相同。形參的定義是在函數(shù)名之后和函數(shù)開始的花括號(hào)之前。
調(diào)用時(shí)填入的參數(shù),我們稱之為實(shí)際參數(shù),簡(jiǎn)稱實(shí)參。
必須確認(rèn)所定義的形參與調(diào)用函數(shù)的實(shí)際參數(shù)類型一致,同時(shí)還要保證在調(diào)用時(shí)形參與實(shí)參的個(gè)數(shù)出現(xiàn)的次序也要一一對(duì)應(yīng)。如果不一致,將產(chǎn)生意料不到的結(jié)果。與許多其它高級(jí)語言不同,(是健壯的,它總要做一些甚至你不希望的事情,幾乎沒有運(yùn)行時(shí)錯(cuò)誤檢查,完全沒有范圍檢測(cè)。作為程序員,必須小心行事以保證不發(fā)生錯(cuò)誤,安全運(yùn)行。
4.3.2 賦值調(diào)用與引用調(diào)用
一般說來,有兩種方法可以把參數(shù)傳遞給函數(shù)。第一種叫做“賦值調(diào)用”(call by value),這種方法是把參數(shù)的值復(fù)制到函數(shù)的形式參數(shù)中。這樣,函數(shù)中的形式參數(shù)的任何變化不會(huì)影響到調(diào)用時(shí)所使用的變量。
把參數(shù)傳遞給函數(shù)的第二種方法是“引用調(diào)用”(call by reference)。這種方法是把參數(shù)的地址復(fù)制給形式參數(shù),在函數(shù)中,這個(gè)地址用來訪問調(diào)用中所使用的實(shí)際參數(shù)。這意味著,形式參數(shù)的變化會(huì)影響調(diào)用時(shí)所使用的那個(gè)變量(詳細(xì)內(nèi)容請(qǐng)參見后續(xù)章節(jié))。
除少數(shù)情況外,C語言使用賦值調(diào)用來傳遞參數(shù)。這意味著,一般不能改變調(diào)用時(shí)所用變量的值。請(qǐng)看例4 - 9。
[例4 - 9]
main ( )
{
int t =10;
printf("%d %d ",sqr(t),t); /* sqr(t)是函數(shù)調(diào)用,t是實(shí)參* /
}
int sqr(x) /* 函數(shù)定義,x是形式參數(shù)* /
int x;
{
x = x * x;
return (x);
}
在這個(gè)例子里,傳遞給函數(shù)sqr( )的參數(shù)值是復(fù)制給形式參數(shù)x的,當(dāng)賦值語句x = x * x執(zhí)行時(shí),僅修改局部變量x。用于調(diào)用sqr( )的變量t,仍然保持著值10。
執(zhí)行程序:
100 10
切記,傳給函數(shù)的只是參數(shù)值的復(fù)制品。所有發(fā)生在函數(shù)內(nèi)部的變化均無法影響調(diào)用時(shí)使用的變量。
4.4 遞歸
C語言函數(shù)可以自我調(diào)用。如果函數(shù)內(nèi)部一個(gè)語句調(diào)用了函數(shù)自己,則稱這個(gè)函數(shù)是“遞歸”。遞歸是以自身定義的過程。也可稱為“循環(huán)定義”。
遞歸的例子很多。例如定義整數(shù)的遞歸方法是用數(shù)字1,2,3,4,5,6,7,8,9加上或減去一個(gè)整數(shù)。例如,數(shù)字1 5是7 + 8;數(shù)字2 1是9 + 1 2; 數(shù)字1 2是9 + 3。
一種可遞歸的計(jì)算機(jī)語言,它的函數(shù)能夠自己調(diào)用自己。一個(gè)簡(jiǎn)單的例子就是計(jì)算整數(shù)階乘的函數(shù)factor( )數(shù)N的階乘是1到N之間所有數(shù)字的乘積。例如3的階乘是1×2×3,即是6。
factor( )和其等效函數(shù)fact( )如例4 - 1 0所示。
[例4 - 1 0 ]
factor(n) /* 遞歸調(diào)用方法* /
int n;
{
int answer;
if (n==1)
return (1);
answer=factor(n-1) * n; /* 函數(shù)自身調(diào)用* /
return(answer);
}
[例4 - 11 ]
fact(n) /* 非遞歸方法* /
int n;
{
int t,a n s w e r;
answer = 1;
for (t=1; t < = n; t ++)
answer = answer * t;
return(answer);
}
非遞歸函數(shù)fact( )的執(zhí)行應(yīng)該是易于理解的。它應(yīng)用一個(gè)從1開始到指定數(shù)值結(jié)束的循環(huán)。
在循環(huán)中,用“變化”的乘積依次去乘每個(gè)數(shù)。
factor( )的遞歸執(zhí)行比fact( )稍復(fù)雜。當(dāng)用參數(shù)1調(diào)用factor( )時(shí),函數(shù)返回1;除此之外的其它值調(diào)用將返回factor(n-1) * n這個(gè)乘積。為了求出這個(gè)表達(dá)式的值,用( n - 1)調(diào)用factor( )一直到n等于1,調(diào)用開始返回。
計(jì)算2的階乘時(shí)對(duì)factor( )的首次調(diào)用引起了以參數(shù)1對(duì)factor( )的第二次調(diào)用。這次調(diào)用返回1,然后被2乘(n的初始值),答案是2(把printf( )語句插入到factor ( )中,察看各級(jí)調(diào)用及其中間答案,是很有趣的)。
如果一個(gè)函數(shù)要使用參數(shù),它就必須定義接受參數(shù)值的變量。
4.3.1 形式參數(shù)與實(shí)際參數(shù)
函數(shù)定義時(shí)填入的參數(shù)我們稱之為形式參數(shù),簡(jiǎn)稱形參,它們同函數(shù)內(nèi)部的局部變量作用相同。形參的定義是在函數(shù)名之后和函數(shù)開始的花括號(hào)之前。
調(diào)用時(shí)填入的參數(shù),我們稱之為實(shí)際參數(shù),簡(jiǎn)稱實(shí)參。
必須確認(rèn)所定義的形參與調(diào)用函數(shù)的實(shí)際參數(shù)類型一致,同時(shí)還要保證在調(diào)用時(shí)形參與實(shí)參的個(gè)數(shù)出現(xiàn)的次序也要一一對(duì)應(yīng)。如果不一致,將產(chǎn)生意料不到的結(jié)果。與許多其它高級(jí)語言不同,(是健壯的,它總要做一些甚至你不希望的事情,幾乎沒有運(yùn)行時(shí)錯(cuò)誤檢查,完全沒有范圍檢測(cè)。作為程序員,必須小心行事以保證不發(fā)生錯(cuò)誤,安全運(yùn)行。
4.3.2 賦值調(diào)用與引用調(diào)用
一般說來,有兩種方法可以把參數(shù)傳遞給函數(shù)。第一種叫做“賦值調(diào)用”(call by value),這種方法是把參數(shù)的值復(fù)制到函數(shù)的形式參數(shù)中。這樣,函數(shù)中的形式參數(shù)的任何變化不會(huì)影響到調(diào)用時(shí)所使用的變量。
把參數(shù)傳遞給函數(shù)的第二種方法是“引用調(diào)用”(call by reference)。這種方法是把參數(shù)的地址復(fù)制給形式參數(shù),在函數(shù)中,這個(gè)地址用來訪問調(diào)用中所使用的實(shí)際參數(shù)。這意味著,形式參數(shù)的變化會(huì)影響調(diào)用時(shí)所使用的那個(gè)變量(詳細(xì)內(nèi)容請(qǐng)參見后續(xù)章節(jié))。
除少數(shù)情況外,C語言使用賦值調(diào)用來傳遞參數(shù)。這意味著,一般不能改變調(diào)用時(shí)所用變量的值。請(qǐng)看例4 - 9。
[例4 - 9]
main ( )
{
int t =10;
printf("%d %d ",sqr(t),t); /* sqr(t)是函數(shù)調(diào)用,t是實(shí)參* /
}
int sqr(x) /* 函數(shù)定義,x是形式參數(shù)* /
int x;
{
x = x * x;
return (x);
}
在這個(gè)例子里,傳遞給函數(shù)sqr( )的參數(shù)值是復(fù)制給形式參數(shù)x的,當(dāng)賦值語句x = x * x執(zhí)行時(shí),僅修改局部變量x。用于調(diào)用sqr( )的變量t,仍然保持著值10。
執(zhí)行程序:
100 10
切記,傳給函數(shù)的只是參數(shù)值的復(fù)制品。所有發(fā)生在函數(shù)內(nèi)部的變化均無法影響調(diào)用時(shí)使用的變量。
4.4 遞歸
C語言函數(shù)可以自我調(diào)用。如果函數(shù)內(nèi)部一個(gè)語句調(diào)用了函數(shù)自己,則稱這個(gè)函數(shù)是“遞歸”。遞歸是以自身定義的過程。也可稱為“循環(huán)定義”。
遞歸的例子很多。例如定義整數(shù)的遞歸方法是用數(shù)字1,2,3,4,5,6,7,8,9加上或減去一個(gè)整數(shù)。例如,數(shù)字1 5是7 + 8;數(shù)字2 1是9 + 1 2; 數(shù)字1 2是9 + 3。
一種可遞歸的計(jì)算機(jī)語言,它的函數(shù)能夠自己調(diào)用自己。一個(gè)簡(jiǎn)單的例子就是計(jì)算整數(shù)階乘的函數(shù)factor( )數(shù)N的階乘是1到N之間所有數(shù)字的乘積。例如3的階乘是1×2×3,即是6。
factor( )和其等效函數(shù)fact( )如例4 - 1 0所示。
[例4 - 1 0 ]
factor(n) /* 遞歸調(diào)用方法* /
int n;
{
int answer;
if (n==1)
return (1);
answer=factor(n-1) * n; /* 函數(shù)自身調(diào)用* /
return(answer);
}
[例4 - 11 ]
fact(n) /* 非遞歸方法* /
int n;
{
int t,a n s w e r;
answer = 1;
for (t=1; t < = n; t ++)
answer = answer * t;
return(answer);
}
非遞歸函數(shù)fact( )的執(zhí)行應(yīng)該是易于理解的。它應(yīng)用一個(gè)從1開始到指定數(shù)值結(jié)束的循環(huán)。
在循環(huán)中,用“變化”的乘積依次去乘每個(gè)數(shù)。
factor( )的遞歸執(zhí)行比fact( )稍復(fù)雜。當(dāng)用參數(shù)1調(diào)用factor( )時(shí),函數(shù)返回1;除此之外的其它值調(diào)用將返回factor(n-1) * n這個(gè)乘積。為了求出這個(gè)表達(dá)式的值,用( n - 1)調(diào)用factor( )一直到n等于1,調(diào)用開始返回。
計(jì)算2的階乘時(shí)對(duì)factor( )的首次調(diào)用引起了以參數(shù)1對(duì)factor( )的第二次調(diào)用。這次調(diào)用返回1,然后被2乘(n的初始值),答案是2(把printf( )語句插入到factor ( )中,察看各級(jí)調(diào)用及其中間答案,是很有趣的)。