当前位置: 首页 > news >正文

C语言函数递归

前言与概述

本文章将通过多个代码并赋予图示,详细讲解C语言函数递归的定义和函数递归的运算过程。

函数递归定义

程序调用自身的编程技巧称为递归。递归作为一种算法在程序设计语言中广泛应用。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法。它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解。递归策略只需要少量的程序便可以描述出解题过程中所需要的多次重复计算,大大节省了程序的代码量,递归的主要思考方式在于大事化小

最简单的递归

在main()函数体内调用main()函数,这是最简单的函数递归。当然,这样的函数递归是错误的,因为main()函数被不断的调用,导致陷入死递归。

示例代码:

//最简单的函数递归
#include <stdio.h>
int main()
{printf("Good!!\n");main();return 0;
}

运行结果:

 

栈溢出

Stack overflow:栈溢出。在计算机内存中,主要分为三大区:栈区、堆区、静态区。栈区存放着局部变量、函数形参、函数返回值等临时性变量。堆区主要用于动态内存分配。静态区主要存放全局变量和静态变量。如果我们把栈区单独拿出,当程序进入main()函数中,main()函数会向栈区申请空间,于是,main()函数会得到一片空间,称为main()函数的栈帧空间。在main()函数体内定义的局部变量会存放在main()函数的栈帧空间里。如果main()函数调用了函数,调用的这个函数同样也会向栈区申请空间。但是栈区的空间是有限的,如果不停的调用函数,就会不停的占用栈区空间,直到栈区空间被耗尽,就会导致栈溢出。当函数完成调用,就会自动销毁,并释放空间。

 

 

打印一个数的每一位

算法

现在有一个整数1234,按照顺序打印这个数的每一位。

整数1234最容易打印的数是4,只需要将这个整数模10(%10)就可以得到。然后将整数1234除10,就可以去掉最后一位数字。接着将得到的整数123模10,打印得到的数字3。再将这个整数除以10,去掉最后一位3,得到整数12。以此类推,当这个整数小于10,就可以直接打印。

% 10 用于得到最后一位;/ 10 用于去掉最后一位。

定义一个函数,用于打印整数的每一位;定义变量number将读取的数值作为实参传给函数。函数会通过对10取模,打印整数的最后一位。接着将整数的值除以10,作为新的实参传给函数。如果整数的值大于9,就重复执行打印、调用函数。否则,只打印不调用函数。

 

如果函数体内先打印后调用函数,得到的结果就是将原整数逆序打印。

 

所以可以先调用函数后打印,这样得到的结果就是将原整数顺序打印。

示例代码

//先调用后打印
#include <stdio.h>
void print(int x)
{if (x > 9){print(x / 10);printf("%d ", x % 10);}else{printf("%d ", x);}
}
int main()
{int number = 0;scanf("%d", &number);print(number);return 0;
}

运行结果

 

 函数递归运行过程

 

 如果我们想在屏幕上按顺序打印整数123的每一位。在控制台上输入数字123,scanf()函数读入用户输入的数值,并赋予变量number。main()函数调用print()函数,把变量number的值作为形参传给print()函数(步骤1)。此时形参x的值是123。x的值大于9,条件成立,将变量x的值除以10的结果作为实参传给print()函数(步骤2)。此时,形参x的值是12,大于9,条件成立,将变量x的值除以10的结果作为实参传给print()函数(步骤3),此时,形参x的值是1,条件不成立。在屏幕上打印变量x的值1。遵循着“从哪里来回到那里去”的原则,返回到上一个函数(步骤4),并直接向下执行,此时,形参x的值是12,在屏幕上打印数字2,并返回到上一个函数(步骤5)此时,形参x的值是123,在屏幕上打印数字3。返回到main()函数(步骤六)。

求n的阶乘

算法

一个数的阶乘就是从1开始,每次乘的数都比上一个乘的数多一,直到乘的数等于它本身。0的阶乘等于1。如4的阶乘就等于1*2*3*4=24。下面设计一个函数,用于根据用户输入的值,求出对应的阶乘。

如果用户输入的数小于等于1,那么n的阶乘就是1;否则,n的阶乘就是n *(n - 1)的阶乘。

示例代码:

//求n的阶乘
#include <stdio.h>
int times(int x)
{if (x <= 1){return 1;}else{return x * times(x - 1);}
}
int main()
{int number = 0;scanf("%d", &number);int result = times(number);printf("%d", result);return 0;
}

运行结果

 

函数递归调用过程 

