欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

搞定C语言“套娃”(递归):一篇助你掌握的C语言递归教程

最编程 2024-08-12 08:37:17
...

前言

前面呢,我们介绍了C语言的函数内容,这次给大家介绍一下C语言的”套娃“(递归)。递归可以把我们日常的大事小事化,那么由我来带大家了解和深入递归。


什么是递归?

程序调用自身的编程技巧称为递归( recursion)。

递归做为一种算法在程序设计语言中广泛应用。 一个过程或函数在其定义或说明中有直接或间接 调用自身的

一种方法,它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解, 递归策略

只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。

递归的主要思考方式在于:把大事化小

注意前方高能

给大家写一个史上最简单递归代码。

int main()
{
  printf("hehe\n");
  main();
  return 0;
}


运行结果>


网络异常,图片无法展示
|


可以看出代码进入了死循环。

我们先来分析一下这个代码>第一次执行打印"hehe"然后接着调用main函数,再打印"hehe",再调用,再打印,就像无限递归一样,就好比镜子里面有个镜子镜子里面有个镜子一直循环下去,但是程序到最后会崩掉(栈溢出了),我们打断点调试一下>



网络异常,图片无法展示
|

可以看到他会报出Stack overflow(栈溢出)的异常


网络异常,图片无法展示
|

由上面内存图我们可以看出在执行mian函数的时候会一直调用main函数,而调用的同时会在栈区上开辟内存空间,照这样递归下去迟早会出现栈溢出,最终程序崩溃,所以说上面的代码是一个错误代码,会发生错误的递归。

那么为了避免以上的情况发生,我们必须要对递归做出限制条件。



递归的两个必要条件

  • 存在限制条件,当满足这个限制条件的时候,递归便不再继续。
  • 每次递归调用之后越来越接近这个限制条件

我们通过几道典型的题目来深入理解一下套娃思路>


练习1

接受一个整型值(无符号),按照顺序打印它的每一位。 例如: 输入:1234,输出 1 2 3 4

.我们来试着分析一下>

如何得到每一位数字呢,我们画图看一下


网络异常,图片无法展示
|


我们用1234%10可以得到他的个位4,再对1234/10可以去掉个位得到123,再对123%10可以得到个位3,然后再对123/10去掉个位得到12,这样依次下去可以得到1234的每一位数字。

我们再来画图看一下



网络异常,图片无法展示
|

我们可以把代码拆分成上面这样,当n是一位数的时候不在才分,然后我们看看代码实现>

void print(int n)
{
  if (n > 9)
  {
    print(n / 10);
  }
  printf("%d ", n % 10);
}
int main()
{
  int num = 1234;
  print(num);
  return 0;
}


我们让代码运行试试>


网络异常,图片无法展示
|

ok没问题是我们要的结果,那代码该怎么理解呢,首先我们要知道递归 的递—“递推”、归—“回归”(递归递归先递再归!)

我们来把代码单独拿出来分析一下>

网络异常,图片无法展示
|

红色的线是,蓝色的线是,看完这个图相信大家已经能够很好的理解递归的过程了。

再来回过头看看这句话:

只需少量的程序就可描述出解题过程所需要的多次重复计算,大大地减少了程序的代码量。

这就是递归的特点。

那么我们来强调两个重点>




网络异常,图片无法展示
|
n>9是保证递归能够停下来,n/10是保证递归能够正常按照我们的需求进行下去!



91694f841a1f40e6acc372ae68e43352.png


练习2

求一个数的阶乘(递归实现不考虑溢出)

参考代码:

int factorial(int n)
{
  if (n <= 1)
    return 1;
  else
    return n * factorial(n - 1);
}

int main()
{
  int n = 5;
  int print_factorial = factorial(5);
  printf("%d", print_factorial);
  return 0;
}


我们再画图分析一下代码>


6823de2b9353465baf8cbb0e3ec7ad94.png

还是一样红色的线是递,蓝色的线是归!!!

看了这个图,大家对递归就有了更深一层次的理解!

提示:


1.许多问题是以递归的形式进行解释的,这只是因为它比非递归的形式更为清晰。

2.但是这些问题的迭代实现往往比递归实现效率更高,虽然代码的可读性稍微差些。

3.当一个问题相当复杂,难以用迭代实现时,此时递归实现的简洁性便可以补偿它所带来的运行时开销。

总结

以上就是我为大家介绍的C语言“套娃”的基本思想,相信大家看了以上内容一定会对递归有更深层次的理解。

种一棵树的最好时间是十年前,其次是现在! 把握好当下,合理利用时间努力奋斗,相信大家一定会实现自己的目标!加油!

创作不易,辛苦各位小伙伴们动动小手,三连一波~~~,本文中也有不足之处,欢迎各位随时私信点评指正!

————————————————

版权声明:本文为****博主「cv工程师小智」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。

原文链接:https://blog.****.net/xz2935117143/article/details/128268404