06-函数嵌套调用与递归调用课件
C语言中函数嵌套调用和递归调用

函数嵌套与递归调用的区别
函数嵌套是语言特性,递归调用是逻辑思想。
1 函数嵌套
函数嵌套允许在一个函数中调用另外一个函数,比如有三个函数
例:
funca()
{
funcb();
}
funcb()
{
funcc();
}
funcc()
{
cout << "Hello" <<endl;
}
这个就叫做嵌套调用,它是一个语言提供的程序设计的方法,也就是语言的特性。
2 递归调用
而递归是一种解决方案,一种思想,将一个大工作分为逐渐减小的小工作,比如说一个和尚要搬50块石头,他想,只要先搬走49块,那剩下的一块就能搬完了,然后考虑那49块,只要先搬走48块,那剩下的一块就能搬完了……,递归是一种思想,只不过在程序中,就是依靠函数嵌套这个特性来实现了。
递归最明显的特点就是,自己调用自己。
例:
funca()
{
if(statement1)
funca();
else
exit(0);
}
3 总结
概括说,函数嵌套就是函数调用函数,是普遍的,递归就是函数调用自身,使函数嵌套的一个特例。
嵌套调用就是某个函数调用另外一个函数,递归调用是一个函数直接或间接的调用自己。
举几个例子:A调用B(嵌套)B调用C(嵌套)A调用A(递归)A 调用B B调用A (递归)A调用B B调用C C调用A (递归)。
12 函数声明、函数嵌套调用、递归函数、数组做函数参数

教学内容:函数声明、函数嵌套调用、递归函数、数组做函数参数教学目标1.掌握函数声明的格式2.理解函数嵌套调用的过程3.理解函数递归调用的过程;掌握常用递归函数的编写4.掌握数组名作为函数参数的应用重点难点1.函数的递归调用2.数组名作为函数参数教学方法与手段1.讲授、实验法2.多媒体教学内容及教学过程一.函数的声明⏹如果使用自己定义的函数,而该函数的位置在调用它的函数后面,应该声明示例说明:输入两个实数,用一个函数求出它们之和。
#include <stdio.h>int main( ){ float add(float x, float y); //函数声明语句float a,b,c;printf("Please enter a and b:");scanf("%f,%f",&a,&b);c=add(a,b);printf("sum is %f\n",c);return 0;}float add(float x,float y){ float z;z=x+y;return(z);}⏹函数声明的形式:float add(float x, float y); float add(float, float);二.函数的嵌套调用◆ C语言的函数定义是互相平行、独立的◆ 即函数不能嵌套定义◆ 但可以嵌套调用函数◆ 即调用一个函数的过程中,又可以调用另一个函数三.函数的递归调用1、函数递归调用的概念在调用一个函数的过程中又出现直接或间接地调用该函数本身,称为函数的递归调用2、递归函数示例age(5)=age(4)+2age(4)=age(3)+2age(3)=age(2)+2 age(2)=age(1)+2age(1)=10递归的两个阶段:回溯阶段和递推阶段#include <stdio.h>int main(){ int age(int n);printf("NO.5,age:%d\n",age(5));return 0;}int age(int n){ int c;if(n==1) c=10;else c=age(n-1)+2;return(c);}3、用递归方法求n !)1(2)1()()1(10)(>+-===n n age n age n n age ⎧===)1,0(1!!n n nint fac(int n){int f;if(n<0)printf("n<0,data error!");else if(n==0 | | n==1)f=1;else f=fac(n-1)*n;return(f);}注意溢出4、Hanoi塔问题介绍Hanoi塔问题的设计思路,理解算法思想即可。
c语言--函数的递归调用PPT参考幻灯片

第机作业:num(n)= 2* (num(n+1)+1) (n<10)
❖ 说有一只调皮的小猴子,摘了一堆水果,第一天 吃了水果的一半,又多吃了一个;第二天吃了剩 下水果的一半,又多吃了一个;依次类推….到第 十天,发现只剩下了10个水果,请问这只猴子到 底摘了多少个水果?
16
可以看到: 1)、3)为同一问题,都为n –1个盘子借助于一个 空塔移至另一塔上。
10
计
例11 Hanoi问题
第五章 函数
A
B
C
11
计
12
程序如下:
A
B
C
A
B
C
A
B
C
A
B
C
第五章 函数
void move(char getone, char putone) {printf("%c--->%c\n",getone,putone); }
1
第五章 函数
张福祥 主编
辽宁大学出版社
1
计
2
第五章 函数
我们先看这样一个例子:
❖ 说有一只调皮的小猴子,摘了一堆水果,第一天 吃了水果的一半,又多吃了一个;第二天吃了剩 下水果的一半,又多吃了一个;依次类推….到第 十天,发现只剩下了1个水果,请问这只猴子到 底摘了多少个水果?
2
计
3
第五章 函数
第五章 函数
age(int n) { int c;
if(n==1) c=10; else c = age(n-1)+2; return(c) ; }
age(5)
n=5
n=4
n=3
n=2
n=1
函数的嵌套调用和递归调用