如果我们想知道3的阶乘,在控制台中输入数字3。scanf()函数从控制台中读取数字3,并赋予变量number。定义变量result,调用times()函数,将变量number的值作为实参传给函数(步骤一)。形参x得到变量number的值3。形参x的值大于1,条件不成立。调用times()函数,并将x - 1的值作为新的实参传给times()函数(步骤2)。此时形参x的值是2,条件不成立,调用times()函数,并将x - 1的值作为新的实参传给times()函数(步骤3)。此时形参x的值是1,条件成立,返回数字1。返回到上一个函数(步骤4),计算x * 1(2 * 1)的值并返回到上一个函数(步骤5)。函数得到返回值2,并将x * 2(3 * 2)的值返回到原调用函数处(步骤6)。变量result得到返回值6,并打印变量result的值。

递归与迭代

区别

迭代具有运行效率高的优点,但是代码量相对较大。递归整体上代码更加简洁,可读性高,但是可能出现栈溢出、运行效率低等问题。

求第n个斐波那契数(递归)

计算方法

什么是斐波那契数列?

1  1   2   3   5   8   13   21   34   55

斐波那契数列的第n个数(n >= 3)等于前两个数之和。

如果n的值小于等于2,那斐波那契数是1,如果n的值大于2,那么该斐波那契数等于第n - 1的斐波那契数加上第n - 2的斐波那契数。

示例代码(递归实现)

//求第n个斐波那契数
#include <stdio.h>
int fib(int x)
{if (x <= 2){return 1;}else{return fib(x - 1) + fib(x - 2);}
}
int main()
{int number = 0;scanf("%d", &number);int result = fib(number);printf("%d", result);return 0;
}

 运行结果 (递归实现)

不足之处 

虽然使用递归可以求出第n个斐波那契数,但如果输入n的值较大,就可能需要计算很长时间,甚至会导致程序崩溃。这主要是因为代码进行大量重复多余的计算。比如求第40个斐波那契数,仅第3个斐波那契数就重复计算了39088168次。于是,我们可以使用迭代来快速寻找到想要的值。

 

示例代码(迭代实现)

//求第n个斐波那契数非递归
#include <stdio.h>
int main()
{int number = 0;scanf("%d",&number);int a = 1;int b = 1;int c = 0;int temp = number;if (temp <= 2){c = 1;}else{while (temp - 2 >= 1){c = a + b;a = b;b = c;temp = temp - 1;}}printf("%d", c);return 0;
}

运行结果 (迭代实现)

代码分析

定义变量a保存第一个元素,定义变量b保存第二个元素,定义变量c保存第三个元素。如果输入的值小于等于2,那么变量c的值就是2。如果输入的值大于2,那么变量c的值就等于变量a的值加上变量b的值。把变量b的值赋予变量a,变量a就成为新的第一个元素,把变量c的值赋予变量b,变量b就成为新的第二个元素。

 

相关文章:

C语言函数递归

前言与概述 本文章将通过多个代码并赋予图示&#xff0c;详细讲解C语言函数递归的定义和函数递归的运算过程。 函数递归定义 程序调用自身的编程技巧称为递归。递归作为一种算法在程序设计语言中广泛应用。一个过程或函数在其定义或说明中有直接或间接调用自身的一种方法。它…...

【python数据分析11】——Pandas统计分析(分组聚合进行组内计算)

分组聚合进行组内计算 前言1、groupby方法拆分数据2、agg方法聚合数据3、apply方法聚合数据4、transform方法聚合数据5 小案例5.1 按照时间对菜品订单详情表进行拆分5.2 使用agg方法计算5.3 使用apply方法统计单日菜品销售数目 前言 依据某个或者几个字段对数据集进行分组&…...

高性能web服务器

目录 一、简介 &#xff08;一&#xff09;nginx-高性能的web服务端 &#xff08;二&#xff09;用户访问体验 二、I/O模型 &#xff08;一&#xff09;概念 &#xff08;二&#xff09;网络I/O模型 &#xff08;三&#xff09;阻塞型 I/O 模型 &#xff08;四&#xf…...

微服务案例搭建

目录 一、案例搭建 1.数据库表 2.服务模块 二、具体代码实现如下&#xff1a; (1) 首先是大体框架为&#xff1a; &#xff08;2&#xff09;父模块中的pom文件配置 &#xff08;3&#xff09;shop_common模块&#xff0c;这个模块里面只需要配置pom.xml&#xff0c;与实体…...

SAP负库存

业务示例 在系统中&#xff0c;对于一些物料而言&#xff0c;不能立即将收到的交货输入为收货。如果要使发货无论如何都是可以过帐的&#xff0c;则需要允许这些物料的负库存。 负库存 发货数量大于预订数量时&#xff0c;过帐该发货就会出现负库存。如果由于组织原因&#…...

