经典语言第六章函数_第1页
经典语言第六章函数_第2页
经典语言第六章函数_第3页
经典语言第六章函数_第4页
经典语言第六章函数_第5页
已阅读5页,还剩89页未读 继续免费阅读

下载本文档

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

文档简介

经典语言第六章函数第1页,共94页,2023年,2月20日,星期二本讲难点:1.函数的调用过程;2.函数参数的定义与使用;3.函数的递归调用;4.局部变量和全局变量的概念和作用域。5.静态局部变量的生存期与作用域及其使用。

教学方法:理论教学与实践教学相结合。第2页,共94页,2023年,2月20日,星期二第6章函数6.1函数的定义6.2函数的调用6.3数据传递方法6.4嵌套调用和递归调用6.5变量的作用域6.6变量的存储类别6.7程序设计举例第3页,共94页,2023年,2月20日,星期二6.1函数的定义1.函数头函数头有经典与现代两种形式,现代形式称之为函数原型。经典形式:函数属性函数类型函数名(函数参数表)参数说明如:staticfloatf1(a,b,c)/*属性static,类型float,函数名f1,函数参数表″a,b,c″/floata,b,c;/*参数说明*/现代形式:函数属性函数类型函数名(参数说明)如:staticdoublef2(floatx,floaty,floatz)第4页,共94页,2023年,2月20日,星期二

2.函数体函数体由服务于函数的数据说明与执行语句两部分组成。数据说明包括数据定义和数据申明,完成数据描述,执行语句完成操作描述。TURBOC中数据说明必须位于函数体或复合语句的开始处,但C++中可根据需要随时定义。一个函数的函数体可以为空,此时的函数称为空函数,空函数常用于程序调试。空函数的形式为:

voidf(){}第5页,共94页,2023年,2月20日,星期二6.1.2返回语句通过在函数中使用返回语句,返回一个值给函数,同时终止函数的调用,返回主函数。格式:

return(表达式);或return表达式;功能:(1)计算表达式的值,将表达式的值返回给函数。(2)从被调用的函数返回主调函数。第6页,共94页,2023年,2月20日,星期二6.1.3函数的定义(1)需定义函数的属性。(2)需定义函数的类型。(3)给函数取一个名字。(4)设计函数的参数。(5)对函数中使用的量进行定义。(6)对函数的执行部分进行描述。第7页,共94页,2023年,2月20日,星期二例6–1求两个数的最大值函数。/*求两个数的最大值函数*/floatmax(x,y)(1)函数值类型floatfloatx,y;(2)函数名max{floatm;(3)函数参数x、y,类型为floatif(x>y)m=x;elsem=y;return(m);/*返回最大值*/}第8页,共94页,2023年,2月20日,星期二说明:(1)函数头可以采用现代形式:floatmax(floatx,floaty)(2)函数体也有多种等价形式:形式一:if(x>y)return(x);elsereturn(y);形式二:return(x>y?x:y);第9页,共94页,2023年,2月20日,星期二例6-2判断两个数是否是相等函数。方法一:/*判断两个数是否是相等函数*/inteq(x,y)(1)函数值类型int,可以缺省floatx,y;(2)函数名eq{floatt;(3)函数参数x、y,类型为floatif(x==y)t=1;elset=0;return(t);/*相等返回1,不等返回0*/}第10页,共94页,2023年,2月20日,星期二方法二:

/*判断两个数是否是相等函数*/inteq(x,y)floatx,y;{if(x==y)return(1);elsereturn(0);}第11页,共94页,2023年,2月20日,星期二方法三:

/*判断两个数是否是相等函数*/inteq(x,y)floatx,y;{return(x==y);}第12页,共94页,2023年,2月20日,星期二例6-3符号函数。方法一:/*符号函数*/charsign(x)(1)函数值类型charfloatx;(2)函数名sign{chars;(3)函数参数x,类型为floatif(x>=0)s=′+′;elses=′-′;return(s);}第13页,共94页,2023年,2月20日,星期二方法二:

