第3章 模块化程序设计.docx
《第3章 模块化程序设计.docx》由会员分享,可在线阅读,更多相关《第3章 模块化程序设计.docx(22页珍藏版)》请在冰豆网上搜索。
第3章模块化程序设计
第3章模块化程序设计
第3章模块化程序设计
教案
课题:
第3章模块化程序设计
(1)
教学目标
1、掌握函数的定义及其调用方法。
2、理解掌握形式参数和实际参数的概念及使用方法。
3、掌握函数的调用及嵌套调用的方法。
4、理解函数的递归调用方法
教学重点、难点
1、掌握函数的调用及嵌套调用的方法。
2、理解函数的递归调用方法
技能培训重点、难点
1、掌握函数的定义。
2、掌握函数的调用。
3、熟悉形式参数和实际参数。
4、理解和应用函数的返回值。
教法
案例教学法
学法
思考,讨论,练习巩固
教具使用
投影仪演示或教学机房
学内容
教师活动
学生活动
备注
导入新课
第二章学习了C语言简单程序设计,掌握了解决简单问题的程序设计方法。
模块化程序设计的思想就是将一个复杂的问题分解为若干个简单的问题求解。
所以,一个较大的应用程序一般由若干个程序模块组成,其中有一个是主模块,每一个模块都实现一个特定的功能。
在C语言中,程序模块是由函数实现的。
一个C语言程序可由一个主函数(主模块)和若干函数(子程序)构成。
主函数调用其它函数,其它函数也可以互相调用。
同一个函数可以被一个或多个函数多次调用。
讲授
新课
小结
案例3.1:
定义函数求平均分
/*源程序:
案例3_1.c*/(略)
1、函数定义的一般形式
(1)无参数函数的定义格式
类型标识符函数名( )
{
声明部分
语句
}
用“类型标识符”指定函数值的类型,即函数返回值的类型。
若函数没有带回函数值,可以不写“类型标识符”。
(2)有参数函数的定义格式
类型标识符函数名(形式参数表列)
{
声明部分
语句
}
(3)“空函数”的定义格式
类型说明符函数名( )
{ }
此函数在调用时,没有产生任何实际作用。
。
2、函数参数。
在定义函数时,函数名后面括号中的参数为“形式参数”(简称“形参”)。
在调用一个函数时,函数名后面括号中的参数(可以是一个表达式)称为“实际参数”(简称“实参”)。
关于形参和实参的说明:
①定义函数中指定的形参,在函数未被调用时,并不占用内存中的存储单元。
只有在函数被调用时,形参才占用内存中的存储单元。
在函数调用结束后,形参所占的内存单元也随之被释放。
②实参可以是常量、变量或表达式,并要求有确定的值。
③在定义函数时,必须指定形参的类型。
④实参与形参的类型应相同或赋值兼容。
⑤C语言规定,实参变量对形参变量的数据传递是“值传递”,即单向传递。
只能由实参传给形参,而不能由形参传给实参。
实参和形参占用不同的存储单元。
例如:
/*源程序:
3_1_1.c*/(略)
3、函数的返回值。
通过函数调用,使主调函数能得到一个确定的值,这就是函数的返回值。
(1)函数的返回值是通过return语句获得的。
return语句的功能是把被调用函数中的一个确定值带回主调函数。
(2)函数值的类型。
函数的返回值都有确定的类型,在定义函数时必须指定函数返回值的类型。
C语言规定,凡不加类型说明的函数,一律自动按整型处理。
在定义函数时,函数值的类型一般和return语句中的表达式类型一致。
(3)如果函数值的类型和return语句中的表达式的类型不一致时,要以函数类型为准。
对数值型数据,可以自动进行类型转换。
即函数类型决定返回值的类型。
(4)为了明确表示“不返回值”,可以用“void”定义“无类型”(或称“空类型”)。
这样,就保证系统不使函数带回任何值。
为确保程序正确,凡是不要求返回函数值的函数,一般定义为void类型。
4、函数的调用。
函数调用的一般形式是:
函数名(实参表列);
调用无参数函数,可以不写“实参表列”,但括号不能省略。
如果是有参数函数,实参与形参的个数应相等,类型应一致。
当实参表列中有多个实参时,各参数之间需要用逗号隔开。
实参与形参按顺序一一对应传递数据。
但应说明的是,如果实参表列中有多个实参,那么系统求实参值的顺序是不确定的,可以按照“自左至右”或“自右至左”的顺序求实参的值。
按照函数在程序中出现的位置不同,其调用方式有以下三种:
①函数语句。
把函数调用作为一个语句。
例如:
temp(a);
②函数表达式。
函数出现在一个表达式中,这种表达式称为函数表达式。
要求函数带回一个确定的值,并参予表达式的运算。
例:
s=sum()*10+5;
函数sum是表达式的一部分。
③函数参数。
把函数调用作为一个函数的实参,例如:
aver=average(s);改成:
aver=average(sum());后,sum()是一次函数调用,它的值作为函数average调用的实参。
函数调用作为函数的参数,实质上也是一种函数表达式。
函数的参数就是表达式形式。
5、被调用函数的声明和函数原型。
被调用函数(在一个函数中调用另一函数)需要具备下列条件:
(1)被调用的函数必须是已经存在的函数(库函数或用户自己定义的函数)。
(2)如果使用库函数,应该在本文件开头用#include命令将调用有关库函数所需要的信息“包含”到文件中。
例如:
#include
(3)如果用户使用自己定义的函数,而且该函数与调用它的函数(即主调函数)在同一个文件中,一般还应该在主调函数中对被调用的函数作声明(向编译系统声明将要调用此函数,并将有关信息通知编译系统)。
(4)函数的“定义”是指对函数功能的确立,包括指定函数名,函数值类型,行参及其类型,函数体等。
7、函数的嵌套调用。
8、函数的递归调用。
3、变量按其作用范围可以分为局部变量和全局变量。
小结:
在C语言中,程序模块是由函数实现的。
一个C语言程序可由一个主函数(主模块)和若干函数(子程序)构成。
主函数调用其它函数,其它函数也可以互相调用。
输入案例程序
教师可以进行启发式提问讲解各功能模块
案例
思考
案例思考
作业
教案
课题:
第3章模块化程序设计
(2)
教学目标
1、熟悉变量的存储属性
2、熟练运用局部变量和全局变量。
教学重点、难点
熟练运用局部变量和全局变量。
技能培训重点、难点
1、理解变量的存储属性。
2、运用变量的存储属性编写程序。
教法
案例教学法
学法
思考,讨论,练习和巩固
教具使用
投影仪演示或教学机房
学内容
教师活动
学生活动
备注
导入
新课
变量是对程序中数据存储空间的抽象表示。
我们在第二章的学习中接触了数据类型,数据类型是变量的操作属性。
影响变量的使用的还有变量的存储属性。
讲授
新课
分析案例程序运行结果
小结
案例3.2:
变量的存储类别
/*源程序:
案例3_2_1.c*/
#include
main()
{
intfact(intn);
intn,k;
printf(“n=”);
scanf(“%d”,&n);
for(k=1;k<=n;k++)
printf(“f=%d\n”,fact(k));
getch();
}
intfact(intk)
{
intf=1;
f=f*k;
return(f);
}
/*源程序:
案例3_2_2.c*/
#include
main()
{
intfact(intn);
intn,k;
printf(“n=”);
scanf(“%d”,&n);
for(k=1;k<=n;k++)
printf(“f=%d\n”,fact(k));
getch();
}
intfact(intk)
{
staticintf=1;
f=f*k;
return(f);
}
/*源程序:
案例4_2.c*/(略)
从案例可以看出,两个程序只有一个地方不同,即fact函数中变量f的定义。
第一个程序是:
intf=1;
第二个程序是:
staticintf=1;
而结果却完全不同。
这是变量的不同存储类别造成的。
1、动态存储方式与静态存储方式。
按变量的作用域来划分将变量分为全局变量和局部变量。
按变量值存在方式(即生存期)来划分,可以分为静态存储方式和动态存储方式。
内存中供用户使用的存储空间可以分成三个部分,如图3-5所示:
用户区
程序区
静态存储区
动态存储区
图3-5
2、auto变量。
函数中的局部变量,如不声明为static存储类别,都使用动态分配技术。
数据存储在动态存储区中。
函数中的形参和在函数中定义的变量(包括在复合语句中定义的变量),都属于auto变量。
在调用该函数时系统会给它们分配存储空间,在函数调用结束时就自动释放这些存储空间。
因此,这类局部变量称为自动变量。
程序中大多数变量属于自动变量。
自动变量用关键字auto作存储类别的声明。
注:
关键字“auto”可以省略,auto不写就默认为“自动存储类别”,它属于动态存储方式。
3、用static声明局部变量。
为了使函数中的局部变量的值在函数调用结束后保留原值,使其占用的存储单元不被释放,以供下次调用该函数时使用。
这时就可指定该局部变量为“静态局部变量”。
用关键字“static”声明。
对静态局部变量的说明:
①静态局部变量属于静态存储类别,在静态存储区域内分配存储单元。
在整个程序运行期间都不被释放。
而自动变量(即动态局部变量)属于动态存储类别,占用动态存储区空间,在函数调用结束后即被释放。
②静态局部变量在编译时赋初值,也只赋一次初值。
在此后调用函数时,不再赋值,而保留上次函数调用结束时的值。
对自动变量赋初值,不是在编译时进行的,而是在函数调用时进行的,每调用一次函数重新赋一次初值。
③如果在定义局部变量时不赋初值。
静态变量在编译时自动赋初值0(对数值型变量)或空字符(对字符型变量);自动变量的值是一个不确定的值。
这是由于每次函数调用结束后存储单元已被释放,下次调用时又重新分配存储单元,而所分配的存储单元中的值是不确定的。
④虽然静态局部变量在函数调用结束后仍然存在,但其它函数是不能引用的。
4、egister变量
5、用extern声明外部变量
6、在多文件的程序中声明外部变量。
7、用static声明外部变量
8、内部函数和外部函数
小结:
变量的存储属性、说明和应用方法。
输入
程序
调试运行
分析讨论
教师可以进行启发式提问
案例
思考
案例思考
作业
习题
教案
课题:
第3章模块化程序设计(3)
教学目标
1、了解模块化程序设计思想。
2、熟练运用局部变量和全局变量。
3、理解内部函数和外部函数的概念。
教学重点、难点
1、熟练运用局部变量和全局变量。
2、模块化程序设计
技能培训重点、难点
1、了解模块化程序设计的思想
2、掌握宏定义、“文件包含”处理命令
教法
案例教学法
学法
思考,讨论,练习和巩固
教具使用
投影仪演示或教学机房
学内容
教师活动
学生活动
备注
导入
新课
在程序设计中,通常将一些常用的功能模块编写成函数,放在函数库中,以供调用。
充分使用库函数,可以减少编写程序的工作量。
本章主要介绍如何使用函数实现C语言的模块化程序设计功能。
讲授
新课
总结
案例3.3:
学籍管理系统的框架函数
/*源程序:
案例3_3.c*
#include
#include
main()
{
voidcreate();
voidsearch();
voidprint();
voidinput();
voidoutput();
voidsearch_num();
voidsearch_name();
voidsearch_class();
voidprint_num();
voidprint_class();
voidprint_score();
intselect;
while
(1)
{
clrscr();
printf(“\n\n\t\t\t学生信息管理系统\n\n”);
printf("\t\t1--学生信息库建立\n");
printf("\t\t2--学生信息查询\n");
printf("\t\t3--学生信息输出\n");
printf("\t\t0--结束\n");
printf("\t\t请输入你的选择(0-3):
");
scanf("%d",&select);
switch(select)
{
case1:
create();
break;
case2:
search();
break;
case3:
print();
break;
case0:
exit(0);
}
}
}
1、案例中函数调用关系
2、“文件包含”处理命令。
所谓“文件包含”处理是指一个源文件可以将另一个源文件(头文件)的全部内容包含进来。
头文件通常以“.h”为后缀,也可用“c”为后缀或者没有后缀。
但用“h”作后缀更能表示此文件的性质。
头文件除了可以包括函数原型和宏定义外,也可以包括结构体类型定义和全局变量定义等。
C语言提供了#include命令用来实现“文件包含”的操作。
“文件包含”可以减少程序设计人员的重复劳动。
其一般格式为:
#include“文件名”
或
#include<文件名>
案例中用到scanf和printf函数,其函数原型在头文件stdio.h中,只要用“文件包含”处理命令:
#include
3、C语言提供的预处理功能:
宏定义、文件包含和条件编译
(1)、宏定义
★不带参数的宏定义
用一个指定的标识符(即名字)来代表一个字符串,它的一般格式为:
#define标识符字符串
★带参数的宏定义。
其定义的一般格式为:
#define标识符(参数表)字符串
字符串中包含参数表中的参数,
(2)、条件编译。
一般情况下,源程序中所有程序行都进行编译。
但是,有时希望在满足一定条件时对程序中部分内容进行编译,这就是“条件编译”。
条件编译就是对部分内容指定编译的条件,当满足某条件时对一组语句进行编译,否则编译另一组语句。
采用条件编译,可以减少被编译的语句,从而减少目标程序的长度,减少运行时间。
当条件编译段比较多时,目标程序长度可以大大减少。
当然直接用if语句也能完成相一项目任务,但会使目标程序增长(因为所有语句都编译)、运行时间变长(程序运行时要对if语句进行测试)。
小结:
1、学籍管理系统的框架函数
2、数据传递方式
3、函数调用方式
4、“文件包含”处理命令
分析讨论
教师可以进行启发式提问
案例
思考
案例思考
作业
习题