C语言程序设计P5-3【应用函数进行程序设计 | 第三节】——知识要点:函数的嵌套调用和递归调用

news2024/12/30 1:47:43

知识要点:函数的嵌套调用和递归调用

视频

目录

一、任务分析

二、必备知识与理论

三、任务实施


一、任务分析

本任务要求用递归法求 n!。

我们知道n!=n×(n-1)×(n-2)×……×1=n(n-1)!递归公式为:

1.上面公式分解为n!=n×(n-1)!,即将求n!的问题变为求(n-1)!的问题,(n-1)!= (n-1)×(n-2)!,即将求(n-1)!的问题变为求(n-2)!的问题,再将求(n-2)!的问题变为求(n-3)!的问题,依此类推,直到最后成为求0!,这是递推过程;

2.反过来求0!=1,1!,2!,3!,……,n!,为“回归过程”。

二、必备知识与理论

 1.函数的嵌套调用

在C语言中,函数定义都是互相平行、独立的模块,无隶属关系,只存在调用和被调用的关系,除了主函数不能被其他函数调用外,其它函数之间都可以互相调用。

【例5.4】写两个函数,分别求两个整数的最大公约数和最小公倍数,用主函数调用这两个函数,并输出结果。

算法分析:在数学上,两数的最小公倍数=两数乘积/两数的最大公约数。

求两个数的最大公约数应用辗转相除法:已知两个整数M和N,假定M>N,则求M%N,若余数r为0,则N即为所求;若余数r不为0,用N除r,再求其余数……直到余数为0,则除数就是M和N的最大公约数。

程序代码如下:

#include <stdio.h>

int gcd(int a,int b)  /* 求最大公约数——辗转相除法 */

{ int r,t;

if(a<b)

  {t=a;a=b;b=t;}

   r=a%b;

   while(r!=0)

{a=b;

b=r;

r=a%b; }

return (b);

 }

int lcm(int a,int b)   /* 求最小公倍数 */

{

  int r;

r=gcd(a,b);

return(a*b/r);

}

main()   /* 主函数 */

{

int x,y; 

printf("please input two numbers:\n"); 

scanf("%d,%d",&x,&y); 

printf("%d\n",gcd(x,y));

  printf("%d\n",lcm(x,y));

}

运行结果:

please input two numbers:

66,78↙

6

     858

在这个例子中,主函数首先调用了函数gcd()求最大公约数,然后调用函数lcm()求最小公倍数,而在函数lcm()中又调用了函数gcd(),这就是一个函数嵌套调用的过程。

注意:①函数之间没有从属关系,一个函数可以被其它函数调用,同时该函数也可以调用其它函数。

②在C语言中,函数可以嵌套调用,但不可以嵌套定义。

2.函数的递归调用

函数的递归调用实际上是函数嵌套调用的一种特殊情况。在调用一个函数的过程中直接或间接地调用该函数本身,称为函数的递归调用。直接调用称为直接递归调用,间接调用称为间接递归调用。程序中常用的是直接递归。将这种在函数体内调用该函数本身的函数称为递归函数。

三、任务实施

用递归的方法求n!

我们知道n!=n×(n-1)×(n-2)×……×1=n(n-1)!递归公式为:

算法分析:

(1)上面公式分解为n!=n×(n-1)!,即将求n!的问题变为求(n-1)!的问题,(n-1)!= (n-1)×(n-2)!,即将求(n-1)!的问题变为求(n-2)!的问题,再将求(n-2)!的问题变为求(n-3)!的问题,依此类推,直到最后成为求0!,这是递推过程;

(2)反过来求0!=1,1!,2!,3!,……,n!,为“回归过程”。

(3)以求4的阶乘为例,4!=4×3!,3! =3×2!,2!=2×1!,1!=1,0!=1,它的递归结束条件是当n=1或n=0时,n!=1。

#include <stdio.h>

float fac(n)

{ float f;

  if(n<0) printf("n<0,data error\n");

  else if(n==0||n==1) f=1;

  else f=fac(n-1)*n;   /* 递归调用 */

  return(f);

}

main()

{

 int n;

 float y;

 printf("input an integer number:");

 scanf("%d",&n);

y=fac(n);    /* 调用递归函数 */

 printf("%d!=%10.0f\n",n,y);

}

运行情况如下:

input an integer number:4↙

4!=        24

递归过程分为两个阶段,第一阶段是“回推”阶段,即将求解4!变成求解4×3!,3!变成求解3×2!……直到1!=1为止;第二阶段是“递推”阶段,即根据2×1!得到2!,再根据3×2!得到3!,4×3!得到4!,结果为24。显然,在一个递归过程中,回推阶段是有限的递归调用过程,这样就必须要有递归结束条件,否则会无限地递归调用下去。