/*符号函数*/charsign(x)floatx;{chars;if(x>=0)return(′+′);elsereturn(′-′);}第14页,共94页,2023年,2月20日,星期二例6-4求三角形面积函数。/*求三角形面积函数*/floatsabc(a,b,c)(1)函数值类型floatfloata,b,c;(2)函数名sabc{floathl;(3)函数参数a、b、c,类型为floathl=0.5*(a+b+c);return(sqrt(hl*(hl-a)*(hl-b)*(hl-c)));}第15页,共94页,2023年,2月20日,星期二例6–5素数判断函数。

/*素数判断函数*/intpn(n)(1)函数值类型intintn;(2)函数名pn{inti;(3)函数参数n,类型为intintflag;/*素数标志*/flag=1;for(i=2;i<=n/2;i++)if(n%i==0){flag=0;break;}return(flag);}第16页,共94页,2023年,2月20日,星期二例6-6阶乘函数。/*阶乘函数*/longintfn(n)intn;{inti;longintt;t=1;for(i=1;i<=n;i++)t*=i;return(t);}第17页,共94页,2023年,2月20日,星期二例6-7平方函数。/*平方函数*/floatsq(x)floatx;{return(x*x);}

说明:C语言的函数是平等的关系、并列的关系,C语言的函数体中不能包含函数的定义,不允许嵌套定义。第18页,共94页,2023年,2月20日,星期二6.2函数的调用6.2.1函数调用的一般形式函数调用的一般形式为:函数名(实参表);第19页,共94页,2023年,2月20日,星期二说明:(1)如果调用无参函数,则无实参表,此时小括号不能省略。(2)调用时,实参与形参的个数应相同,类型应一致。(3)实参与形参按顺序对应,一一传递数据。调用后,形参得到实参的值。(4)实参可以是表达式。如是表达式实参,先计算表达式的值,再将值传递给形参。第20页,共94页,2023年,2月20日,星期二(5)在C语言中,实参表的求值顺序有的系统按自左至右的常规顺序,有的系统则按自右至左的顺序求实参数值。大多数C(包括TURBOC)采用自右而左的顺序求值。例如:inti=3;printf(“%d,%d”,i,++i);①实参求值自左至右,输出3,4;②实参求值自右至左,输出4,4。为了避免出现意外情况,尽可能将参数表达式的计算移至调用函数前进行。(6)主函数由系统调用。第21页,共94页,2023年,2月20日,星期二6.2.2函数调用的方式

