C语言——函数递归与迭代
(1)递归的例子:
顺序打印一个整数,打印整数的每一位。
例如:
input:1234
output:1 2 3 4
input:520
output:5 2 0
我们可能会想到用这种方法:(但是运行之后,我们发现结果是事与愿违的)
#include <stdio.h>int main()
{int n = 0;scanf_s("%d",&n);while (n){printf("%d",n%10);n = n / 10;}return 0;
}
正确的分析思路是怎样的呢?
例如,我们要打印1234的每一位:
1.先打印出123的每一位(1234/10------>123)
2.打印4(1234%10--------------->4)
以此类推。我们可以了解到,递归是逐渐将原来一个大的问题逐渐细化为一个小问题。
对于文章最开始提出的那个问题,如何使用函数递归实现呢?
#include <stdio.h>void Print(int n)
{if (n > 9){Print(n/10);}printf("%d ",n%10);
}int main()
{int n = 0;scanf_s("%d",&n);Print(n);return 0;
}
分析:
从内存的角度上看,是怎么回事呢?
函数的每一次调用,都会向栈区申请一块内存空间。这一块空间主要用来存放函数中的局部变量,和函数调用过程的上下文信息。这个空间一般叫做,函数的运行时堆栈,也叫函数栈帧空间。编译会自动根据需要开辟空间。
(2)迭代
函数不返回,函数对应的栈帧空间就一直占用,所以如果函数调用中存在递归调用的话,每一次递归函数调用都会开辟属于自己的栈帧空间。直到函数递归不再继续,开始回归,才逐层释放栈帧空间。
迭代的本质是做一件重复的事情,例如for循环的过程。
我们来看一个计算阶乘的例子:
源码:
#include <stdio.h>//计算一个数字的阶乘
int Fac(int n)
{int i = 0;int ret = 1;for (i = 1;i <= n;i++){ret = ret * i;}return ret;
}int main()
{int n = 0;scanf_s("%d",&n);int ret = Fac(n);printf("%d\n",ret);return 0;
}