本例的递归结束条件为:当n的值为0或为1时,fac(n)的值为1; n<0时,作为错误输入数据。

在递推阶段中,函数执行完后必定要返回主调函数,通过return语句将fac(n)的值带回到上一层fac(n)函数,一层一层返回,最终在主函数中得到fac(4)的结果。

注意:一个合法的递归应该由两部分构成,一是递推公式,二是结束条件,缺少任何一个都无法利用递归解决问题。

最后对递归函数作如下概括:

(1)有些问题既可以用递归的方法解决,也可以用递推的方法解决。有些问题不用递归是难以得到结果的,如汉诺塔。某些问题,特别是与人工智能有关的问题,本质上是递归的。

(2)递归函数算法清晰,代码简练。如汉诺塔问题可谓复杂,程序却极为简单。

(3)从理论上讲,递归函数似乎很复杂,其实它是编程中一类问题的算法,最为直 接。一旦熟悉了递归,它就是处理这类问题的最清晰的方法。

(4)C编译系统对递归函数的自调用次数没有限制,但当递归层次过多时,可能会引起内存不足而造成运行出错,尤其是函数内部定义较多的变量和较大的数组时。

(5)函数递归调用时,在栈上为局部变量和形参分配存储空间,并从头执行函数代 码。递归调用并不复制函数代码,只是重新分配相应的变量,返回时再释放存储空间。递归需要保存变量、断点、进栈、出栈,增加许多额外的开销,会降低程序的运行效率,所以程序设计中又有一个递归消除的问题。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2255282.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

word实践:正文/标题/表图等的共用模板样式设置

说在前面 最近使用word新建文件很多&#xff0c;发现要给大毛病&#xff0c;每次新建一个word文件&#xff0c;标题/正文的字体、大小和间距都要重新设置一遍&#xff0c;而且每次设置这些样式都忘记了参数&#xff0c;今天记录一下&#xff0c;以便后续方便查看使用。现在就以…

【工具变量】上市公司企业劳动密集度数据(2008-2023年)

一、测算方式&#xff1a; 参考《数量经济技术经济研究》陈勇兵&#xff08;2023&#xff09;老师的做法&#xff0c;使用员工数量与销售收入的比值作为劳动密集度的度量标准* o/ b% C( e* U我们做的比他完善&#xff0c;分为四类大家可以做核心变量或者稳健性检验Labor1&…

YOLOv11修改推理图片的标签字体大小

先打开ultralytics/utils/plotting.py&#xff0c;并搜索font scale(vscode快捷键ctrlF): 在这行代码动手脚&#xff0c;例如调小分母就是把字改大&#xff1a; self.sf self.lw 完成&#xff0c;可以正常运行&#xff1a;

TCP Analysis Flags 之 TCP Spurious Retransmission

前言 默认情况下&#xff0c;Wireshark 的 TCP 解析器会跟踪每个 TCP 会话的状态&#xff0c;并在检测到问题或潜在问题时提供额外的信息。在第一次打开捕获文件时&#xff0c;会对每个 TCP 数据包进行一次分析&#xff0c;数据包按照它们在数据包列表中出现的顺序进行处理。可…

在paddle中安装python-bidi出错

翻看网上解决方式&#xff0c;是由于系统中缺少 Rust 及其包管理器 Cargo。python-bidi 依赖 Rust 来编译其扩展&#xff0c;如果没有安装 Rust 和 Cargo&#xff0c;安装过程将无法继续。 解决方式 curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh但是我的终端…

自动化测试工具Ranorex Studio(五十四)-CSV文件

CSV文件 你也可以通过选择CSV文件数据连接器来使用CSV文件为你的测试套件提供数据。在添加了CSV数据连接器后&#xff0c;管理数据源的对话框将被打开。 你可以在表色标示部分编辑数据连接器的名字&#xff0c;也可以在绿色标示的部分选择你要用的CSV文件。选择或者取消蓝色标示…

Flume基础概念

目录 作用组件构成ClientFlowAgentSourceSinkEvent 和Log4j的区别与定位事务传出流程输入到sourcesource端输入Channel 接收输入到SinkSink输出 作用 Flume可以从各种来源&#xff08;如日志文件、消息队列、网络数据、文件系统、数据库等&#xff09;收集数据&#xff0c;并将…

FPGA实战篇(IP核之MMCM/PLL实验)

1.MMCM/PLL IP 核简介 锁相环作为一种反馈控制电路&#xff0c;其特点是利用外部输入的参考信号控制环路内部震荡信号的频率和相位。因为锁相环可以实现输出信号频率对输入信号频率的自动跟踪&#xff0c;所以锁相环通常用于闭环跟踪电路。 锁相环在工作的过程中&#xff0c;当…

Numpy基础练习