1.表达式方式函数调用出现在一个表达式中,这种表达式称为函数表达式。这时要求函数返回一个确定的值以参加表达式的运算。例如:y=max(a,b)+max(c,d),两次函数调用都是表达式的一部分,分别以返回a与b、c与d的最大值参与表达式运算。第22页,共94页,2023年,2月20日,星期二2.语句方式把函数调用作为一个语句。常用于只要求函数完成一定的操作,不要求函数返回值。这在scanf()函数及printf()函数的调用中已多次使用。在其它高级语言中,函数的调用只能以表达式方式进行。C语言中的语句方式调用,实际还是以表达式方式调用为基础。第23页,共94页,2023年,2月20日,星期二3.参数方式函数调用作为另一个函数的实参。例如:m=max(max(a,b),max(c,d)),max(a,b)与max(c,d)两次函数调用作为另一次max()函数调用的实参,用来求出a、b、c、d的最大值。以参数方式调用实际上是表达式调用方式的一种特殊情况。第24页,共94页,2023年,2月20日,星期二例6-8用调用函数的方式来求下面两个三角形的面积。/*程序7-8,用调用函数的方式来求三角形的面积*/floatsf(a,b,c)/*求三角形的面积函数*/floata,b,c;{floathl;hl=0.5*(a+b+c);return(sqrt(hl*(hl-a)*(hl-b)*(hl-c)));}main()/*主函数*/{floatx,y,z;clrscr();x=3,y=4,z=5;第25页,共94页,2023年,2月20日,星期二if((x+y>z)&&(y+z>x)&&(z+x>y))printf(″三边为%5.2f,%5.2f,%5.2f的三角形面积等于%5.2f\n″,sf(x,y,z));elseprintf(″不能构成三角形!\n″);x=y=z=1;if((x+y>z)&&(y+z>x)&&(z+x>y))printf(″三边为%5.2f,%5.2f,%5.2f的三角形面积等于%5.2f\n″,sf(x,y,z));elseprintf(″不能构成三角形!\n″);}运行结果:三边为3.00,4.00,5.00的三角形面积等于6.00三边为1.00,1.00,1.00的三角形面积等于0.43第26页,共94页,2023年,2月20日,星期二例6-9调用函数求2~1000之间的所有素数。/*程序7-9,调用函数求2~1000之间的所有素数*/intpf(n)/*素数判断函数*/intn;{inti;intflag;flag=1;for(i=2;i<=n/2;i++)if(n%i==0){flag=0;break;}return(flag);}第27页,共94页,2023年,2月20日,星期二main()/*主函数*/{inti;intcount=0;/*统计素数个数,用以控制输出格式*/clrscr();printf(″2~1000之间的素数如下:\n″);for(i=2;i<=1000;i++)if(pf(i)==1){printf(″%6d″,i);count++;if(count%5==0)printf(″\n″);/*每行输出5个素数*/}}第28页,共94页,2023年,2月20日,星期二6.2.3被调函数说明用户自定义函数一般需在调用前在主调函数中进行说明。函数说明是一种申明,是告诉主调函数这里调用的是一个什么样的函数。函数说明的一般形式为:被调函数类型被调函数名();注意,不是函数定义,其后有分号。第29页,共94页,2023年,2月20日,星期二例6-10求2~n之间的所有素数。main(){intn;inti;intcount=0;intpf();/*函数说明*/clrscr();printf(″请输入n:″);scanf(″%d″,&n);printf(″2~n之间的素数如下:\n″);for(i=2;i<=n;i++)if(pf(i)==1)/*调用前申明的函数*/{printf(″%6d″,i);count++;if(count%5==0)printf(″\n″);}}第30页,共94页,2023年,2月20日,星期二有下面一些情况,在调用函数前可不加说明:(1)如果是整型函数或字符型函数,可以不加说明,系统自动按整型函数处理。(2)如果被调用函数的定义出现在主调函数之前,可以不加说明。例7-8、7-9就属于这种情况。(3)如果已在所有函数定义之前,或在文件的开头,或在函数的外部已作说明,可以不加说明。除了上述情况,其它情况均必须对被调用的函数在调用前进行说明。第31页,共94页,2023年,2月20日,星期二另请注意:(1)函数一般先定义,后使用。(2)为清晰起见,一般均对被调用的函数在调用前进行说明,以增加程序的可读性。(3)函数不能重复定义,但可以反复说明。(4)对于标准函数,还应在文件开头用文件包含指令#include指明调用有关库函数时所需用到的信息。例如:#include″stdio.h″,stdio.h是一个头文件,它包含了输入输出库函数所用到的一些宏定义信息,第32页,共94页,2023年,2月20日,星期二6.3数据传递方法

C语言程序由若干相对独立的函数组成,在程序运行期间,必然存在数据在函数中流动,流入或流出,这就是函数之间的数据传递,也是函数之间的接口。一般语言中,数据传递有参数传递和全局变量传递两种方法,C语言也提供这两种传递方法。参数传递是数据传递的主门(正门),全局变量传递是数据传递的辅门(后门),数据传递时一般宜用参数传递。第33页,共94页,2023年,2月20日,星期二例如,求三个数的最大值:①主调函数:……

