函数与预编译

上传人:206****923 文档编号:51699112 上传时间:2018-08-16 格式:PPT 页数:92 大小:904KB
返回 下载 相关 举报
函数与预编译_第1页
第1页 / 共92页
函数与预编译_第2页
第2页 / 共92页
函数与预编译_第3页
第3页 / 共92页
函数与预编译_第4页
第4页 / 共92页
函数与预编译_第5页
第5页 / 共92页
点击查看更多>>
资源描述

《函数与预编译》由会员分享,可在线阅读,更多相关《函数与预编译(92页珍藏版)》请在金锄头文库上搜索。

1、假如不模块化读多少行的程序能让你不头疼?main()当中能放多少行程序?假如 cout()函数由10行代码替换, 那么你见过的程序会成什么样子?如果所有代码都在main()当中,团队怎么合作?如果代码都在一个文件中,怎么团队合作?模块化思想 模块各司其职 每个模块只负责一件事情,它可以更专心 便于进行单个模块的设计、开发、调试、测试和维护 等工作 一个模块一个模块地完成,最后再将它们集成 开发人员各司其职 按模块分配任务,职责明确 并行开发,缩短开发时间 分而治之(Wirth, 1971 ) 信息隐藏(Parnas, 1972)在结构化程序设计中,函数是将任务进行模块划分的基 本单位。一个函数

2、实现一项功能。在面向对象程序设计中,函数是对数据的一项操作,也 是实现一项功能。第四章 函数与预编 译要掌握函数的使用,必须理解函数调用时的内部实现机 制,以及与此相关的内存分配机制、变量生命期和作用域。本章还将介绍关于函数重载的概念,介绍递归算法 、内联函数、默认参数函数以及多文件组织、编译预处 理、工程文件的概念和运行库函数。第四章 函数与预编 译 4.1 函数的定义与调用 4. 5 作用域与标识符的可见性 4.4 函数调用机制 4.3 全局变量和局部变量 4.2 函数的参数传递,返回值及函数声明 4.10 编译预处理 4.9 头文件与多文件结构 4.6 存储类型与标识符的生命期 4.8

3、函数的一些高级议题 4.7 函数的递归调用 4.1 函数的定义与调用4.1.1 函数概述4.1.2 函数的定义4.1.3 函数的调用 4.1.1 函数概述函数是C+程序的基本组成模块。通过函数,可以把一个复杂任务分解成为若干 个易于解决的小任务。充分体现逐步细化的设计思想 。组成C+程序的若干函数中,有一个称为main() 函数,是程序执行的入口,它可以调用其他函数,但 不可以被调用。而其他一般函数既可以调用也可以被 调用。函数概念的引入:入口函数:4.1.1 函数概述main ( )fun2( )fun1( )fun3( )funa( )funb( )func( )图4.1 函数调用层次关系

4、4.1.1 函数概述4.1.1 结束库函数和自定义函数:库函数或标准函数,是由编译系统预定义的, 如一些常用的数学计算函数、字符串处理函数、图 形处理函数、标准输入输出函数等。库函数都按功能分类,集中说明在不同的头文 件中。用户只需在自己的程序中包含某个头文件, 就可直接使用该文件中定义的函数。用户根据需要将某个具有相对独立功能的程序 定义为函数,称自定义函数。4.1.2 函数的定义无参函数定义格式为:数据类型函数名(void)函数体说明:数据类型指函数返回值类型,可以是任一种数据类型, 默认为返回整型值(但新标准要求写明,不用默认方式)。 没有返回值应将返回值类型定义为void。函数名采用合

5、法标识符表示。对无参函数,参数括号中的void通常省略,但括号不能 省略。函数体由一系列语句组成。函数体可以为空,称为空函 数。 1 1 无参函数无参函数4.1.2 函数的定义例: 打印一个表头 void TableHead ( ) cout=b?a:b); 问题:定义函数时究竟哪些变量应当作为函数的参数?哪些 应当定义在函数体内?提示原则:函数在使用时被看成 “黑匣子”,除了输入输出外,其 他部分可不必关心。从函数的定义看出,函数头正是用来反 映函数的功能和使用接口,它所定义的是“做什么”。即明确 了“黑匣子”的输入输出部分,输出就是函数的返回值,输入 就是参数。因此,只有那些功能上起自变量