import numpy as np 1.创建一个长度为10的一维全为0的ndarray对象,然后让第5个元素等于1 n np.zeros(10,dtypenp.int32) n[4] 12.创建一个元素从10到49的ndarray对象 n np.arrange(10,50)3.将第2题的所有元素位置反转 n[::-1]使用np.random.random创建一个10*10的ndarray对象…

Probabilistic Face Embeddings 论文阅读

Probabilistic Face Embeddings 论文阅读 Abstract1. Introduction2. Related Work3. Limitations of Deterministic Embeddings4. Probabilistic Face Embeddings4.1. Matching with PFEs4.2. Fusion with PFEs4.3. Learning 5. Experiments5.1. Experiments on Different Bas…

基于SSM框架企业人事管理系统的设计与实现

系统合集跳转 源码获取链接 一、系统环境 运行环境: 最好是java jdk 1.8&#xff0c;我们在这个平台上运行的。其他版本理论上也可以。 IDE环境&#xff1a; Eclipse,Myeclipse,IDEA或者Spring Tool Suite都可以 tomcat环境&#xff1a; Tomcat 7.x,8.x,9.x版本均可 操作系统…

云数据库 MongoDB

MongoDB 是一个基于文档的 NoSQL 数据库&#xff0c;它与传统的关系型数据库不同&#xff0c;采用的是灵活的文档结构&#xff08;类似 JSON 格式&#xff09;。MongoDB 是开源的&#xff0c;且高度可扩展&#xff0c;通常用于处理大量的非结构化或半结构化数据。 云数据库 Mon…

AcWing 3496. 特殊年份

文章目录 前言代码思路 前言 写简单题没啥。反正都是要写的&#xff0c;先把能拿到的分数拿了&#xff0c;之后有机会再去啃一啃硬骨头。啃不下来就算了。 代码 #include<bits/stdc.h> using namespace std; char a1[10],a2[10],a3[10],a4[10],a5[10]; int main(){cin…

Vite+Vue3项目实战:组件化开发与通信指南

一、典型的ViteVue3项目结构 续上文成功创建Vue3项目的脚手架&#xff0c;通过visual Studio Code软件打开刚刚创建的文件夹&#xff0c;将会看到这样一个项目结构。 使用Vite构建Vue3项目时&#xff0c;项目结构通常遵循一定的组织规则&#xff0c;以保持代码的清晰和可维护性…

Html笔记()蜘蛛纸牌之卡牌吸附

目的 蜘蛛纸牌中要实现牌组的连接&#xff0c;就需要吸附功能。从效果图中可以看出我们把一张牌拖到另一张卡牌上的时候&#xff0c;它会自动吸附过去并且左对齐。 效果 代码 <!DOCTYPE html> <html><head><style>body {display: flex;justify-cont…

CDC YAML 在阿里云的最佳实践

摘要&#xff1a;本文投稿自阿里云开源大数据平台数据通道团队&#xff0c;主要介绍了 Flink CDC YAML 在实时计算Flink版的最佳实践。内容分为以下五个部分&#xff1a; CDC YAML 简介CDC YAML 核心能力CDC YAML 应用场景阿里云 Flink CDC 企业级功能十分钟在阿里云免费实现一…

在21世纪的我用C语言探寻世界本质——字符函数和字符串函数(2)

人无完人&#xff0c;持之以恒&#xff0c;方能见真我&#xff01;&#xff01;&#xff01; 共同进步&#xff01;&#xff01; 文章目录 一、strncpy函数的使用二、strncat函数的使用三、strncmp函数的使用四、strstr的使用和模拟实现五、strtok函数的使用六、strerror和pe…

Cursor vs VSCode:主要区别与优势分析

Cursor - The AI Code Editor 1. AI 集成能力 Cursor的优势 原生AI集成&#xff1a; # Cursor可以直接通过快捷键调用AI # 例如&#xff1a;按下 Ctrl K 可以直接获取代码建议 def complex_function():# 在这里&#xff0c;你可以直接询问AI如何实现功能# AI会直接在编辑器中…

利用 360 安全卫士极速版关闭电脑开机自启动软件教程

在使用电脑的过程中&#xff0c;过多的开机自启动软件会严重拖慢电脑的开机速度&#xff0c;影响我们的使用体验。本教程中简鹿办公将详细介绍如何使用 360 安全卫士极速版关闭电脑开机自启动软件&#xff0c;让您的电脑开机更加迅速流畅。 一、打开 360 安全卫士极速版 在电…

电子信息工程自动化 基于单片机的居室安全报警系统

摘要 本课题设计了基于STM32F103C6T6单片机为主控核心的居室安全报警系统。为了解决家庭居室的安全监控&#xff0c;通过温湿度芯片SHT30、烟雾传感器MQ-2、天然气传感器MQ-4来获取居室的温湿度、烟雾、天然气含量&#xff0c;使用了一个热释电传感器、菲涅耳透镜、红外传感信…