C语言递归示例详解

mac2026-05-11  1

一个函数在他的函数体内调用它自身称为递归调用,这种函数称为递归函数。执行递归函数将反复调用自身(也就是相当于嵌套函数),每一次的调用就进入新的一层函数,执行到最后结束的那一行代码就开始从里面一层一层的退出函数

#include <stdio.h> //求n的阶层 int factorial(int n) { if (n<2) { return 1; //最里层的结束语句 }else{ return factorial(n-1)*n;//return是最后退出的时候执行,如果没有退出递归是不会执行return的 } }

递归的进入

(1)求5!,即调用factorial(5).当进入factorial()函数体后,由于形参n的值为5,不等于0或1,所以执行factorial(n-1)*n,也就是执行了factorial(4)*5.为了求得这个表达式的结果,就必须先调用factorial(4),并暂停其他操作,换句话说,在得到factorial(4)de 结果前,不能进行其他操作,以此类推一直到n==1,结束。 

                                                                                                                                                 逐层进入递归过层层次/层数实参/形参调用形式需要计算的表达式需要等待的结果1n=5factorial(5)factorial(4)*5factorial(4)的结果2n=4factorial(4)factorial(3)*4factorial(3)的结果3n=3factorial(3)factorial(2)*3factorial(2)的结果4n=2factorial(2)factorial(1)*2factorial(1)的结果5n=1factorial(1)1无

递归的退出

当递归进入到最内层的时候,递归就结束了,就开始逐层退出了,也就是逐层执行return语句。

(1)n的值为1的时候达到最内层,此时return 出去的结果为1,也就是factorial(1)的调用结果为1.

(2)有了factorial(1)的结果,就可以返回上一层的计算factorial(1)*2的值,此时得到的值为2,return 出去的结果也为2,也即factorial(2)的调用结果为2.

 层次/层数实参/形参调用形式

从内层递归得到的结果

(内层函数的返回值)

表达式的值

(当次调用的结果)

5factorial(1)1无 4factorial(2)factorial(1)*2

factorial(1)的返回值,也就是1

1*2 = 23factorial(3)factorial(2)*3factorial(2)的返回值,也就是22*3 = 62factorial(4)factorial(3)*4factorial(3)的返回值,也就是66 * 4 = 241factorial(5)factorial(4)*5factorial(4)的返回值,也就是2424 * 5  = 120

递归的条件

每一次递归函数都应该只进行有限次的递归调用,否则它就会进入死胡同,永远也不会退出,将会没有任何意义

-------------------------------------------                      分割线            --------------------------------------------------

中间递归函数

所谓中间递归就是发生递归的函数在函数的中间,而不是末尾

字符串反转(逆置)

#include <stdio.h> #include <stdlib.h> char *reverse(char *char){ int len = strlen(str); if (len > 1) { char ctemp = str[0];//临时变量存每一次递归的第一个元素 str[0] = str[len-1]; str[len-1] = '\0'; reverse(str + 1);//递归调用 str[len-1] = ctemp;//每一次递归函数返回之后,最后一个元素都等于每一次递归的第一个元素 } return str; } int main(){ char str[20] = "hello world"; printf("%s\n",reverse(str)); return 0; }

递归的过程

第十一行代码,调用reverse()的实参为 str+1,这个会导致形参的str的指向改,每次递归调用str都会向后移动一个字符位置

 

reverse() 的整体思路是,每次调用函数只交换字符串开头和末尾的两个字符串,其他字符一律不管,并且这个交换过程也是分两个阶段完成的

1,在逐层进入递归阶段,reverse()只是把字符串最后的一个字符移动到最前面,但是并没有把最前面的字符串移动到最后边,而是把最前边的字符保存到ctemp变量

2,在逐层退出递归的阶段,reverse()才把ctemp变量保存的字符放到字符串最后

在一个字符串中"\0"就是一个字符串的结束

 

最新回复(0)