集团数字化转型方案(三)

集团数字化转型方案通过系统整合人工智能&#xff08;AI&#xff09;、大数据、云计算和物联网&#xff08;IoT&#xff09;技术&#xff0c;建立了一个全面智能化的业务管理平台&#xff0c;涵盖从业务流程自动化、数据驱动决策支持&#xff0c;到客户体验优化和供应链管理的各…...

ESP32智能设备:蓝牙音箱、AI语音助手、环境监测与调节以及智能控制,基于BLE与MQTT技术(代码详解)

本文将介绍如何实现一个功能丰富的ESP32项目&#xff0c;集成蓝牙音箱、AI语音助手、智能设备控制器、环境监测与调节等功能。通过本项目&#xff0c;您将学习到硬件设计、嵌入式编程、蓝牙技术、音频处理、人工智能与语音识别、物联网平台、数据分析及用户界面构建等技术。 一…...

web渗透测试 学习导图

web渗透学习路线 前言 一、web渗透测试是什么&#xff1f; Web渗透测试分为白盒测试和黑盒测试&#xff0c;白盒测试是指目标网站的源码等信息的情况下对其渗透&#xff0c;相当于代码分析审计。而黑盒测试则是在对该网站系统信息不知情的情况下渗透&#xff0c;以下所说的Web…...

WordPress禁止后台自定义功能

wordpress后台可以彻底禁止主题的自定义菜单功能&#xff0c;下面这段代码添加到functions.php文件中&#xff0c;后台外观菜单中的”自定义”就会消失不见了。 add_filter(map_meta_cap, function($caps, $cap){if($cap customize){return [do_not_allow];}return $caps; },…...

(六)Flink 窗口计算

窗口(Window)是处理无界流的关键所在。窗口可以将数据流装入大小有限的“桶”中,再对每个“桶”加以处理。 目录 时间概念 窗口类型 窗口划分 窗口的生命周期 Window Assigners 窗口函数 Triggers 窗口触发器 Evictor 数据剔除器 Allowed Lateness 旁路输出 时间…...

SQL 布尔盲注 (injection 第六关)

简介 SQL注入&#xff08;SQL Injection&#xff09;是一种常见的网络攻击方式&#xff0c;通过向SQL查询中插入恶意的SQL代码&#xff0c;攻击者可以操控数据库&#xff0c;SQL注入是一种代码注入攻击&#xff0c;其中攻击者将恶意的SQL代码插入到应用程序的输入字段中&am…...

OpenAI 重回巅峰:ChatGPT-4O 最新模型超越谷歌 Gemini 1.5,多项测试夺冠!

谷歌上周发布的Gemini 1.5 Pro模型&#xff0c;在LMSYS办的聊天机器人竞技场Chatbot Arena中获得第一名。但是&#xff0c;OpenAI迅速反应&#xff0c;推出了最新的chatgpt-4o-latest模型&#xff0c;重新夺回了冠军头衔。 chatgpt-4o-latest模型简介 OpenAI最近推出了名为gpt-…...

软件工程(2)面向对象方法:Booch方法与开发实例

Booch方法&#xff08;Booch Method&#xff09;是由Grady Booch提出的一种面向对象的软件开发方法。它是一种系统分析与设计的框架&#xff0c;主要用于设计和建模面向对象的系统。Booch方法特别关注对象模型的构建&#xff0c;以及类、对象和它们之间的关系。以下是Booch方法…...

高阶面试-concurrentHashMap的整理

算不上死磕&#xff0c;里面太痛苦了&#xff0c;现在很多位移等操作还看不懂&#xff0c;只是先理清大致思路&#xff0c;面试用 concurrentHashMap的实现原理 为啥会用到&#xff1f;并发安全。之前都用的hashtable实现线程安全的map&#xff0c;但是太过笨重&#xff0c;不…...

VSCode系列 - 如何用VSCode搭建C++高效开发环境(1)

VSCode是笔者用过的最好用的开发工具&#xff0c;没有之一。笔者14年的码龄生涯中&#xff0c;先后用过Eclipse、 IntelliJ IDEA、 WebStorm、 PyCharm、 Visual Studio(2010/2013/2015)、 NetBeans、 Sublime Text等&#xff0c;但自从用VSCode之后&#xff0c;就再没换过其他…...

【人工智能】Python融合机器学习、深度学习和微服务的创新之路

