资讯详情

C语言递归函数详解:从入门到精通

📅 2026/10/8 19:38:28 | 华诺云谱 👁 阅读
C语言递归函数详解:从入门到精通
本篇文章是C语言入门系列的第31篇文章。在C语言的众多知识里, 递归函数确实是一个比较让人头疼、需要大费脑筋才能理解的概念。要说它的难度等级, 它完全可以和指针相提并论。如果把这两种知识点放在一起对比的话, 它们绝对称得上是C语言中难度最高的两颗双子星。函数被进行了定义, 函数也被进行了调用。所谓定义函数, 这个操作是在向系统进行说明, 该函数具体具备什么样的功能特征。而调用函数, 这个操作相当于要实际去执行以实现这一既定功能的意图。把一个函数给它定义下来的这个行为, 实际上就是相当于是在写一个剧本, 去明确地告诉那个负责执行的导演, 这个剧具体是要去表现一些什么样的具体内容。所谓调用函数, 其实就跟拍电影差不多, 它的作用就是把这个剧本里所描绘的故事给展现出来。所谓函数的定义, 其具体的语法格式为:数据类型名称, 后面紧跟着一个左圆括号, 然后是一个形式参数列表, 最后以右圆括号作为结尾。函数体上面提到的那个用来放形式参数的东西, 它属于是一个可以选择要不要有的部分, 并不是说每一个函数都必须带有这种叫做形式参数的内容。调用函数的语法, 格式是这样的。函数名后面加上一对括号, 再接一个分号。或者调用这个函数, 把那个由实际参数凑成的表当实参递进去, 后面跟着一个分号结束。如果你在为那个函数进行定义操作的时候, 没有把它设置成拥有形参的样子, 那么当你去调用这个函数的时候, 也是不会有跟那个位置相对应实的实参存在的。如果在定义这个函数的时候, 里面确实是有形式参数的存在的话, 那么在进行调用操作的那个时刻, 也是必须得有相对应的那个实际参数来作为搭配的。关于形参的要求, 它必须被定义为一个变量这一事实, 在另一方面来看待实参的时候是可以发现, 实参可以是常数。当一个函数可以被其他函数调用的时候, 它同时也能够去调用其他的函数。1函数的普通调用我们现在来一起观看一下, 那个非常简单的, 我们所说的程序。程序1函数f2把函数f1给调用了, 然后呢, 主函数又把函数f2给调用了。程序运行结果当调用函数的时候, 程序就转变到被调用的那个函数里面去, 接着执行这个被调用函数内部的语句, 等到这些语句都执行结束之后, 再转回到原来调用它的那个函数中继续运行下去。函数的这种调用情况, 其实属于递归调用的范畴。在程序1里面, 函数f2调用了函数f1, 还有函数main也调用了函数f1。这些情况, 都算是调用了其他的函数呀。所谓函数调用自己, 这个现象通常被称作递归调用。所谓的递归调用这种方式, 其实就是指函数在执行过程中自己去调用自己。我们来对其中所包含的一个具体案例进行查看。当有5个人并排坐在一起的时候, 王老师向站在最右边位置的那一位也就是大家所称的第五个人询问他年龄究竟是多少岁这件事。这个第5个人提到自己比那个坐在他左手边的家伙要大2岁的年纪, 而那个家伙就被我们定义为第4个人。于是, 王老师就去问那个排在第四个位置的人究竟多大年纪了。那个第四个人就回答说坐在他那一侧左手边的人也就是我们所说的第三个人的岁数比他还要多出两岁来着。王老师向位于排序中的第三位的人员询问其具体的年龄状况。对此, 这位第三位人员做出了回应, 他明确表示, 此刻安坐于其左手侧位置的个体, 被我们定义为第二位人员, 该人员在年龄层面要高出两岁的大小之差。王老师向第二位人士询问其年龄状况, 那位第二位人士作出回应, 指出坐于其左侧的人员情况, 此人在语境中被标识为第一位人士, 且该人士的 age 要比他大一整岁。王老师去询问第一个人到底是多少岁, 那个第一个人往他左边瞧了一眼, 发现压根没有人, 所以没辙, 只能回复说自己今年8岁的这个信息。请问第五个人的岁数一共是多大一点。我们计算第五个人的年龄, 是不是需要进行这样的步骤:第5个人的年龄是建立在第4个人的基础之上的, 在此基础上需要加上数2才可以得到最终的结果。就是算一算第4个人的岁数, 这个数值等于把第3个人的岁数拿过来然后再给它加上数字2。第三个人的年龄等于第二个人的年龄加上2这个数值。这第二个人的年龄数值, 应当等于前面那个第一个人的年龄数值, 再加上数字二。第1个人的岁数 8递归函数这回事儿, 就跟之前提到过的那个套娃道理是一模一样的, 它就是这么一层又一层地嵌套下去, 中间的过程可能有点绕弯子, 但目的就是要费劲巴拉地把最里面藏得最深的那个核心套娃给找出来。假如存在一个名为age的函数, 其内部逻辑能够针对传入的参数n计算出对应第n个人的年龄数值, 那么当参数n被设定为1时, 即指代的是排在第一位的那个人, 在此种特定的情形之下, 我们可以非常清晰地明确他的实际岁数就是8岁。如果n大于1, 那么, 第n个人的岁数, 就等于第n-1个人的岁数加上2。我们可以利用一个名为age的函数, 这个函数的功能是表示第n个人的岁数, 这样一来, 前面提到的那些公式就都能够被改写成下面的这种样式了:函数age拥有一个返回值, 该返回值指的是第n个人的岁数。所以, 这个函数的返回值的类型是整数型的int, 关于那个名字叫做age的函数, 它具体的定义形式如下所示:返回一个数值, 这个数值是整数类型, 它代表的是第n个人的年龄, 也就是岁数是多少。当那个n的值等于一开始的那1也就是第1个人的时候, 那么返回的数字就是8, 要不然的话就返回前面那一位人士的具体岁数加上数字2。完整程序如下程序1程序1运行结果排在第5位的那个人, 现在的年纪是16岁。让我们再来瞧瞧一个实例的情形, 具体的操作是输入那个整数n, 然后咱们要去算出n的阶乘是多少这个事儿。n的阶乘, 这个概念用符号n来代表, 指的是从1开始, 依次乘以2、3、4, 如此一直乘下去, 最终得到的数值就是n的阶乘。这个程序如果使用普通的循环函数去做, 那是完全可以实现的, 所以呢就根本就不需要再去用递归函数了。咱们先用那种最普通的函数来把东西实现出来。程序2我们将用于计算n的阶乘这一段逻辑, 编写到了名为fact的函数之中, 而在这个名为fact的函数内部它会执行一个动作, 这个动作是让该函数去返回作为形参所给定的那个n值对应的阶乘结果。在主函数里面去调用fact这个函数, 打个比方来说, 如果需要求出5的阶乘的话, 那么调用的语句就会写作: fact(5)。可是, 计算阶乘这个动作, 我们也是能够采用递回归调函数这样的手段来予以实现的。我们清楚地了解到一个基本的事实, 那就是零的阶乘等于一, 与此同时, 一的阶乘也同样等于一。如果情况当中的n是等于0的话, 或者n是等于1的情况的时候, 那么n的阶乘就是结果为1的状态。只要n这个数大于1, 那么n的阶乘就等于拿n去乘以(n-1)的阶乘。因此, 求得阶乘的具体计算公式表现如下所示:如果我们用表示n的阶乘的这个函数fact(n来写的话, 前面说的那个公式就可以写成下面这样的形式。函数fact存在返回值的情况, 这个具体的返回值体现出来的内容是第n的阶乘。把函数fact的类型设置成是int, 关于函数fact是怎么定义的, 具体的内容如下。你可以将程序2里面那个fact函数的定义方式, 修改成使用递归的形式, 这样做之后运行出来的结果和原来是一模一样的。如果咱们想在程序运行的时候, 在主要的函数部分输入一个整数, 然后呢, 计算出来这整个数值的阶乘结果, 具体操作可以这样来写:程序3运行结果当你输入数字5之后, 系统会去计算5这个东西的阶乘是多少, 最后得到的结果是120。可是, 当输入的整数很大, 比如说输入的数字是100的时候, 我们来看一下程序运行的结果是怎么样的。假如输入的数字是32, 那么程序运行之后的结果会表现为:一百的阶乘是零, 还有那三十二的阶乘变成了负数, 这样的情况出现的话, 肯定是不对的。这是因为, 32的阶乘已经太大了, 已经超出了int类型的取值范围, 所以就产生了一个溢出错误。这种情况, 就相当于给int类型的房间装载数据, 所能够装入的数值, 有一个最小的范围和一个最大的范围, 一旦超过了这个既定的范围。就无法再装下了, 这是因为这个房间的实际容量太小了, 这个时候, 就必须更换一个更大的房间来存放这些数值, 否则的话, 就会出现溢出这样的错误。因此, 在当下这个时段, 我们理应把函数fact给定义为双精度实型的那一种数据类型, 这么去做的话, 也就不会有什么问题了。运行结果我们观察得到的输出结果里存在着6位的数字在小数点后面。实际上阶乘这个计算不会产生小数部分这样的内容, 所以可以把程序代码当中对变量x进行输出时使用的格式控制符%f替换成%.0f就可以了。这样做能够保留0位的小数位数, 也就是说不显示任何小数点后尾数部分的内容。3 总结函数是可以去调用任何其他的函数的, 同时呢, 它也是完全可以自己去进行调用的。所谓的递归函数, 指的就是一种会自己调用自己的函数。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