m=max(a,b,c);abcm(max)

……↓↓↓↑②被调函数:floatmax(x,y,z)xyzt

floatx,y,z;{floatt;t=x;if(y>t)t=y;if(z>t)t=z;return(t);}第34页,共94页,2023年,2月20日,星期二6.4嵌套调用和递归调用6.4.1嵌套调用第35页,共94页,2023年,2月20日,星期二例6-11定义一个函数求2~n之间的完数,调用完数判断函数完成。/*定义一个函数求2~n之间的完数,调用完数判断函数完成*/voidwsh(n)intn;{inti;intwf();/*函数说明*/printf(″2~%d之间的完数如下:\n″,n);for(i=2;i<=n;i++)if(wf(i)==1)printf(″%6d″,i);}第36页,共94页,2023年,2月20日,星期二/*定义一个函数判断x是否为完数*/intwf(x)intx;{inti,s=0;intw;for(i=1;i<x;i++)if(x%i==0)s+=i;if(s==x)w=1;elsew=0;return(w);}函数调用过程:主函数→wsh(n)→wf(i)第37页,共94页,2023年,2月20日,星期二例6-12定义求组合数函数,/*求阶乘函数*/longintjf(n)intn;{inti;longintt;for(t=1,i=1;i<=n;i++)t*=i;return(t);}/*求组合数函数*/longintcmn(m,n)intm,n;{return(jf(m)/(jf(n)*jf(m-n));}第38页,共94页,2023年,2月20日,星期二函数调用过程为:主函数→cmn(m,n)→jf(m),jf(n),jf(m-n)第39页,共94页,2023年,2月20日,星期二6.4.2递归调用包含有递归调用的函数称为递归函数。递归算法具有两个基本特征:(1)转化。(2)终止。第40页,共94页,2023年,2月20日,星期二例如:计算n!。①转化:n!→(n-1)!→(n-2)!→…→2!→1!→0!n!=n*(n-1)!②终止:n=0,0!=1相应的递归函数为:longintjf(n)/*求阶乘的递归函数*/intn;{longintj;if(n>0)j=n*jf(n-1);/*递归调用*/elsej=1;/*递归终止*/return(j);}第41页,共94页,2023年,2月20日,星期二我们也可先判断是否为递归调用终止条件,如不是,按转化规则转化来写递归函数。longintjf(n)iintn;{longintj;if(n==0)j=1;/*递归终止*/elsej=n*jf(n-1);/*递归调用*/return(j);}第42页,共94页,2023年,2月20日,星期二如下是计算4!的过程:if(4)=4*jf(3)if(4)=24↓↑

if(3)=3*jf(2)if(3)=6↓↑

if(2)=2*jf(1)if(2)=2↓↑

if(1)=1*jf(0)if(1)=1↓↑

if(0)=1第43页,共94页,2023年,2月20日,星期二例6-13用递归方法计算mn

的函数。方法一:①转化:mn→mn-1→mn-2→…→m2→m1→m0mn=m*mn-1②终止:n=0,m0=1相应的递归函数为:longintmn(m,n)/*计算m的n次方递归函数*/intm,n;{longintj;if(n>0)j=m*mn(m,n-1);/*递归调用*/elsej=1;/*递归终止*/return(j);}

第44页,共94页,2023年,2月20日,星期二方法二:①转化:n为偶数,mn→mn/2→…→m0,mn=(mn/2)2n为奇数,mn→m(n-1)/2→…→m0,mn=m*(m(n-1)/2)2②终止:n=0,m0=1相应的递归函数请读者自己编程实现。采用方法二,递归调用的次数比方法一要少许多。第45页,共94页,2023年,2月20日,星期二例6-14用递归方法计算Fibonacci数列的第n项函数。①转化:n>2,f(n)=f(n-1)+f(n-2)②终止:n=1、2,f(1)=f(2)=1相应的递归函数为:

intfib(n)/*计算Fibonacci数列的第n项*/intn;{intj;if(n>2)j=f(n-1)+f(n-2);/*递归调用*/elsej=1;/*递归终止*/return(j);}第46页,共94页,2023年,2月20日,星期二

例6-15年龄问题。有5个人坐在一起,问第5个人多少岁,他说比第4个人大2岁。问第4个人多少岁,他说比第3个人大2岁。问第3个人多少岁,又说比第2个人大2岁。问第2个人多少岁,说比第1个人大2岁。最后问第1个人多少岁,他说是10岁。请问第5个人多少岁?。①转化:n>1,age(n)=age(n-1)+2②终止:n=1,age(1)=10

第47页,共94页,2023年,2月20日,星期二age(n)/*求年龄的递归函数*/intn;{inta;/*用作存放函数的返回值*/

if(n==1)a=10;elsea=age(n-1)+2;return(a);}main()/*主函数*/{

printf(″第5个人的年龄=%d\n″,age(5));}运行结果:第5个人的年龄=18

第48页,共94页,2023年,2月20日,星期二6.5变量的作用域

6.5.1局部变量(1)在一个函数内部定义的变量是局部变量,只能在函数内部使用。(2)在主函数内部定义的变量也是局部变量,其它函数也不能使用主函数中的变量。(3)形式参数是局部变量。(4)在复合语句中定义的变量是局部于复合语句的变量,只能在复合语句块中使用。(5)局部变量在函数被调用的过程中占有存储单元。(6)不同函数中可以使用同名变量。第49页,共94页,2023年,2月20日,星期二例如,有如下程序:main(){inta=1;intb=2;/*a,b为局部变量*/{intb=1;/*此b非前b,语句块中局部变量*/printf(″复合语句中a=%d,b=%d\n″,a,b);}printf(″复合语句外a=%d,b=%d\n″,a,b);}运行结果:复合语句中a=1,b=1

复合语句外a=1,b=2第50页,共94页,2023年,2月20日,星期二6.5.2全局变量(1)在函数外部定义的变量是全局变量,其作用域是变量定义位置至整个程序文件结束。(2)使用全局变量,可增加函数间数据联系的渠道。全局变量可以将数据带入在作用域范围内的函数,也可以将数据带回在作用域范围内的其它函数。第51页,共94页,2023年,2月20日,星期二inta,b;/*a,b为全局变量*/ints(){a=a*a;/*函数中a、b即为前定义的全局变量*/b=b*b;return(a+b);}main(){intsum;a=2;b=3;sum=s();printf(″sum=%d,a=%d,b=%d″,sum,a,b);}运行结果:

sum=13,a=4,b=9第52页,共94页,2023年,2月20日,星期二(3)提前引用外部变量,需对外部变量进行说明,或称申明。形式:extern类型变量表;作用:说明这些变量是已在外部定义过的变量。例如,有如下程序:

main(){externinta,b;/*外部变量说明*/……}inta,b;/*外部变量定义*/第53页,共94页,2023年,2月20日,星期二(4)使用程序中非本程序文件的外部变量,也要对使用的外部变量进行同上的申明,或用文件包含处理。(5)局部变量如与外部变量同名,则在局部变量的作用域内,外部变量存在,但不可见,外部变量的作用被屏蔽。(6)全局变量在程序运行过程中均占用存储单元。(7)在编程时,原则上尽量少用全局变量;能用局部变量,不用全局变量,要避免局部变量全局化。第54页,共94页,2023年,2月20日,星期二

6.5.3标识符的作用域从变量的作用域可延伸考虑量的作用域,进一步考虑标识符的作用域,即标识符的使用范围。标识符除了标识变量,还用来标识常量、函数、类型等。第55页,共94页,2023年,2月20日,星期二6.6变量的存储类别6.6.1变量的存储类别内存中供用户使用的存储空间分为代码区与数据区两个部分。变量存储在数据区,数据区又可分为静态存储区与动态存储区。静态存储是指在程序运行期间给变量分配固定存储空间的方式。如全局变量存放在静态存储区中,程序运行时分配空间,程序运行完释放。第56页,共94页,2023年,2月20日,星期二动态存储是指在程序运行时根据实际需要动态分配存储空间的方式。如形式参数存放在动态存储区中,在函数调用时分配空间,调用完成释放。对于静态存储方式的变量可在编译时初始化,默认初值为0或空字符。对动态存储方式的变量如不赋初值,则它的值是一个不确定的值。在C语言中,具体的存储类别有自动(auto)、寄存器(register)、静态(static)及外部(extern)四种。静态存储类别与外部存储类别变量存放在静态存储区,自动存储类别变量存放在动态存储区,寄存器存储类别直接送寄存器。第57页,共94页,2023年,2月20日,星期二变量存储类别定义方法:存储类别类型变量表;例如:(1)a,b,c为整型自动存储类别变量:autointa,b,c;(2)x,y,z为双精度型静态存储类别变量:staticdoublex,y,z;第58页,共94页,2023年,2月20日,星期二6.6.2局部变量的存储方式(1)局部变量一般用自动方式存储,用保留字auto加以定义,此时称为自动变量,是动态存储,在函数的调用过程中存在,由编译系统自动处理。例如:

voidf(){autointi,j;autofloatx,y;/*局部变量i,j,x,y以自动方式存储*/……}

第59页,共94页,2023年,2月20日,星期二(2)如果希望函数调用完后局部变量的值被保留,不释放其所占存储单元,这时必须将其存储方式定义为静态存储方式,用保留字static加以定义。用静态方式存储的局部变量称为局部静态变量,在函数调用完后其值被保留,由于“局部”的作用域,这个保留的值其它函数并不能使用,只有本函数能够使用。第60页,共94页,2023年,2月20日,星期二例6-16计算1到5的阶乘。intjf(n)intn;{staticintf=1;f=f*n;return(f);}main(){inti;for(i=1;i<=5;i++)printf(″%d!=%d\n″,i,jf(i));}运行结果为:1!=12!=23!=64!=245!=120第61页,共94页,2023年,2月20日,星期二(3)如果对数据的读写频繁,存取速度要求较快,C语言允许用寄存器方式直接处理变量,用保留字register加以定义,此时称为寄存器变量。例如:longsum(n)intn;{inti;registerlongs=0;for(i=1;i<=n;i++)s+=i;return(s);}第62页,共94页,2023年,2月20日,星期二(4)局部变量的缺省存储方式是自动存储方式。第63页,共94页,2023年,2月20日,星期二6.6.3全局变量的存储方式(1)全局变量一般用外部存储方式存储,用保留字extern加以定义。此时,变量的作用域是构成整个程序的所有程序文件,也就是定义的外部变量可供其它程序文件使用。例如,程序由两个程序文件file1.c与file2.c组成。/*file1.c*/externinta;/*定义extern存储方式变量a*/main(){intpow();intn;intp;第64页,共94页,2023年,2月20日,星期二scanf(″%d″,&n);p=pow(n);printf(″p=%d\n″,p);}/*file2.c*/externinta;/*申明本文件中使用的是已定义的外部变量a*/intpow(x)intx;{inti,t=1;for(i=1;i<=x;i++)t*=i;return(t);}第65页,共94页,2023年,2月20日,星期二2)如果希望全局变量仅限于本程序文件使用,而其它程序文件中不能引用,这时必须将其存储方式定义为静态存储方式,用保留字static加以定义。此时称为静态外部变量。例如,在上例文件file1.c中,如果作这样的定义:

