【文档说明】《C语言程序设计教程》课件.ppt,共(31)页,704.001 KB,由小橙橙上传
转载请保留链接:https://www.ichengzhen.cn/view-44449.html
以下为本文档部分文字说明:
《C语言程序设计教程》HuanghuaiUniversityDepartmentofComputerScience主讲:傅丰黄淮学院计算机科学系高等教育出版社谭浩强张基温等编著第四章模块化程序设计•§1函数–§4.1.1C程序结构–§4.1.2函数定义与
函数声明–§4.1.3函数的(传值)调用–§4.1.4函数的嵌套调用–§4.1.5函数的递归调用•§2变量的存储属性•§3编译预处理2学时2学时本节2学时2学时§1函数(程序模块)一、C程序的结构较大的程序一般分为若干个程序模块。每个模块实现一个特定的功能。常将一些常用的功能模块编
写成函数,以被多个程序调用。main(){…f1();…f2();…}f1(){…f11();…}f2(){…f21();…f22();…}f11(){…}f21(){…}f22(){…}main()f1()f2()f11()f21()f22()P102例1(略)函数值类型函数名
(类型形参,…){函数体}二、函数定义与函数声明1、函数定义(自定义函数,即程序模块)1、函数值类型:即函数体中return语句中表达式值的类型。无返回值时(无return语句),函数值类型为void。默认为int型。2、形式参数:形参间用逗号分隔,无参时括号不能省。编译时不为形参分配存储空
间,调用时才临时为其分配存储空间,从调用函数的实参得到值,称为“虚实结合”。调用结束时,形参所占空间被释放。3、函数体:由声明部分和语句部分组成。函数体中定义的变量只在执行该函数时才存在。声明部分和语句部分都省略时,为空函数:voidf(){}4、函数的返回:
函数执行到最后一个操作或遇到return语句时,返回主调函数,同时撤消为函数体中变量及形参分配的存储空间。5、函数不能嵌套定义,一个函数不能定义在别的函数内部。说明声明部分语句部分return(表达式);所需的已知量P104例2:找出函数定义部分main(){…do
ublenew_style(inta,doublex);…}doublenew_style(inta,doublex){…/*函数体*/}func1(){…func2(){…}…}错P107:函数不能嵌套定义intjdz(intx){return(x>=0?x:-x);}P105例3:编
写求一个整数的绝对值的函数main(){inta,b;scanf(“%d”,&a);b=jdz(a);printf(“%d\n”,b);}函数定义函数调用形参实参①实参形参②执行函数体③返回调用处P106例4:编写打印n个空格的函数voidspc(intn){inti;for(i=1;i<=n
;i++)printf(“”);}main(){intm;scanf(“%d”,&m);spc(m);}函数定义函数调用形参实参①实参形参②执行函数体③返回调用处P106例5:编写求表达式值的函数:y=floatf(floatx){if(x<0)return(x*x+x+1);elser
eturn(x*x*x+x+3);}main(){floatx,y;scanf(“%f”,&x);y=f(x);printf(“%f\n”,y);}函数定义函数调用形参实参①实参形参②执行函数体③返回调用处x2-x+1x<0x3+x+
3x≥0一个函数中允许有一个或多个reutrn语句。每个return语句中表达式的类型应相同。func(intn){if(n>10)return(2*n+3);elsereturn();}错P107例6:例:函数定义:doublefunc(doublea,intb,floatc){/*函数
体*/}函数声明应为:doublefunc(doublea,intb,floatc);或:doublefunc(doublex,inty,floatz);1、可不写形参名:doublefunc(double,int,float);2、不能只写形参名而不写类型:doublefunc(x,y,z
);3、只有函数返回值为int或char时,函数值类型才可以省略。4、函数定义的声明中形参的次序与类型要一致。如:doublefunc(inty,floatz,doublex);错误5、当某函数要被多个函数调用时,可将函数的调用声明写在所有函数前。如:2、函数声明:函数值类型函数
名(类型形参,…);对在本函数中要调用的函数所做的说明函数原型(函数定义的第一行)说明fun1(){…f(a,b);…}fun2(){…f(c,d);…}floatf(floatx,floaty){…}main(){…}flo
atf(floatx,floaty);③②①三、函数的(传值)调用函数名(实参,实参,…)无返回值:函数名(实参表);有返回值:变量=函数名(实参表);P109例7:main(){inta=3,b=5;voidswap(i
ntx,inty);swap(a,b);printf(“a=%d,b=%d\n”,a,b);}voidswap(intx,inty){inttemp;temp=x,x=y,y=temp;printf(“x=%d,y=%d\n”,x,y);}函数调用函数定
义形参实参②执行函数体③返回函数值释放相应空间函数声明①实参形参实参形参35ab335xy533tempx=5,y=3a=3,b=5程序的运行:②③①值传递P110例8:实参与形参的个数类型要一致main
(){floatadd();floatx=1.5,y=-5.7;printf(“%f+%f=%f\n”,x,y,add(x,y));}floatadd(unsignedinta,unsignedintb){printf(“a=%u,b=%u\n”,a,b);re
turn(a+b);}函数调用形参实参②执行函数体③返回函数值释放相应空间函数声明①实参形参实参形参1.5-5.7xyab①a=0,b=01.500000+-5.700000=0.000000程序的运行:00②函数定义P13
6习题9:写出程序的输出结果main(){inti,j,x,y,n,g;i=2;j=3;g=x=5;y=9;n=7;fun(n,6);printf(“g=%d;i=%d;j=%d;\n”,g,i,j);printf(“x=%d;y=%d\n”,x,y);fun
(n,6);}fun(inti,intj){intx,y,g;g=8;x=7;y=2;printf(“g=%d;i=%d;j=%d\n”,g,i,j);printf(“x=%d;y=%d\n”,x,y);}形参实参②③①实参7n6①g=8;i=7;j=6;x
=7;y=2g=5;i=2;j=3;x=5;y=9g=8;i=7;j=6;x=7;y=2程序的运行:ijgxy23559形参ij76②②gxy872③形参ij76②②gxy872②②main(){u=f1(i,t);}函数不能嵌套定义,但可以嵌套调用四、
函数的嵌套调用{c=f2(b-1,b+1);}return(x);main函数f1函数f2函数①②⑥⑦⑤③④课堂练习main(){intx,n,s;s=power(x,n);}P136习题1:指出程序中的错误power(y){inti,p=1
;for(i=1;i<=n;++i)p=p*y;};①power函数的调用未声明。②实参x、n未赋值。③实参x、n与形参y个数不符。④整个程序无输出。⑤未说明形参y的类型。⑥变量n未定义,应将之作为形参定义。⑦通过主函数对power函数的调用可以看出该函数有返回值,因此power函数定
义中应有return(p);语句,且在第一行应说明函数值的类型。⑧最后的;号多余。求ynmain(){intn;charch;scanf(“%c%d”,&ch,&n);p(ch,n);}P136习题3:编写一个函数重复打印给定的字符n次voidp(charc,intn){in
ti;for(i=1;i<=n;i++)printf(“%c”,c);printf(“\n”);}#definePI3.14#include“math.h”main(){intx,y,i;doublerd=PI/180;for(x=0
;x<=360;x=x+15){y=(int)(10+10*sin(x*rd));for(i=1;i<=y;i++)printf(“”);printf(“*\n”);}}P136习题2:画正弦曲线若画下列形式的正弦曲线,则
每行应输出:y个空格、1个*号、换行空格数y与sin值有关。而sin值在[-1,1]内,故应将放大同样倍数的sin值作为y值。算法分析:y个空格*********sin(x)P136习题4:编写求一个给定数字的所有因子的
函数。voidf(intn){inti=2;while(n!=i){if(n%i==0){printf(“%d*”,i);n=n/i;}elsei++;}printf(“%d\n”,n);}如:72=2*2*2
*3*3n变小i变大递推函数n=n/in%i==0是否当因子i不是n时(还有因子)输出因子ii=i+1输出最后没有因子的数n或ii取最小因子2判断正负P136习题8:编写将整数转换为字符串的函数itoavoidi
toa(intx){charch1,ch2,ch3,ch4,ch5;intn;if(x<0){printf(“-”);x=-x;}if(x/10000!=0)n=5;elseif(x/1000!=0)n=4
;elseif(x/100!=0)n=3;elseif(x/10!=0)n=2;elsen=1;ch5=x/10000+„0‟;ch4=(x%10000)/1000+„0‟;ch3=(x%1000)/100+„0‟;ch2=(x%100)/10+„0‟;
ch1=x%10+„0‟;输出每一位对应的字符}也可用数组实现switch(n){case5:printf(“%c”,ch5);case4:printf(“%c”,ch4);case3:printf(“%c”,ch3);case2:pr
intf(“%c”,ch2);case1:printf(“%c”,ch1);}判断位数求每一位所对应的字符输出每一位对应的字符课后作业及上机任务教材P136习题:1~4、8编写判断一个数是否为素数的函数,然后用主程序
调用该函数。编写并调试习题2~3、8五、函数的递归调用从一个故事和图片观察到的…从前有座山,山里有个庙,庙里有个老和尚,老和尚在对小和尚讲故事,故事讲的是:“从前有座山,山里有个庙,庙里有个老和尚,老和尚在对小和尚讲故事,
故事讲的是:‘从前有座山,山里有个庙…‟”。故事和图片都是直接由这个故事和图片本身组成的。观察到的规律:P111图4.8说明:这里主要讨论函数的直接递归调用递归就是某一事物直接或间接地由自己组成。如果一个函数在它的函数体内,直接或间接地调用自身,则称这个函数为递归函数,称这种调用方式为
函数的递归调用。1、递归的概念intf(intn){……x=f(n-1);……}intA(intn){……x=B(n-1);……}intB(intm){……y=A(m-1);……}直接递归间接递归2、递归函数的执行执行过程(设n=3):P111例9:通过函数的递归调用计算n的
阶乘。longfact(intn){longx;if(n<=1)x=1;elsex=n*fact(n-1);return(x);}main(){intn;longy;scanf("%d",&n);y=fact
(n);printf("%d!=%ld\n",n,y);}y=fact(3)输出yfact(3)main()x=3*fact(2)返回x的值x=2*fact(1)返回x的值x=1返回x的值fact(2)fact(1)123645递归回溯参数传递执行返回递归函数递归公式终止条件3、递归函数的编写
从要解决的问题出发,按倒推的方法来思考:如果要解决一个规模大的问题,只要解决与之相似的小规模问题就好了(寻找递归公式);直到倒推到一个显而易见的已知问题为止,使这个已知的问题成立的条件就是递归终止条件。longfact(intn){longx;if(n<=1)x=1;elsex=fa
ct(n-1)*n;return(x);}1n<=1n*fact(n-1)n>1fact(n)=n!=n*(n-1)!(n-1)!=(n-1)*(n-2)!……2!=2*1!1!=1fact(n)=n*fact(n-1)fact(n-1)=(n-1)*fac
t(n-2)……fact(2)=2*fact(1)fact(1)=1递归公式终止条件递归公式递归终止条件设f(n)为求数列第n项的函数,则:f(n)=f(n-1)+f(n-2)f(n-1)=f(n-2)+f(n-3)……f(3)=f(1)+f(2)而f(1)=f(2)=1问题:用递归函
数求Fibonacci数列的第n项。课堂训练(补充)递归公式和终止条件:递归函数:longf(intn){longx;if(n<=2)//终止条件x=1;elsex=f(n-1)+f(n-2);//递归公式return(x);}倒推1n<=2f(n-1)+f(
n-2)n>2f(n)=321算法分析:P113例10:汉诺(hanoi)塔问题相传在古代印度的布拉玛(Bramah)庙中,僧侣们常玩一种称为汉诺塔(TowerofHanoi)的游戏,据说游戏结束就标志着世界末日的到来。游戏的装置是一块铜板,上面有三根杆,最左杆从上到下、从小到大顺序串了
64个盘子,呈塔形。游戏要求把盘子从一根杆移到另一根杆,移动过程中要求:一次只能移动一个盘子,并且不允许大盘在小盘上面。如果每秒移动一只盘子,也需要大约5800亿年才能完成。hanio(n-1,a,c,b);printf(MoveNO%dfrom%cto%c
\n”,n,a,b);hanio(n-1,c,b,a);终止条件:①把n-1个盘子从a借助b移到cn>0时,n=0时,终止递归Ann-1……1Cn-1……1Bnn-1……1123②把第n个盘子从a移到b③把n-1个盘子从c借助a移到b递归函数:voidhanio(intn,chara,charb
,charc){if(n>0){}}递归分析:设按规则把n个盘子从A借助C移到B的算法为hanoi(n,a,b,c),则:请仔细体会递归算法的执行过程。汉诺塔游戏汉诺塔问题的具体执行过程演示程序:zlhnt.exe小结代码清晰、简洁。符合人们的思维方式,使复杂问
题自然、易于理解。执行效率不高。递归算法在可计算性理论中占有重要地位,对拓展编程思路非常有用。但要建立起递归概念并不容易。特别是递归函数的执行过程,是本节也是本课程的一个重点和难点。递归算法的优缺点:优点缺点P136习题5:编写计算函数Ack(m,n)的值的递归函数。longA
ck(intm,intn){longy;if(m==0)y=n+1;elseif(n==0)y=Ack(m-1,1);elsey=Ack(m-1,Ack(m,n-1));return(y);}Ack(0,n
)=n+1Ack(m,0)=Ack(m-1,1)Ack(m,n)=Ack(m-1,Ack(m,n-1))递归公式终止条件课堂练习floatH(intn,floatx){floati,x0,x1,x2;x0=1.0,x1=2*x;switch(n){cas
e0:return(x0);break;case1:return(x1);break;default:if(x<=1)printf(“error\n”);else{for(i=2.0;i<=n;i+=1.
0){x2=2*x*x1-2*(i-1)*x0;x0=x1;x1=x2;}return(x2);}}}floatH(intn,floatx){if(n==0)return(1.0);elseif(n==1)return(2*x);elseif(x>1)return(2*x*H(n-1,x
)-2*(n-1)*H(n-2,x);elseprintf(“error\n”);}递归函数P136习题6:分别写出计算Hermite多项式Hn(x)的值的递推和递归函数。H0(x)=1H1(x)=2xHn(x)=2xHn-1(x)-2(n-1)H
n-2(x)当x>1时递推函数递推公式x0x1x2=2x*x1-2(n-1)*x0x0x1x2=…课后作业及上机任务教材P136习题:5、6编写一个求n的阶乘的函数,然后调用该函数求1!+2!+3!+4!+5!。编写并调试习题5、6通过汉诺塔游
戏(hanio.swf或zlhnt.exe),体会递归算法的执行过程思考扩展汉诺塔问题的算法:m个杆,有一根杆上自上而下从小到大有n个盘子,一次只能移动一个盘子,并且不允许大盘在小盘的上面,请问将这些盘子全部移动到另一根杆上,
最少需要移动多少次?