c語(yǔ)言 深入理解函數(shù)的遞歸
前言:
?首先,遞歸是什么,遞歸就是在定義函數(shù)時(shí),然后在函數(shù)里調(diào)用這個(gè)函數(shù),通俗講,就是函數(shù)自己調(diào)用自己。那么遞歸的好處是什么呢?它能夠?qū)?fù)雜的問(wèn)題,用少量的代碼來(lái)表示,增加了代碼的可讀性。
但是遞歸有一個(gè)條件,就是每一次的重復(fù)調(diào)用都需要越接近這個(gè)限制條件。
1.用遞歸打印一個(gè)整數(shù)的每一位
題目的要求是打印一個(gè)整數(shù)的每一位,就比如說(shuō)1234,打印的結(jié)果就是1234,我們學(xué)過(guò)用循環(huán)打印過(guò)4321,但順著打印,用循環(huán)來(lái)做,相對(duì)于遞歸來(lái)解,就會(huì)有點(diǎn)復(fù)雜。
#include<stdio.h>//打印一個(gè)整數(shù)的每一位,用遞歸
print(int n)
{
int i = 0;
if(n>9)
{
print(n / 10);
}
printf("%d", n%10);
}
int main()
{
int num = 0;
printf("請(qǐng)輸入一個(gè)整數(shù):");
scanf("%d",&num);
print(num);
return 0;
}
這道題就是利用了遞歸的思想,此時(shí)的遞歸函數(shù)就是print函數(shù)。
首先是遞歸中的“遞”
當(dāng)我們?cè)趕canf函數(shù)中輸入一個(gè)整數(shù)1234時(shí),第一次進(jìn)入print函數(shù)里,通過(guò)if語(yǔ)句再次進(jìn)入print函數(shù)里,注意這時(shí)還未進(jìn)行printf打印出結(jié)果。
這就到了第二次進(jìn)入print函數(shù)里,此時(shí)進(jìn)入函數(shù)的數(shù)子不在時(shí)?1234,而是除以十后的123,進(jìn)入print函數(shù)后,再次通過(guò)if語(yǔ)句,進(jìn)入print函數(shù),注意這時(shí)也還未進(jìn)行printf打印出結(jié)果。
第三次進(jìn)入print函數(shù)里,是除以十后的12,12依然大于9,所以再次通過(guò)if語(yǔ)句,進(jìn)入print函數(shù),這時(shí)進(jìn)入print函數(shù)的是除以十后的1.注意這時(shí)也還未進(jìn)行printf打印出結(jié)果
第四次調(diào)用print函數(shù)時(shí),此時(shí)的n就是1,顯然不滿足大于9的條件。這時(shí)的1余以十的結(jié)果還是1,于是首先打印出1。
然后就是遞歸中的“歸”
打印完1后,第四次進(jìn)入循環(huán)的過(guò)程就結(jié)束了,此時(shí),接著歸回上一次的循環(huán),我們知道上次的循環(huán)到進(jìn)入if語(yǔ)句后,就沒(méi)有再次往下進(jìn)行,歸時(shí)就接著上次的操作,往下進(jìn)行運(yùn)行,就打印12余十的結(jié)果2,同理,就打印出最終的1234.
2.遞歸求n的階乘
你是否還記得上次求n的階乘還是說(shuō)在上次。這次用遞歸來(lái)求解n的階乘,實(shí)際上也是非常的簡(jiǎn)單,先寫出不用遞歸來(lái)求n的循環(huán)。
#include<stdio.h>//求n的階乘
int main()
{
int num = 0; int i = 0; int ret = 1;
printf("請(qǐng)輸入一個(gè)值:");
scanf("%d",&num);
for (i = 2; i <=num; i++)
{
ret *= i;
}
printf("%d", ret);
return 0;
}
然后就是遞歸求n的階乘:
#include<stdio.h>//求n的階乘
int fac(int n)
{
if (n > 1)
return n * fac(n - 1);
else
return 1;
}
int main()
{
int ret = 0;
int num = 0;
printf("請(qǐng)輸入n的值:");
scanf("%d", &num);
ret=fac(num);
printf("%d", ret);
return 0;
}
這時(shí)的n就是輸入的值,fac(n-1)就重復(fù)調(diào)用此函數(shù),又可以無(wú)限接近這個(gè)n大于1的這個(gè)條件。這就用到了遞歸的思想。我們知道求n的階乘,也可以表示成n乘以(n-1)的階乘。以此重復(fù),n-1等于1時(shí)就停止。就達(dá)到求n的階乘的目的~~
3.用遞歸和非遞歸求字符串的長(zhǎng)度
求字符串的長(zhǎng)度,不就是strlen函數(shù)嗎?
但是,不用這個(gè)庫(kù)函數(shù)呢
我們依然可以用兩種方法進(jìn)行求解。
首先用非遞歸來(lái)求字符串的長(zhǎng)度,也就是用我們自己的my_strlen函數(shù)。
#include<stdio.h>//用非遞歸求字符串的長(zhǎng)度
my_strlen(char *arr)
{
int a = 0; int ret = 0;
char c = *(arr+a);
while(arr[a] != '\0')
{
a++;
ret++;
}
return ret;
}
int main()
{
int ret = 0;
char arr[] = "abc";
ret=my_strlen(arr);
printf("%d", ret);
return 0;
}
遞歸如下:
#include<stdio.h>
my_strlen(char* arr)
{
int i = 0;
if (*arr == '\0')
return 0;
if (*arr != '\0')
return 1 + my_strlen(arr + 1);
}
int main()
{
int ret = 0;
char arr[] = "abc";
ret = my_strlen(arr);
printf("%d", ret);
return 0;
}
這道題的思路就是一個(gè)一個(gè)字符來(lái)數(shù),知道\0來(lái)結(jié)束此程序,我們知道“abc”是由abc\0四個(gè)字符組成,而遞歸的思路就是先數(shù)出a這個(gè)字符然后再數(shù)b,直到\0結(jié)束。
4.輸入一個(gè)數(shù)求各位數(shù)之和
這題的意思就是求出一個(gè)整數(shù)個(gè)十百千位之和,比如1234結(jié)果為10;
#include<stdio.h>//輸入一個(gè)數(shù)求各位數(shù)之和
sum(int x)
{
int ret = 0;
if (x > 9)
{
return x % 10 + sum(x / 10);
}
else
return x;
}
int main()
{
int num = 0;
printf("請(qǐng)輸入一個(gè)數(shù)之和:");
scanf("%d", &num);
printf("%d",sum(num));
return 0;
}
5.用遞歸求n的k次方
#include<stdio.h>//用遞歸求n的k次方
tmp(int x,int y)
{
if (y <= 0)
{
return 1;
}
else
return x * tmp(x, y - 1);
}
int main()
{
int k = 0; int n = 0;
printf("請(qǐng)輸入一個(gè)n和k:");
scanf("%d %d",&n, &k);
int ret=tmp(n,k);
printf("%d", ret);
return 0;
}
6.計(jì)算斐波那契數(shù)
#include<stdio.h>//計(jì)算斐波那契數(shù)
feibona(int n)
{
if (n >= 3)
return feibona(n - 1) + feibona(n - 2);
else 1;
}
int main()
{
int n = 0;
printf("請(qǐng)輸入一個(gè)n:");
scanf("%d", &n);
int ret=feibona(n);
printf("%d", ret);
return 0;
}
斐波那契數(shù)就是1 1 2 3 5 8 13……前兩個(gè)數(shù)之和得到第三個(gè)數(shù)
這里給出不用遞歸的求解:
#include<stdio.h>//用非遞歸求斐波那契數(shù)\
int feibona(int N)
{
int i = 1;
int j = 1;
int sum = i + j;
for (i = 4; i <= N; i++)
{
i = j;
j = sum;
sum = i + j;
}
return sum;
}
int main()
{
printf("請(qǐng)輸入一個(gè)n:");
scanf("%d",&n);
int ret=feibona(n);
printf("%d", ret);
return 0;
}
結(jié)語(yǔ):
以上這些都利用到了遞歸函數(shù)的求解方法,思想都是差不多的,如果你仔細(xì)琢磨,會(huì)發(fā)現(xiàn)遞歸的魅力,這些例題可以拿來(lái)復(fù)習(xí),歡迎大家支持 點(diǎn)贊 收藏~~
到此這篇關(guān)于c語(yǔ)言 深入理解函數(shù)的遞歸的文章就介紹到這了,更多相關(guān)c語(yǔ)言 函數(shù)遞歸內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)實(shí)驗(yàn)設(shè)備管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)實(shí)驗(yàn)設(shè)備管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-06-06
opencv利用霍夫變換檢測(cè)直線進(jìn)行圖片校正
這篇文章主要為大家詳細(xì)介紹了opencv利用霍夫變換檢測(cè)直線對(duì)圖片進(jìn)行校正,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-12-12
OPENMP?SECTIONS?CONSTRUCT原理示例解析
這篇文章主要為大家介紹了OPENMP?SECTIONS?CONSTRUCT原理示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-03-03
基于Opencv實(shí)現(xiàn)顏色識(shí)別
這篇文章主要為大家詳細(xì)介紹了基于Opencv實(shí)現(xiàn)顏色識(shí)別,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07
在std::thread中創(chuàng)建并管理QEventLoop的全面解析
QEventLoop的工作原理可以簡(jiǎn)單地理解為一個(gè)無(wú)限循環(huán),它會(huì)不斷地檢查是否有新的事件需要處理,如果有,就將事件從事件隊(duì)列中取出,然后找到相應(yīng)的事件處理器進(jìn)行處理,這篇文章主要介紹了在std::thread中創(chuàng)建并管理QEventLoop的全面指南,需要的朋友可以參考下2023-06-06

