≡菜单

C递归基础实例

在C编程语言中,当一个函数一遍又一遍地调用自身时,该函数称为递归函数。

重复调用自身的过程称为递归。

在本教程中,我们将使用实际示例来理解递归的概念。

1. C递归概念

让我们从一个非常基本的递归示例开始:

#include <stdio.h>

void func(void)
{
    printf("\n 这是一个递归函数 \n");
    func();
    return;
}

int main(void)
{
    func();
    return 0;
}

在上面的代码中,您可以看到函数func()在其定义中进行了调用。因此,func()成为递归函数。您能猜出执行上面显示的代码时会发生什么吗?如果我们按代码进行操作,main()函数将调用一次func(),然后func()将永远继续调用自身。这是确切的行为吗?

让我们执行代码并检查一下。这是输出:

$ ./recrsn
这是一个递归函数 

 这是一个递归函数 

 ....
 ....

 这是一个递归函数 

 这是一个递归函数 

 这是一个递归函数
分段故障 (core dumped)

在上面的输出中:

  • 印刷品“这是一个递归函数”连续打印多次。
  • 一组三个点“…”用于省略实际输出的很大一部分,但只不过是相同的印刷品。
  • 接近驾驶室的输出端“Segmentation fault”或正如我们通常所说的,程序崩溃。

早些时候,我们认为该程序将继续执行,因为递归函数func()会永久调用它自己,但事实并非如此。程序崩溃了。为什么会崩溃?

这是此崩溃的原因:

  • 对于每次对func()的调用,都会创建一个新的函数堆栈。
  • 通过func()连续调用自身,还可以连续创建新的函数堆栈。
  • 在某一时刻,这会导致 堆栈溢出 因此程序崩溃了。

与此相关的是,对您有一个很好的了解也很重要 缓冲区溢出链表.

2. C递归的实例

对于完全的新手,最好有一个类似的问题 什么’递归的实际使用?在本节中,我将提供一些实际示例,在这些示例中,递归可以使事情变得非常简单。

Suppose you have numbers from 0 to 9 和 you need to calculate the 和 of these numbers in the following way :

0 + 1 = 1
1 + 2  = 3
3 + 3 = 6
6 + 4 = 10
10 + 5 = 15
15 + 6 = 21
21 + 7  =28
28 + 8 = 36
36 + 9 = 45

因此,您可以看到我们从0和1开始,将它们加起来并将结果加到下一个数字(即2)中,然后再次将结果加到3并继续这样。

现在,我将向您展示如何使用递归在C代码中为此要求定义逻辑:

#include <stdio.h>

int 计数 = 1;

void func(int 和)
{
    和  = 和 + 计数;
    计数 ++;

    if(count <= 9)
    {
        func(sum);
    }
    else
    {
        printf("\nSum is [%d] \n", 和);
    }

    return;
}

int main(void)
{
    int 和 = 0;
    func(sum);
    return 0;
}

如果您尝试了解上述代码的作用,则将观察到:

  • 什么时候func() was called through main(), ‘sum’ was zero.
  • 每次调用func()时,的值‘sum’用增加‘count’(最初为1),每次调用本身都会增加。
  • 递归终止的条件是当‘count’超过9。这正是我们的期望。
  • 什么时候‘count’超过9,此刻的值‘sum’是我们想要的最终数字,因此是解决方案。

这是另一个示例,其中可以使用递归来计算给定数字的阶乘:

#include <stdio.h>

int func(int num)
{
    int res = 0;

    if(num <= 0)
    {
        printf("\n Error \n");
    }
    else if(num == 1)
    {
        return num;
    }
    else
    {
        res  = num * func(num -1);
        return res;
    }

    return -1;

}

int main(void)
{
    int num = 5 ;
    int fact  = func(num);

    if (fact > 0)
        printf("\n The factorial of [%d] is [%d]\n", num, fact);

     return 0;
}

请注意,我使用了硬编码号码‘5’计算其阶乘。您可以增强此示例以接受用户的输入。