【程序设计】
--------------------------------------------------
功能:求k!(k〈13),所求阶乘的值作为函数值返回。
(要求使用递归)
------------------------------------------------*/
【程序填空】
---------------------------------------------------------
题目:下面程序的功能是用递归法求n!。
-------------------------------------------------------*/
#include
void main()
{
/***********SPACE***********/
【?】;
int n;
long y;
printf("input an integer number:");
scanf("%d",&n);
/***********SPACE***********/
y=【?】;
printf("%d!=%ld\n",n,y);
B) C语言程序中,main函数是没有参数的
C)一个函数通过其他函数间接的调用了自身,这种情况也是一种递归调用
D)若要通过函数参数带回一个或多个返回值,则应使用按地址传送的参数结合方式
答案:B
有以下程序:
#include
fun(int n)
{ if(n==1|| n==2)return 2;
嵌套与递归

递归计算n 递归计算n!
之前,我们曾用循环的方法实现了n!的计算。现在 之前,我们曾用循环的方法实现了n!的计算。现在 我们用递归的方法计算。n 我们用递归的方法计算。n!可以!
n=0 n>0
按照这个公式,可以将求 的问题变成求 的问题变成求( 的问题。 按照这个公式,可以将求n!的问题变成求(n-1)!的问题。因为当 的问题 求出以后, 的问题, (n-1)!求出以后,再乘以 ,就是 。而求(n-1)!的问题,又可以变 求出以后 再乘以n,就是n!。而求( 的问题 成求( 的问题, 成求(n-2)!的问题,如此继续,直到最后变成求 !的问题,而根据 的问题 如此继续,直到最后变成求0!的问题, 公式有0!= 再反过来依次求出1!, !,3! !=1,再反过来依次求出 !,2!, 公式有 != 再反过来依次求出 !, !, !……,直到最后求出 , n!。 。
结论1:在主程序的VAR说明区 中定义的变量称为全程变量。其 作用域是主程序的执行部分,如 果主程序的执行部分中调用了函 数或过程,则全程变量的作用域 也包括函数或过程在内。 结论2:在函数或过程的VAR说明 区中定义的变量称为局部变量。其 作用域是该函数或过程的执行部分, 如果该函数或过程的执行部分中还 调用了下级函数或过程,则局部变 量的作用域也包括下级函数或过程 在内。
函数或过程调用它本身,称为递归。函数 或过程a直接调用a 或过程a直接调用a本身,称直接递归。函数 或过程a调用函数或过程b 或过程a调用函数或过程b,b又调用a,称为 又调用a 间接递归。
递归在解决某些问题中,是一个十分有用的方法, 递归在解决某些问题中,是一个十分有用的方法,它可以使 某些看起来不易解决的问题变得容易解决, 某些看起来不易解决的问题变得容易解决,写出的程序较简 短,但是递归通常要花费较多的机器时间和占用较多的存储 空间,效率不太高。 空间,效率不太高。
c++函数--ppt课件

28
ppt课件
函数的嵌套调用和递归调用
❖ 函数的嵌套调用 ➢ 嵌套调用是指在一个函数体中调用另一个函数。 ➢ 注意,函数可以嵌套调用,但是不能嵌套定义!
main
A
B
C
D
E
29
ppt课件
函数的嵌套调用和递归调用
#include <iostream.h> void fun1(),fun2(),fun3(); void main() {
❖ 什么是函数 ➢函数(function)就是一段实现某个功能的代 码。
6
ppt课件
什么是函数
❖ 一个程序包含若干个函数(但只有一个主函数),程 序从主函数开始执行。
❖ 执行过程中,主函数调用其它函数,其他函数相互调 用。
❖ 实际应用中,主函数一般比较简单,作用就是调用其 它函数,而程序的功能全部都是由函数实现的。
函数
主要内容
1. 什么是函数? 2. 函数的定义和说明 3. 函数的参数和返回值 4. 函数的参数和返回值 5. 函数的调用方式 6. 函数的嵌套调用和递归调用
2
ppt课件
什么是函数
❖ 编写函数,计算并打印若干给定整数(1、3、4) 的阶乘,要求每次打印数据后打印一行星号(10 个)。 1 ********************** 6 ********************** 24 ********************** ……
14
ppt课件
函数的参数和返回值
❖ 1、函数的参数
➢ 在未被调用时,形参没有确定值,只是形式上的参
数,只有被调用时才从调用函数中获得实际参数。
void fun(int m){ cout<<m;
函数的嵌套调用和递归调用

说明: (1)一个C程序由一个或多个程序模块组成,每一个 程序模块作为一个源程序文件。 对于较大的程序,一般不把所有内容全放在一个源 程序文件中,而是将它们分别放在若干个源文件中, 由若干个源程序文件组成一个C程序。 这样便于分别编写、分别编译,提高调试效率。 一个源程序文件可以为多个C程序所调用。
解题思路:
要求第5个年龄,就必须先知道第4个年龄 要求第4个年龄必须先知道第3个年龄 第3个年龄又取决于第2个年龄 第2个年龄取决于第1个年龄 每个学生年龄都比其前1个学生的年龄大2
age(5)=age(4)+2 age(4)=age(3)+2 age(3)=age(2)+2 age(2)=age(1)+2 age(1)=10
课前预习将手机调到静音认真做笔记及时完成作业了解函数的含义学会定义和调用函数的方法函数的嵌套调用函数的递归调用函数的概念定义和调用函数函数的嵌套调用函数的递归调用71函数概述如果程序的功能比较多规模比较大把所有的程序代码都写在一个主函数中就会使主函数变得庞杂头绪不清使阅读和维护程序变得困难
上课要求
(2) 一个源程序文件由一个或多个函数以及其他有 关内容组成。一个源程序文件是一个编译单位,在 程序编译时是以源程序文件为单位进行编译的,而 不是以函数为单位进行编译的。 (3) 不论main函数出现在什么位置,总是从main函 数开始执行。如果在main函数中调用其他函数,在 调用后流程返回到main函数,在main函数中结束整 个程序的运行。
课前预习 将手机调到静音 认真做笔记 及时完成作业
学习目标
了解函数的含义 学会定义和调用函数的方法 函数的嵌套调用 函数的递归调用
学习内容
函数的概念 定义和调用函数 函数的嵌套调用 函数的递归调用
函数的嵌套及递归调用

四、函数的嵌套及递归调用
2.函数的递归调用
fac(4) =fac (3)*4
fac (4) =24
fac (3) =fac (2)*3
结束条件
fac (3) =6
fac (2) =fac (1)*2
fac (2) =2
递推阶段
fac (1) =1
回归阶段
四、函数的嵌套及递归调用
2.函数的递归调用 【例2】5个人坐在一起报岁数,问 第5个人几岁?他说比第4个人大两 岁;问第4个人几岁?他说比第3个 人大两岁;问第3个人几岁?他说比 第2个人大两岁;问第2个人几岁? 他说比第1个人大两岁;最后问第1 个人几岁?他说10岁。
四、函数的嵌套及递归调用
2.函数的递归调用 • 递推阶段:递推归纳,逐层调用,调用函数自身,直至
递归结束条件,这时递推阶段结束。
• 回归阶段:逐层求值回归,返回到调用该层的位置,结 束回归阶段,完成递归调用。
四、函数的嵌套及递归调用
2.函数的递归调用 【例1】用递归调用的方法求n!
n!=n*(n-1)*(n-2)*……*1=n(n-1)!。
四、函数的嵌套及递归调用
2.函数的递归调用
四、函数的嵌套及递归调用
2.函数的递归调用 一个函数(除主函数)直接或间接调用自己称为递归调用。
直接递归
间接递归
四、函数的嵌套及递归调用
2.函数的递归调用
递归(recursion)满足2个条件: ①有反复执行的过程(调用自身) ②有跳出反复执行过程的条件(递归出口)。
四、函数的嵌套及14
10
有终止 18 16
age(n)
10 age(n
1)
2
n 1 n 1
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
int x, y, z, max; scanf("%d%d%d",&x,&y,&z); max = Max3(x, y, z); printf("max=%d\n",max); return 0; }
int Max3(int a, int b, int c) {
int max; max = Max(a, b); max = Max(max, c); return max; }
else f = n*fact(n-1);
y = fact(n);
return f;
printf("%d!=%ld\n", n,y);
}
}
main函数
fact函数
fact函数
fact函数
y=fact (3)
f=3*fact (2)
f=2*fact (1)
f=1
return 6
return 2
return 1
8
例4 用递归方法计算 n!
n!
1 n(n -
1)!
递归的终止条件 n 0,1 n 1
#include <stdio.h>
void main()
递归方式
long fact(int n)
{ long y;
{ long f;
int n;
if(n==1||n==0) f = 1;
scanf("%d", &n);
int age(int n); int n; scanf(("%d", &n); printf("NO. 5, age: %d\n" ,age(n));
14
long sum( int n ) //素数求和 { int i;
long s = 0; for( i=2; i<=n; i++ )
if ( isprime(i)==1 ) s = s+i; return s; }
int isprime( int m ) //判断素数 { int i, k;
k=sqrt(m); for( i=2; i<=k; i++ )
age(n) 10
(n 1)
age(n) age(n 1) 2 (n 1)
12
#include <stdio.h> int age(int n) { int c;
age(n) 10 age(n) age(n 1) 2
if(n==1) c = 10;
else c = age(n-1) + 2;
– 存在递归的终止条件; – 存在导致问题求解的递归方式。 – 递归方法:递推、回归。
• 使用递归的优缺点
- 优点:程序简洁,代码紧凑。 - 缺点:每调用函数一次,在内存堆栈区分配空间,用于存放
函数变量、返回值等信息。所以递归次数过多,可能引起 堆栈溢出,且时间效率较差。
7
递归函数fact求解求9的阶乘过程
嵌套调用:在调用一个函数的过程中,又调用另一个函数。 C语言不能嵌套定义,但可以嵌套调用!
main( ) 调用函数a 结束
a函数
调用函数b
b函数
——函数嵌套调用的示意图
1
例3 函数嵌套调用实例—求三个变量中的最大值。
#include <stdio.h> int Max3(int a, int b, int c); int Max(int a, int b);
max = Max3(x, y, z);
int Max(int a, int b)
printf("max=%d\n",max);
return 0;
}
输出:max= 8
{ ⑤ if( a > b ) return a; ⑧ else return b; }
2x 5y 8z 8 max ……
2a 5b 8c 58 max …… 25 a 85 b
int Max(int a, int b) {
if( a > b ) return a; else return b; }
例3 求三个变量的最大值程序调用执行过程。
内存示意图
~
#include <stdio.h> int Max3(int a, int b, int c); int Max(int a, int b);
if( m%i == 0 ) return 0; return 1; }
什么是递归调用?
在调用一个函数的过程 中又出现直接或间接地调用 该函数本身,称为函数的递 归调用。
前者称为直接递归,后 者称为间接递归。
C语言的特点之一就在 于允许函数的递归调用。
直接递归 间接递归
6
递归函数的执行过程
• 用递归求解问题的特点
int Max3(int a, int b, int c) {
③ int max;
int main()
max = Max(a, b);
{
②
max = Max(max, c);
① int x, y, z, max;
}
scanf("%d%d%d",&x,&y,&z); ⑩
return max;
④⑦
⑥ ⑨
10
解题思路: • 要求第5个年龄,就必须先知道第4个年龄; • 要求第4个年龄必须先知道第3个年龄; • 第3个年龄又取决于第2个年龄; • 第2个年龄取决于第1个年龄; • 每个学生年龄都比其前1个学生的年龄大2岁。
11
解题思路:
age(5) = age(4) + 2 age(4) = age(3) + 2 age(3) = age(2) + 2 age(2) = age(1) + 2 age(1) = 10
fact(9)=9*fact( 8) fact(8)=8*fact( 7)
fact(9)=9*fact( 8) fact(8)=8*fact( 7)
·····
·····
递 fact(3)=3*fact( 2)
fact(3)=3*2*1
回
推
fact(2)=2*fact( 1)
fact(2)=2*1
归
fact(1)=1
9
练习:利用递归求解下列问题。 有 5 个学生坐在一起, • 问第 5 个学生多少岁?他说比第 4 个学生大 2 岁; • 问第 4 个学生岁数,他说比第 3 个学生大 2 岁; • 问第 3 个学生,又说比第 2 个学生大 2 岁; • 问第 2 个学生,说比第 1 个学生大 2 岁; • 最后问第 1 个学生,他说是 10 岁; • 请问第 5 个学生的年龄是多少?
例4 求 1~n 之间所有素数的和。 问题分析: • 该问题的主体结构是求和运算,而参与求和的数是 1~n
之间的素数。 • 程序编写main函数和判断素数以及求素数和的2个函数。 • 求素数:用2,3,4…… ������ 依次除n,如果n能被2~ ������中任
何一个数整除,则不是素数,否则即是素数。 • 程序分3步求解:
retur输出结果:
{
printf("NO. 5, age: %d\n ", age(5));
return 0;
}
(n 1) (n 1)
13
#include <stdio.h> int main() {
int age(int n); printf("NO. 5, age: %d\n ", age(5)); return 0; } int age(int n) { int c; if(n==1) c = 10; else c = age(n-1) + 2; return(c); }
① 输入n的值;
② 求和运算(在求和计算中调用判断素数函数);
③ 输出结果。
例4 求 1~n 之间所有素数的和。
#include <stdio.h> #include <math.h> long sum( int n ); int isprime( int m ); int main() {
int n; long s; scanf("%d", &n); s = sum(n); printf("Sum = %ld\n", s); return 0; }