版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第四章 函数与模块化程序设计方法,学习目标 1.掌握函数定义和函数原形说明的方法及二者的区别。 2.掌握函数的参数传递方式与函数调用方法。 3.理解掌握变量的作用于和存储类的概念。 4.了解模块设计方法。,难点内容 1.正确理解“单向值传递”的函数参数传递方式。 2.理解自动变量与静态局部变量在应用中的区别。 3.在实际应用中,学会采用模块化设计方法解决问题。,第四章 函数与模块化程序设计方法,4.1 函数 4.2 宏定义 4.3 变量的作用域和存储类 4.4 模块化程序设计方法 4.5 多文件方式组织的程序,C语言是一种较现代化的程序开发语言。 它提供如下一些支持模块化软件开发的功能: 1.
2、函数式的程序结构。程序整体由一个或多个函数组成。 每个函数都具有各自独立的功能。 2.允许通过使用不同存储类别的变量,控制模块内部及外 部的信息交换。 3.具有编译预处理功能,为程序的调试、移植提供了方便, 也支持了模块化程序设计。,4.1 函数,用C语言设计程序就是编写函数。 C程序至少并且必须有一个main()函数,执行时,从main()开始。 C程序中可以有若干个其他函数,这些函数只有在执行main() 函数的过程中被调用执行,调用可以是互相的。,main( ) f1( ); f2( ); ,f1( ) f11( ); ,f2( ) f21( ); f22( ); ,f11( ) ,f2
3、1( ) ,f22( ) ,在高级语言中函数用function(功能)来表示。 一个函数代表一种功能,换句话说一种功能用一个函数来实现。 设计时,一般从主函数main( )开始,考虑主函数的算法。 当需要某一功能时先写上调用具有该功能的函数的表达式, 至于这个函数如何实现,可先不考虑。一个main( )可能包含 若干个功能,可以用若干个函数表示,这些函数一类是系统 提供的标准函数(库函数),可以直接使用;另一类是需要 用户自己定义的,需要编程序。 这就体现了模块化程序设计的思想:自顶向下、逐步细化。 除main( )函数以外,函数是平行的,定义是独立的,不可 互相嵌套定义,但可以互相调用。,函
4、数分类,标准函数(库函数) 用户自定义函数,无参函数 有参函数,4.1.1 函数的分类,4.1.2 函数的定义,1.函数定义的现代风格形式 类型 函数名(类型 参数1,类型 参数2,. ) 函数体 ,2. 函数定义的传统形式 类型 函数名(形参表列 ) 形参说明: 函数体 教材第115页例题,说明: (1)若在函数定义时,无形参表列,则表示定义一个无参函数,无数据传送。 (2)若在定义时,有形参表列,表示定义一个有参函数,表示函数调用时 有数据传送。 形式参数在定义函数时,函数名后括号中的变量名称。 (3)若函数体为空,说明定义的是“空函数”。 (4)函数的类型为函数值的类型。 (5)函数定义
5、的外部特性。 函数不能嵌套定义,即一个函数不能定义在别的函数内部,一个程序 如果用到多个函数,可以定义在不同的文件中,一个文件可以含有不 同程序中的函数。,4.1.3 函数的调用与参数传递,几方面内容,调用 参数 返回值,1. 函数调用的一般形式 函数名(实参表列); 说明: (1)实参在主调函数中调用一个函数时,函数名后括号中 的参数(可以是一个表达式),称为实际参数。 (2)无实参表列,表示调用无参函数。,参数1,参数2,.,几种调用方式 (1) 函数语句 printstar( ); (2)函数表达式 c=max(a,b); 见教材第116页例4.1 (3)函数参数是一个函数调用 m=ma
6、x(a,max(b,c);,2.关于形参和实参的说明 (1)形参是在定义函数中指定的; 在函数未被调用时,不占用内存的存储单元,在函数被调用时, 形参才被分配内存单元,函数调用结束时,形参所占内存被释放。 形参只在定义它的函数中起作用,属于局部变量。 (2)形参必须指定类型。 max(int x,int y) (3)实参是在函数调用时指定的,可以是常量、变量或表达式。 实参必须有确定的值。 (4)实参值 形参,实现数据单向传递, 二者类型应相同,个数相同。,例 比较两个数并输出大者,main() int a,b,c; scanf(%d,%d, ,main( ) int max(int x,in
7、t y); int a,b,m; scanf(“%d,%d”, ,a b m,x y,4,5,5,5,5,4,z,函数的参数 可以作为函数参数的量有多种,如变量、数组元素、数组 名、指针以及变量指针。 (1)用变量和数组元素作形参和实参,实现数据的“值传递”, 即“单向传递”。 见教材第117页例4.2,例 交换两个数,/*ch7_2.c*/ #include main() int x=7,y=11; printf(x=%d,ty=%dn,x,y); printf(swapped:n); swap(x,y); printf(x=%d,ty=%dn,x,y); swap(int a,int b)
8、 int temp; temp=a; a=b; b=temp; ,值传递,变量作函数参数,数组元素作函数参数,#include void swap2(int x,int y) int z; z=x; x=y; y=z; main() int a2=1,2; swap2(a0,a1); printf(a0=%dna1=%dn,a0,a1); ,值传递,(2) 数组名作形参和实参,实现数据的“地址传递”,即把实参数组 的起始地址传递给形参数组,使两个数组共占同一段内存的存 储单元,这样,形参数组元素值变化,使实参数组元素的值同 时发生变化。,a a0 a1 . a9,x0 x1 . x9,1000
9、,int a10; Sort(a); . void sort(int x) ,地址传递,#include void swap2(int x) int z; z=x0; x0=x1; x1=z; main() int a2=1,2; swap2(a); printf(a0=%dna1=%dn,a0,a1); ,地址传递,数组名作函数参数举例,地址传递 方式:函数调用时,将数据的存储地址作为参数传递给形参。 特点: 形参与实参占用同样的存储单元 “双向”传递 实参和形参必须是地址常量或变量,/*ch9_3.c*/ swap(p1,p2) int *p1,*p2; int p; p=*p1; *p1
10、=*p2; *p2=p; main() int a,b; scanf(%d,%d, ,例 交换两个数,地址传递,4.1.4 函数的返回值(函数值) 1. 调用一个函数一般希望得到一个确定的值函数返回值。 函数的返回值通过return(表达式)获得。表达式的值即为 函数返回值。return语句也标志函数调用结束。 2. 函数返回值的类型是在定义函数时指定的。若不加说明的, 按int处理;若定义的类型与return返回的值的类型不一致, 则以定义的类型为准。 3. 若无return语句,则函数无确定的返回值。若明确表示函数无 返回值,则用void 定义类型。 见教材第116页例,函数声明 在调用某
11、一个函数之前,需对该函数做声明。 声明是指向编译系统提供被调函数的必要信息: 函数名、函数的类型、函数的参数个数、类型及 排列次序。 1.声明的形式 函数类型标识符 函数名(形参表列);,类型标识1 参数1,类型标识2 参数2,.,函数原型,4.1.5 函数原形的说明,2.说明 (1)区分函数定义与函数声明。 “定义”是指对函数功能的确立,它是一个完整的、独立的 函数单位(程序); “声明”的作用则是把函数的名字、类型以及形参的类型、 个数和顺序通知编译系统,以便调用该函数时系统按此进行 对照检查。 (2) 声明是对用户自定义函数而言的。 (3)被调函数在以下情况下,可以不做声明: 无返回值或
12、函数值为整型的被调函数。,当被调用函数位于调用函数之前定义 int max(int x,int y) int z; z=xy:x,y; return(z); main( ) int a,b,m; scanf(“%d,%d”, ,如果已在所有函数定义之前,在函数的外部已做了函数声明, 则在各个主调函数中不必对所调用的函数再作声明。 int max(int x,int y); main( ) m=max(a,b); int max(int x,int y) . ,4.2 宏定义 不带参数的宏定义 形式: #define 标识符 字符串 如符号常量 #define PRICE 30 带参数的宏定义
13、形式: #define 宏名(参数表) 字符串 说明: 参数表中的参数是形式参数 字符串中包括参数表中的参数 见教材第120页,不带参数的宏定义举例,例1 符号常量举例 #define PRICE 30 main() int num,total; num=10; total=num*PRICE; printf(total=%d,total); ,运行结果:total=300,例2 #define s(a,b) a*b m=s(3,4);,例3 #define square(n) (n)*(n) main() int s; s=square(3+5); printf(“%d”,s); ,运行结果
14、:m=12,运行结果:s=64,不带参数的宏定义举例,带参宏与函数的比较 1. 函数调用时,先求出实参表达式的值,然后带入函数定义中函数的形参; 而用带参宏是进行简单的字符替换,不进行计算。 2. 函数调用是在程序运行时处理的,分配临时的内存单元; 而宏扩展则是在编译之前进行的,在展开时并不分配内存单元,也不进行 值的传递处理,也没有“返回值”的概念。 3. 对函数的实参和形参都要定义类型,且二者的类型要求一致,如不一致应 进行类型转换;而宏不存在类型问题,宏名无类型,它的参数也无类型, 只是一个符号代表,展开是带入指定的字符即可。 4. 函数只可得到一个返回值,而用宏可以设法得到几个结果。
15、5. 多次使用宏时,宏展开后源程序变长,而函数不使源程序变长。 6. 宏替换不占运行时间,只占编译处理时间,而函数调用则占用运行时间。,用宏可以设法得到几个结果 #define PI 3.14159 #define CIRCLE(R,L,S) L=2*PI*R;S=PI*R*R main() float L,S; CIRCLE(5,L,S); printf(“L=%f, S=%f”,L,S); ,4.3.1 变量的作用域 变量的作用域是指在程序中定义变量的位置及其能被读写 访问的范围。根据变量的作用域是在程序的某个局部范围内还 是在整个程序内,将变量分为局部变量 (Local Variable
16、) 和全局 变量 (Global Variable)。,4.3 变量的作用域和存储类,1.局部变量 定义:在一个函数内部定义的变量,局部变量的作用域 仅限于该函数内部。离开该函数,其值就不能在引用。,main() int x,y; . int i,j; max(int x, int y) int z; ,i和j作用范围,主函数 main()中x和y作用范围,自定义函数max()中x、y、z作用范围,例 关于局部变量的应用 (教材第121页),int f(int a) a=a+4; return(a); main( ) int a; a=3; printf(“%dn”,f(a); printf(
17、“%dn”,a); ,执行结果: 7 3,形参 a的作用范围,main函数中的局部变量a的作用范围,2.全局变量 定义:在所有函数外部定义的变量,又称外部变量, 其作用域是从定义变量的位置开始到本程序文件的末尾。,int x=1,y=0; float f1(int a) int b,c; char c1,c2; char f2(int x,int y) int i,j; . main( ) int m,n; .,全局变量c1,c2的作用范围,全局变量x,y的作用范围,说明: (1)全局变量增加了函数间数据传递的通道,在一个函数中全局变量 的 改变,将影响其他函数。 (2)如果在某个全局变量定义
18、之前,某个函数要引用此全局变量, 需用extern在函数内加以说明,方可使用。 (见教材123页例) (3)在同一源文件中,全局变量与局部变量同名,则局部变量在其作 用范围内屏蔽全局变量,即局部变量起作用,全局变量不起作用。 (4)尽量不使用全局变量,以节省存储空间,增加模块的“内聚性”, 降低“耦合性”,使模块间联系少。,例4.4 / 4.5 分析程序运行结果。 (见教材123页例),void de( ) int n=100; n- =20; main() int n=100; printf(“n=%dn”,n); for(;n=60;) de( ); printf(“n=%dn”,n);
19、,int n=100; void de( ) n-=20; main() /*printf(“n=%dn”,n);*/ for(;n=60;) de( ); printf(“n=%dn”,n); ,结果是:n=100 n=100 .,结果是:n=80 n=60 n=40,例4.6 分析程序运行结果。,int m=10,n=100; void de( ) int n=100; n- =20; m- =2; main( ) int n=80; for(;n=60;) de( ); n=n-20; printf(“%dn”,n+m); ,结果是: 68 46,例 模拟一个数字时钟。,(见教材123页
20、例),4.3.2 变量的存储类 在C语言中每个变量都有两个属性:数据类型和存储类别。 在定义一个变量时,一般形式为: 存储类 数据类型 变量名表; 变量的存储类是数据在内存中的存储方式,是从变量的生存期角度来描述的。,存放数据的区域,静态存储区:分配固定的存储空间,直到程序运行结束。,动态存储区:数据在使用(调用函数)时,分配存储空间, 函数结束立即释放存储空间。,存储类别,静态存储,动态存储,static(静态变量),全局变量 局部变量,extern(外部变量):全局变量,auto(自动变量),register(寄存器变量),形参 局部变量,形参 自动变量,1. 局部变量的存储方式 (1)
21、未被说明的局部变量都为 auto(自动变量),自动变量存放在动态存储区内。 int a,b; auto int a,b; (2) 用 static 说明的局部变量为“静态局部变量”,与其他局部变量不同之处在于: 存放在静态存储区内; 函数结束,变量不释放存储空间,其值有继承性,下一次调 用定义其函数 时可继续引用,但不能被其他函数引用; 静态局部变量在函数定义时赋初值一次,以后每次调用不重新赋值; (3) 自动变量在函数调用时赋初值,每调用一次重新赋初值。 (4) 自动变量和形参可以存放在寄存器中,用register说明。,(5) register变量的变量类型只限于 int、char。,例
22、局部变量和静态局部变量的区别。 f(int a) int b=0; static int c=3; /*c的值具有继承性*/ b=b+1; c=c+1; return(a+b+c); main() int a=2,i; for(i=0;i3;i+) printf(“%d”,f(a); ,例 求15的阶乘。,int fac(int n) static int f=1; /* 思考静态局部变量的作用?*/ f=f*n; return(f); main( ) int i; for(i=1;i=5;i+) printf(“%d!=%dn”,i,fac(i); ,2. 全局变量的存储方式 (1) 全局变
23、量存储在静态存储区。 (2) 允许其他文件中的函数引用或在定义前引用,引用时用“extern” 声明;extern 的使用与其他存储类别不同,它是引用时“声明”用 的,而非“定义”用的。 (4) 用 static 说明的全局变量为“静态全局变量”(静态外部变量), 静态外部变量仅限于定义其的文件中引用。,静态外部变量,外部变量,静态存储区,作用范围不同,例 用 extern 扩展变量的作用域。,int max(int x,int y) int z; z=xy;x:y; main() extern a,b; printf(“%dn”,max(a,b); int a=13,b=-8;,例 用ext
24、ern 将变量的作用域扩展到其他文件。,file1.c int a; main( ) int power(int ); int b=4,c,d,m; printf(“input a number:n”); scanf(“%d,%d”, ,file2.c extern a; power(int n) int i,y=1; for(i=1;i=n;i+) y*=a; return(y); ,局部变量,动态,作用域,全局变量,静态外部变量(只限本文件引用) 外部变量(允许其他文件引用),自动变量(离开函数,值就消失) 静态局部变量(离开函数,值仍保留) 寄存器变量(离开函数,值就消失) 形参可为au
25、to 或register,生存期 (作用时间),静态,静态局部变量(函数内有效) 静态外部变量(本文件内有效) 外部变量(其他文件可引用),自动变量(本函数内有效) 寄存器变量(本函数内有效) 形式参数,小结,存储位置,动态区,寄存器,内存,静态区,静态局部变量 静态外部变量 外部变量,形参 自动变量,形参 自动变量,4.4 结构化程序设计方法,一、结构化程序 结构化程序就是由三种基本结构组成的程序,也就是用高级语言表示的结构化算法。 优点:便于编写、阅读、修改、维护,可靠性高。 二、设计方法 (1)自顶向下 (2)逐步细化 (3)模块化设计 (4)结构化编码,降低系统的复杂性、容易修改; 使
26、系统各部分并行开发,提高效率。,例:“鸡兔同笼”问题。 已知:鸡兔的总头数为H,鸡兔总脚数为F, 求:鸡、兔各多少只? 1. 确定数学模型: 设鸡为X只,兔为Y只,据已知条件列方程:,2X+4Y=F X+Y=H,解方程得: X=(4H-F)/2 Y=(F-2H)/2,2. 采用“自顶向下,逐步细化”的方法: 第一步:输入鸡、兔总头数H和总脚数F; 第二步:求鸡、兔的个数; 第三步:输出鸡、兔的个数。,求鸡、兔个数,输入鸡兔总头数H 输入鸡兔总脚数F,求鸡个数X 求兔个数Y,输出鸡、兔 的个数X,Y,求鸡的个数X 求兔的个数 Y,2. 采用“自顶向下,逐步细化”的方法: 第一步:输入鸡、兔总头数H和总脚数F; 第二步:求鸡、兔的个数; 第三步:输出鸡、兔的个数。,求鸡、兔个数,输入鸡兔总头数H 输入鸡兔总脚数F,求鸡个数X 求兔个数Y,输出鸡、兔 的个数X,Y,求鸡的个数X 求兔的个数 Y,三、归纳总结 采用结构化程序设计方法就是对于一个复杂的问题, 首先有一个总体的考虑方案,然后按功能逐步细化分解, 这就形成了模块。每个模块若仍很复杂,继续细化,直到 子模块的功能独立(只完成一个功能),即可
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026年湖南省怀化市新晃侗族自治县初三下学期第一次联物理试题含解析
- 2026年河南省安阳市安阳县达标名校5月初三月考数学试题含解析
- 2026年大学大一(基础医学)组织胚胎学基础测试题及答案
- 2025年前台防疫接待礼仪能力测试
- 护理健康教育课件及配套作业
- (一模)邯郸市2026届高三第一次模拟检测语文试卷(含答案详解)
- 护理教学中的职业素养与职业道德
- 护理中的研究方法与论文写作
- 如何在合作作文中激发学生修改作文的兴趣
- 2026二年级数学下册 用乘法口诀求商
- 主管聘用合同2024年
- 国家核安保技术中心社会招聘笔试真题2022
- 主持人培训完整课件
- 《设计公司各专业负责人岗位职责》
- 人工智能行业的智能产品设计与开发培训
- “三新”背景下 的2024年高考物理复习备考策略讲座
- 江苏建筑职业技术学院单招职业技能测试参考试题库(含答案)
- 销售技术培训教材
- 《机车乘务作业》 课件 01段内作业过程
- 动车组牵引传动系统-牵引变流器
- 科室轮转医生考核评分表
评论
0/150
提交评论