前面的示例仅演示了如何在func()的最终调用中计算总和,但是我使用示例的原因是因为它演示了如何使用返回值可以产生期望的结果。在上面的示例中,跨不同函数栈的调用序列可以显示为:

res  = 5 * func(5 -1); // This is func() stack 1
res  = 4 *func(4-1);   // This is func() stack 2
res  = 3 *func(4-1);   // This is func() stack 3
res  = 2 *func(2-1);   // This is func() stack 4
return 1;              // This is func() stack 5

现在,将堆栈5的返回值替换为堆栈4,将堆栈4的返回值(即res)替换为堆栈3,依此类推。最后,在堆栈1中,您将得到类似

res = 5 * 24

这是120,即5的阶乘,如执行此递归程序时的输出所示。

$ ./recrsn 

 The factorial of [5] is [120]

如果您喜欢这篇文章,您可能还会喜欢..

  1. 50个Linux Sysadmin教程
  2. 50个最常用的Linux命令(包括示例)
  3. 排名前25位的最佳Linux性能监视和调试工具
  4. 妈妈,我找到了! – 15个实用的Linux Find命令示例
  5. Linux 101 Hacks第二版电子书 Linux 101黑客手册

Bash 101 Hacks书 Sed和Awk 101黑客手册 Nagios Core 3书 Vim 101黑客手册

{ 14 评论… 加一 }

  • 亚历克斯 2013年9月22日,下午3:49

    int fact(int n)
    {
    如果(n == 0)
    返回1;
    返回n *事实(n– 1);
    }

  • 杜斯科科西卡 2013年10月2日,上午7:26

    是否有可能将主要功能称为自我?
    我知道,有些人不会说…,但让我们考虑一下。
    两个函数同时调用彼此如何工作。
    还有一件事,忽略全局变量是一件好事,您只需’在上述问题上不需要它。谁写总和=总和+计数,唐’您只是为了+ =而知道,这不是上帝的缘故。
    还有哪些更有趣的问题!
    理论如何看待递归,何时使用和不使用递归等…
    关于这个主题有很多话题要说。

  • 克里斯 2013年10月8日,上午6:53

    很棒的帖子!递归的另一个很好的介绍是遍历树结构。一世’我为我的学生使用了几次,他们似乎明白了。

  • 杜斯科科西卡 2013年10月9日,上午3:32

    太好了!
    那你为什么不’与我们分享在遍历树结构方面的智慧,我相信这将对该主题做出巨大贡献…

  • Sandeep 2015年6月30日,晚上11:40

    它很棒,非常有用

  • 尼西·辛格 2015年9月5日,上午4:10

    是的,它’可以调用main()函数。

  • 帕尔先生 2015年9月10日,上午7:40

    这很棒….
    非常感谢您的帮助

  • 希普拉 2015年10月15日,上午11:04

    它易于学习c并且非常有用。

  • 卡蒂克·基斯库(Kartick Kisku) 2015年12月24日,上午4:58

    哦!
    真正的高手。我想通过不同类型的序列计算示例了解更多信息。

  • 琳达·詹妮弗(Linda Jenifer) 2016年2月10日,上午4:04

    谢谢,这对我非常有用

  • 尚丹·杜塔(Chandan Dutta) 2016年12月14日,上午10:34

    先生,您的回答很好,我对程序非常简单。

  • 徐碧 2016年12月19日,上午8:58

    任何人都可以帮助我解决以下问题或递归问题:——————————————
    输入文件:
    A | B,C,D,E,F
    B | U,L
    C | Y,Z
    Z |钾

    给定A作为功能输入时,所需的输出应返回:
    A | U,L,Y,Z,K,S,E,F

  • 瓦伦·曼朱纳斯 2017年4月15日,上午12:20

    对于基础学生来说,提高他们的概念理解非常有用

  • 公牛 2017年5月6日,上午10:02

    上面的例子对理解非常有用…

发表评论