staticinta;

则变量a的作用域被缩小至本程序文件file1.c,文件file2.c中不能引用。第66页,共94页,2023年,2月20日,星期二(3)全局变量的缺省存储方式是外部存储方式。前面章节中的程序没有见到变量的存储类别定义,实际上采用变量的缺省存储方式。对局部变量采用auto方式,对全局变量采用extern方式。第67页,共94页,2023年,2月20日,星期二1.变量定义的一般形式存储类别数据类型变量表;2.变量定义的作用①规定了变量的取值范围。②规定了变量进行的运行操作。③规定了变量的作用域。④规定了变量的存储方式。⑤规定了变量占用的存储空间。第68页,共94页,2023年,2月20日,星期二3.局部变量和全局变量局部变量:①自动变量,即动态局部变量(离开函数,值就消失).②静态局部变量(离开函数,值仍保留)。③寄存器变量(离开函数,值就消失)。④形式参数可以定义为自动变量或寄存器变量。全局变量:①静态外部变量(只限本程序文件使用)。②外部变量(即非静态的外部变量,允许其它程序文件引用)。第69页,共94页,2023年,2月20日,星期二4.动态存储和静态存储动态存储:①自动变量(函数内有效)。②寄存器变量(函数内有效)。③形式参数。静态存储:①静态局部变量(函数内有效)。②静态外部变量(本程序文件内有效)。③外部变量(整个程序可引用)。第70页,共94页,2023年,2月20日,星期二5.静态存储区和动态存储区从变量值存放的位置可将变量存储区分为静态存储区和动态存储区:内存中静态存储区:①静态局部变量。②静态外部变量。③外部变量(可被同一程序其它文件引用)。内存中动态存储区:自动变量和形式参数。第71页,共94页,2023年,2月20日,星期二

