




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第七章 用函数实现模块化程序设计交实验报告140页3题格式:按照上机指导书171页附录D格式书写采用统一的实验报告纸算法是解决具体问题的方案基本要求:根据给出的算法编写程序7.1 为什么要用函数实际的软件开发实际问题往往由多个基本问题构成。要求软件开发人员首先分析问题,将问题分解为基本问题。其次,逐个解决每个基本问题。程序与问题的关系对软件开发人员的要求分析并分解问题(高级要求)。设计解决基本问题的函数(基本要求)。例iA 和 iB 为两个整数,iA 是基数,iB 是指数.如何计算变量result保存最后结果,base为底数,exponent为指数。result=1;for(counter=1
2、;counter=exponent;counter+)result*=base;计算35、 55、 85问题如果要分别计算100对整数的次幂,需要多少for?解决方案我们制造一个零件(函数),它负责计算次幂当需要计算次幂时,告诉零件基数和指数,零件返回结果。 函数就象提供服务的人。第一个角度:程序就是机器。函数就是零件。程序由函数构成。第二个角度:函数可以为其他函数提供服务,就象服务人员。1. 什么是函数?函数就是可以完成某项基本任务的一组语句。函数名是唯一的。 函数可以被其他的函数使用,称为函数的调用。参数主调用函数给被调用函数一些数据,即参数。被调用函数根据参数值完成相应的工作。 返回值被
3、调用函数完成工作后,可能会返回某些数据作为计算结果。函数的要素函数名参数返回值函数体(语句)函数调用示例:main() /* 主函数 */ print_star(); /*调用print_star函数画*/ print_message(); /*调用print _message函数写字*/ print_star() ; /*调用print_star函数画*/ print_star() /*定义print_star函数*/ prinf(“* n”); print_message() /*定义print_message函数*/ prinf(“ Hello! n ”); 运行结果:* Hello!
4、* 一个源文件由一个或多个函数组成,是一个独立编译单元。一个C程序由一个或多个源文件组成;C程序执行总是从main函数开始,调用其他函数后流程回到main。函数不能嵌套定义,但可互相调用。注意不能调用main函数。 函数的分类 1.函数参数形式无参函数有参函数2. 从用户使用的角度分标准函数(库函数)用户自己定义的函数库函数编译系统提供的已设计好的函数,用户只需调用而无需要去实现它(scanf,printf,getchar,putchar等)。用户自定义函数程序员自己定义和设计的函数。有参函数例(输出两数中大者)#include main( ) int max(int x,int y); in
5、t n1,n2,a; scanf(%d,%d,&n1,&n2); a = max(n1,n2); printf(max=%d,a); int max( int x, int y ) int z; if(xy) z=x; else z=y; return (z);无参函数例main() print_star(); print_message(); print_star() ; print_star() prinf(“* n”); print_message() prinf(“ Hello! n ”); 7.2 怎样定义函数 例如: print_message() printf(“Hello! n
6、 ”);二、 有参函数的定义形式类型标识符 函数名(形参表列) 说明部分 语句 有参数传递例如:求x和y二者中大者int max (int x, int y) /*x,y为形参*/ int z; /*函数体中变量的说明*/ z=xy?x:y; return (z) ; /*将z的值作为函数返回值*/类型标识符 函数名() 说明部分 语句 无参数传递一、 无参函数的定义形式三、 空函数的定义形式类型标识符 函数名( ) 功能:调用后什么也不做。用处:建立程序结构,在需要时补充功能。 例如:dummy() 若无参数,类型标识符写void或不写函数返回值的类型,若不说明类型,默认为整型。是被初始化的
7、内部变量,寿命和可见性仅限于函数内部四、 形式参数和实际参数形式参数定义函数时函数名后面括弧中的变量名,简称形参。实际参数调用函数时函数名后面括弧中的表达式,简称实参。 c=max(a, b); - 实参:在运行时 把函数的 max(int x,int y) 把值传给函数。 结果赋给 函数名 returu (z); 形参:通知系统 要预留内存位置。 上例中形参与实参、函数名与返回值之间的关系main( ) int max( int x, int y); int a,b,c; scanf (“%d,%d,&a,&b); c=max(a,b); printf(“Max is %d”,c);int
8、max( int x, int y) int z; z=xy? x:y; return(z);形参表实参表函数的返回值语句return将被调函数的一个确定值带回主调函数。return(函数返回值); 或 return 函数返回值; 通过函数调用使主调函数得到一个确定的值五、函数的返回值main( ) int max( int x, int y) ;int a,b,c; scanf (“%d,%d,&a,&b); c=max(a,b); printf(“Max is %d”,c);int max( int x, int y) int z; z=xy? x:y; return(z);此时函数的返回
9、值是5,因此c=5有确定值的常量、变量或表达式函数不加类型说明按整型处理函数和return类型不一致以函数类型为准。函数不返回值定义为void六、函数值的类型 void print_star() main( ) int max( int x, int y) ; int a,b,c; scanf (“%d,%d,&a,&b); c=max(a,b); printf(“Max is %d”,c);int max( int x, int y) int z; z=xy? x:y; return(z);小结int Power ( int iBase, int iExponent )返回类型: int 函
10、数名:Power形式参数: iBase,iExponent形式参数的数值由实际参数决定。注意:int Power ( int iBase, int iExponent )谁是被定义的函数?谁是参数?第一个int的作用是什么?后两个int的作用是什么?函数的使用者应该明确指明什么,才能使用函数?调用函数就是使用函数。调用函数之前,必须首先声明函数。声明函数就是声明:函数名、函数返回值的类型和参数的类型。例:int Power(int, int);7.3 调用函数 一、函数调用的一般形式 函数名(实际参数表) 有参数函数无参数函数 函数名() void print_star()printf(“*”
11、);main( ) int a,b,c; scanf (“%d,%d,&a,&b); c=2*max(a,b); print-star(); printf(“c= %d”,c);int max( int x, int y) int z; z=xy? x:y; return(z);二、函数调用的具体方式1.函数调用作为一个语句 函数名(实际参数表);调用可忽略或没有返回值的函数(如:scanf函数和printf函数) 2.函数调用出现在表达式中变量名=函数表达式调用带返回值的函数,其返回值参加表达式运算。无返回值函数的调用,不能出现在表达式中3.函数参数 函数调用作为一个函数的参数。如:m=ma
12、x(a,max(b,c) 在程序编译阶段,对调用函数的合法性进行全面检查。如没有函数声明,编译到包含函数调用的语句时(如xx(a,b)),编译系统不知道xx是函数名,也无法判断实参(a,b)的类型和个数是否正确,无法进行正确性的检查。只有在运行时才会发现实参与形参的类型或个数不一致,出现运行错误。 7.4、对被调用函数的声明和函数原型 对被调用函数说明的前提条件必须是已存在的函数,如用户自定义函数或库函数。2.被调用函数是用户自定义函数的函数说明主调函数和被调用函数在同一文件中,在主调函数中说明被调函数类型。在C语言中,以上的函数说明称为函数原型。 /*定义add函数*/float add (
13、float x,float y) float z; z=x+y; return (z); main() float add(float x,float y); float a, b, c; scanf(“ %f, %f”, &a, &b); c=add(a,b) ; printf(“ sum is %f ”, c );对被调用函数的说明作为表达式被调用3. 被调用函数是库函数的函数说明文件开头用#include命令将调用库函数时需用到的信息“包含”到文件中(对这些库函数的原型说明全部都写在对应的头文件里)。 常用的头文件:# include “stdio.h” # include “math.
14、h”# include “string.h”4.省略被调用函数声明的三种情况 float add (float x,float y) float z; z=x+y; return (z); main() float a, b, c; scanf(“ %f, %f”, &a, &b); c=add(a,b) ; printf(“ sum is %f ”, c );(1)被调函数定义在主函数前(2)函数返回值为整型或字符型,系统按整型处理。main( ) int a,b,c; scanf (“%d,%d”,&a,&b); c=max(a,b); printf(“Max is %d”,c); max
15、(int x,int y) int z; z=xy? x:y; return(z); 无函数说明整型函数所有函数定义前,在函数的外部已说明函数类型。char letter( char,char);float f(float,float );int i(float,float);main( ) .char letter (char c1,char c2)float f(float x,float y)int i(float,float)在所有函数之前说明函数类型此处不必说明定义函数letter、f和i复习函数的要素:名字、返回值、参数和代码定义函数:编写代码声明函数:声明名字、参数类型和返回值类
16、型调用函数:给出名字和实际参数,如果有返回值则保存。main() int i; long t; t=1; for(i=1; i=n; i+) t=t*i; printf(“n!=%ldn”,t); long xx(int x) long t=1; int i; if(x=0) printf(“error”); else for(i=1;i=x,i+) t=t*i; return (t); main() int n;long s; scanf(“%d”,&n); s=xx(n); printf(“%ld”,s);例1:编写函数,求n!。例题1:求1+2+3+.+100的和。main() int
17、i,s=0; for (i=1;i=100;i+) s=s+i; printf(“s=%d”,s);例2:编写函数,求1+2+3+.n。int mm(int x) int t=0; int i; for(i=1;i=x,i+) t=t+i; return (t); main() int n; int s; scanf(“%d”,&n); s=mm(n); printf(“%d”,s);执行细节 - 步骤 程序将从主函数开始执行当发生函数调用时,主调用函数暂停实际函数的值将被复制给形式参数(不需要任何语句,程序自动做该项工作).被调用函数执行遇到返回语句时,被调用函数将结果返回给主调用函数主调用
18、函数恢复执行执行细节-存储分配被调用函数执行前,系统为其变量分配内存空间(包括形式参数)。实际参数的值被复制给形式参数 (值传递).当被调用函数结束执行后,内存空间将被释放,下次调用时重新分配。例:你可以判断出下面程序的结果吗?程序的执行过程是怎样的?void Swap(int iA, int iB)int iTemp;iTemp=iA;iA=iB;iB=iTemp;main()int iFirst=13, iSecond=27;Swap(iFirst, iSecond);printf(niA is %d, iFirst);printf(niB is %d, iSecond);main()in
19、t iFirst=13;int iSecond=27;Swap(iFirst, iSecond);printf(niFirst is %d, iFirst);printf(niSecond is %d, iSecond);iFirst=13iSecond=27iFirst=13iSecond=27iB=27iA=13iTempmain()int iFirst=13;int iSecond=27;Swap(iFirst, iSecond);printf(niFirst is %d, iFirst);printf(niSecond is %d, iSecond);void Swap(int iA,
20、 int iB)int iTemp;iTemp=iA;iA=iB;iB=iTemp;iFirst=13iSecond=27iB=27iA=13iTempiFirst=13iSecond=27iB=13iA=27iTempmain()int iFirst=13;int iSecond=27;Swap(iFirst, iSecond);printf(niFirst is %d, iFirst);printf(niSecond is %d, iSecond);iFirst=13iSecond=27总结参数传递的时候,实际参数的数值复制给形式参数形式参数是实际参数的“复印件”。修改形式参数,不影响实际
21、参数的数值。这一机制称为:call-by-value7.5 函数的嵌套调用C语言不能嵌套定义,但可以嵌套调用。嵌套定义:在定义一个函数时,该函数体内包含 另一个函数的定义。一.嵌套调用调用一个函数的过程中,又调用另一个函数。main函数调用A函数结 束A函数调用B函数B函数192873456例题:编写函数,求1!+3!+5!+.k! 其中k是小于9的奇数,要求该函数中调用求阶乘函数求出各阶乘的值。double xx(int x) double t=1; int i; for(i=1;i=x,i+) t=t*i; return (t) ;double yy(int m) double s=0;
22、int i; for(i=1;i1)main() double jx(int m) int n; double t; printf(“Input n :”); scanf(“%d”,&n); t= jx(n); printf(%f,t);double jx(int m) double f; if(m=1) f=1; else f=jx(m-1)*m; return f; 数组作参数的时候,函数可以使用数组元素的“原件”。数组的存储原理决定了这一效果。例: int iListLENGTH; 7.7 数组作为函数参数 数组的存储原理100010021004100610081020304050iLi
23、st0iList1iList2iList3iList4数组元素的地址如果数组iList存储在1000开始的内存空间,那么1000是iList0的地址,1002是iList1的地址,1004是iList2的地址。请问,iListi的地址?1000+i*2计算机访问数组元素的原理计算机根据数组的首地址、元素的下标和数据元素在内存的长度,计算元素的地址,然后根据地址访问数组元素。元素的下标由程序员指定。元素的类型是预先声明的。数组的首地址保存在数组名中。数组名就是数组的首地址。计算机访问数组元素的原理访问iListi,就是访问地址为iList+i*sizeof(int)其中,iList是首地址,i是
24、元素的下标,sizeof(int) 是元素在内存的长度(字节为单位)。问题如果iArray也是数组名,而且iArray中存储的地址与iList相同,那么iArrayi与iListi有什么关系?答:它们是同一数据元素。一、数组元素做函数实参例题:有两个数组A,B各有10个元素,将它们逐个对应相比,如果A数组中的元素大于B数组中相应的元素数目多于B数组中的元素大于A数组中相应的元素数目,则认为A数组大于B数组,并分别统计出两个数组相应元素大于,小于和等于的个数。程序设计:1、函数large(x, y) :比较两个数组元素的 大小。 返回值 flag=1 当 xy0 当 x=y-1 当 xy) fl
25、ag=1;else if(x: 4 =: 1 : 5 a bmain ( ) int a10, b10, i, n=0, m=0, k=0;for ( i=0; i10; i+) scanf(“%d”, &ai);for ( i=0;i10; i+) scanf(“%d”, &bi);for (i=0; ik) printf(“abn”); else if (nk) printf(“abn”); else printf(“a=bn”); 二、数组名做函数参数数组名代表数组在内存中存放区域首地址。数组名作函数参数实现大量数据传递。数组名做函数的参数方法:在主调函数和被调函数中分别定义数组; 实参
26、数组和形参数组类型应一致;实参数组和形参数组大小不一定一致,形参数 组可以不指定大小(这里指一维数组)。说明数组名做函数的实参和形参时是“地址传递”。形参数组各元素的值发生变化会使实参数组各元素值发生同样的变化。例1:编写函数,求一维数组中存放学生成绩的平均值。float aver( float a , int n ) int i; float pj,sum=0; for(i=0;in;i+) sum=sum+ai; pj=sum/n; return(pj); main() float xs10,pjf; int i; for(i=0;i10;i+) scanf(“%f”,&xsi); pjf
27、=aver( xs ,10); printf(“pjf=%f”,pjf); 一维数组作函数参数时形参数组可不指定大小一维数组的大小把一维数组xs的首地址传给形参数组a例2:对数组中10个整数按由小到大排序。void sort (int array , int n) int v, j, t; for (i=0; in-1; i+) for (j=i+1; jn; j+) if (arrayjarrayk) t=arrayk; arrayk=arrayi; arrayi=t; main ( ) int a10, i; for (i=0; i10; i+) scanf (“ %d ”,&ai); s
28、ort(a, 10); for (i=0; i10; i+) printf (“ %d ”, ai); 由于地址传递,实参数组 a 改变例3:写一函数,使给定的一个二维整形数组(3*3)转置,即行列互换。void xx(int a33 ) int i,j; for(i=0;i3;i+) for(j=0;j3;j+) printf(“%d”,aji;) printf(“n”); main() int a33,i,j; for(i=0;i3;i+) for(j=0;j3;j+) scanf(“%d”,&aij); xx(a);二维数组名做函数参数,可以指定每一维的大小或省略第一维的大小如 : in
29、t array 310; 或 int array 10;但 int array 3 ; 和 int array ; 总结当数组的名字作为形式参数时,被复制的是数组的首地址函数根据首地址处理的是数组元素的“原件”,而不是“复印件”。7.8 局部变量和全局变量在函数内部或复合语句内部定义的变量作用域:函数内或复合语句内。 局部变量主函数 main 定义的变量只在主函数中有效,主函数不能使用其它函数定义的变量。不同函数中的同名变量互不影响。形参也是局部变量。在本函数中a、b、c有效f1(int a) int b,c; 在本函数中a、b、c、d有效但与f1函数中的a、b、c不同f1(int a,int
30、 b) int d,c; 在本函数中m、n有效main() int m,n; 例: main() int a=10,b=10; int c c=a+b; a、b在此 c在此范围 范围内有效 内有效 . 在函数外部定义的变量(也称外部变量) 。 作用域:可以为本文件中所有的函数公用。全局变量从定义变量的位置开始到本文件结束,这段程序中的函数可直接使用外部变量。如果在定义点之前的函数想使用外部 变量,则应该在该函数中用关键字 extern 作“外部变量”说明。如果在同一源文件中,外部变量和局部变量同名,则在局部变量的作用范围内,外部变量不起作用。优点增加了函数间数据联系同一文件中的一些函数引用全局
31、变量,当某个函数中改变了全局变量的值,其它函数中的全局变量值也随之改变。函数可以得到多个返回值缺点全局 变量在程序的全部执行过程中都占用存储单元。使用全局变量不符合程序设计中要求模块间“强内聚性、弱偶合性”的原则。使用全局变量过多,会降低程序的可读性和可维护性。变量的存储类别 1.静态存储方式和动态存储方式静态存储方式:程序运行期间分配固定存储 空间的方式。动态存储方式:程序运行期间根据需要进行 动态的分配存储空间的方式。程序区静态存储区动态存储区全局变量,局部静态变量形式参数局部变量(自动)函数调用的现场保护和返回地址7.9 变量的存储方式和生存期2.静态存储变量和动态存储变量静态存储变量:
32、用静态存储方式存储的变量。动态存储变量:用动态存储方式存储的变量。特点:在 静态存储区分配存储单元,整个程序 运行期间都不释放。 特点:函数开始调用时为变量分配存储空间, 函数结束时释放这些空间。一个程序两 次调用同一函数,其中同一个局部变量 的内存地址可能不同。C语言变量的属性:数据类型 存储类型存储类型:数据在内存中的存储方式。 即静态存储方式和动态存储方式。3.变量的属性及其定义数据类型:整型,实型,字符型存储分类符:auto (自动的)、register(寄存器的)static (静态的)、 extern(外部的)定义变量的一般形式:存储分类符 类型标识符 变量名;如:auto int
33、 a; static int b; register int d;auto(自动的)例如:auto int a; 4.变量的存储类型auto说明局部变量,该局部变量是自动变量; 自动变量存放在动态存储区,属于动态存储变量; 变量作用域是其所在的函数内部。说明:在一个函数内如果局部变量不作存储类 型说明,均为自动变量;形式参数缺省存储类型是auto,但不能 将auto加在形参说明之前。 如:int b, c=3 等价于 auto int b, c=3; 如:int max(auto int x, auto int y) static(静态的)static可用于说明局部变量局部静态变量全局变量外部静态变量局部静态变量 作用域仅限于定义它的函数内部 。存放在静态存储区,整个程序运行期间都不释放。编译时赋初值,每次调用不再赋初值,只保留调用结束时变量的值。 自动变量调用一次,重新赋值一次。局部静态变量不赋初值,编译时自动赋0。 自动变量不赋初值,其值不确定。例如:打印1!5!int f
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年贵州省安全员考试题库
- 2025年吉林省安全员B证考试题库
- 重庆工商大学派斯学院《酒店营销》2023-2024学年第二学期期末试卷
- 青岛港湾职业技术学院《口腔设备学》2023-2024学年第二学期期末试卷
- 武汉东湖学院《社会哲学》2023-2024学年第二学期期末试卷
- 2025年海南省建筑安全员-C证考试(专职安全员)题库附答案
- 南京信息工程大学《少儿体操与健美操》2023-2024学年第二学期期末试卷
- 南京审计大学金审学院《生物合成实验》2023-2024学年第二学期期末试卷
- 广东青年职业学院《建筑法规1》2023-2024学年第二学期期末试卷
- 武汉生物工程学院《妇女健康与康复》2023-2024学年第二学期期末试卷
- 员工互评表(含指标)
- 美国电话区号一览表
- 【MOOC】英语口语进阶-南京大学 中国大学慕课MOOC答案
- 2024-2030年中国干细胞美容产业竞争格局及投资战略研究报告
- 《霉菌的形态和结构》课件
- 人群聚集或集会事故应急处理预案(5篇)
- 陕西省咸阳市2023-2024学年高一上学期期末考试 数学 含答案
- 期末试题-2024-2025学年人教PEP版英语六年级上册 (含答案)
- 知识产权师招聘面试题及回答建议(某大型央企)
- 科技结合的小学种植园活动方案
- 2024小学语文课标培训
评论
0/150
提交评论