6、作用的变量才必 须作为参数定义在参数表中;函数体中具体描述“如何做”, 因此除参数之外的为实现算法所需用的变量应当定义在函数 体内。C+中不允许函数的嵌套定义,即在一个函数中定义另一 个函数。4.1.3 函数的调用 函数调用:所谓函数调用,就是使程序转去执行函数体。在C+中,除了主函数外,其他任何函数都不能单独作为 程序运行。任何函数功能的实现都是通过被主函数直接或间 接调用进行的。无参函数的调用格式:函数名( )有参函数的调用格式:函数名(实际参数表) 其中实际参数简称实参,用来将实际参数的值传递给形参, 因此可以是常量、具有值的变量或表达式。【例4.1】 输入两个实数,输出其中较大的数4.

7、2 函数的参数传递、返回值及 函数声明4.21 函数的参数传递及传值调用 4.23 函数声明4.22 函数返回值 参数传递:函数调用首先要进行参数传递,参数传递的方向是由实 参传递给形参。传递过程是,先计算实参表达式的值,再将该值传递给 对应的形参变量。一般情况下,实参和形参的个数和排列顺 序应一一对应,并且对应参数应类型匹配(赋值兼容),即 实参的类型可以转化为形参类型。而对应参数的参数名则不 要求相同。4.2.1 函数的参数传递及传值调用 传值调用和引用调用: 按照参数形式的不同,C+有两种调用方式:传值调用和引 用调用。传值调用传递的是实参的值,本章介绍传值调用。4.2.1 函数的参数传

8、递及传值调用 传值调用: 将实参的值复制给形参,在函数中参加运算的 是形参,而实参不会发生任何改变。传值调用 起了一种隔离作用。【例4.2】 实参和形参对应关系的示例。4.2.2 函数返回值return语句的格式:return 表达式;函数的计算结果通过该语句传递回主调函数。【例4.3】设计函数,根据三角形的三边长求面积。如 果不能构成三角形,给出提示信息。 分析:函数为计算三角形面积,一般三角形返回面积值, 若不能构成三角形则返回-1。设计一个主函数完成函数测 试。根据返回值情况输出相应结果。4.2.2 函数返回值函数可以有返回值,也可以没有返回值。对于 没有返回值的函数,功能只是完成一定操

9、作,应将 返回值类型定义为void ,函数体内可以没有 return语句,当需要在程序指定位置退出时,可以 在该处放置一个:return ;讨论:4.2.2 结束4.2.3 函数声明函数声明是一条以分号结束的语句: 函数返回值类型函数名 (形参表); 语法上对程序文件中函数的排列次序要求满足先定义后 使用。但从结构化程序设计的角度,通常是先调用后定义。 使用函数声明,则既符合由粗到精的思维方式,又满足了语 法要求。其中形参表可以逐个列出每个参数的类型和参数名, 也可以列出每个形参的类型,参数名可省略,各形参之间 以逗号分隔。函数声明和所定义的函数必须在返回值类型 、函数名、形参个数和类型及次序

10、等方面完全对应一致, 否则将导致编译错误。 函数声明的引入:函数声明的格式:下面是一个使用结构化程序设计思想开发的企业管理 报表程序的框架。它使用了函数声明。 void menu_print(); void account_report(); void engineering_report(); void marketing_report(); int main()int choice;do menu_print(); cinchoice;while(choice=4);switch(choice)case 1: account_report(); break;case 2: engineer