例6-17仔细阅读程序,注意变量的作用域#,存储类别,分析程序的运行结果。/*程序7-17,变量的作用域、存储类别*/voidf1(x,y){autointi;staticintj;/*调用完,j值保留*/printf(″i=%5d,j=%5d\n″,i,j);i=x+y;j+=x+y;printf(″i=%5d,j=%5d\n″,i,j);printf(″x=%5d,y=%5d\n″,x,y);}第72页,共94页,2023年,2月20日,星期二staticintk,l,m;/*在本程序文件内使用*/voidf2(a,b,c)inta,b,c;{k=a+b+c;l=a*b*c;m=k+l;printf(″a=%5d,b=%5d,c=%5d\n″,a,b,c);printf(″k=%5d,l=%5d,m=%5d\n″,k,l,m);}main(){intd,e,f,g,h;inti,j,x,y,a,b,c;printf(″请输入d,e,f,g,h:″);scanf(″%d,%d,%d,%d,%d″,&d,&e,&f,&g,&h);printf(″第一次调用函数f1()\n″);f1(d,e);第73页,共94页,2023年,2月20日,星期二printf(″i=%5d,j=%5d\n″,i,j);printf(″x=%5d,y=%5d\n″,x,y);printf(″d=%5d,e=%5d\n″,d,e);printf(″第二次调用函数f1()\n″);f1(d,e);printf(″i=%5d,j=%5d\n″,i,j);printf(″调用函数f2()\n″);f2(f,g,h);printf(″k=%5d,l=%5d,m=%5d\n″,k,l,m);printf(″a=%5d,b=%5d,c=%5d\n″,a,b,c);printf(″f=%5d,g=%5d,h=%5d\n″,f,g,h);}第74页,共94页,2023年,2月20日,星期二运行结果:请输入d,e,f,g,h:1,2,3,4,5第一次调用函数f1()i=34(随机值),j=0i=3,j=3x=1,y=2i=34(随机值),j=1985(随机值)x=-19(随机值),y=2340(随机值)d=1,e=2第75页,共94页,2023年,2月20日,星期二第二次调用函数f1()i=34(随机值),j=3i=3,j=6x=1,y=2i=34(随机值),j=1985(随机值)调用函数f2()a=3,b=4,c=5k=12,l=60,m=72k=12,l=60,m=72a=13(随机值),b=124(随机值),c=2525(随机值)f=3,g=4,h=5第76页,共94页,2023年,2月20日,星期二6.7程序设计举例【例6-18】用直接插入排序的方法将一组整数降序排列。insertsort(int*a,intn){inti,j,t;for(i=1;i<n;i++){for(t=a[i],j=i-1;j>=0&&t>a[j];j--)a[j+1]=a[j];a[j+1]=t;}}#defineN10第77页,共94页,2023年,2月20日,星期二main(){intx[N],i;for(i=0;i<N;i++)scanf("%d",x+i);insertsort(x,N);for(i=0;i<N;i++)printf("%d",x[i]);printf("\n");}〖运行结果〗:34781290398747926517↙92908778654739341712

