C++函數(shù)的嵌套調(diào)用和遞歸調(diào)用學(xué)習(xí)教程
C++函數(shù)的嵌套調(diào)用
C++不允許對(duì)函數(shù)作嵌套定義,也就是說(shuō)在一個(gè)函數(shù)中不能完整地包含另一個(gè)函數(shù)。在一個(gè)程序中每一個(gè)函數(shù)的定義都是互相平行和獨(dú)立的。
雖然C++不能嵌套定義函數(shù),但可以嵌套調(diào)用函數(shù),也就是說(shuō),在調(diào)用一個(gè)函數(shù)的過(guò)程中,又調(diào)用另一個(gè)函數(shù)。
在程序中實(shí)現(xiàn)函數(shù)嵌套調(diào)用時(shí),需要注意的是:在調(diào)用函數(shù)之前,需要對(duì)每一個(gè)被調(diào)用的函數(shù)作聲明(除非定義在前,調(diào)用在后)。
【例】用弦截法求方程f(x)=x3-5x2+16x-80=0的根。
這是一個(gè)數(shù)值求解問題,需要先分析用弦截法求根的算法。根據(jù)數(shù)學(xué)知識(shí),可以列出以下的解題步驟:
1) 取兩個(gè)不同點(diǎn)x1,x2,如果f(x1)和f(x2)符號(hào)相反,則(x1,x2)區(qū)間內(nèi)必有一個(gè)根。如果f(x1)與f(x2)同符號(hào),則應(yīng)改變x1,x2,直到f(x1), f(x2)異號(hào)為止。注意x1?x2的值不應(yīng)差太大,以保證(x1,x2)區(qū)間內(nèi)只有一個(gè)根。
2) 連接(x1, f(x1))和(x2, f(x2))兩點(diǎn),此線(即弦)交x軸于x,見圖。
x點(diǎn)坐標(biāo)可用下式求出:
再?gòu)膞求出f(x)。
3) 若f(x)與f(x1)同符號(hào),則根必在(x, x2)區(qū)間內(nèi),此時(shí)將x作為新的x1。如果f(x)與f(x2)同符號(hào),則表示根在( x1,x)區(qū)間內(nèi),將x作為新的x2。
4) 重復(fù)步驟 (2) 和 (3), 直到 |f(x)|<ξ為止, ξ為一個(gè)很小的正數(shù), 例如10-6。此時(shí)認(rèn)為 f(x)≈0。
這就是弦截法的算法,在程序中分別用以下幾個(gè)函數(shù)來(lái)實(shí)現(xiàn)以上有關(guān)部分功能:
1) 用函數(shù)f(x)代表x的函數(shù):x3-5x2+16x-80。
2) 用函數(shù)xpoint (x1,x2)來(lái)求(x1,f(x1))和(x2,f(x2))的連線與x軸的交點(diǎn)x的坐標(biāo)。
3) 用函數(shù)root(x1,x2)來(lái)求(x1,x2)區(qū)間的那個(gè)實(shí)根。顯然,執(zhí)行root函數(shù)的過(guò)程中要用到xpoint函數(shù),而執(zhí)行xpoint函數(shù)的過(guò)程中要用到f函數(shù)。
根據(jù)以上算法,可以編寫出下面的程序:
#include <iostream>
#include <iomanip>
#include <cmath>
using namespace std;
double f(double); //函數(shù)聲明
double xpoint(double, double); //函數(shù)聲明
double root(double, double); //函數(shù)聲明
int main( )
{
double x1,x2,f1,f2,x;
do
{
cout<<"input x1,x2:";
cin>>x1>>x2;
f1=f(x1);
f2=f(x2);
} while(f1*f2>=0);
x=root(x1,x2);
cout<<setiosflags(ios::fixed)<<setprecision(7);
//指定輸出7位小數(shù)
cout<<"A root of equation is "<<x<<endl;
return 0;
}
double f(double x) //定義f函數(shù),以實(shí)現(xiàn)f(x)
{
double y;
y=x*x*x-5*x*x+16*x-80;
return y;
}
double xpoint(double x1, double x2) //定義xpoint函數(shù),求出弦與x軸交點(diǎn)
{
double y;
y=(x1*f(x2)-x2*f(x1))/(f(x2)-f(x1)); //在xpoint函數(shù)中調(diào)用f函數(shù)
return y;
}
double root(double x1, double x2) //定義root函數(shù),求近似根
{
double x,y,y1;
y1=f(x1);
do
{
x=xpoint(x1,x2); //在root函數(shù)中調(diào)用xpoint函數(shù)
y=f(x); //在root函數(shù)中調(diào)用f函數(shù)
if (y*y1>0)
{
y1=y;
x1=x;
}
else
x2=x;
}while(fabs(y)>=0.00001);
return x;
}
運(yùn)行情況如下:
input x1, x2:2.5 6.7↙ A root of equation is 5.0000000
對(duì)程序的說(shuō)明:
1) 在定義函數(shù)時(shí),函數(shù)名為f,xpoint和root的3個(gè)函數(shù)是互相獨(dú)立的,并不互相從屬。這3個(gè)函數(shù)均定為雙精度型。
2) 3個(gè)函數(shù)的定義均出現(xiàn)在main函數(shù)之后,因此在main函數(shù)的前面對(duì)這3個(gè)函數(shù)作聲明。
習(xí)慣上把本程序中用到的所有函數(shù)集中放在最前面聲明。
3) 程序從main函數(shù)開始執(zhí)行。
4) 在root函數(shù)中要用到求絕對(duì)值的函數(shù)fabs,它是對(duì)雙精度數(shù)求絕對(duì)值的系統(tǒng)函數(shù)。它屬于數(shù)學(xué)函數(shù)庫(kù),故在文件開頭用#include <cmath>把有關(guān)的頭文件包含進(jìn)來(lái)。
C++函數(shù)的遞歸調(diào)用
在調(diào)用一個(gè)函數(shù)的過(guò)程中又出現(xiàn)直接或間接地調(diào)用該函數(shù)本身,稱為函數(shù)的遞歸(recursive)調(diào)用。C++允許函數(shù)的遞歸調(diào)用。例如:
int f(int x)
{
int y, z;
z=f(y); //在調(diào)用函數(shù)f的過(guò)程中,又要調(diào)用f函數(shù)
return (2*z);
}
以上是直接調(diào)用本函數(shù),見下面的圖。
下圖表示的是間接調(diào)用本函數(shù)。在調(diào)用f1函數(shù)過(guò)程中要調(diào)用f2函數(shù),而在調(diào)用f2函數(shù)過(guò)程中又要調(diào)用f1函數(shù)。
從圖上可以看到,這兩種遞歸調(diào)用都是無(wú)終止的自身調(diào)用。顯然,程序中不應(yīng)出現(xiàn)這種無(wú)終止的遞歸調(diào)用,而只應(yīng)出現(xiàn)有限次數(shù)的、有終止的遞歸調(diào)用,這可以用if語(yǔ)句來(lái)控制,只有在某一條件成立時(shí)才繼續(xù)執(zhí)行遞歸調(diào)用,否則就不再繼續(xù)。
包含遞歸調(diào)用的函數(shù)稱為遞歸函數(shù)。
【例】有5個(gè)人坐在一起,問第5個(gè)人多少歲?他說(shuō)比第4個(gè)人大兩歲。問第4個(gè)人歲數(shù),他說(shuō)比第3個(gè)人大兩歲。問第3個(gè)人,又說(shuō)比第2個(gè)人大兩歲。問第2個(gè)人,說(shuō)比第1個(gè)人大兩歲。最后問第1個(gè)人,他說(shuō)是10歲。請(qǐng)問第5個(gè)人多大?
每一個(gè)人的年齡都比其前1個(gè)人的年齡大兩歲。即:
age(5)=age(4)+2 age(4)=age(3)+2 age(3)=age(2)+2 age(2)=age(1)+2 age(1)=10
可以用式子表述如下:
age(n)=10 (n=1) age(n)=age(n-1)+2 (n>1)
可以看到,當(dāng)n>1時(shí),求第n個(gè)人的年齡的公式是相同的。因此可以用一個(gè)函數(shù)表示上述關(guān)系。圖4.11表示求第5個(gè)人年齡的過(guò)程。
可以寫出以下C++程序,其中的age函數(shù)用來(lái)實(shí)現(xiàn)上述遞歸過(guò)程。
#include <iostream>
using namespace std;
int age(int);//函數(shù)聲明
int main( )//主函數(shù)
{
cout<<age(5)<<endl;
return 0;
}
int age(int n)//求年齡的遞歸函數(shù)
{
int c; //用c作為存放年齡的變量
if(n==1) c=10; //當(dāng)n=1時(shí),年齡為10
else c=age(n-1)+2; //當(dāng)n>1時(shí),此人年齡是他前一個(gè)人的年齡加2
return c; //將年齡值帶回主函數(shù)
}
運(yùn)行結(jié)果如下:
18
【例】用遞歸方法求n!。
求n!可以用遞推方法,即從1開始,乘2,再乘3……一直乘到n。求n!也可以用遞歸方法,即5!=4!×5,而4!=3!×4,…,1!=1??捎孟旅娴倪f歸公式表示:
n! = 1 (n=0, 1) n * (n-1)! (n>1)
有了例4.10的基礎(chǔ),很容易寫出本題的程序:
#include <iostream>
using namespace std;
long fac(int);//函數(shù)聲明
int main( )
{
int n;//n為需要求階乘的整數(shù)
long y; //y為存放n!的變量
cout<<"please input an integer :"; //輸入的提示
cin>>n; //輸入n
y=fac(n);//調(diào)用fac函數(shù)以求n!
cout<<n<<"!="<<y<<endl; //輸出n!的值
return 0;
}
long fac(int n) //遞歸函數(shù)
{
long f;
if(n<0)
{
cout<<"n<0,data error!"<<endl; //如果輸入負(fù)數(shù),報(bào)錯(cuò)并以-1作為返回值
f=-1;
}
else if (n==0||n==1) f=1; //0!和1!的值為1
else f=fac(n-1)*n;//n>1時(shí),進(jìn)行遞歸調(diào)用
return f;//將f的值作為函數(shù)值返回
}
運(yùn)行情況如下:
please input an integer:10↙ 10!=3628800
許多問題既可以用遞歸方法來(lái)處理,也可以用非遞歸方法來(lái)處理。在實(shí)現(xiàn)遞歸時(shí),在時(shí)間和空間上的開銷比較大,但符合人們的思路,程序容易理解。
欄 目:C語(yǔ)言
下一篇:簡(jiǎn)單舉例說(shuō)明C++中break和continue語(yǔ)句的用法
本文標(biāo)題:C++函數(shù)的嵌套調(diào)用和遞歸調(diào)用學(xué)習(xí)教程
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/2736.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)”問題方法
- 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ī)閱讀
- 01-10C#中split用法實(shí)例總結(jié)
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-10delphi制作wav文件的方法
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 04-02jquery與jsp,用jquery
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改


