C++函数、递推、递归_第1页
C++函数、递推、递归_第2页
C++函数、递推、递归_第3页
C++函数、递推、递归_第4页
C++函数、递推、递归_第5页
已阅读5页,还剩72页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、C+语言程序设计第第九九讲讲 函函数数、递推、递归、递推、递归第九讲函数、递推、递归递推递推递递推推是计算机数值计算中的一个重要算法。大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部2思思路路:通过数学推导,将复杂的运算化解为若干重复的简单运算,以充分发挥计算机长于重复运算的特点;递递推推法法特特点点:从一个已知的事实出发,按一定规律推 出下一个事实,再从这个新的已知事实出发,再向下 推出一个新的事实。第九讲函数、递推、递归递推举例(递推举例(1 1)大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部3例: (猴猴子子吃桃问吃桃问题题)猴子第1天摘下若干桃子,当即吃了

2、一半,还不过瘾, 又多吃了一个。第2天早上又将剩下的桃子吃掉一半, 又多吃了一个。以后每天早上都吃了前一天剩下的一 半另加一个。到第10天早上想再吃时,就只剩下一个 桃子了。问第1天猴子共摘了多少桃子?第九讲函数、递推、递归解题思路:大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部4假设用 S(i) 表示第 i 天没吃之前的桃子数目;则S(1) 即为第 1 天所摘的桃子数;S(10) = S(9) * 1/2 1 第 10 天没吃之前的桃子数S(2) = S(1) * 1/2 1第 2 天没吃之前的桃子数S(3) = S(2) * 1/2- 1第 3 天没吃之前的桃子数S(9)

3、= S(8) * 1/2- 1第 9 天没吃之前的桃子数第九讲函数、递推、递归一一般形般形式式:S(i) = S(i-1) * 1/2 1,大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部5i = 2, 3, , 10;这这个个公式可用公式可用于于知知第第 1 1 天没吃之前的桃子数推算天没吃之前的桃子数推算第第 2 2 天天 没吃之前没吃之前的的,再推算,再推算第第 3 3天没吃之前天没吃之前的的,. .。现在要求。现在要求的是的是 第第 1 1 天没吃之前天没吃之前的的。能否倒过来,先。能否倒过来,先知知 第第 1 10 0 天没吃之前的天没吃之前的 的再的再反反推推第第 9

4、 9天没吃之天没吃之的的,直到直到第第 1 1 天没吃之前天没吃之前的的。为。为 此将上式改写此将上式改写为:为:S(i-1) = 2 * (S(i) + 1), i = 10, 9, 8, 2第九讲函数、递推、递归程序:大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部 6第九讲函数、递推、递归分析:分析:一般形式一般形式:S(i-1) = 2 * (S(i) + 1), i = 10, 9, 8, 2;初始:初始:s2 = 1 ; / S(10) = 1大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部7i = 9s1 = 2 * (s2 + 1) ;s2 = s1

5、 ;s1 = 2 * (s2 + 1) ;s2 = s1 ;s1 = 2 * (s2 + 1) ;s2 = s1 ;/ S(9) = 2 * (S(10) + 1)/ s2 = s1 = S(9)/ S(8) = 2 * (S(9) + 1)/ s2 = s1 = S(8)/ S(7) = 2 * (S(8) + 1)/ s2 = s1 = S(7)i = 8i = 7i = 6s1 = 2 * (s2 + 1) ;s2 = s1 ;/ S(6) = 2 * (S(7) + 1)/ s2 = s1 = S(6)第九讲函数、递推、递归i = 5大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区

6、基础教学部8s1 = 2 * (s2 + 1) ;s2 = s1 ;/ S(5) = 2 * (S(6) + 1)/ s2 = s1 = S(5)/ S(4) = 2 * (S(5) + 1)/ s2 = s1 = S(4)/ S(3) = 2 * (S(4) + 1)/ s2 = s1 = S(3)/ S(2) = 2 * (S(3) + 1)/ s2 = s1 = S(2)/ S(1) = 2 * (S(2) + 1)/ s2 = s1 = S(1)i = 4s1 = 2 * (s2 + 1) ;s2 = s1 ;s1 = 2 * (s2 + 1) ;s2 = s1 ;s1 = 2 * (

7、s2 + 1) ;s2 = s1 ;s1 = 2 * (s2 + 1) ;s2 = s1 ;i = 3i = 2i = 1第九讲函数、递推、递归递推举例(递推举例(2 2)大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部9递推数列 一个数列从某一项起,它的任何一项都可以用它前面的若干项 来确定,这样的数列称为递推数递推数列列,表示某项与其前面的若干 项的关系就称为递推公递推公式式。例如自然数 1,2,,n 的阶乘就可 以形成如下数列:1!,2!,3!,,(n-1)!, n!另fact(n) 为 n 阶乘,依据后项与前项的关系可以写出递推公式:fact(nfact(n) ) = =

8、 n n * * fact(fact(n n-1-1) ) ( (通项公通项公式式) )fact(1fact(1) ) = = 1 1(边界条件)(边界条件)第九讲函数、递推、递归递推算例(递推算例(3 3)大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部10递推算法程序实现:递推算法程序实现: 有了通项公式和边界条件后,采用循环结构,从边界条件出 发,利用通项公式通过若干步递推过程就可以求出结果;例:例:王小二自称刀工不错,有人放一张大的煎饼在砧板上,问他:“饼不许离开砧板,切 100 刀最多能分成多少块?”第九讲函数、递推、递归分析:切一刀切一刀大连理大连理工大学工大学 盘锦

9、校盘锦校区基础教学部区基础教学部11切二刀切二刀切三切三刀刀切四刀切四刀令 q(n) 表示切 n 刀能分成的块数,由上图可知q(1) = 1 + 1 = 2q(2) = 1 + 1 + 2 = 4q(3) = 1 + 1 + 2 + 3 = 7q(4) = 1 + 1 + 2 + 3 + 4 = 11第九讲函数、递推、递归分析:切一刀切一刀大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部12切二刀切二刀切三切三刀刀切四刀切四刀在切法上是让每两条线都有交点。用归纳法可得出q(n) = q(n-1) + nq(0) = 1 (边界条边界条件件)第九讲函数、递推、递归递推算例(递推算例

10、(3 3)参考程序:大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部13第九讲函数、递推、递归递归递归递归算递归算法法在可计算理论中占有重要地位,它是算法设计的有力工具,对于拓展编程思路非常有用。就递归算递归算法法而言不涉及高深数学知识,只不过初学者建立起递 归概念不太容易。看一个简单的例子:大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部14第九讲函数、递推、递归递归递归有 5 个人坐在一起,问第 5 个人多少岁? 他说比第 4 个人大两岁。问第 4 个人岁数,他说比第 3 个人大两岁。问第 3个人,又说比第 2 个人大两岁。问第 2 个人,说比第 1 个人大两岁

11、。最后问第 1 个人,他说是 10 岁。请问第 5 个人多大?解题思路: 假设用 age(i) 表示第 i 个人的岁数,则大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部15借助循环结构采用递推方法求解!借助循环结构采用递推方法求解!age(5) = age(4) + 2;age(4)age(3)=age(3)age(2)+2;2;age(2) = age(1) + 2;age(1) = 10;第九讲函数、递推、递归一般形式:age(n) = 10age(n) = age(n-1) + 2( n = 1 )( n 2 )大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学

12、部16第九讲函数、递推、递归分析:上述求解是从求解目标出发,即将第 n 个人的年龄表示第 (n-1) 个人的年龄,再回溯到第 (n-2)个人的年龄 直 到第 1 个人的年龄;(回溯回溯阶段)然后,采用递推方法,从第 1 个人的已知年龄推算第 2 个人的年龄,在推算第 3 个人的年龄,直到推算出第 5 个人的 年龄;(递推递推阶段)这是一个递归问题,对它的求解可以分成 回溯 和 递推 两 个阶段;显而易见,如果不希望递归过程无限制的进行下如果不希望递归过程无限制的进行下去去, 必须必须有一个结束递归过结束递归过程程的条件;如:age(1) = 10大连理大连理工大学工大学 盘锦校盘锦校区基础教学

13、部区基础教学部17第九讲函数、递推、递归计算年龄函数:int age(int n)大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部18int c;if( n = 1) c = 10; else c = age(n - 1) + 2; return c;第九讲函数、递推、递归递归调用递归调用大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部19在调用一个函数的过程中又出现直接或间接地调用该函数本身,称为函数的递归递归(r re ec cururs si iv ve e)调调用用;C+C+ +允允许许函函数的递数的递归归调调用用; 例:int f(int x)int y,

14、 z; z = f(y);return 2 * z;第九讲函数、递推、递归递归调用递归调用直接调用直接调用大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部20间接调用间接调用注意注意:上述两种情况都是无终无终止止的自身调用;显然, 程序中不应该出现这种无终止的调用,而只应出现 有限次的,有终止的递归调用;可可以以用用if语语句句控制控制, 实现递归调用结实现递归调用结束束;第九讲函数、递推、递归递归函数递归函数包含递归递归调调用用的函数,称为递递归函归函数数;计算年龄函数:int age(int n)int c;if( n = 1) c = 10; else c = age(n

15、- 1) + 2; return c;大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部21第九讲函数、递推、递归递归函数递归函数大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部22计算年龄递归函数执行过程:age(5) = age(4) + 2/ c = age(4) + 2= age(3) + 2 + 2/ c = age(3) + 2= age(2) + 2 + 2 + 2 / c = age(2) + 2= age(1) + 2 + 2 + 2 + 2;/ c = 10;第九讲函数、递推、递归计算年龄程序计算年龄程序大连理大连理工大学工大学 盘锦校盘锦校区基础

16、教学部区基础教学部23第九讲函数、递推、递归递归算例(递归算例(2 2)大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部24用递归方法计算 n!算法思路:若 n = 10, 则 n! = 10 * 9!定义函数 fact(n) 表示计算 n!的函数,则有fact(n) = n * fact(n-1), n 1fact(n) = 1,n = 0, n = 1;第九讲函数、递推、递归递归算例(递归算例(2 2)大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部25阶乘计算递归函数:i in nt t f fa ac ct t( (i in nt t n n) ) int

17、c;if( c n= =n = * 0 f |an ct= (n = -1 1); c = 1; r ee ls tu ern c;c = n * fact(n-1);return c;结束递归条件结束递归条件第九讲函数、递推、递归递归算例(递归算例(3 3)大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部26用递归函数计算组合数:C(m,n),即从 m 个数中取 n 个数的组合数;C(m,n) = C(m-1, n) + C(m-1,n-1); C(m,n) = 0, m 0, n 10 ) return -1; if(n = 10) c = 1; elsec = 2 * (c

18、ount(n+1) + 1); return c;大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部33第九讲函数、递推、递归递归方法递归方法大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部34递归实现:在时间和空间上的开销比较大;但符合人们的思路,程序容易理解;递归函数: 只须写出递归递归公公式式和递递归归结束条结束条件件(即边 界条件),即可很容易写出递归函数;第九讲函数、递推、递归局部变量和局部变量和全局全局变变量量大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部35一个程程序序可以包括若干个源源程程序文序文件件(文件模块); 每个源程序文件又包括

19、若干个函数函数; 在每个函数中和函数外都可以定义变变量量。这些在不同地方定义的变量是否都在程序的全部范围 内有效?如果不是,他们的有有效范效范围围是什么呢?第九讲函数、递推、递归局部变量和局部变量和全局全局变变量量大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部36局局部变部变量量在一个函数内部定义的变量是内部变量,它只在 本函数范围内有效,换句话说只有在本函数内才能使 用它们,在此函数之外是不能使用这些变量的。同样 的,在复合语句中定义的变量只在复合语句内范围内 有效。第九讲函数、递推、递归float f1(int a)/函数f1int b,c;char f2(intint i

20、,j;int main( )int m,n;int p,q;b、c有效a有效x, int y) i、j有效/函数f2x、y有效/主函数p、q在复合语句中有效m、n有效大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部37第九讲函数、递推、递归a也只在f1函数中有效。其他函数不能调用。大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部38说明:(1) 主函数main中定义的变量(m,n)也只在主函数 中有效,不会因为在主函数中定义而在整个文件或 程序中有效。主函数也不能使用其他函数中定义的 变量。(2) 不同函数中可以使用同名的变量,它们代表不 同的对象,互不干扰。例如,

21、在f1函数中定义了变量 b和c,倘若在f2函数中也定义变量b和c,它们在内存 中占不同的单元,不会混淆。(3) 可以在一个函数内的复合语句中定义变量,这 些变量只在本复合语句中有效,这种复合语句也称 为分程序或程序块。(4) 形式参数也是局部变量。例如f1函数中的形参第九讲函数、递推、递归大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部39(5) 在函在函数数声明中声明中出出现的参现的参数数名,其名,其作作用范围用范围只只在在本本 行行的括号的括号内内。实际上,编译系统对函数声明中的变量 名是忽略的,即使在调用函数时也没有为它们分配存储单元。 例如int max(int a,in

22、t b);int max(int x,int y) coutxyendl;coutabendl;/函数声明中出现a、b/函数定义,形参是x、y/合法,x、y在函数体中有效/非法非法,a a、b b在函数体中无效在函数体中无效编译时认为max函数体中的a和b未经定义。第九讲函数、递推、递归全局变量全局变量大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部40程序的编译单位是源程序源程序文文件件(. .c cp pp p),一个源文 件可以包含一个或若干个函函数数。在函数内定义的变量是局局部部变变量量,而在函数之外定 义的变量是外部变量,称为全全局变局变量量(global variab

23、le,也称全程变量)。全局变量的有效范围为从定义变量的位置开始到 本源文件结束。如第九讲函数、递推、递归int p=1,q=5;/全局变量float f/定义函数f11(a)int a;围全局变量c1、c2的作用范围(int a)大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部41int b,c;char c1,c2;char f2 (int x, int y) /定义函数f2int i,j;main ( )/主函数int m,n;第九讲函数、递推、递归大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部42p、q、c1、c2都是全局变量,但它们的作用范围不 同,在ma

24、in函数和f2函数中可以使用全局变量p、q、 c1、c2,但在函数f1中只能使用全局变量p、q,而 不能使用c1和c2。在一个函数中既可以使用本函数中的局部变量,又 可以使用有效的全局变量。说明:(1) 设全局变量的作用是增加函数间数据联系的渠 道。(2) 建议不在必要时不要使用全局变量,因为: 全局变量在程序的全部全部执执行过程行过程中中都占用存储单元,而不是仅在需要时才开辟单元。第九讲函数、递推、递归大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部43 在程序设计中,在划分模块时要求模块的内聚性强、与其他模块的耦合性弱。即模模块块的功能的功能要要单单 一一(不要把许多互不相干

25、的功能放到一个模块中), 与其他模块的相互影响要尽量少,而用全局变量是 不符合这个原则的。一般要求把程序中的函函数数做成一个封闭体,除 了可以通过“实参形参”的渠道与外界发生联 系外,没有其他渠道。这样的程序移植性好,可读性强。第九讲函数、递推、递归大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部 44 使用全局变量过多,会降低程序的清晰性。在各个函数执行时都可能改变全局变量的值,程序容易 出错。因此,要限制使用全局变量。(3) 如果如果在在同一个同一个源源文件中文件中,全局变全局变量量与局部与局部变变量量 同同名,则名,则在在局部变局部变量量的作用的作用范范围内,围内,全全局变

26、量局变量被被屏屏 蔽蔽,即它,即它不不起作用起作用。变量的有效范围称为变量的变量的作作用用域域(scope)。归纳起 来,变量有4种不同的作用域: 文件作用域(file scope)、函数作用域(function scope)、块作用域 (block scope)和函数原型作用域(functionprototype scope)。文件作用域是全局的,其他三者是局部的。第九讲函数、递推、递归变量的存储变量的存储类别类别大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部45已介绍了变量的一种属性作作用用域域,作用域是从 空空间的角间的角度度来分析的,分为全全局变局变量量和局部变局部变量

27、量。变量还有另一种属性存储存储期期( (storage duration,也称生生命命期期)。存储期是指变量在内存中 的存在时间。这是从变量值存在的时时间间角角度度来分析 的。存储期可以分为静态存储期(static storage duration)和动态存储期(dynamic storage duration)。这是由变量的静静态存态存储储方式和动动态态存存储储 方式决定的。第九讲函数、递推、递归存储方式存储方式大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部46静静态存态存储储方式是指在程序运行期间,系统对变量分配固定的存储空间。动动态存态存储储方式则是在程序运行期间,系统对

28、变量动 态地分配存储空间。第九讲函数、递推、递归存储方式存储方式先看一下内存中的供用户使用的存储空间的情况。这个存储空间可以分为三部分,即:(1) 程序区(2) 静态存储区(3) 动态存储区大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部47第九讲函数、递推、递归静态存储区静态存储区大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部48数据分别存放在静态存储区和动态存储区中。全全局变局变量量全部存放在静态存静态存储储区区中,在程序开始执行 时给全局变量分配存储单元,程序执行完毕就释放这 些空间。在程序执行过程中它们占据固定的存储单元,而不是 动态地进行分配和释放。第九

29、讲函数、递推、递归动态存储区动态存储区大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部49在动态存储区中存放以下数据:函数形式参数。在调用函数时给形参分配存储空间。函数中的自动变量(未加static声明的局部变量, 详见后面的介绍)。函数调用时的现场保护和返回地址等。 对以上这些数据,在函数调函数调用用开开始始时分配动态存储空 间,函数结束时释放这些空间。在程序执行过程中,这种分配和释放是动态的,如果在一个程序中两两次次调用同一函数,则要进行两次两次分分配和释配和释放放,而两次分配给此函数中局部变量的存储空间地址可能是不不相同相同的。第九讲函数、递推、递归50大连理大连理工大学工

30、大学 盘锦校盘锦校区基础教学部区基础教学部如果在一个程序中包含若干个函数,每个函数中的 局部变量的存储期存储期并不等于整个程序的执行周期,它 只是整个程序执行周期的一部分。根据函数调用的情况,系统对局部变量动态地分配和释放存储空间。在C+中变量除了有数数据据类类型型的属性之外,还有存存 储储类类别别(storage class) 的属性。存储类别指的是数 据在内存中存储的方法。存储方法分为静态存静态存储储和动动 态态存存储储两大类。具体包含4种:自动自动的的(auto)、静态的静态的 (static)、寄存寄存器器的(register)和外外部的部的(extern)。根据变量的存储类存储类别别

31、,可以知道变量的作用域和存储期。第九讲函数、递推、递归自动变量自动变量大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部51函函数数中中的局部的局部变变量,如量,如果果不用关不用关键键字字stastat ti ic c加加以以声声明明,编译,编译系系统对它统对它们们是动态是动态地地分配存分配存储储空间空间的的。函数的形参和在函数中定义的变量(包括在复合语 句中定义的变量)都属此类。在调用该函数时,系统给形参和函数中定义的变量 分配存储空间,数据存储在动态存储区中。在函数调 用结束时就自动释放这些空间。如果是在复合语句中 定义的变量,则在变量定义时分配存储空间,在复合 语句结束时自动

32、释放空间。因此这类局局部变部变量量称为自 动变量(auto variable)。第九讲函数、递推、递归用用r re eg gi is steter r声明声明寄寄存器存器变变量量一般情况下,变量的值是存放在内存中的。当程序中用到哪一个变量的值时,由控制器发出指令将内存中 该变量的值送到CPU中的运算器。经过运算器进行运算, 如果需要存数,再从运算器将数据送到内存存放。如图 所示。为提高执行效率,C+允许将局局部部变变量量的 放在CPU中的寄存寄存器器中,需要用时直接从寄 存器取出参加运算,不必再到内存中去存 取。这种变量叫做寄存器变量,用关关键键字字regiregis st te er r作声

33、明。但但是,是是,是建建议性的议性的;值大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部52第九讲函数、递推、递归用用s st ta ati tic c声声明静明静态态局部局部变变量量大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部53有时希望函数中的局部变量的值在函数调用结束后不 消失而保留原值,即其占用的存储单元不释放,在下 一次该函数调用时,该变量保留上一次函数调用结束 时的值。这时就应该指定该局部变量为静态局静态局部部变变量量 (ststa at ti ic c l locaocal l v va ar riabiabl le e)。第九讲函数、递推、递归大

34、连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部54第九讲函数、递推、递归先后3次调用f函数时,b和c的值如书中表所示。大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部55第九讲函数、递推、递归静态局部变静态局部变量说明量说明(1) 静态静态局局部变部变量量在静态存静态存储储区区内内分配存储单元。 在程序整个运行期间都不释放。而自自动动变变量量(即动动 态态局局部变部变量量)属于动动态存储态存储类别类别,存储在动态存储 区空间(而不是静态存储区空间),函数调用结束后 即释放。(2) 为静静态态局部变局部变量量赋初值是在编译编译时时进行值的, 即只赋初只赋初值值一次,在

35、程序运行时它已有初值。以后 每次调用函数时不再重新赋初值而只是保留上次函 数调用结束时的值。而为自自动动变量赋变量赋初值初值,不是在 编译时进行的,而是在函数调用时进行,每调用一 次函数重新给一次初值大大连连,理理工工相大大学学当盘锦盘锦校校于区区基基执础础教教行学学部部一次赋值语句。 56第九讲函数、递推、递归(3) 如果在定义局部变量时不赋初值的话,对静态静态 局局部变部变量量来说,编译时自动赋初值0(对数值型变量) 或空字符(对字符型变量)。而对自自动动变变量量来说,如 果不赋初值,则它的值是一个不确定不确定的的值值。这是由 于每次函数调用结束后存储单元已释放,下次调用时又重新另分配存储

36、单元,而所分配所分配的的单元中单元中的的值值 是是不确定不确定的的。大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部57(4) 虽然静静态局部态局部变变量量在函数调用结束后仍然存在,但其他函数是不能引用它的,也就是说,在其他函数中它是“不可见”的。第九讲函数、递推、递归静态局部变静态局部变量使用量使用大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部58在什么情况下需要用局部静态变量呢?1 1. . 需需要要保保留函数留函数上上一次调一次调用用结束时结束时的的值值。例如可以用下例中的方法求!。如:int fac(int n) static int f=1;/f为静态局

37、部变量,函数结束/ 时f的值不释放/在f原值基础上乘以nf=f*n; return f;第九讲函数、递推、递归静态局部变静态局部变量使用量使用大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部592. 如果初始化后,变量只被引用而不改变其值,则这时用静态局部变量比较方便,以免每次调用时重新赋值。第九讲函数、递推、递归用用e ex xt te er rn n声声明外明外部部变量变量大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部60全全局局变变量量( (外外部部变变量量) )是是在函数在函数的的外部定外部定义义的,的,它它 的的作用域作用域为为从变量从变量的的定义处定义

38、处开开始,到始,到本本程序文程序文件件的的末末 尾尾。在此作用域内,全局变量可以为本文件中各个函 数所引用。编译编译时时将全局变量分配在静态存储区。有有时时需需要用要用extexte er rn n来来声声明明全全局变量局变量,以扩展以扩展全全局局变变量量的作用的作用域域。第九讲函数、递推、递归在一个文件在一个文件内声内声明明全局全局变变量量提提前引用前引用声声明明大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部61第九讲函数、递推、递归在多文件程在多文件程序中序中声声明外明外部部变量变量大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部62外外部变量部变量声声明明分

39、析下例: file1.cpp file1.cpp extern int a,b; int main( )couta,bendl; return 0;注意:注意:file2.cpp file2.cpp inta=3,b=4;extern 是用作变量声明变量声明,而不是变量定变量定义义。它只是对一 个已定义的外部变量作声明,以扩展其作用作声明,以扩展其作用域域。第九讲函数、递推、递归用extern扩展全局变量的作用域,虽然能为程序设 计带来方便,但应十分慎重,因为在执行一个文件中的大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部63函数时,可可能会改能会改变变了该全了该全局局变量的变

40、量的值值,从而会影响到另一文件中的函数执行结果。第九讲函数、递推、递归用用s st ta ati tic c声声明静明静态态外部外部变变量量大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部64有时在程序设计中希望某些外部变量只只限于被限于被本本文文 件件引用,引用,而而不能被不能被其其他文件他文件引引用用。这时可以在定义 外部变量时加一个statstati ic c声声明明。例如:file1.cpp file1.cpp statistatic c inint t a=3;a=3; inint t maimain n ( ( ) ) file2.cppfile2.cppextere

41、xtern n inint t a;a;inint t fufun n (in(int t n)n) a=aa=a* *n;n; 第九讲函数、递推、递归这种加上static声明、只能用于本文件的外部变量(全局变量)称为静静态外部态外部变量变量。这就为程序的模块化、 通用性提供了方便。如果已知道其他文件不需要引用本 文件的全局变量,可以对本文件中的全局变量都加上static,成为静态外部变量,以免被其他文件误用。大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部65需要指出,不要误认为用static声明的外部变量才采 用静态存储方式(存放在静态存储区中),而不加 static的是动态

42、存储(存放在动态存储区)。实际上, 两种形式的外部变量都用静态存储方式,只是作用范围不同而已,都是在编译时分配内存的。第九讲函数、递推、递归存储期和作存储期和作用域用域大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部66第九讲函数、递推、递归变量的声明变量的声明和定义和定义大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部67关于声明和定义:针对函数而言,函数的声明是函数的原型,而函数的定义是函数功能的建立;在声明部分出现的变量有两种情况:一种是需要建立 存储空间的(如 i in nt t a a );另一种是不需要建立存储 空间的(e exterxtern n i

43、in nt t a a );前者称为定义性声明,或简称定义;后者称为引引用性声用性声明明;第九讲函数、递推、递归为叙述方便,把建立存储空间的声明称为定义;大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部68如:int a;而把不需要建立存储空间的声明称为声明;如:extern int a;第九讲函数、递推、递归外部外部变变量定量定义义和外部变外部变量量声声明明的含义是不同的。外大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部69部变量的定义只能有一次,它的位置在所有函数之外, 而同一文件中的外外部部变量的变量的声声明明可以有多次,它的位置 可以在函数之内,也可以在函

44、数之外。系统根据外部变 量的定义定义分配存储单元。对外部变量的初始化初始化只只能在能在定定 义义时进时进行行,而不能在声明中进行。所谓声明,其作用是 向编译系统发出一个信息,声明该变量是一个在后面定 义的外部变量,仅仅是为了提前引用该变量而作的声明。exteexter rn n只只用用作声明作声明,而不用而不用于于定义定义。第九讲函数、递推、递归用用static来声明一个变量的作用有来声明一个变量的作用有二二:大连理大连理工大学工大学 盘锦校盘锦校区基础教学部区基础教学部70(1)对局部变量用static声明,使该变量在本函数调用结 束后不释放,整个程序执行期间始终存在,使其存储 期为程序的全过程。(2)全局变量用static声明,则该变量的作用域只限于本文件模块(即被声明的文件中)。第九讲函数、递推、递归内部函数和内部函数和外部外部函函数数大连理大连理工大学工大学 盘锦校盘锦校区基础教

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论