11、ing_report(); break;case 3: marketing_report(); break; return 0;void menu_print() cout=0 其中的iostream是在标准名字空间域std中定义的头文件。对应 的传统方式的文件名为,头文件以“.h”为后缀。系统定义的头文件中定义了一些常用的公用标识符和函数 ,用户只要将头文件包含进自己的文件,就可使头文件中定义 的标识符在用户文件中变得可见,也就可以直接使用头文件中 定义的标识符和函数。 4.9.1 头文件自定义头文件: 除了系统定义的头文件外,用户还可以自定义头文件 。对于具有外部存储类型的标识符,可以在其

12、他任何 一个源程序文件中经声明后引用,因此用户完全可以 将一些具有外部存储类型的标识符的声明放在一个头 文件中。具体地说,头文件中可以包括:用户构造的 数据类型(如枚举类型),外部变量,外部函数、常 量和内联函数等具有一定通用性或常用的量,而一般 性的变量和函数定义不宜放在头文件中。4.9.2 多文件结构 在开发较大程序时,通常将其分解为多个源程序文件 ,每个较小的程序用一个源程序文件建立。程序经过建立 、编译、连接,成为一个完整的可执行程序。多文件结构 通过工程进行管理,在工程中建立若干用户定义的头文件 .h和源程序文件.cpp。头文件中定义用户自定义的数据类 型,所有的程序实现则放在不同的

13、源程序文件中。编译时 每个源程序文件单独编译,如果源程序文件中有编译预处 理指令,则首先经过编译预处理生成临时文件存放在内存 ,之后对临时文件进行编译生成目标文件.obj,编译后临 时文件撤销。所有的目标文件经连接器连接最终生成一个 完整的可执行文件.exe。图4.11是一个多文件系统的开发过程。4.9.2 多文件结构 编译预编译编译预编译 预编译编译图4.11 C+程序开发过程file1.hfile1.cppfile2.hfile2.cppfilen.hfilen.cpp临时文件1临时文件2临时文件nfile1.objfile2.objfilen.objFilename. exe.lib C

14、+标准类库连接运行4.10 编译预处理(选读) 4.10.1 宏定义指令 4.10.2 文件包含指令 4.10.3 条件编译指令 4.10.1 宏定义指令1 不带参宏定义 用来产生与一个字符串对应的常量字符串,格式为: #define 宏名 常量串 预处理后文件中凡出现该字符串处均用其对应的常量 串代替。替换过程称为宏替换或宏展开。例如,如果 使用指令 #define PI 4.1415926 则程序中可以使用标识符PI,编译预处理后产生一个 中间文件,文件中所有PI被替换为4.1415926。 宏替换只是字符串和标识符之间的简单替换,预处理 本身不做任何数据类型和合法性检查,也不分配内存 单

15、元。4.10.1 宏定义指令2 带参数的宏定义 带参宏定义的形式很象定义一个函数,格式为: #define 宏名 ( 形参表 ) 表达式串 例如作如下宏定义: #define S(a,b) (a)*(b)/2 程序中可使用S(a,b),预处理后产生中间文件,其中S(a,b)被 替换成(a)*(b)/2。注意,宏定义时形参通常要用括号括起来 ,否则容易导致逻辑错误。例如,如果定义: #define S(a,b) a*b/2 那么程序中的S(3+5,4+2)就会被宏展开为3+5*4+2/2,不 符合定义的真正的意图。 带参宏定义形式上象定义函数,但它与函数的本质不同,宏定 义仍然只是产生字符串替代

16、,不存在分配内存和参数传递。 4.10.2 文件包含指令文件包含用#include指令,预处理后将指令中指明的源程序 文件嵌入到当前源程序文件的指令位置处。格式为: #include 或 #include 文件名 第一种方式称为标准方式,预处理器将在include子目录下搜 索由文件名所指明的文件。这种方式适用于嵌入C+提供的 头文件,因为这些头文件一般都存在C+系统目录的 include子目录下。而第二种方式编译器将首先在当前文件所 在目录下搜索,如果找不到再按标准方式搜索。这种方式适 用于嵌入用户自己建立的头文件。一个被包含的头文件中还可以有#include指令, 即include指令可以嵌套,但是,如果同一个头文 件在同一个源程序文件中被重复包含,就会出现标 识符

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号