计算机小白的成长历程——函数(5)

大家好,很高兴又和各位见面啦!上一篇咱们认识了什么是函数递归,也了解了递归的两个必要条件,今天咱们将继续探讨函数递归的相关内容。

七、函数递归

3.递归与迭代

迭代:就是重复的去做一件事情,也就是循环。

理解:我对于迭代的理解,就是在函数体内使用循环

我们在探讨函数的嵌套调用的时候有提过,所谓的嵌套就是在函数体内调用函数。到递归的时候,我也提过,递归就是一种特殊的函数嵌套,只不过这时嵌套的函数是它本身。在上一篇内容中我们在编写按顺序打印1 2 3 4时,我也提到过,在进行递归时,函数就进入了循环,此时也就不需要在额外使用循环了。迭代也就是在函数体中通过使用循环来让函数重复的做一件事。

可能不太好理解,怎么我们在将函数,你这里又是函数嵌套又是函数递归,现在又说迭代,咋又提到了循环呢?没关系,我们下面来通过代码进一步理解:

代码语言:javascript
复制
//函数的递归与迭代
// 题目1:求n的阶乘(不考虑溢出)
//正常编写:
int main()
{
	int n = 0;
	int j = 1;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++)
	{
		j *= i;
	}
	printf("%d!=%d\n", n, j);
	return 0;
}

我们正常编写时,在主函数内需要借助循环来完成,下面输入5来测试结果:

计算机小白的成长历程——函数(5)_递归

下面我们通过递归来实现一下n的阶乘,编写前我们需要了解一下,我们在求n的阶乘的时候,有这么一个公式:n=1,n!=1;n>1,n!=n*(n-1)。在知道了这个公式后,我们再来进行编写:

代码语言:javascript
复制
//通过函数递归完成n的阶乘;
int fac(int a)
{
	if (a==1)
	{
		return 1;
	}
	else
	{
		return a * fac(a - 1);
	}
}

int main()
{
int n = 0;
scanf("%d", &n);
printf("n!=%d\n", fac(n));
}

下面还是用5来测试结果:

计算机小白的成长历程——函数(5)_n的阶乘_02

这里可以看到,通过递归的好处就是我们将复杂的问题简单化了,原本是要求n的阶乘,通过递归后变成了求n*(n-1),下面我们来通过函数的迭代来完成求n的阶乘:

代码语言:javascript
复制
//通过函数迭代完成n的阶乘;
int fac(int a)
{
int b = 1, c = 1;
for (b; b <= a; b++)
{
c *= b;
}
return c;
}

int main()
{
int n = 0;
scanf("%d", &n);
printf("n!=%d\n",fac(n));
return 0;
}

看到这个代码,大家有没有什么感受啊,貌似跟我们直接编写的代码大差不差的,只不过原先是在主函数中使用了循环,现在是在自定义函数中使用了循环,这里我要说明的就是,这种方式就是迭代。

通过这个例子,不知道大家有没有那种醍醐灌顶的感觉。有朋友可能就会说了,既然迭代就是在函数体中使用循环,那为什么不直接在主函数体中使用循环呢?这样不是更简洁一点吗?

这个问题我是这么理解的:

首先,我们知道,在函数体中使用循环的这种方式就叫做迭代,那么在我看来在主函数体中使用循环也是迭代;

其次,我们在编写像现在的这些代码时有一点肯定的是,直接在主函数中编写会更简洁一点,因为我们编写的内容都是比较简短的,但是咱们想象一下,如果我们工作了,有一天需要编写代码时大量重复的使用求n的阶乘这个功能,那是不是意味着我们要不停的编写这些内容呢?但是如果我通过定义函数来完成,那在进行复数使用时,我们是不是只需要调用一下函数就可以了;

最后,自定义函数我们在初识C中有提到过,函数的作用就是简化代码,代码复用。

结语

那函数迭代的内容到这里咱们就介绍完了,希望这篇能够帮助大家更好的理解函数递归与迭代。接下来随着学习的深入,我会继续给大家分享我在学习过程中的感受,感谢大家的翻阅,咱们下一篇见。