C语言程序设计第四章函数和作用域.ppt_第1页
C语言程序设计第四章函数和作用域.ppt_第2页
C语言程序设计第四章函数和作用域.ppt_第3页
C语言程序设计第四章函数和作用域.ppt_第4页
C语言程序设计第四章函数和作用域.ppt_第5页
已阅读5页,还剩44页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第四章 函数和作用域,第四章,第一节 函数的定义和说明,第四章,一、函数的定义格式 在C+中一个函数的定义格式 : () 函数的定义格式的几点说明: 1、构成了函数的函数 头。 2、用花括号括起来的组成了函数体。函 数体内无论多少条语句,花括号是不可省的。,第四章,3、是该函数的类型,即为该函数返回值的类 型,如果该函数没有返回值,只是一个过程调用,则 该函数的类型为 void ,在C+程序中函数的类型不 可省略。 4、是由0个、1个或多个参数组成,参数个 数为0,表示没有参数 ,但是圆括号不可省,多个参 数之间应用逗号分隔;每个参数包括参数类型和参 数名。中的参数称为形式参数,简称形 参。形参在该函数被调用时才被初始化的。形参的 使用将使被调用函数可以从调用函数那里获取数 据。如果被调用函数不需要从调用函数那里获取数 据,则该函数参数为空。,第四章,二、函数的说明方法: 1、说明调用函数的方法: (); 函数说明又称为原型说明。其格式同于定义函数 时的函数头,包括函数的类型、函数名和函数参数的 个数及其对应的类型。原型说明与C语言中的简单说明 是不同的。 2、在C+中函数的说明原则: 如果一个函数定义在先,调用在后,调用前可以 不必说明;如果一个函数定义在后,调用在先,调用 前则必须说明。 例1、使用原型说明的例子,第四章,#include void fun1(),fun2(),fun3(); void main() cout”It is in main.“endl; fun2(); cout“It is back in main.“endl; void fun1() cout“Its in fun1.”endl; fun3(); cout”Its back in fun1.”endl; ,第四章,void fun2() cout“Its in fun2.“ endl; funl(); cout”Its back in fun2.“end1; void fun3() cout“Its in fun3.“endl; ,第四章,第二节 函数的调用,第四章,一、函数的值和类型: 一个函数被定义以后就是为了将来对它调用,函 数的调用是用一个表达式来表示的。 函数调用格式: () 、可以是0个、1个或多个实在参数,如 果是多个参数用逗号分隔。 、每个参数是一个表达式。 、实参的个数由形参决定, 实参是用来在调用函 数时给形参初始化的,因此实参的个数和类型要 与形参的个数和类型一致,并且初始化时是按其 位置对应进行。,第四章,二、函数的调用: 1、函数的传值调用: 该调用同C语言,分如下两种: (1)、传值调用:传递变量本身值的函数调用。 使用传值调用时,调用函数的实参用常量、变量 值或表达式,被调用函数的形参用变量名,实参将复 制副本形参。 传值调用的特点是在被调用函数中形参的改变将 不影响调用函数的实参。 例2、一个传值调用的例子。,第四章,#include void swap1(int x, int y) int temp; temp=x; x=y; /将y值赋予了x y=temp; /将x的值赋予y cout“x=“x“,“y=“yendl; void main() int a(5),b(9); swap1(a,b); cout“a=“a“,“b=“bendl; ,第四章,(2)、传址调用:传递变量地址值的函数调用。 使用传址调用方式时,调用函数的实参用地址值, 被调用函数的形参用指针,调用时将实参地址值传送 给形参指针,即让指针指向实参变量或对象。在被调 用函数中可以通过改变形参指针所指向的实参变量值 来间接改变实参值。 传址调用的特点是可以通过改变形参所指向的变 量值来影响实参。 例3、一个传址调用的例子。,第四章,#include void swap2(int *x,int *y) int temp; temp=*x; *x=*y; *y=temp; cout“x=“*x“,“y=“*yendl; void main() int a(5),b(9); swap2( ,第四章,2、引用调用: 引用调用是C+中的一种函数调用方式,C语言中 没有这种调用方式。 引用调用时,调用函数的实参用变量名或对象 名,被调用函数的形参用变量或对象的引用。而实际 传送的是地址值。在被调用函数中改变形参值,则调 用函数中实参值也被改变。 引用调用具有传址调用的特点,而在操作中又比 传址调用方便、直观。因此,在C+程序中多用引用调 用。 例4、一个引用调用的例子,第四章,#include void swap3(int ,第四章,三、 函数的嵌套调用: C+程序中允许函数的嵌套调用:函数调用是逐级 调用,然后逐级返回的过程。即在调用A函数的过程中, 可以调用B函数,在调用B函数的过程中,还可以调用C函 数。当C函数调用结束后,返回到B函数,当B函数调 用结束后,再返回到A函数。 四、函数的递归调用: 递归调用:是指在调用一个函数时,直接或间接 地调用该函数自身的过程。 直接递归调用:是指在调用一个函数的过程中, 又调用了该函数。,第四章,间接递归调用:是指在调用一个函数的过程中调 用了另一个函数,而在另一个函数中又调用了该函数。 1、递归调用的特点及方法: (1)、特点:使用递归调用方法编写的程序简洁清 晰,可读性强,但是程序在执行时占用的时间和空 间都比较大。 (2)、方法:将原有问题能够分解为一个新问题,而 新问题又用到原有问题的解法,这就出现了递归。 实际中,有限的递归调用是有意义的,而无限的递 归调用是没有意义的。数学中求正整数阶乘的问题 就是典型的有限的递归调用的例子。,第四章,2、递归调用的过程: 具体可分为两个阶段: 第一个阶段称为“递推”阶段。这一阶段将原有问 题不断地分解为新的子问题,逐渐从未知的向已知的 方向推测,最终到达已知的条件,即递归结束条件, 这时递推阶段结束。 第二个阶段称为“回归”阶段。此阶段是从已知的 阶段出发,按照“递推”的逆过程,逐一求值回归,最后 到达递推的开始处,结束回归阶段,完成递归调用。 如求正整数阶乘的问题。,第四章,第三节 函数参数及内联函数,第四章,一、函数参数的求值顺序: 当一个函数带有多个参数时,C+语言没有规定在 函数调用时实参的求值顺序,而编译器根据对代码进 行优化的需要自行规定对实参的求值顺序。因此应注 意不同编译系统中,函数参数求值的顺序可能不同, 当实参表达式中出现有副作用的运算符时,可能产生 二义性。 二、设置函数参数的默认值: 在C+语言中,允许在函数的说明或定义时给一个 或多个参数指定默认值。具体规则如下:,第四章,(1)、设置参数默认值时,要求从右向左设置,即要求 在一个指定了默认值的参数的右边不能出现没有指 定默认值的参数。 (2)、调用设置了默认参数的函数时,对应实参如果 没有,则用默认值,如果存在,则用实参值。 (3)、如果一个函数有说明出现时,设置参数默认值 应放在函数说明中。 例5、一个将参数默认值设置在函数的说明中的例子,第四章,#include int m(8); int add_ int (int x, int y=7,int z=m); void main() int a(5),b(15),c; int s=add_int(a,b,c); coutsendl; int add _ int ( int x, int y, int z) return x+y+z; 运行结果:28,第四章,三、数组名可作为函数参数: 数组作函数参数可以分为三种情况,这三种情况所 采用的调用机制不同,但是结果相同。 1、形参和实参都用数组: 调用函数的实参用数组名,被调用函数的形参用数 组,这种调用的机制是形参和实参共用内存中的同一个 数组。因此,在被调用函数中改变了数组中某个元素的 值,对调用函数该数组的该元素值也被改变。 例6: #include int a8=1,3,5,7,9,11,13; void fun(int b ,int n) for (int i=0;in-1;i+),第四章,b7+=b i; void main() int m=8; fun (a, m); couta7endl; 运行后结果为:49 2、形参和实参都用对应数组的指针: 在C+中,数组名被规定为是一个指针,该指针便是 指向该数组的首元素的指针。实际中,形参和实参一个 用指针,另一个用数组也是可以的。在使用指针时可以 用数组名,也可以用另外定义的指向数组的指针。,第四章,例7: #include int a8=1,3,5,7,9,11,13; void fun(int *pa, int n) for(int i=0;in-1;i+) *(pa+7)+=*(pa+i); void main() int m=8; fun(a,m); /a是数组的数组名,是一个地址值 couta7endl; 运行结果:49,第四章,3、实参用数组名,形参用引用。 采用这种情况时,应先用类型定义语句定义一个 与实参数组类型相一致的数组类型。 四、内联函数: 1、 内联函数引入的原因: 引入内联函数的目的是为了提高程序中函数调用 的效率问题。引入内联函数,在程序编译时,编译 器将程序中出现的内联函数的调用表达式用内联函数 的函数体来进行替换,因此,引入内联函数是以目标 代码的增加为代价来换取时间的节省。,第四章,2、内联函数的定义方法: 在函数头前加上关键字inline,其格式: inline () 3、使用内联函数应注意的事项: (1)、内联函数通常情况下是将一些函数体不大,而 且使用频繁的函数; (2)、内联函数体内不允许用循环语句和开关语句; (3)、内联函数的定义必须出现在第一次调用之前; (4)、类体内定义的所有成员函数都是内联函数。,第四章,例8、编程求110中各个数的平方。 #include inline int power_int(int x) return (x) * (x); void main() for (int i=1;i=10;i+) int p=power_int(i); couti“ * “i“=“pendl; 运行结果:分别是110 的平方。,第四章,第四节 函数的重载,第四章,一、函数重载定义: 函数重载:是指同一个函数名对应着多个不同的 实现。 二、 定义重载函数时的注意事项: 1、多个重载的同名函数在定义时要注意它们的参 数 的不同,主要是参数的个数、类型和顺序的不同。 2、在选择重载函数的不同实现时,主要根据参数不同 进行选择。 例9、求两个操作数之和。 #include int add(int,int); double add(double,double);,第四章,void main() coutadd(5,10)endl; coutadd(5.0,10.5)endl; int add(int x, int y) return x+y; double add(double a ,double b) return a+b; 程序的输出结果: 15 15.5,第四章,例10、找出几个int型数中最小者。 #include int min (int a , int b); int min (int a ,int b , int c); int min (int a ,int b ,int c ,int d); void main() coutmin(13,5,4,9)endl; coutmin(-2,8,0); int min (int a ,int b) return ab? a :b; int min (int a ,int b ,int c) ,第四章,int t=min(a,b); return min(t,c); int min(int a ,int b ,int c ,int d) int t1=min(a,b); int t2=min(c,d); return min(t1,t2); 运行结果:4 -2,第四章,第五节 作用域,第四章,一、用作标识符的作用域规则: 作用域又称作用范围。在程序中出现的各种标识 符,它们的作用域是不同的。标识符只能在说明它或定 义它的范围内是“可见的”,即是可以进行存取或访问操 作的;而在该范围之外是“不可见”的,也就是指不可 以进行存取或访问操作的。 二、作用域的种类 : 作用域的按大小可分为: 1、程序级:作用域最大, 属于程序级作用域的有外部 函数和外部变量。 2、文件级:仅在所定义的文件内,属于文件级作用域 的有内部函数和外部静态类变量。,第四章,3、函数级:在它所定义的函数体内,属于函数级作用 域的有函数的形参和在函数内定义的自动类变量和 内部静态类变量以及语句标号。 4、块级 :在某一程序块内,属于块级作用域的有定 义在分程序、if语句、switch 语句以及循环语句中 的自动类变量和内部静态类变量。 三、关于重新定义标识符的作用域规定: 在某个作用范围内定义的标识符在该范围内的子 范围内中可以重新定义,这时原定义的标识符在子范 围内是不可见的,但是它还是存在的,只是在子范围内 由于出现了同名的标识符而被暂时地隐藏起来。出了 子范围后,它又是可见的。,第四章,第七节 存储类及系统函数,第四章,一、存储类: 1、变量的存储类: (1)、变量存储类的种类: 、自动类:是在函数体或分程序内定义的变量, 定义时可加auto说明符,也可以省略。 、寄存器类:也是定义在函数体内或分程序内的变量,定义时前边加说明符rigester。寄存器类变量有 可能被存放到CPU的通用寄存器中, 此时可提高存取 速度,但是由于CPU的通用寄存器数量有限,如果没 被存放到通用寄存器中便按自动类变量处理。 、外部类:是一种定义在函数体外,定义时不加任 何存储类说明的一种变量。外部变量在引用之前需,第四章,要说明,说明外部变量时应在其前面加说明符 extern。 外部变量的定义和说明是两回事:在一个程 序中,一个外部变量只能定义一次,但是可以说明 多次。外部变量不管是在同一文件中,还是在另 外一个文件中被引用, 都要在引用前必须对它进行 说明。 、静态类(内部静态和外部静态): 内部静态类变量也是在函数体内或分程序内定 义的变量,用说明符static说明。它的作用域与自 动变量相同,但是它的生存期(即寿命)是长的,是一 种可见性与存在性不一致的变量:在定义它的作用,第四章,域外,它虽然不可见,但是它仍然存在,且没有被释放 掉,一旦它回到作用域后,仍然保留其原来的值。 外部静态类变量被定义在函数体外,也用说明符 static说明,其作用域是文件级的,可见性与存在 性也是不一致的(它的作用域不是整个程序,但其 生存期却在整个程序)。 (2)、不同存储类变量的作用域和寿命: 、作用域分为程序级、文件级、函数级和分程序级 、寿命分为长和短两种。存放在内存的静态区的寿 命长,存放在寄存器和内存的动态区的寿命短。 2、函数的存储类: (1)、函数存储类的种类: 函数存储类分两种: 内部函数和外部函数。,第四章,a、内部函数:用关键字static 说明的函数,也称为 静态函数。在定义它的文件中可以被调用,而在同一 程序的其他文件中不可被调用。 定义格式: static () b、外部函数:用关键字extern 说明的函数,其作用 域在整个程序中,包含组成该程序的若干个文件。 定义格式:,第四章,extern() 一般情况下,关键字extern可以省略。 二、系统函数: 1、使用系统函数的注意事项: C+系统将所提供的系统函数的说明分类放在不同 的 .h 文件中。因此,编程者在使用系统函数时,应该 注意: (1)、了解你所使用的C+系统

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论