第78页,共94页,2023年,2月20日,星期二【例6-19】汉诺塔问题。有三根柱子,分别标记为A、B和C,A柱上有若干个大小不同的盘子叠放成塔形,现将A柱上的这些盘子借助于B柱移到C柱上去。但是每次只能移动一个盘子,而且大盘不能放到小盘之上。请给出移动方法。这是一个比较典型的递归程序设计,我们可以想象先把A上的除最下面的盘子外都移到B柱上,然后把最大的盘子移到C柱上,再把B柱上的盘子移到C柱上,这就可以完成了。但是把一些盘子移到B柱上及从B柱上再移到C柱上这本身又是一个递归问题。第79页,共94页,2023年,2月20日,星期二move(charx,chary){printf("%c——>>%c\n",x,y);}intcount=0;hanoi(intn,charA,charB,charC){if(n==1){move(A,C);count++;}else{hanoi(n-1,A,C,B);move(A,C);count++;hanoi(n-1,B,A,C);}}第80页,共94页,2023年,2月20日,星期二main(){intn;printf("Howmanyplates?");scanf("%d",&n);hanoi(n,’A’,’B’,’C’);printf("Totalmoved:%d\n",count);}第81页,共94页,2023年,2月20日,星期二〖运行结果〗:Howmanyplates?4↙A——>>BA——>>CB——>>CA——>>BC——>>AC——>>BA——>>BA——>>CB——>>CB——>>AC——>>AB——>>CA——>>BA——>>CB——>>CTotalmoved:15第82页,共94页,2023年,2月20日,星期二【例6-20】将一个M×N的二维数组按列优先转存为一个长度为M×N的一维数组。#defineM3#defineN4voidfunab(int(*a)[N],int*b,intm,intn)/*a为数组指针变量名*/{inti,j,k=0;/*在二维数组中按列扫描数组元素*/for(j=0;j<n;j++)for(i=0;i<m;i++)

b[k++]=*(*(a+i)+j);}第83页,共94页,2023年,2月20日,星期二main(){intx[M][N],y[M*N];

inti,j;printf("Input2_dimensionarray:\n");

for(i=0;i<M;i++)for(j=0;j<N;j++)scanf("%d",x[i]+j);

funab(x,y,M,N);printf("The1_dimensionarrayare:\n");for(i=0;i<M*N;i++)

printf("%d",y[i]);printf("\n");}〖运行结果〗:Input2_dimensionarray:1234↙5678↙9101112↙The1_dimensionarrayare:1

59261037114812第84页,共94页,2023年,2月20日,星期二【例6-21】将一个n阶方阵的下三角阵存入一个一维数组中。#defineN5voidfunab(inta[][N],int*b,intn){inti,j,k=0;for(i=0;i<n;i++)for(j=0;j<=i;j++)

b[k++]=*(*(a+i)+j);}main(){intx[N][N]={{1,2,3,4,5}, {6,7,8,9,10}, {11,12,13,14,15}, {16,17,18,19,20}, {21,22,23,24,25}},y[N*(N+1)/2];

温馨提示

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

评论

0/150

提交评论