C语言第11讲 函数的嵌套调用和递归调用

合集下载

c语言函数递归调用

c语言函数递归调用

c语言函数递归调用在调用一个函数的过程中又出现直接或间接地调用该函数本身,这种用法称为函数的递归调用。

例如:int f ( int x ){int x,z;z=f(x );//在执行f函数的过程中又要调用f函数return (2+z);}在调用函数f的过程中,又要调用f函数(本函数),这是直接调用本函数。

如果在调用f1函数过程中要调用f2函数,又在调用f2的数过程中又要调用f1,这就是间接调用本函数。

这两种递归调用都是无终正的自身调用,程序中不应出现这种无终止的递归调用,只应出现有限次数的、有终止的递归调用,用if语句来控制,只有在某一条件成立时才继续执行递归调用:否则就不再继续。

如n=1;c=10,没有条件一直调用,有条件把递归调用变已知值,无调用函数,消失了。

例:有5个学生坐在一起,问第5个学生多少岁,他说比第4个学生大2岁,问第4个学生岁数,他说比第3个学生大2岁。

问第3个学生,又说比第2个学生大2岁,问第2个学生,说比第1个学生大2岁。

最后问第1个学生,他说是10岁。

请问第5个学生多大。

每一个学生的年龄都比其前1个学生的年龄大2。

说明共用一个函数关系。

可以用数学公式表述如下:age ( n )=10 (n =1)age ( n )= age ( n -1)+2 ( n >1)当n > 1时,不断调用同一个函数,就是一个递归问题。

回溯将第5个学生的年龄表示直到第1个学生的年龄。

此时age (1)已知等于10,没有可调用函数,出现已知值,不再出现调用。

从第1个学生的已知年龄推算出第2个学生的年龄(12岁),一直推算出第5个学生的年龄18岁为止。

如果要求递归过程不是无限制进行下去,必须具有一个结束递归过程的条件。

就是要出现已知值,不再调用下去。

如:age (1)=10,就是使递归结束的条件,出现已知值,不再调用了,也就终止递归了。

编写程序:用一个函数来描述上述递归过程:int age ( int n )//求年龄的递归函数,内有调用自身的函数。

c语言函数嵌套调用举例

c语言函数嵌套调用举例

c语言函数嵌套调用举例在C语言中,函数嵌套调用是一种常见的编程技巧,它能够充分利用函数的模块化特性,使程序结构更加清晰,并提高代码的复用性。

本文将以函数嵌套调用为主题,深入探讨其实际应用,并通过举例让读者更好地理解和掌握这一编程技巧。

首先,让我们来了解一下函数的概念。

在C语言中,函数是一段执行特定任务的独立代码块,它可以接受输入参数,并返回一个值。

通过将程序划分为多个函数,我们可以更好地组织和管理代码,提高代码的可读性和可维护性。

函数嵌套调用是指在一个函数内部调用另一个函数。

通常情况下,被调用的函数可以是系统库函数,也可以是自己定义的函数。

函数嵌套调用的好处是可以将复杂的问题分解为多个简单的子问题,从而使得程序更易于编写和调试。

为了更好地理解函数嵌套调用的具体应用,我们以一个计算数字阶乘的例子来说明。

假设我们需要编写一个函数,输入一个正整数n,计算其阶乘并返回结果。

首先,我们可以定义一个名为factorial的函数来完成阶乘的计算,其代码如下:cint factorial(int n) {if (n == 0 n == 1) {return 1;} else {return n * factorial(n - 1);}}在这个函数中,我们利用了递归的思想来计算阶乘。

当n等于0或1时,阶乘的结果为1,这是一个递归的终止条件。

当n大于1时,我们通过递归调用自身来计算n的阶乘。

具体地,我们将n乘以n-1的阶乘作为递归调用的参数。

现在,我们可以编写一个主函数来测试factorial函数的正确性。

主函数的代码如下:c#include <stdio.h>int main() {int n;printf("请输入一个正整数:");scanf("d", &n);int result = factorial(n);printf("d的阶乘是:d\n", n, result);return 0;}在主函数中,我们首先通过scanf函数从用户输入获取一个正整数n。

C语言函数的递归和调用

C语言函数的递归和调用

C语⾔函数的递归和调⽤函数记住两点:(1)每个函数运⾏完才会返回调⽤它的函数;每个函数运⾏完才会返回调⽤它的函数,因此,你可以先看看这个函数不⾃我调⽤的条件,也就是fun()中if条件不成⽴的时候,对吧,不成⽴的时候就是N==0的时候,所以返回;(2)还有⼀点就是函数实参传给形参之后,形参的变化是不会改变原实参的值的。

c语⾔函数递归调⽤的问题#include <stdio.h>void fun(int);int main(){int a = 3;fun(a);printf("\n");return 0;}void fun(int n){if(n>0){fun(--n);printf("%d", n);fun(--n);}}解释答案为什么是0120过程分析:先调⽤fun(3),fun(3)中调⽤fun(2),fun(2)中调⽤fun(1),fun(1)中调⽤fun(0),此时n=0,,条件不成⽴,这时开始以⼀层⼀层返回,返回到fun(1),fun(1)中第⼀条调⽤完了(刚返回的),--n此时n=0,输出0,然后接着递归调⽤fun(--n),n已经变成-1,这时fun(1)全执⾏完了,返回到fun(2),,同样fun(2)中第⼀条调⽤完了(刚返回的),--n,此时n=1,输出1,然后接着递归调⽤fun(--n),n已经变成0,,这时fun(2)全执⾏完了,返回到fun(3),,同样fun(3)中第⼀条调⽤完了(刚返回的),--n,此时n=2,输出2,然后接着递归调⽤fun(--n),n已经变成1,,在递归调⽤fun(1)中⼜有⼀次输出0(跟前⾯那次调⽤⼀样),,这时fun(3)全执⾏完了,返回到主函数。

理解C语⾔递归函数的逐级返回(return)2016年07⽉05⽇ 10:28:25阅读数:8110递归函数,也即调⽤⾃⾝的函数。

C Primer Plus中有个例⼦很棒:/*理解C语⾔递归函数*/#include<stdio.h>void up_and_down(int);int main(void){up_and_down(1);return 0;}void up_and_down(int n){printf("level %d: n loacation %p\n", n, &n);/*1*/if (n < 4)up_and_down(n + 1);printf("level %d: n loacation %p\n", n, &n);/*2*/}该段代码中,up_and_down不断调⽤⾃⼰,输出如下结果:相信输出level1、level2、level3、level4,很好理解,但是为什么还会输出level4、level3、level2、level1呢?原来,在第⼀次输出level4之后,函数不再继续调⽤up_and_down()函数,⽽是执⾏return语句,此时第四级调⽤结束,把控制返回给函数的调⽤函数,也就是第三级调⽤函数,第三级调⽤函数中前⼀个执⾏过的语句是在if语句中进⾏第四级调⽤,因此,执⾏其后续的代码,也就是语句#2,这将会输出level3。

c语言函数嵌套

c语言函数嵌套

c语言函数嵌套摘要:1.函数嵌套的概念2.函数嵌套的分类3.函数嵌套的实例4.函数嵌套的注意事项正文:C 语言函数嵌套是指在一个函数中调用另一个函数。

这种技术可以实现代码的模块化,使程序更加清晰易懂。

函数嵌套可以分为两类:递归函数和非递归函数。

递归函数是指一个函数在其定义中调用自身。

递归函数通常用于解决具有相似子问题的复杂问题。

例如,计算阶乘的函数就是一个典型的递归函数。

非递归函数是指一个函数在其定义中调用其他函数,而不是调用自身。

这类函数通常用于实现一些具体的功能。

下面是一个函数嵌套的实例。

假设我们需要计算一个数的阶乘,我们可以编写一个递归函数来实现:```c#include <stdio.h>int factorial(int n) {if (n == 1) {return 1;} else {return n * factorial(n - 1);}}int main() {int num;printf("请输入一个正整数:");scanf("%d", &num);printf("数%d的阶乘为:%d", num, factorial(num));return 0;}```在这个例子中,我们定义了一个名为`factorial`的递归函数,用于计算一个数的阶乘。

在`main`函数中,我们调用`factorial`函数来计算用户输入的数的阶乘,并将结果输出。

在使用函数嵌套时,需要注意以下几点:1.确保调用的函数已经定义。

如果调用的函数在当前文件中定义,那么需要在调用函数之前包含该文件。

如果调用的函数在其他文件中定义,那么需要使用`#include`指令包含该文件。

2.确保调用的函数与被调用的函数具有相同的返回类型。

如果返回类型不匹配,需要使用类型转换来解决。

3.避免无限递归。

无限递归会导致程序陷入死循环,导致栈溢出。

c语言函数递归调用

c语言函数递归调用

c语言函数递归调用递归是一种编程技巧,它能够使代码更加简介、易读。

在c语言中,通过函数递归调用实现递归,函数调用本身就是一种递归性的行为。

递归函数实现的程序可读性高,便于理解,当然它也有其自身的一些弊端。

二、函数递归调用函数递归调用比较常用,它的优点主要有:1、代码简洁,可读性高,容易理解。

2、代码量少,运行效率高,可以减少汇编语言代码量。

函数递归调用的一般过程如下:(1)设置递归函数,这个函数将调用自身;(2)检测函数的结束条件;(3)根据递归函数的定义,调用自身;(4)处理函数返回值;(5)退出递归函数。

三、函数递归调用的应用(1)斐波那契数列斐波那契数列是一个非常经典的递归问题,通过函数递归调用实现的代码一般如下:int Fibonacci(int n){if(n == 0 || n == 1)return n;elsereturn Fibonacci(n-1) + Fibonacci(n-2);}(2)汉诺塔问题汉诺塔问题可用函数递归实现,代码一般如下:void Hanoi(int n, char A, char B, char C){if (n == 1)printf('%c-->%c', A, C);else{Hanoi(n-1, A, C, B);printf('%c-->%c', A, C);Hanoi(n-1, B, A, C);}}四、函数递归调用的弊端(1)代码实现的复杂度较大,容易出现程序崩溃或者未知的BUG;(2)实现的代码有一定的浪费,有时会由于重复调用函数导致性能损失;(3)数据量较大时,容易出现栈溢出的问题;(4)不利于代码的优化和维护。

五、总结函数递归调用是一种编程技巧,它可以让代码更加简洁,便于理解和维护,但是同时也有一定的弊端,因此在实际开发中需要合理使用,合理应用才能发挥最大效率。

c语言函数嵌套

c语言函数嵌套

c语言函数嵌套(原创版)目录1.C 语言函数嵌套的概念2.函数嵌套的实现方式3.函数嵌套的注意事项4.函数嵌套的实例解析正文C 语言函数嵌套是指在一个函数中调用另一个函数。

这种技术可以实现代码的模块化和复用,使得程序的设计更加简洁和清晰。

在 C 语言中,函数嵌套可以通过返回值和参数来实现。

首先,让我们了解一下函数嵌套的实现方式。

在 C 语言中,可以通过在函数内部调用另一个函数来实现函数嵌套。

被调用的函数可以是自定义的函数,也可以是系统提供的标准库函数。

调用方式和使用普通函数一样,只是在函数内部进行调用。

其次,函数嵌套的注意事项。

在使用函数嵌套时,应当避免函数调用过深,以免导致程序运行效率降低。

同时,应当注意函数嵌套可能会引发的递归调用过深问题。

如果发现函数嵌套过于复杂,可以考虑使用其他设计模式,如模块化或结构体等。

接下来,我们通过一个实例来解析函数嵌套。

假设我们需要计算一个矩形的面积和周长,可以定义两个函数分别计算面积和周长。

在计算面积的函数中,我们需要知道矩形的长和宽,而这两个参数可以通过用户输入或其他方式获取。

下面是一个简单的函数嵌套实例:```c#include <stdio.h>// 获取用户输入的矩形长和宽void getDimensions(double *length, double *width) {printf("请输入矩形的长:");scanf("%lf", length);printf("请输入矩形的宽:");scanf("%lf", width);}// 计算矩形的面积double calculateArea(double length, double width) {return length * width;}// 计算矩形的周长double calculatePerimeter(double length, double width) { return 2 * (length + width);}int main() {double length, width;getDimensions(&length, &width);double area = calculateArea(length, width);double perimeter = calculatePerimeter(length, width); printf("矩形的面积为:%.2lf", area);printf("矩形的周长为:%.2lf", perimeter);return 0;}```在上面的代码中,我们定义了一个`getDimensions`函数来获取用户输入的矩形长和宽,然后分别调用`calculateArea`和`calculatePerimeter`函数计算矩形的面积和周长。

函数的嵌套调用和递归调用

函数的嵌套调用和递归调用
/*------------------------------------------------
【程序设计】
--------------------------------------------------
功能:求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;

c语言函数的嵌套和递归调用方法的实验小结

c语言函数的嵌套和递归调用方法的实验小结

C语言函数的嵌套和递归调用方法的实验小结一、引言在C语言程序设计中,函数的嵌套和递归调用是两种常用的方法,它们在解决问题和实现特定功能时具有重要作用。

本文将结合实验结果,对C语言函数的嵌套和递归调用方法进行总结和分析,旨在加深对这两种方法的理解和应用。

二、函数的嵌套1. 概念与特点函数的嵌套是指在一个函数内部调用另一个函数。

当函数A中调用了函数B,函数B又调用了函数C,函数C又调用了函数D时,就形成了函数的嵌套调用。

函数的嵌套具有以下特点:(1)提高了程序的模块化和可读性,减少了代码的复杂度。

(2)可以在不同的函数之间传递参数,实现更灵活的功能组合。

(3)需要注意函数的声明顺序和作用域,避免出现未声明的函数引用错误。

2. 实验验证为了验证函数的嵌套调用,在实验中我们设计了一个简单的例子:编写两个函数,分别实现计算阶乘和计算组合数的功能,然后在主函数中进行嵌套调用,计算组合数的值。

实验结果表明,函数的嵌套调用可以实现相互依赖的功能模块,在程序设计中具有一定的灵活性和适用性。

三、递归调用1. 概念与特点递归调用是指一个函数在执行过程中调用了自身,从而形成了一种函数调用的循环结构。

通过递归调用,可以使函数不断重复执行,直到满足特定的条件才停止。

递归调用具有以下特点:(1)简化了程序的结构,使代码更加清晰和易于理解。

(2)能够处理一些需要多级嵌套的问题,极大地提高了代码的复用性和灵活性。

(3)需要设置递归调用的终止条件,避免形成无限循环,导致程序崩溃。

2. 实验验证为了验证递归调用的功能和特点,我们设计了一个典型的递归程序:计算斐波那契数列的前n项值。

实验结果表明,递归调用在实现该问题时具有简洁、高效的特点,使得代码易于阅读和理解,优雅地解决了该问题。

四、两种方法的比较1. 灵活性与适用性函数的嵌套调用主要适用于需要实现不同功能模块之间的交互和依赖关系的情况,具有较强的灵活性和可扩展性。

递归调用主要适用于解决问题具有明显的递归结构或需要多级嵌套的情况,具有较好的适用性和简洁性。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

WANGJINLING
合 肥 工 业 大 学
变量的作用域:变量在程序中的可使用范围(有效性)。 作用域可以是一个函数或一个复合语句,取决于定义变量 的位置,可分为局部变量和全局变量。 1. 局部变量
WANGJINLING
定义在函数内部的变量。也称为内部变量。放在动态区中, 只有调用它的函数才能使用它。调用时才分配内存单元,调用 结束,内存即刻被释放,
模块设计的原则:
内聚性强,耦合性弱。外部变量的使用占 用内存且增加模块的耦合性,使函数的通 用性降低,使程序的模块化、结构化变差 因此,应尽量不使用外部变量。
WANGJINLING
几次调 用函数 ?
合 肥 函数的作用:打印五个’$’ 。 工 业 外部变量应用见p143 例 5.19 大 学
#include<stdio.h> 运行结果: i=1,a=0,b=-10,c=0 综 int i=1; void other(void); i=33,a=4,b=0,c=15 合 void main() i=33,a=0,b=-10,c=8 { static int a; 举 int b=-10,c=0; i=75,a=6,b=4,c=15 例: printf(“i=%d,a=%d,b=%d,c=%d\n”,i,a,b,c); c=c+8; other(); printf(“i=%d,a=%d,b=%d,c=%d\n”,i,a,b,c); i=i+10; other(); ★ 课堂作业: } 编写函数求二维方阵的主对角线上的 void other() { static int a=2; 最大值及其位置。 static int b; 要求:在主函数中输入a[3][3],通过 int c=10; 该函数求a[3][3]主对角线的最大元素 a=a+2; i=i+32; 和位置。 c=c+5; printf(“i=%d,a=%d,b=%d,c=%d\n”,i,a,b,c); b=a; }
#include<stdio.h> void main(void) { char ch ; printf("******\n ") ; ch=getchar() ; if(ch!='9') main() ;
WANGJINLING
} 只有通过控制条件,使递归调用终止,才能应用。
合 肥 工 业 大 学
递归举例:求 n! = n×(n-1)×(n-2)× … × 3×2×1=n×(n-1)! 1 n=0或n=1 n>1 1 n=0或n=1 n>1
合 作用域:仅限于函数内部或复合语句内。 肥 生存期:函数调用期间。 工 注意: 不同的函数或复合语句中可以使用相同的变量名。因为 业 它们作用域不同,所以它们互不干预。即:同名,不同作用 大 域的变量是不同的变量。 学
例: (见p137 例5.13) #include<stdio.h> void func(); main() { int y=10; printf(“1:y=%d\n”,y); func(); printf(“2:y=%d\n”,y); } 运 行 结 果 : 1: y=10 @ x=1 @@ x=3 @@@ x=5 2: y=10 void func() { int x=5; { int x=3; { int x=1; printf(“@ x=%d\n”,x); } printf(“@@ x=%d\n”,x); } printf(“@@@ x=%d\n”,x); }
n!=
n(n-1)!
f(n)=
nf(n-1)
#include <stdio.h> long lfac(long); lfac(4) void main(void) 4*lfac(3) { long i,x; 3*lfac(2) scanf("%ld",&i); 2*flac(1) 递推 x=lfac(i); printf("\n%ld",x); 2*1 4*3*2*1 3*2*1 } long lfac(long n) 回归 { if (n==0||n==1) return 1; else return(n*lfac(n-1)); }
WANGJINLING
合 肥 工 业 大 学
2. 全局变量 定义在函数之外的变量。也称为外部变量。放在静态区中。 作用域:从定义直到文件结束。 生存期:在程序的整个执行过程中。 #include <stdio.h> void add(void); 外部变量 int a,b,c; void main(void) { 注意: scanf(“%d,%d”,&a,&b); 1. 任何函数对外部变量的修 作 add( ); 用 printf(“%d”,c); 改都会影响其他函数对它的 域} 引用。 void add(void) 2. 当函数中出现和全局变量 { 同名的局部变量时,局部变 c=a+b; 量优先。 }
WANGJINLING
动态存储方式
合 静态存储方式 肥 完整的变量说明格式: 确定变量在内存中的表示方法。 工 存储类型 数据类型 变量名表; 业 确定变量的生存期和作用域。该项省略 大 表示auto存储类型。 学
1、 自动类型— auto(C 默认的存储方式) 定义在复合语句的开始处。块内生存块内有效。 #include <stdio.h> void main(void) { auto int a,b; scanf(“%d,%d”,&a,&b); if(b>a) T { int T; T T=a; 的 作 a=b; 用 b=T; 域 } printf(“Max=%d”,a); } 生存期: 执行到复合语句时建立内 存变量。执行出复合语句后变 量消亡。 2、 寄存器类型— register
WANGJINLING
a b 的 作 用 域
合 作用域和生存期与auto相同, 肥 差别: 如果CPU内部寄存器空闲, 工 则使用寄存器作为变量的存储单 元,以提高速度。主要用于循环 业 变量。(见p140 例5.16) 大 学
3、 静态类型— static(局部/全局)
作用域:在定义的复合语句内引用,出了复合语句不可见。 肥 工 业 大 学
5.4.2 函数的递归调用(嵌套调用的特例 ) 概念:函数直接或间接地自我调用称为递归函数。 int fun1(int x) int fun1(int x) int fun2(int t) { { { … … … z=fun1(y); z=fun2(y); c=fun1(a); … … … 直接引用自身 } 间接引用自身 } } 递归在没有控制条件的情况下是无穷的递归。 #include<stdio.h> void main(void) { printf("*****\n"); main(); }
5.4 函数的嵌套调用和递归调用 <stdio.h > #include
5.4.1 函数的嵌套调用
double fact( int m ) { double a=1;int i ; C语言不允许函数嵌套定义(单一性、独立性)。但允许函数嵌 for (i=1 ; i<=m ; i++ a=a*i ; 套调用,即被调函数中又调用其它函数(见P133 例5.11)。 return a ; fact函数 } squa函数 mian 函数 double squa( int n ) ① ② ③ ④ { double b;int k ; k=n*n ; 调用squa函数 调用fact函数 b=fact( k ) ; s=s+squa(i) ⑤ b=fact(k) return b ; } ⑨ void main( void ) ⑦ ⑥ ⑧ { int i; double s=0 ; } } } for (i=1; i<=5 ; i++) 结 束 s=s+squa( i ) ; printf ("s=%e\n", 两层嵌套的执行过程 s); }
文件1定义的外部变量 a1的外部变量
WANGJINLING
如果只希望在本文件中使用,可以加static说明。
合 肥 工 业 大 学
外部变量的副作用 #include <stdio.h> int i; void prt(void); void main( void ) { i==5 ?? i==0 for(i=0;i<5;i++) i==5 prt( ); i==0 } i==5 i==0 void prt(void) i==5 { i==0 for(i=0;i<5;i++) i==1 i==4 i==3 i==2 i==5 i==0 printf(“%c”, ’$’); printf(“\n”); }
执行出{ }时,原值并不消失,下次调用时变量中仍保留上次调用结束时的值。
生 存 期 从 第 一 次 调 用 到 程 序 结 束 。
void row (void) ; void main ( void ) ① 静态局部变量特点: { 1.系统自动为静态局部变量 int b ; for (b=1 ; b<=9 ; b++) 赋初值 0 。 row ( ) ; 2.作用域与局部变量相同。 } 3.生存期与局部变量不同。 void row (void ) { 说明a为静态局部变量 a static int a=1 ; 的 int b ; 作 for (b=1 ; b<=9 ; b++) printf ("%3d" , a*b ) ; 用 printf ("\n") ; 域 a++ ; }
WANGJINLING
合 肥 工 业 大 学
相关文档
最新文档