您好,欢迎访问三七文档
#includestdio.hvoidmain(){intmax_4(inta,intb,intc,intd);inta,b,c,d,max;printf(Pleaseenter4intergernumbers:);scanf(%d%d%d%d,&a,&b,&c,&d);max=max_4(a,b,c,d);printf(max=%d\n,max);}intmax_4(inta,intb,intc,intd){intmax_2(inta,intb);intm;m=max_2(a,b);m=max_2(m,c);m=max_2(m,d);return(m);}intmax_2(inta,intb){return(ab?a:b);}7.6函数的递归调用或a(x){……b();……}b(){……a(y);/*间接的递归调用*/……}C语言中,允许函数直接或间接地调用自己,这种调用方式称为函数的递归调用。C语言的特点之一就在于它允许函数的递归调用。其一般形式为:a(x){……a(y);/*直接的递归调用*/……}intage(intn){intc;if(n==1)c=10;elsec=age(n-1)+2;return(c);}#includestdio.hvoidmain(){printf(%d\n,age(5));}例7.6有5个人坐在一起,第5个从比第4个人大2岁,第4个比第3个人大2岁,…,第1个人是10岁。问第5个人多大?算法分两个阶段;第一阶段为“回溯”第二阶段为“递推”。不应出现无终止的递归调用,因此,应该给定一个限制递归次数的条件。递归调用对应的一般算法:f(x)=终了公式递归公式#includestdio.hvoidmain(){longfac(intn);intn;longy;printf(inputanintegernumber:);scanf(%d,&n);y=fac(n);printf(%d!=%ld\n,n,y);}例7.7用递归方法求n!。求n!可以用递推算法,即从1开始,乘2,再乘3,一直乘到n。这种方法容易理解,也容易实现。递推法的特点是从一个已知的事实出发,按一定的规律推出下一个事实,再从这新的已知事实出发,再向下推出一个新的事实。另一种方法是递归算法,即5!=4!X5,4!=3!X4,,1!=1。longfac(intn){longf;if(n0)printf(n0,dataerror!);elseif(n==0||n==1)f=1;elsef=fac(n-1)*n;return(f);}例7.8Hanoi(汉诺)塔问题。古代有一个梵塔,塔内有3个座A,B,C,开始时A座上有64个大小不等的盘子,大的在下小的在上。有一个老和尚想把这64个盘子从A座移到C座,但每次只允许移动一个盘子,且在移动的过程中在3个座上都始终保持大盘在下,小盘在上。在移动过程中可以利用B座。为实现以上目标,老和尚:1)、命令第2个和尚将63个盘子从A座移到B座。2)、自己将1个盘(最底下的、最大的盘子)从A座移到C座。3)、再命令第2个和尚将63个盘子从B座移到C座。为解决将63个盘子从A座移到B座,第2个和尚:1)、命令第3个和尚将62个盘子从A座移到C座。2)、自己将1个盘子从A座移到B座。3)、再命令第2个和尚将62个盘子从C座移到B座。如此层层下放,到第63个和尚,让他完成将2个盘子从一个座移到另一个座。第64个各尚将1个盘子从一个座移到另一个座。为便于理解,先分析将A座上3个盘子移到C座上的过程:1、将A座上的2个盘子移到B座上(借助C)。2、将A座上1个盘子移到C座上。3、将B座上2个盘子移到C座上(借助A)。其中第2步可以直接实现,第1步又可以用递归方法分解为:1)、将A上1个盘子从A座移到C座。2)、将A上1个盘子从A座移到B座。3)、将C上1个盘子从C座移到B座。综合以上,可得移动3个盘子,经历7步,步骤为:A→C,A→B,C→B,A→C,B→A,B→C,A→C其中第3步又可以分解为:1)、将B上1个盘子从B座移到A座。2)、将B上1个盘子从B座移到C座。3)、将A上1个盘子从A座移到C座。综合以上分析,将n个盘子从A座移动到C座可以分解为以下3步:1、将A座上n-1个盘子借助C座先移到B座上。2、将A座上剩下的1个盘子移到C座上。3、将n-1个盘子从B座借助A座移到C座上。上面的第1步和第3步,都是把n-1个盘子从一个座移到另一个座,采用的办法是一样的,只是座名不同而已。因此,可以把上面的3个步骤,归成两类操作:1)、将n-1个盘子从一个座移到另一个座上(n1)。2)、将1个盘子从一个座移到另一个座上。移动n个盘子要经历2n-1步,移动64个盘子,要经历264-1步。#includestdio.hvoidmain(){voidhanoi(intn,charone,chartwo,charthree);intm;printf(inputthenumberofdiskes:);scanf(%d,&m);printf(Thesteptomoveing%ddiskes:\n,m);hanoi(m,'A','B','C');}voidhanoi(intn,charone,chartwo,charthree){voidmove(charx,chary);if(n==1)move(one,three);else{hanoi(n-1,one,three,two);/*从A到B借助C*/move(one,three);/*从A到C*/hanoi(n-1,two,one,three);/*从B到C借助A*/}}voidmove(charx,chary){printf(%c--%c\n,x,y);;}因此,可以把上面的3个步骤,归成两类操作:1)、将n-1个盘子从一个座移到另一个座上(n1)。由hanoi()完成2)、将1个盘子从一个座移到另一个座上。由move()完成。7.7数组作为函数参数#includestdio.hvoidmain(){intlarge(intx,inty);inta[10],b[10],i,n=0,m=0,k=0;printf(enterarraya:\n);for(i=0;i10;i++)scanf(%d,&a[i]);printf(\n);printf(enterarrayb:\n);for(i=0;i10;i++)scanf(%d,&b[i]);printf(\n);7.7.1数组元素作函数实参例7.9有两个数组a和b,各有10个元素。n,m,k分别累计a数组元素大于、等于、小于b数组元素的个数。for(i=0;i10;i++){if(large(a[i],b[i])==1)n++;elseif(large(a[i],b[i])==0)m++;elsek++;}large(intx,inty){intflag;if(xy)flag=1;elseif(xy)flag=-1;elseflag=0;return(flag);}printf(a[i]b[i]%dtimes\na[i]=b[i]%dtimes\na[i]b[i]%dtimes\n,n,m,k);if(nk)printf(arrayaislargerthanarrayb\n);elseif(nk)printf(arrayaissmallerthanarrayb\n);elseprintf(arrayaisequaltoarrayb\n);}#includestdio.hvoidmain(){floataverage(floatarray[10]);floatscore[10],aver;inti;printf(input10scores:\n);for(i=0;i10;i++)scanf(%f,&score[i]);printf(\n);aver=average(score);printf(averagescoreis%5.2f\n,aver);}7.7.2数组名作函数实参例7.10求10个学生成绩的平均成绩。floataverage(floatarray[10]){inti;floataver,sum=array[0];for(i=1;i10;i++)sum=sum+array[i];aver=sum/10;return(aver);}可以用数组名作函数参数,只是将数组的首元素的地址传递给所对应的形参,因此形参应当是数组名或指针变量。(传址)说明:1、用数组名作函数参数,应在主调函数和被调函数分别定义数组。不能只定义一方。2、实参数组与形参数组类型应一致。3、编译系统对形参数组大小不做检查,只是将实参数组的首元素的地址传给形参数组。4、在被调函数中,声明形参数组时,可以不指定大小,在定义数组时可以在数组名后跟一个空的方括号。#includestdio.hvoidmain(){floataverage(floatarray[],intn);floatscore_1[5]={98.5,97,91.5,60,55};floatscore_2[10]={67.5,89.5,99,69.5,77,89.5,76.5,54,60,99.5};printf(TheaverageofclassAis%6.2f\n,average(score_1,5));printf(TheaverageofclassBis%6.2f\n,average(score_2,10));}例7.11分别求10个、5个学生成绩的平均成绩。floataverage(floatarray[],intn){inti;floataver,sum=array[0];for(i=1;in;i++)sum=sum+array[i];aver=sum/n;return(aver);}#includestdio.hvoidmain(){voidsort(intarray[],intn);inta[10],i;printf(enterarray:\n);for(i=0;i10;i++)scanf(%d,&a[i]);sort(a,10);printf(Thesortedarray:\n);for(i=0;i10;i++)printf(%d,a[i]);printf(\n);}例7.12用选择法对数组按由小到大排序。voidsort(intarray[],intn){inti,j,k,t;for(i=0;in-1;i++){k=i;for(j=i+1;jn;j++)if(array[j]array[k])k=j;t=array[k];array[k]=array[i];array[i]=t;}}#includestdio.hmain(){intmax_value(intarray[][4]);inta[3][4]={{1,3,5,7},{2,4,6,8},{15,17,34,12}};printf(Maxvalueis%d\n,max_value(a));}7.7.3用多维数组名作函数参数可以用多维数组名作为函数的实参和形参。在被调用函数中对形参数组定义时可以指定每一维的大小,也可以省略第一维的大小说明。但不能省略第二维以及其它高维的大小说明。在第二维大小相同的前提下,形参数组的第一维可以与实参数组不同。intmax_value(intarray[][4]){inti,j,max;max=array[0][0];for(i=0;i3;i++)for(j=0;j4;j++)if(array[i][j]max)max=array[i][j];return(max);}例7.13求3×4的二维数组所有元素中的最大值。在第二维大小相同的前提下,形参数组的第一维可以与实参数组不同。例如:实参数组定义为:intscore[5][10];而形参数组定义为:intarray[3][10];或intarray[8]
本文标题:第7章 函数调用
链接地址:https://www.777doc.com/doc-3995328 .html