版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
5.3自定义函数5.2标准函数5.1函数概述5.4函数与数组的应用实例
5.5递归算法与递归函数
第5章程序的组织结构
5.3自定义函数5.2标准函数5.1函数概述5.4函15.1函数概述结构化程序设计方法的核心是自顶向下,逐步求精,具体的实现策略是将复杂的问题逐步分解成相对简单的子问题,这样将有利于降低解决问题的难度,提高程序开发的效率。将一个问题分解成若干个子问题的过程称为模块化。在C程序中,模块用函数实现。函数是构成C程序的基本单位。它由函数首部和函数体两个部分组成,函数首部包含函数的返回类型、函数名称和参数表的声明,函数体包含实现特定功能所需要执行的语句序列。5.1函数概述结构化程序设计方法的核心是自顶向下,逐步求精25.2标准函数C语言提供了很多标准函数,它们被放置在一起,形成了一个标准函数库。函数原型函数原型是指不包含函数体的函数声明。C语言规定,所有的函数必须先定义后调用。对于标准函数而言,由于它们的定义已经在C语言提供的标准函数库中,所以,人们在调用它们的时候,只需要在程序的前面利用编译预处理命令include将相应的函数原型加入到程序中就可以了。5.2标准函数C语言提供了很多标准函数,它们被放置在一起,3例1:根据给定的两个坐标点(x1,y1)和(x2,y2),计算两点之间的距离。
问题分析计算两点之间距离的公式为d=在这个公式中含有平方和开平方的运算,可以直接利用C语言提供的标准函数实现这两个运算。
例1:根据给定的两个坐标点(x1,y1)和(x2,y2),计4算法描述
算法描述5#include<stdio.h>#include<math.h>main(){intx1,y1,x2,y2;doubledistance;printf("\nEnter2coordinates(x1,y1,x2,y2)\n");scanf("%d%d%d%d",&x1,&y1,&x2,&y2); printf("\nThefirstcoordinateis(%d,%d)",x1,y1); printf("\nThesecondcoordinateis(%d,%d)",x2,y2);distance=sqrt(pow(x2-x1,2)+pow(y2-y1,2)); printf("\nThedistanceis%f",distance); }程序代码#include<stdio.h>程序代码6例2:掷骰子游戏。骰子是一个有六个面的正方体,每个面分别印有1~6之间的小圆点代表点数。假设这个游戏的规则是:两个人轮流掷骰子6次,并将每次投掷的点数累加起来。点数多者获胜;点数相同平局。请编写程序,模拟这个游戏的过程,并给出玩100盘之后,谁是最终的获胜者。
随机数的产生及应用实例例2:掷骰子游戏。随机数的产生及应用实例7问题分析由于每个人掷骰子所得到的点数是随机的,所以需要借助随机数发生器,每次产生一个1~6之间的整数,以此模拟玩者掷骰子的点数。为了计算在每盘中,甲、乙两人所掷的点数,需要定义两个int型变量d1,d2,用于作为记录每个人投掷点数的累加器。为了记录每个人的获胜盘数,需要再定义两个int型变量c1,c2,用于记录每个人获胜的盘数。问题分析8算法描述
算法描述9#include<stdio.h>#include<stdlib.h>main(){intd1,d2,c1,c2,i,j;c1=c2=0; /*初始化*/randomize(); /*初始化随机数产生器*/for(i=1;i<=100;i++){ /*模拟游戏过程*/d1=d2=0;for(j=1;j<=6;j++){ /*两个人轮流掷骰子*/d1=d1+random(6)+1;d2=d2+random(6)+1;}if(d1>d2)c1++; /*累加获胜盘数*/elseif(d1<d2)c2++;}if(c1>c2) /*输出最终获胜者信息*/printf("\nThefirstwin.");elseif(c1<c2) printf("\nThesecondwin.");else printf("Theytie.");}程序代码#include<stdio.h>程序代码105.3自定义函数函数的定义基本格式
<函数返回类型><函数名>(<参数表>){ <函数体>;}
例:
doubledistance(intx,inty){ doubled; d=sqrt(x*x+y*y); returnd;}5.3自定义函数函数的定义11C语言规定,一个函数可以有返回值,也可以没有返回值。如果有返回值,返回值的类型在函数名前声明,并在函数体中利用return语句将返回值返回;如果没有返回值,在函数名前声明void。默认的返回类型是int。
函数名不但应该符合C语言的自定义标识符命名规范,还应该“见名知意”。参数表是函数之间交换信息的接口。既可以通过它将外界的数据传递给函数,也可以通过它将函数的操作结果带出函数。如果形式参数属于一维数组类型,无须指出一维数组的元素个数。函数体是函数的核心部分,在这里列出了需要执行的语句序列。
C语言规定,一个函数可以有返回值,也可以没有返回值。如果有返12函数的调用
函数调用语句的基本格式为:<函数名>(<实在参数表>);实在参数与形式参数的数据类型和个数一一对应。
函数的返回值在声明函数的时候,函数名前使用了保留字void,说明这个函数没有返回值;否则,这个函数执行完毕后,应该返回一个相应类型的数值。return表达式;函数的调用函数的返回值13参数的传递
定义函数时所给的参数被称为形式参数,这是由于当函数没有处于执行状态时,系统并不为这些参数分配存储空间,换言之,这些参数此时并不存在,只是用来说明在调用这个函数时需要在这个位置向函数提供的数据类型,因此,在调用函数之后,参数传递需要经历两个基本步骤:首先,根据形式参数的声明格式,为每一个形式参数分配存储空间;然后再将实在参数的值赋给对应的形式参数。参数的传递14例3:输出乘法口诀表。乘法口诀表又被称为“九九表”,是一种小学生在学习乘法运算时需要熟背的一个口诀表。它是一个9行9列的二维表格,加上一个行标题和一个列标题,显示出来应该是10行10列。自定义函数的应用实例例3:输出乘法口诀表。自定义函数的应用实例15问题分析行与行之间可以采用若干个“=”或“-”字符表示表格之间的线段,为此,可以定义一个函数,专门用来连续地显示若干个字符,以避免在每次需要显示线段的时候,都重复地书写相应的语句序列。
问题分析16#include<stdio.h>voiddrawLine(intn,charch); /*连续显示n个ch字符*/main(){inti,j;printf("\n9.9table\n"); /*显示表名*/drawLine(30,'='); /*显示每列的标题*/printf("\n123456789");drawLine(30,'=');for(i=1;i<=9;i++){ /*显示每行的内容*/printf("\n%3d",i);for(j=1;j<=9;j++)printf("%3d",i*j);if(i<9) drawLine(30,'-');else drawLine(30,'=');}}#include<stdio.h>17voiddrawLine(intn,charch)/*连续显示n个ch字符*/{inti;putchar('\n');/*换行*/for(i=1;i<=n;i++)putchar(ch);/*连续显示n个字符ch*/}voiddrawLine(intn,charch)18例4:计算
要求精确度达到10-6。
问题分析在这个公式中,第i项的分子是xi;分母是i!。为了便于计算每一项的数值,设计了两个函数power()和factorial()分别用来完成计算xi和i!的任务。另外,为了更好地体现模块化的设计思路,再设计一个函数e()用于计算ex。
例4:计算
要求精确度达到10-6。
问题分析19算法描述
算法描述20#include<stdio.h>longpower(intx,inty);longfactorial(intn);doublee(intx);main(){intx;printf("\nEnterx:");scanf("%d",&x);printf("\ne^%d=%f",x,e(x));}longpower(intx,inty) /*计算xy*/{longp=1;inti;for(i=1;i<=y;i++)p=p*x;returnp;}程序代码#include<stdio.h>程序代码21longfactorial(intn) /*计算n!*/{inti;longf=1;for(i=2;i<=n;i++)f=f*i;returnf;}doublee(intx) /*计算ex*/{doubleresult=1.0,tmp;inti=1;do{tmp=power(x,i)*1.0/factorial(i++);result+=tmp;}while(tmp>=1E-6); /*精度的检查*/returnresult;}程序代码longfactorial(intn) 225.4函数与数组的应用实例
计算最长文本行
所谓文本行是指以换行符‘\n’作为结束标志的文本序列。
例5:从键盘输入一组文本行,求出最长行并且输出。5.4函数与数组的应用实例计算最长文本行例5:从键盘输入23问题分析从问题的求解要求可知,没有必要保存输入的所有文本行。只需保存已经输入各行中的最长行,以及刚输入的当前行。设计一个专门用于计算最长文本行的函数voidreadline(charmaxline[])。其实现过程为:一边输入文本行保存于数组line、一边与当前最长的文本行长度进行比较。如果新输入的文本行更长,则更新记录最长文本行的信息,最后得到的最长文本行将通过参数带出去。问题分析24算法描述
算法描述25#include<stdio.h>#include<string.h>voidreadline(charmaxline[]);main(){charmaxline[80]="";readline(maxline); /*输入并计算最长行*/printf("\nThelongestlineis:\n");puts(maxline); /*输出最长行*/}程序代码#include<stdio.h>程序代码26voidreadline(charmaxline[]) /*输入并计算最长文本行*/{charline[80];intmaxlength;intn;maxlength=0;/*初始化*/line[0]='\0';printf("\nEntertextlines:\n");do{gets(line);/*输入文本行*/n=strlen(line);if(n>strlen(maxline)){/*与记录的最长文本行进行比较*/maxlength=n;/*更新记录最长文本行的信息*/strcpy(maxline,line);}}while(n>0);}程序代码voidreadline(charmaxline[])27冒泡排序为了便于查找、统计,排序是一种经常需要进行的操作。排序的方法有很多种,上一章中介绍的简单选择排序是一种基于选择手段实现的排序方法。冒泡排序的基本思路是不断地将所有相邻数据进行比较,如果前面的数据大于后面的数据(a[j]>a[j+1]),就将两个位置的数据进行交换,最终实现将所有的数据按照非递减的顺序重新排列的目的。
冒泡排序28问题分析将整个待排序的数据序列划分成有序区域和无序区域。初始状态有序区域为空,无序区域包括所有待排序的数据。对无序区域从前向后依次对相邻的两个数据进行比较,若逆序则将其交换,从而使得较小的数据像泡沫一样“飘浮”(向前),较大的数据“下沉”(向后)。每经过一趟冒泡排序,都会使无序区域中的最大数据进入有序区域。如果有n个数据等待排序,则最多经过n-1趟冒泡排序就可以将所有的数据排列好。例6:冒泡排序。
问题分析例6:冒泡排序。29算法描述
算法描述30#include<stdio.h>#include<stdlib.h>#defineNUM10voidinput(intvalue[]);voidoutput(intvalue[]);voidsort(intvalue[]);main(){intvalue[NUM]; /*存储待排序的数据数列*/input(value);output(value);sort(value);output(value);}voidinput(intvalue[]) /*输入待排序数据*/{inti;printf("\nEnter%dintegers:",NUM);for(i=0;i<NUM;i++)scanf("%d",&value[i]);}程序代码#include<stdio.h>程序代码31voidoutput(intvalue[]) /*输出显示数据数列*/{inti;printf("\n");for(i=0;i<NUM;i++)printf("%5d",value[i]);}voidsort(intvalue[]) /*冒泡排序函数*/{inti,j,temp;for(i=NUM-1;i>=1;i--) /*控制排序趟数*/for(j=0;j<i;j++) /*相邻数据比较大小*/if(value[j]>value[j+1]){ /*如果两个相邻数据逆序,交换*/temp=value[j];value[j]=value[j+1];value[j+1]=temp;}}程序代码voidoutput(intvalue[]) /*325.5递归算法与递归函数概述n!其含义为1234(n-1)n。从这个数学公式中可以发现,n!等于n与(n-1)!的乘积。即将计算n!的过程分解成n与(n-1)!的乘积;这样分解的子问题除了n的值以外,与原问题具有相同的特征,所以求解子问题的基本方法与求解整个问题所采用的方法一样。具有这种特征的求解算法被称为递归算法,5.5递归算法与递归函数概述33实现阶乘递归算法的递归函数
longfact(intn){ if(n==0)return1; elsereturnn*fact(n-1);}
实现阶乘递归算法的递归函数34y=fact(3)3*fact(2)2*fact(1)1*fact(0)111*112*123*26递归函数的调用过程y=fact(3)3*fact(2)2*fact(1)1*35问题分析解决这个问题似乎有些复杂,但采用递归方式就简单多了。3个数的全排列是每个数轮流充当一次第一个数,再加上后面n-1个数的全排列,而求解n-1个数的全排列方法与求解n个数的全排列方法完全一样,因此,可以设计一个递归函数,实现求n个数全排列的操作。考虑到每次递归过程中,将针对n个数据进行排列,而这些数据来自同一数据序列,故设置数组保存数据序列,以数组名和数据个数作为函数的参数。例7:求解n个数据的全排列。问题分析例7:求解n个数据的全排列。36#include<stdio.h>#defineNUM3voidanagram(int[],int);voidprint(int[]);main(){intd[NUM];inti;for(i=0;i<NUM;i++) /*初始化*/d[i]=NUM-i;anagram(d,NUM);}voidprint(intd[]) /*输出数组内容*/{inti;printf("\n");for(i=NUM-1;i>=0;i--){printf("%d",d[i]);}}程序代码#include<stdio.h>程序代码37voidanagram(intd[],intn) /*求解n的全排列*/{inti,j,temp;if(n==1){ /*n=1直接输出*/print(d);return;}for(i=0;i<n;i++){anagram(d,n-1); /*对后面n-1个数全排列*/temp=d[0]; /*轮换第一个位置的数*/for(j=1;j<=n-1;j++){d[j-1]=d[j]; /*将每个数据向前移*/}d[n-1]=temp;}}程序代码voidanagram(intd[],intn)38用递归函数实现二分查找二分查找的问题,它是对有序数列进行查找操作的一种有效方法。实际上,这种查找方法是一个递归的过程。
用递归函数实现二分查找39问题分析二分查找也是信息处理中常用的一个算法。为了提高这个算法的重用性,单独设置一个函数来实现该算法是适当的。二分查找算法可以描述为:针对一个已经从小到大排序的数据序列,用给定数据key与查找区间中央位置的数据比较,如果相等则表明查找成功;否则,如果key比中央位置的数据小,则在前半个区间用同样的方法继续查找;否则在后半个区间用同样的方法继续查找。因此,这是一个递归的过程。当查找区间的长度为0时,说明查找不成功。
例8:采用递归方式实现二分查找。问题分析例8:采用递归方式实现二分查找。40#include<stdio.h>#include<stdlib.h>#defineNUM10voidinput(intvalue[]);voidoutput(intvalue[]);intsearch(intvalue[],intkey,intlow,inthigh);main(){intvalue[NUM],result,key;input(value); /*输入有序序列*/output(value); /*输出有序数列*/printf("\nEnterakey:"); /*输入待查找的数值*/scanf("%d",&key);result=search(value,key,0,NUM-1);/*调用二分查找函数进行查找*/if(result!=-1) /*输出查找结果*/ printf("\nThe%disthe%dthelement",key,result);
else printf("\nFailtofind%d",key);}程序代码#include<stdio.h>#includ41voidinput(intvalue[]) /*创建有序数列*/{inti;for(i=0;i<NUM;i++) scanf("%d",&value[i]);}voidoutput(intvalue[]) /*输出数列*/{inti;
printf("\n");for(i=0;i<NUM;i++)printf("%4d",value[i]);}程序代码voidinput(intvalue[]) /42intsearch(intvalue[],intkey,intlow,inthigh) {/*二分查找的递归函数*/intmid;
if(low>high) return-1; /*查找区间为空*/mid=(low+high)/2; /*求中间位置*/if(value[mid]==key) returnmid; /*得到查找的数据位置*/if(key<value[mid]) returnsearch(value,key,low,mid-1); /*在下半区查找*/elsereturnsearch(value,key,mid+1,high); /*在上半区查找*/}程序代码intsearch(intvalue[],intk43变量的生存期与作用域变量是存储空间在程序中的一种表示,它承担着存储操作数据和结果的重任,是程序中不可缺少的主要元素。C语言规定,每个变量必须先定义后引用。人们将变量占据存储空间的时间称为变量的生存期,将变量可以引用的区域称为变量的作用域。从作用域角度划分全局变量:在函数外部定义的变量被称为全局变量。局部变量:在函数内部定义的变量,包括参数表中定义的形式参数被称为局部变量。
在复合语句中定义的变量被称为块变量。变量的生存期与作用域44生存期在复合语句中定义的变量,其生存期为所在的复合语句块中。在函数内部和形式参数表中定义的变量都属于局部变量。作用域是定义这些变量的函数。全局变量的生存期是定义这个变量的程序文件,作用域是从定义处开始到程序文件的结束处为止。如果程序文件中的某些局部变量与之同名,则全局变量的作用域应该去除这部分区域。生存期45自动变量和静态变量变量的生存期是由存储类别控制的。常见的存储类别有两种,一个是静态的;另一个是自动的。具有静态存储类别的变量在程序开始运行时系统就为之分配存储空间,等到程序结束时才将为其分配的所有存储空间回收,这种变量被简称为静态变量;具有自动存储类别的变量在函数开始执行时为之分配存储空间,函数执行完毕后,立即回收这些存储空间,这种变量被简称为自动变量。在默认情况下,局部变量都属于自动变量。自动变量和静态变量46说明:在默认情况下,函数内部定义的变量属于自动变量;当使用static存储类别说明符将其指定为静态变量时,只有首次调用这个函数时,系统为之分配空间并初始化,随后的调用不再进行初始化。当程序结束时,系统才回收存储空间。这样就可以达到延长局部变量生存期的目的。将局部变量指定为static,可以延长生存期,但并没有扩展它的作用域。当函数执行时,可以引用这些静态变量;当退出函数时,这些静态变量存在,但不可引用。全局变量可以也被描述为static静态变量。这种全局静态变量的作用域仅限于本源程序文件的范围内,也就是说不允许其他文件中定义的函数访问该变量。说明:47voidfun(){ staticcount=0;count++;printf(“%4d”,count);}采用下面的语句段调用上面的函数
for(i=1;i<=10;i++){fun();}将会再屏幕上看到12345678910
voidfun()采用下面的语句段调用上面的函数148intcount=2;voidfun(){staticcount=0;count++;printf("%4d",count);}main(){inti;printf("%d\n",count);for(i=1;i<=10;i++)fun();printf("\n%d\n",count);}将会再屏幕上看到2123456789102intcount=2;2495.3自定义函数5.2标准函数5.1函数概述5.4函数与数组的应用实例
5.5递归算法与递归函数
第5章程序的组织结构
5.3自定义函数5.2标准函数5.1函数概述5.4函505.1函数概述结构化程序设计方法的核心是自顶向下,逐步求精,具体的实现策略是将复杂的问题逐步分解成相对简单的子问题,这样将有利于降低解决问题的难度,提高程序开发的效率。将一个问题分解成若干个子问题的过程称为模块化。在C程序中,模块用函数实现。函数是构成C程序的基本单位。它由函数首部和函数体两个部分组成,函数首部包含函数的返回类型、函数名称和参数表的声明,函数体包含实现特定功能所需要执行的语句序列。5.1函数概述结构化程序设计方法的核心是自顶向下,逐步求精515.2标准函数C语言提供了很多标准函数,它们被放置在一起,形成了一个标准函数库。函数原型函数原型是指不包含函数体的函数声明。C语言规定,所有的函数必须先定义后调用。对于标准函数而言,由于它们的定义已经在C语言提供的标准函数库中,所以,人们在调用它们的时候,只需要在程序的前面利用编译预处理命令include将相应的函数原型加入到程序中就可以了。5.2标准函数C语言提供了很多标准函数,它们被放置在一起,52例1:根据给定的两个坐标点(x1,y1)和(x2,y2),计算两点之间的距离。
问题分析计算两点之间距离的公式为d=在这个公式中含有平方和开平方的运算,可以直接利用C语言提供的标准函数实现这两个运算。
例1:根据给定的两个坐标点(x1,y1)和(x2,y2),计53算法描述
算法描述54#include<stdio.h>#include<math.h>main(){intx1,y1,x2,y2;doubledistance;printf("\nEnter2coordinates(x1,y1,x2,y2)\n");scanf("%d%d%d%d",&x1,&y1,&x2,&y2); printf("\nThefirstcoordinateis(%d,%d)",x1,y1); printf("\nThesecondcoordinateis(%d,%d)",x2,y2);distance=sqrt(pow(x2-x1,2)+pow(y2-y1,2)); printf("\nThedistanceis%f",distance); }程序代码#include<stdio.h>程序代码55例2:掷骰子游戏。骰子是一个有六个面的正方体,每个面分别印有1~6之间的小圆点代表点数。假设这个游戏的规则是:两个人轮流掷骰子6次,并将每次投掷的点数累加起来。点数多者获胜;点数相同平局。请编写程序,模拟这个游戏的过程,并给出玩100盘之后,谁是最终的获胜者。
随机数的产生及应用实例例2:掷骰子游戏。随机数的产生及应用实例56问题分析由于每个人掷骰子所得到的点数是随机的,所以需要借助随机数发生器,每次产生一个1~6之间的整数,以此模拟玩者掷骰子的点数。为了计算在每盘中,甲、乙两人所掷的点数,需要定义两个int型变量d1,d2,用于作为记录每个人投掷点数的累加器。为了记录每个人的获胜盘数,需要再定义两个int型变量c1,c2,用于记录每个人获胜的盘数。问题分析57算法描述
算法描述58#include<stdio.h>#include<stdlib.h>main(){intd1,d2,c1,c2,i,j;c1=c2=0; /*初始化*/randomize(); /*初始化随机数产生器*/for(i=1;i<=100;i++){ /*模拟游戏过程*/d1=d2=0;for(j=1;j<=6;j++){ /*两个人轮流掷骰子*/d1=d1+random(6)+1;d2=d2+random(6)+1;}if(d1>d2)c1++; /*累加获胜盘数*/elseif(d1<d2)c2++;}if(c1>c2) /*输出最终获胜者信息*/printf("\nThefirstwin.");elseif(c1<c2) printf("\nThesecondwin.");else printf("Theytie.");}程序代码#include<stdio.h>程序代码595.3自定义函数函数的定义基本格式
<函数返回类型><函数名>(<参数表>){ <函数体>;}
例:
doubledistance(intx,inty){ doubled; d=sqrt(x*x+y*y); returnd;}5.3自定义函数函数的定义60C语言规定,一个函数可以有返回值,也可以没有返回值。如果有返回值,返回值的类型在函数名前声明,并在函数体中利用return语句将返回值返回;如果没有返回值,在函数名前声明void。默认的返回类型是int。
函数名不但应该符合C语言的自定义标识符命名规范,还应该“见名知意”。参数表是函数之间交换信息的接口。既可以通过它将外界的数据传递给函数,也可以通过它将函数的操作结果带出函数。如果形式参数属于一维数组类型,无须指出一维数组的元素个数。函数体是函数的核心部分,在这里列出了需要执行的语句序列。
C语言规定,一个函数可以有返回值,也可以没有返回值。如果有返61函数的调用
函数调用语句的基本格式为:<函数名>(<实在参数表>);实在参数与形式参数的数据类型和个数一一对应。
函数的返回值在声明函数的时候,函数名前使用了保留字void,说明这个函数没有返回值;否则,这个函数执行完毕后,应该返回一个相应类型的数值。return表达式;函数的调用函数的返回值62参数的传递
定义函数时所给的参数被称为形式参数,这是由于当函数没有处于执行状态时,系统并不为这些参数分配存储空间,换言之,这些参数此时并不存在,只是用来说明在调用这个函数时需要在这个位置向函数提供的数据类型,因此,在调用函数之后,参数传递需要经历两个基本步骤:首先,根据形式参数的声明格式,为每一个形式参数分配存储空间;然后再将实在参数的值赋给对应的形式参数。参数的传递63例3:输出乘法口诀表。乘法口诀表又被称为“九九表”,是一种小学生在学习乘法运算时需要熟背的一个口诀表。它是一个9行9列的二维表格,加上一个行标题和一个列标题,显示出来应该是10行10列。自定义函数的应用实例例3:输出乘法口诀表。自定义函数的应用实例64问题分析行与行之间可以采用若干个“=”或“-”字符表示表格之间的线段,为此,可以定义一个函数,专门用来连续地显示若干个字符,以避免在每次需要显示线段的时候,都重复地书写相应的语句序列。
问题分析65#include<stdio.h>voiddrawLine(intn,charch); /*连续显示n个ch字符*/main(){inti,j;printf("\n9.9table\n"); /*显示表名*/drawLine(30,'='); /*显示每列的标题*/printf("\n123456789");drawLine(30,'=');for(i=1;i<=9;i++){ /*显示每行的内容*/printf("\n%3d",i);for(j=1;j<=9;j++)printf("%3d",i*j);if(i<9) drawLine(30,'-');else drawLine(30,'=');}}#include<stdio.h>66voiddrawLine(intn,charch)/*连续显示n个ch字符*/{inti;putchar('\n');/*换行*/for(i=1;i<=n;i++)putchar(ch);/*连续显示n个字符ch*/}voiddrawLine(intn,charch)67例4:计算
要求精确度达到10-6。
问题分析在这个公式中,第i项的分子是xi;分母是i!。为了便于计算每一项的数值,设计了两个函数power()和factorial()分别用来完成计算xi和i!的任务。另外,为了更好地体现模块化的设计思路,再设计一个函数e()用于计算ex。
例4:计算
要求精确度达到10-6。
问题分析68算法描述
算法描述69#include<stdio.h>longpower(intx,inty);longfactorial(intn);doublee(intx);main(){intx;printf("\nEnterx:");scanf("%d",&x);printf("\ne^%d=%f",x,e(x));}longpower(intx,inty) /*计算xy*/{longp=1;inti;for(i=1;i<=y;i++)p=p*x;returnp;}程序代码#include<stdio.h>程序代码70longfactorial(intn) /*计算n!*/{inti;longf=1;for(i=2;i<=n;i++)f=f*i;returnf;}doublee(intx) /*计算ex*/{doubleresult=1.0,tmp;inti=1;do{tmp=power(x,i)*1.0/factorial(i++);result+=tmp;}while(tmp>=1E-6); /*精度的检查*/returnresult;}程序代码longfactorial(intn) 715.4函数与数组的应用实例
计算最长文本行
所谓文本行是指以换行符‘\n’作为结束标志的文本序列。
例5:从键盘输入一组文本行,求出最长行并且输出。5.4函数与数组的应用实例计算最长文本行例5:从键盘输入72问题分析从问题的求解要求可知,没有必要保存输入的所有文本行。只需保存已经输入各行中的最长行,以及刚输入的当前行。设计一个专门用于计算最长文本行的函数voidreadline(charmaxline[])。其实现过程为:一边输入文本行保存于数组line、一边与当前最长的文本行长度进行比较。如果新输入的文本行更长,则更新记录最长文本行的信息,最后得到的最长文本行将通过参数带出去。问题分析73算法描述
算法描述74#include<stdio.h>#include<string.h>voidreadline(charmaxline[]);main(){charmaxline[80]="";readline(maxline); /*输入并计算最长行*/printf("\nThelongestlineis:\n");puts(maxline); /*输出最长行*/}程序代码#include<stdio.h>程序代码75voidreadline(charmaxline[]) /*输入并计算最长文本行*/{charline[80];intmaxlength;intn;maxlength=0;/*初始化*/line[0]='\0';printf("\nEntertextlines:\n");do{gets(line);/*输入文本行*/n=strlen(line);if(n>strlen(maxline)){/*与记录的最长文本行进行比较*/maxlength=n;/*更新记录最长文本行的信息*/strcpy(maxline,line);}}while(n>0);}程序代码voidreadline(charmaxline[])76冒泡排序为了便于查找、统计,排序是一种经常需要进行的操作。排序的方法有很多种,上一章中介绍的简单选择排序是一种基于选择手段实现的排序方法。冒泡排序的基本思路是不断地将所有相邻数据进行比较,如果前面的数据大于后面的数据(a[j]>a[j+1]),就将两个位置的数据进行交换,最终实现将所有的数据按照非递减的顺序重新排列的目的。
冒泡排序77问题分析将整个待排序的数据序列划分成有序区域和无序区域。初始状态有序区域为空,无序区域包括所有待排序的数据。对无序区域从前向后依次对相邻的两个数据进行比较,若逆序则将其交换,从而使得较小的数据像泡沫一样“飘浮”(向前),较大的数据“下沉”(向后)。每经过一趟冒泡排序,都会使无序区域中的最大数据进入有序区域。如果有n个数据等待排序,则最多经过n-1趟冒泡排序就可以将所有的数据排列好。例6:冒泡排序。
问题分析例6:冒泡排序。78算法描述
算法描述79#include<stdio.h>#include<stdlib.h>#defineNUM10voidinput(intvalue[]);voidoutput(intvalue[]);voidsort(intvalue[]);main(){intvalue[NUM]; /*存储待排序的数据数列*/input(value);output(value);sort(value);output(value);}voidinput(intvalue[]) /*输入待排序数据*/{inti;printf("\nEnter%dintegers:",NUM);for(i=0;i<NUM;i++)scanf("%d",&value[i]);}程序代码#include<stdio.h>程序代码80voidoutput(intvalue[]) /*输出显示数据数列*/{inti;printf("\n");for(i=0;i<NUM;i++)printf("%5d",value[i]);}voidsort(intvalue[]) /*冒泡排序函数*/{inti,j,temp;for(i=NUM-1;i>=1;i--) /*控制排序趟数*/for(j=0;j<i;j++) /*相邻数据比较大小*/if(value[j]>value[j+1]){ /*如果两个相邻数据逆序,交换*/temp=value[j];value[j]=value[j+1];value[j+1]=temp;}}程序代码voidoutput(intvalue[]) /*815.5递归算法与递归函数概述n!其含义为1234(n-1)n。从这个数学公式中可以发现,n!等于n与(n-1)!的乘积。即将计算n!的过程分解成n与(n-1)!的乘积;这样分解的子问题除了n的值以外,与原问题具有相同的特征,所以求解子问题的基本方法与求解整个问题所采用的方法一样。具有这种特征的求解算法被称为递归算法,5.5递归算法与递归函数概述82实现阶乘递归算法的递归函数
longfact(intn){ if(n==0)return1; elsereturnn*fact(n-1);}
实现阶乘递归算法的递归函数83y=fact(3)3*fact(2)2*fact(1)1*fact(0)111*112*123*26递归函数的调用过程y=fact(3)3*fact(2)2*fact(1)1*84问题分析解决这个问题似乎有些复杂,但采用递归方式就简单多了。3个数的全排列是每个数轮流充当一次第一个数,再加上后面n-1个数的全排列,而求解n-1个数的全排列方法与求解n个数的全排列方法完全一样,因此,可以设计一个递归函数,实现求n个数全排列的操作。考虑到每次递归过程中,将针对n个数据进行排列,而这些数据来自同一数据序列,故设置数组保存数据序列,以数组名和数据个数作为函数的参数。例7:求解n个数据的全排列。问题分析例7:求解n个数据的全排列。85#include<stdio.h>#defineNUM3voidanagram(int[],int);voidprint(int[]);main(){intd[NUM];inti;for(i=0;i<NUM;i++) /*初始化*/d[i]=NUM-i;anagram(d,NUM);}voidprint(intd[]) /*输出数组内容*/{inti;printf("\n");for(i=NUM-1;i>=0;i--){printf("%d",d[i]);}}程序代码#include<stdio.h>程序代码86voidanagram(intd[],intn) /*求解n的全排列*/{inti,j,temp;if(n==1){ /*n=1直接输出*/print(d);return;}for(i=0;i<n;i++){anagram(d,n-1); /*对后面n-1个数全排列*/temp=d[0]; /*轮换第一个位置的数*/for(j=1;j<=n-1;j++){d[j-1]=d[j]; /*将每个数据向前移*/}d[n-1]=temp;}}程序代码voidanagram(intd[],intn)87用递归函数实现二分查找二分查找的问题,它是对有序数列进行查找操作的一种有效方法。实际上,这种查找方法是一个递归的过程。
用递归函数实现二分查找88问题分析二分查找也是信息处理中常用的一个算法。为了提高这个算法的重用性,单独设置一个函数来实现该算法是适当的。二分查找算法可以描述为:针对一个已经从小到大排序的数据序列,用给定数据key与查找区间中央位置的数据比较,如果相等则表明查找成功;否则,如果key比中央位置的数据小,则在前半个区间用同样的方法继续查找;否则在后半个区间用同样的方法继续查找。因此,这是一个递归的过程。当查找区间的长度为0时,说明查找不成功。
例8:采用递归方式实现二分查找。问题分析例8:采用递归方式实现二分查找。89#include<stdio.h>#include<stdlib.h>#defineNUM10voidinput(intvalue[]);voidoutput(intvalue[]);intsearch(intvalue[],intkey,intlow,inthigh);main(){intvalue[NUM],result,key;input(value); /*输入有序序列*/output(value); /*输出有序数列*/printf("\nEnterakey:"); /*输入待查找的数值*/sca
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年四川武胜县交通运输公司招聘笔试参考题库含答案解析
- 2025年福建闽商报传媒有限公司招聘笔试参考题库含答案解析
- 宁波市城市管理局直属事业单位招考14名事业编制工作人员高频重点提升(共500题)附带答案详解
- 复旦大学历史学系招考聘用教授高频重点提升(共500题)附带答案详解
- 国网福建省电力限公司2025年高校毕业生(第二批)招聘高频重点提升(共500题)附带答案详解
- 国网2025年高校毕业生招聘湖南省电力公司招聘481人历年高频重点提升(共500题)附带答案详解
- 国家统计局泰兴调查队劳务派遣人员招考聘用(江苏)高频重点提升(共500题)附带答案详解
- 国家电网限公司直流建设分公司2025年高校应届毕业生第二批招聘高频重点提升(共500题)附带答案详解
- 国家机关事务管理局所属事业单位度公开招考22名工作人员高频重点提升(共500题)附带答案详解
- 四川遂宁市属事业单位2025第三季度招聘历年高频重点提升(共500题)附带答案详解
- 鲁教版七年级数学下册(五四制)全册完整课件
- 患者突发昏迷应急预案演练脚本-
- 智能机器人技术导论PPT完整全套教学课件
- 危险性较大的分部分项工程清单 及安全管理措施
- 中职英语语文版(2023)基础模块1 Unit 1 The Joys of Vocational School 单元测试题(含答案)
- 最全-房屋市政工程安全生产标准化指导图册
- 算法向善与个性化推荐发展研究报告
- 聚合物的流变性详解演示文稿
- 电气设备预防性试验安全技术措施
- 压力弹簧力度计算器及计算公式
- 内科学教学课件:免疫性血小板减少症(ITP)
评论
0/150
提交评论