1. &#x1f680; 引言1.1 &#x1f680; 人工智能的现状与发展趋势1.2 &#x1f4dc; 机器学习、深度学习和神经网络的基本概念1.3 &#x1f3c6; 微服务架构在人工智能中的作用 2. &#x1f50d; 机器学习的演变与创新2.1 &#x1f31f; 机器学习的历史回顾2.2 &#x1f9e0;…...

Stability AI发布了单目视频转4D模型的新AI模型:Stable Video 4D

开放生成式人工智能初创公司Stability AI在3月发布了Stable Video 3D&#xff0c;是一款可以根据图像中的物体生成出可旋转的3D模型视频工具。Stability AI在7月24日发布了新一代的Stable Video 4D&#xff0c;增添了赋予3D模移动作的功能。 Stable Video 4D能在约40秒内生成8…...

网站如何被Google收录?

想让你的网站快速被Google收录&#xff1f;试试GSI快速收录服务吧&#xff0c;这是通过谷歌爬虫池系统来实现的。这套系统吸引并圈养Google爬虫&#xff0c;提高你网站的抓取频率。每天有大量Google爬虫抓取你的网站页面&#xff0c;大大提高了页面的收录概率&#xff0c;从而增…...

LearnOpenGL——法线贴图、视差贴图学习笔记

LearnOpenGL——法线贴图、视差贴图学习笔记 法线贴图 Normal Mapping一、基本概念二、切线空间1. TBN矩阵2. 切线空间中的法线贴图 三、复杂模型四、小问题 视差贴图 Parallax Mapping一、基本概念二、实现视差贴图三、陡峭视差映射 Steep Parallax Mapping四、视差遮蔽映射 P…...

界面优化 - 绘图

目录 1. 基本概念 2. 绘制各种形状 2.1 绘制线段 2.2 绘制矩形 2.3 绘制圆形 2.4 绘制文本 2.5 设置画笔 2.6 设置画刷 3. 绘制图片 3.1 绘制简单图片 3.2 平移图片 3.3 缩放图片 3.4 旋转图片 1. 基本概念 虽然 Qt 已经内置了很多的控件, 但是不能保证现有控件就…...

业务系统对接大模型的基础方案:架构设计与关键步骤

业务系统对接大模型&#xff1a;架构设计与关键步骤 在当今数字化转型的浪潮中&#xff0c;大语言模型&#xff08;LLM&#xff09;已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中&#xff0c;不仅可以优化用户体验&#xff0c;还能为业务决策提供…...

OpenLayers 可视化之热力图

注&#xff1a;当前使用的是 ol 5.3.0 版本&#xff0c;天地图使用的key请到天地图官网申请&#xff0c;并替换为自己的key 热力图&#xff08;Heatmap&#xff09;又叫热点图&#xff0c;是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...

C++初阶-list的底层

目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...

基于ASP.NET+ SQL Server实现(Web)医院信息管理系统

医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上&#xff0c;开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识&#xff0c;在 vs 2017 平台上&#xff0c;进行 ASP.NET 应用程序和简易网站的开发&#xff1b;初步熟悉开发一…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

【ROS】Nav2源码之nav2_behavior_tree-行为树节点列表

1、行为树节点分类 在 Nav2(Navigation2)的行为树框架中,行为树节点插件按照功能分为 Action(动作节点)、Condition(条件节点)、Control(控制节点) 和 Decorator(装饰节点) 四类。 1.1 动作节点 Action 执行具体的机器人操作或任务,直接与硬件、传感器或外部系统…...

Java 加密常用的各种算法及其选择

在数字化时代&#xff0c;数据安全至关重要&#xff0c;Java 作为广泛应用的编程语言&#xff0c;提供了丰富的加密算法来保障数据的保密性、完整性和真实性。了解这些常用加密算法及其适用场景&#xff0c;有助于开发者在不同的业务需求中做出正确的选择。​ 一、对称加密算法…...

管理学院权限管理系统开发总结

文章目录 &#x1f393; 管理学院权限管理系统开发总结 - 现代化Web应用实践之路&#x1f4dd; 项目概述&#x1f3d7;️ 技术架构设计后端技术栈前端技术栈 &#x1f4a1; 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 &#x1f5c4;️ 数据库设…...

从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障

关键领域软件测试的"安全密码"&#xff1a;Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力&#xff0c;从金融交易到交通管控&#xff0c;这些关乎国计民生的关键领域…...

云原生周刊:k0s 成为 CNCF 沙箱项目

开源项目推荐 HAMi HAMi&#xff08;原名 k8s‑vGPU‑scheduler&#xff09;是一款 CNCF Sandbox 级别的开源 K8s 中间件&#xff0c;通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度&#xff0c;为容器提供统一接口&#xff0c;实现细粒度资源配额…...