在结构化程序设计中函数是将任务进行模块划分的基本单位.ppt
《在结构化程序设计中函数是将任务进行模块划分的基本单位.ppt》由会员分享,可在线阅读,更多相关《在结构化程序设计中函数是将任务进行模块划分的基本单位.ppt(109页珍藏版)》请在三一文库上搜索。
1、在结构化程序设计中,函数是将任务进行模块划分的基本单位。一个函数实现一项功能。 在面向对象程序设计中,函数是对数据的一项操作,也是实现一项功能。,第三章 函数,要掌握函数的使用,必须理解函数调用时的内部实现机制,以及与此相关的内存分配机制、变量生命期和作用域。,本章还将介绍关于函数重载的概念,介绍递归算法、内联函数、默认参数函数以及多文件组织、编译预处理、工程文件的概念和运行库函数。,练习:编写程序,输入x,根据下面y和x的关系,计算y值并输出,int main() float x,y; cinx; if(x1) y=x; else if(1=x10) y=2*x-1; else y=3*x-
2、11; couty; ,int main() float x,y; cinx; if(x1) y=x; else if(1=x ,int main() float x,y; cinx; if(x1) y=x; else if(1x10) y=2*x-1; else y=3*x-11; couty; ,int main() float x,y; cinx; x=10?y=3x-11:y=2x-1 couty; ,int main() float x,y; cinx; if(x1) y=x; else if(x10) y=2*x-1; else y=3*x-11; couty; ,第三章 函数,3
3、.1 函数的定义与调用,3. 5 作用域与标识符的可见性,3.4 函数调用机制,3.3 全局变量和局部变量,3.2 函数的参数传递, 返回值及函数声明,3.10 编译预处理,3.9 头文件与多文件结构,3.6 存储类型与标识符的生命期,3.8 函数的一些高级议题,3.7 函数的递归调用,3.1 函数的定义与调用,3.1.1 函数概述,3.1.2 函数的定义,3.1.3 函数的调用,3.1.1 函数概述,函数是C+程序的基本组成模块。,通过函数,可以把一个复杂任务分解成为若干个易于解决的小任务。充分体现逐步细化的设计思想。,组成C+程序的若干函数中,有一个称为main()(Winmain())函
4、数,是程序执行的入口,它可以调用其他函数,但不可以被调用。而其他一般函数既可以调用也可以被调用。,函数概念的引入:,入口函数:,3.1.1 函数概述,3.1.1 函数概述,3.1.1结束,库函数和自定义函数: 库函数或标准函数,是由编译系统预定义的,如一些常用的数学计算函数、字符串处理函数、图形处理函数、标准输入输出函数等。 库函数都按功能分类,集中说明在不同的头文件中。用户只需在自己的程序中包含某个头文件,就可直接使用该文件中定义的函数。 用户根据需要将某个具有相对独立功能的程序定义为函数,称自定义函数。,四个要素: 返回值类型,函数名,参数列表和函数体,3.1.2 函数的定义,无参函数定义
5、格式为: 数据类型函数名(void)函数体,说明: 数据类型指函数返回值类型,可以是任一种数据类型。没有返回值应将返回值类型定义为void。 函数名采用合法标识符表示。 对无参函数,参数括号中的void通常省略,但括号不能省略。 函数体由一系列语句组成。函数体可以为空,称为空函数。,1 无参函数,3.1.2 函数的定义,例: 打印一个表头 void TableHead ( ) cout*endl; cout* example *endl; cout*endl; ,2 有参函数,有参函数的定义格式为 数据类型函数名 (参数类型1 形式参数1,参数类型2 形式参数2,函数体,例: 返回两个整数中较
6、大一个的值 int max (int a, int b) int x=a=b?a:b; return(x); ,有参函数的参数表中列出所有形式参数的类型和参数名称。各参数即使类型相同也必须分别加以说明。 形式参数简称形参,只能是变量名,不允许是常量或表达式。,Why?,找错误,int f() string s; . return s; ,f2(int i) ,int f(int v1,int v2) . ,double square(double x) return x*x;,问题:定义函数时究竟哪些变量应当作为函数的参数?哪些应当定义在函数体内? 原则:函数在使用时被看成 “黑匣子”,除了输
7、入输出外,其他部分可不必关心。从函数的定义看出,函数头正是用来反映函数的功能和使用接口,它所定义的是“做什么”。即明确了“黑匣子”的输入输出部分,输出就是函数的返回值,输入就是参数。因此,只有那些功能上起自变量作用的变量才必须作为参数定义在参数表中;函数体中具体描述“如何做”,因此除参数之外的为实现算法所需用的变量应当定义在函数体内。 C+中不允许函数的嵌套定义,即在一个函数中定义另一个函数。,提示,3.1.3 函数的调用,函数调用: 所谓函数调用,就是使程序转去执行函数体。 在C+中,除了主函数外,其他任何函数都不能单独作为程序运行。任何函数功能的实现都是通过被主函数直接或间接调用进行的。
8、无参函数的调用格式: 函数名( ) 有参函数的调用格式: 函数名(实际参数表) 其中实际参数简称实参,用来将实际参数的值传递给形参,因此可以是常量、具有值的变量或表达式。,【例3.1】 输入两个实数,输出其中较大的数,函数的调用规则,1、调用函数时,函数名必须与调用处的函数名完全一致。 2、实参的个数必须与形参的个数一致。 3、函数必须先声明或定义,后调用。 4、函数可以直接或间接地自己调用自己,称为递归调用。,int main() int add(int x, int y); int a=100,b=200,c ; c =add(a,b); int add (int x, int y ) i
9、nt z ; z=x+y; return(z); ,错误: c=ad(a,b); c=add(a);,int add(int , int );,3.2 函数的参数传递、返回值及 函数声明,321 函数的参数传递及传值调用,323 函数声明,322 函数返回值,参数传递: 函数调用首先要进行参数传递,参数传递的方向是由实参传递给形参。 传递过程是,先计算实参表达式的值,再将该值传递给对应的形参变量。一般情况下,实参和形参的个数和排列顺序应一一对应,并且对应参数应类型匹配(赋值兼容),即实参的类型可以转化为形参类型。而对应参数的参数名则不要求相同。,3.2.1 函数的参数传递及传值调用,传值调用和
10、引用调用: 按照参数形式的不同,C+有两种调用方式:传值调用和引用调用。传值调用传递的是实参的值,本章介绍传值调用。,在调用函数时,一般 在主调函数和被调用函数之间有 信息传递 这是由函数中的参数来完成的。,调用函数和被调用函数之间的参数传递,实际参数,形式参数,(实参),(形参),int main() int a=5,b=10, c ; c=max(a,b); printf(“c=%dn”, c); return 0; ,int max(int x, int y) int t; if (xy) t=x; else t=y; return(t); ,5,10,5,10,t,10,10,10,i
11、nt main() int a=5,b=10, c ; c=max(a,b); printf(“c=%dn”, c); return 0; ,信息传递原则:实参到形参 单向值传递,特点:实参与形参各占用不同的内存单元,3.2.1 函数的参数传递及传值调用,传值调用: 将实参的值复制给形参,在函数中参加运算的是形参,而实参不会发生任何改变。传值调用起了一种隔离作用。,【例3.2】 实参和形参对应关系的示例。,注意:【例1.3】中调用函数strcpy(s3, s2),却实现了字符数组s2的内容复制到字符数组s3中。这是因为数组名实际上代表存储数组的内存的首地址,复制给形参的是实参数组的首地址,结果
12、参加运算的是实参数组。数组作为参数,定义时形参用数组名加一对方括号,调用时实参只用数组名,练习,int add (int x, int y) int z ; z=(+x)+(+y) ; return(z); int main() int a=100,b=200,c ; c =add(a,b); coutcendl; return 0; ,101,201,add (a , b) ;,int add ( x, y ),A) 11 B) 20 C) 21 D) 31,请写出下列程序的运行结果,main() int x=6,y=7,z=8,r ; r=f (x-,y+,x+y),z-); cout“r
13、=“rendl; ,C) 21,课下作业,查找资料,如何向主函数main() 传递参数? 程序举例说明。,3.2.2 函数返回值,return语句的格式: return 表达式; 函数的计算结果通过该语句传递回主调函数。,【例3.3】设计函数,根据三角形的三边长求面积。如果不能构成三角形,给出提示信息。 分析:函数为计算三角形面积,一般三角形返回面积值,若不能构成三角形则返回-1。设计一个主函数完成函数测试。根据返回值情况输出相应结果。,思考:表达式值的类型和函数返回值类型关系?,3.2.2 函数返回值,函数可以有返回值,也可以没有返回值。对于没有返回值的函数,功能只是完成一定操作,应将返回值
14、类型定义为void ,函数体内可以没有return语句,当需要在程序指定位置退出时,可以在该处放置一个: return ;,讨论:,3.2.2结束,3.2.3 函数声明,函数声明是一条以分号结束的语句: 函数返回值类型函数名 (形参表);,语法上对程序文件中函数的排列次序要求满足先定义后使用。但从结构化程序设计的角度,通常是先调用后定义。使用函数声明,则既符合由粗到精的思维方式,又满足了语法要求。,其中形参表可以逐个列出每个参数的类型和参数名,也可以列出每个形参的类型,参数名可省略,各形参之间以逗号分隔。函数声明和所定义的函数必须在返回值类型、函数名、形参个数和类型及次序等方面完全对应一致,否
15、则将导致编译错误。,函数声明的引入:,函数声明的格式:,int max(int x, int y); /ok int max(int,int); /ok int max(int) /X float max(int,int) /X int max(int x, int y) int t; if (xy) t=x; else t=y; return(t); ,下面是一个使用结构化程序设计思想开发的企业管理报表程序的框架。它使用了函数声明。 void menu_print(); void account_report(); void engineering_report(); void market
16、ing_report(); int main() int choice; do menu_print(); cinchoice; while(choice=4); switch(choice) case 1: account_report(); break; case 2: engineering_report(); break; case 3: marketing_report(); break; return 0;,void menu_print() cout”系统功能:”endl; cout”1 财务报表”endl; cout”2 工程报表”endl; cout”3 市场报表”endl;
17、 cout”选择业务序号:”; void account_report() /生成财务报表 void engineering_report() /生成工程报表 void marketing_report() /生成市场报表; ,3.2.3 函数声明,【例3.4】 输出所有满足下列条件的正整数m:10m1000且m、m2、m3均为回文数。,分析:回文指左右对称的序列。如121、353等就是回文数。判断整数是否回文数用函数实现,其思想是将该数各位拆开后反向组成新的整数,如果该整数与原数相等则为回文数。,m m*m m*m*m 11 121 1331 101 10201 1030301 111 12
18、321 1367631,运行结果:,3.3 全局变量和局部变量,331 变量的存储机制与C+的内存布局,332 全局变量,333 局部变量,3.3.1 变量的存储机制与C+的内存布局,操作系统为一个C+程序的运行所分配的内存分为四个区域,如图3.3 所示:,存储区域说明: (1)代码区(Code area):存放程序代码,即程序中各个函数的代码块; (2)全局数据区(Data area):存放全局数据和静态数据;分配该区时内存全部清零,结果变量的所有字节自动初始化为零。 (3)栈区(Stack area):存放局部变量,如函数中的变量等;分配栈区时不处理内存,即变量取随机值。 (4)自由存储区
19、(Free store area):存放与指针相关的动态数据。分配自由存储区时不处理内存。参见第七章。,3.3.1 变量的存储机制与C+的内存布局,3.3.2 全局变量,在所有函数之外定义的变量称为全局变量。,全局变量在编译时建立在全局数据区,在未给出初始化值时系统自动初始化为全0。,全局变量可定义在程序开头,也可定义在中间位置,该全局变量在定义处之后的任何位置都是可以访问的,称为可见的。,【例3.5】 多个函数使用全局变量的例子。,全局变量引入:,3.3.3 局部变量,定义在函数内或块内的变量称为局部变量。,程序中使用的绝大多数变量都是局部变量。,局部变量在程序运行到它所在的块时建立在栈中,
20、该块执行完毕局部变量占有的空间即被释放。,局部变量在定义时可加修饰词auto,但通常省略。局部变量在定义时若未初始化,其值为随机数。,局部变量引入:,【例3.6】 使用局部变量的例子。,思考:如果定义一个对象/变量为全局模式还是局部模式?,1、主函数中定义的变量也只用在主函数中有效;,2、不同函数中可以使用相同的变量名,且它们代 表不同的存储单元,互不干扰;,3、形式参数也是局部变量。其它函数是不能调用 该形参的;,4、在一个函数内部,可以在复合语句中定义变量 ,这些变量只能在本复合语句中有效。,3.4 函数调用机制,局部变量占用的内存是在程序执行过程中“动态”地建立和释放的。这种“动态”是通
21、过栈由系统自动管理进行的。,(1)建立栈空间;,(6)恢复现场:取主调函数运行状态及返回地址,释放栈空间;,(7)继续主调函数后续语句。,(5)释放被调函数中局部变量占用的栈空间;,(4)执行被调函数函数体;,(3)为被调函数中的局部变量分配空间,完成参数传递;,(2)保护现场:主调函数运行状态和返回地址入栈;,调用过程:,3.4 函数调用机制,void fun1(int, int); void fun2(float); int main() int x=1;y=2; fun1(x, y); return 0; void fun1(int a,int b) float x=3; fun2(x)
22、; void fun2(float y) int x; ,此图例说明在程序执行过程中怎样通过栈“动态”地建立和释放局部变量占用的内存的,3.5 作用域与标识符的可见性,3 文件作用域,2 函数声明作用域,作用域:指标识符能够被使用的范围。只有在作用域内标识符才可以被访问(称为可见)。,本节重点讨论局部域和文件域(全局域),其中局部域包括块域和函数声明域。任何标识符作用域的起始点均为标识符说明处。,下面分别介绍:,1 块作用域,函数中定义的标识符,包括形参和函数体中定义的局部变量,作用域都在该函数内,也称作函数域。,块域,块指一对大括号括起来的程序段。块中定义的标识符,作用域在块内。,复合语句是
23、一个块。,函数也是一个块。,复合语句中定义的标识符,,作用域仅在该复合语句中。,【例3.7】 输入两数,按从大到小的顺序保存。,块的引入:,块域,由VC+平台运行,结果如下: 输入两整数: 3 5 调用前:实参a=3,b=5 调用中 交换前:形参a=3,b=5 交换后:形参a=5,b=3 调用后:实参a=3,b=5 交换失败,局部变量具有局部作用域使得程序在不同块中可以使用同名变量。这些同名变量各自在自己的作用域中可见,在其它地方不可见。,【例3.8】设计函数完成两数交换,用主函数进行测试。,块域,对于块中嵌套其它块的情况,如果嵌套块中有同名局部变量,服从局部优先原则,即在内层块中屏蔽外层块中
24、的同名变量,换句话说,内层块中局部变量的作用域为内层块;外层块中局部变量的作用域为外层除去包含同名变量的内层块部分。,如果块内定义的局部变量与全局变量同名,块内仍然局部变量优先,但与块作用域不同的是,在块内可以通过域运算符“:”访问同名的全局变量。,【例3.9】 显示同名变量可见性。,函数声明作用域,函数声明不是定义函数,在作函数声明时,其中的形参作用域只在声明中,即作用域结束于右括号。正是由于形参不能被程序的其他地方引用,所以通常只要声明形参个数和类型,形参名可省略。,3 文件作用域,文件作用域也称全局作用域。定义在所有函数之外的标识符,具有文件作用域,作用域为从定义处到整个源文件结束。文件
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 结构 程序设计 函数 任务 进行 模块 划分 基本单位
链接地址:https://www.31doc.com/p-2734498.html