C语言程序设计第9章.ppt

上传人:牧羊曲112 文档编号:6504149 上传时间:2023-11-07 格式:PPT 页数:35 大小:224.49KB
返回 下载 相关 举报
C语言程序设计第9章.ppt_第1页
第1页 / 共35页
C语言程序设计第9章.ppt_第2页
第2页 / 共35页
C语言程序设计第9章.ppt_第3页
第3页 / 共35页
C语言程序设计第9章.ppt_第4页
第4页 / 共35页
C语言程序设计第9章.ppt_第5页
第5页 / 共35页
点击查看更多>>
资源描述

《C语言程序设计第9章.ppt》由会员分享,可在线阅读,更多相关《C语言程序设计第9章.ppt(35页珍藏版)》请在三一办公上搜索。

1、第9章 函数与变量,9.1 函数定义9.2 函数定义与使用9.3 变量的作用域9.4 变量的存储类型9.5 内部函数和外部函数,退出,9.1 函数定义,C源程序是由函数组成的。虽然在前面的示例程序中都只有一个主函数main(),但在实际编程中往往有多个函数组成。函数是C源程序最基本的模块,相当于其它高级语言的子程序。C语言提供了极为丰富的库函数,库函数相当于标准程序。编写程序就是编写函数以及使用库函数。各个函数之间为模块化关系。可从不同的角度对函数分类。,9.1.1 根据来源定义 从定义的角度把函数分为库函数和用户定义函数。1 库函数 库函数由系统提供,无须用户定义,也不必在程序中作类型说明,

2、但必须在程序最前面使用包含有该函数原型的头文件。库函数如:printf、scanf、getchar、putchar、gets、puts。2 用户定义函数 由用户自己编写的函数。它不仅要在程序中定义,而且必须在调用它的函数模块中进行类型说明。,9.1.2 根据返回情况定义 把函数分为有返回值函数和无返回值函数两种。1 有返回值函数 函数被调用执行完后将向调用者返回一个执行结果,称为函数返回值。如数学函数即属于此类函数。用户定义的有返回值的函数,必须在函数定义和函数说明中明确返回值的类型。2 无返回值函数 执行完成后不向调用者返回函数值。这类函数类似于其它语言的过程。由于函数无返回值,在定义时可指

3、定它为“空类型”,空类型的说明符为“void”。,9.1.3 根据参数传递定义 从主调函数和被调函数之间数据传送的角度可分为无参函数和有参函数两种。1 无参函数 调用函数与被调函数之间没有数据传送。则此类函数在定义、说明及调用中均不带参数。,2 有参函数 调用函数与被调函数之间有数据传送。则此类函数在定义、说明及调用中均带参数。函数是C语言的核心,而所有的函数在定义时是平等关系(包括主函数main在内),所谓平等是指:在一个函数的函数体内,不能再定义另一个函数,即不能嵌套定义。这与其它语言的子程序关系十分不同。这叫做“函数定义的外部性”。函数之间允许调用,也允许嵌套调用。甚至可以自己调用自己(

4、称为递归调用)。但是,对主函数main函数而言,可以调用其它函数,而不能被其它函数调用。程序的执行总是从main函数开始,完成对其它函数调用后再返回到main函数,最后由main函数结束整个程序。一个源程序必须有、也只能有一个主函数main。习惯上把调用者称为主调函数。被调用者称为被调函数。,9.2 函数定义与使用,9.2.1 无参函数定义的一般形式 无参函数定义通常采用如下形式:类型说明符 函数名()函数内部变量类型说明;语句序列;类型说明符和函数名称为函数头。类型说明符指明了本函数的类型,就是函数返回值的类型。函数名是由用户定义的标识符。中的内容称为函数体,这是函数的核心。函数体中的类型说

5、明用来说明函数体内部所用变量的类型。若不要求无参函数有返回值,则函数类型符可以写为void。【例9-1】(见课本),9.2.2 有参函数定义的一般形式 有参函数定义通常采用如下形式:类型说明符 函数名(形式参数列表)函数内部变量类型说明;语句序列;1 函数类型 就是函数返回值的类型。系统默认为int,故对int或char型可以不定义类型。对于不需要返回值的类型,则应定义为空函数,即函数类型为:void。2 函数名 函数的标识,即给不同的函数起不同的名字。函数名应符合C语言对标识符的规定。,3 形式参数列表 形式参数列表逐一列出形式参数的类型与名称,之间用逗号隔开。如:int a,double

6、x 形式参数的类型决定函数可以接受的数据类型。形式参数实际上是一种替身,代替实际参数在函数中先占位置。它有点像代数式中的变量xy。4 函数体 是函数中最独特的部分,实际上它决定了函数的功能。函数体可以是空的,此函数就是空函数,什么也不做。5 类型说明 形式参数既然作为变量应有类型说明。,6 函数的返回 返回就是函数执行结束,返回到调用它的函数。有返回值则代回,也可以没有返回值。通常用return语句来实现返回。return语句可以包含表达式。此时,则返回表达式的值。若return语句不包含表达式,则返回一个不确定的值。为避免可能引起的问题,此时应指定函数的类型为void。函数可以有多个出口,即

7、可以有多个return语句。但是,每 个return语句中的表达式的类型应相同。7 函数定义的位置无关性 函数的定义可以放在任意位置,既可放在主函数main之前,也可放在main之后。总之,函数主要由三要素组成:输入、过程及输出。【例9-2】(见课本)【例9-3】(见课本),9.2.3 函数声明 对本函数要定义的函数作一个声明,以便编译系统对函数进行检查。主要声明函数的输入信息:函数名,函数类型,形式参数的类型、个数及次序。格式如下:函数类型 函数名(形式参数列表);注意格式末尾的分号不可缺少。在实际使用中,最好在文件程序对本程序所使用的函数逐一、全部、集中声明。在以下几种情况下,可以不做声明

8、:函数的返回值是整形或字符型时;被调用函数的定义位置在主函数位置之前时;在所有函数定义之前、在文件的开头已经说明了时;【例9-4】(见课本),9.2.4 函数调用 调用函数就是使用已经定义了的函数,通常通过对函数的调用来执行函数体,其过程与其它语言的子程序调用相似。函数调用 的一般形式为:函数名(实际参数列表)实际参数表中的参数可以是常数,变量或其它构造类型数据及表达式。各实际参数之间用逗号分隔。对无参函数调用时则无实际参数表。其格式为:函数名 在C语言中,可以用多种方式调用函数。以下简述之。,1 函数表达式 函数作为表达式中的一项出现在表达式中,以函数返回值参与表达式的运算。这种方式要求函数

9、是有返回值的。例如:z=max(x,y)这是一个赋值表达式,把max的返回值赋予变量z。2 函数语句 把函数作为一个语句,即一般形式加上分号。例如:printf(%D,a);scanf(%d,都是以函数语句的方式调用函数。,3 函数实际参数 函数作为另一个函数调用的实际参数出现。这种情况是把该函数的返回值作为实际参数进行传送,因此要求该函数必须是有返回值的。例如:printf(%d,max(x,y);即是把max调用的返回值又作为printf函数的实际参数来使用的。【例9-5】(见课本),9.2.5 函数调用的类型 函数调用的方式主要有以下几种。这些调用方式极大地增强了函数的作用。其功能强大,

10、但使用中也应细心,否则造成的问题也严重。1 传值调用 调用时,把实际参数的值传递给形式参数,再执行函数。可以有返回值,也可以没有返回值而只是执行某种操作。,实际参数是调用函数中的变量,形式参数是被调用函数中的变量。在存储方面有以下特点:形式参数与实际参数各占独立的存储空间;形式参数的存储空间是调用时才分配的;调用结束时,撤消分配给形式参数的临时存储区;实际参数可以是常量、变量、表达式、函数等,无论实际参数是何种类型的量,在进行函数调用时,它们都必须具有确定的值,以便把这些值传送给形式参数;实际参数和形式参数的数量、类型、顺序应严格一致;函数调用中发生的数据传送是单向的。即只能把实际参数的值传送

11、给形式参数,而不能把形式参数的值反向地传送给实际参数。因此在函数调用过程中,形式参数的值发生改变,而实际参数中的值不会变化;【例9-6】(见课本),2 嵌套调用 嵌套调用就是在被调用的函数中再调用其它函数。【例9-7】(见课本)3 递归调用 直接或间接地调用函数本身。此时应特别注意递归的结束条件,仔细推敲它是否真正有效,必要时可人为设置递归终止条件(如控制调用次数)。【例9-8】(见课本),9.3 变量的作用域,变量有效的范围称为变量的作用域。语言中的变量,按作用域范围可分为两种,即局部变量和全局变量。9.3.1 局部变量 局部变量也称为内部变量。局部变量是在函数内作定义说明的。其作用域仅限于

12、函数内,离开该函数后再使用这种变量是非法的。【例9-9】(见课本)1 主函数的变量只能用于主函数中 主函数中定义的变量也只能在主函数中使用,不能在其它函数中使用。同时,主函数中也不能使用其它函数中定义的变量。因为主函数也是一个函数,它与其它函数是平行关系。这一点是与其它语言不同的,应予以注意。,2形式参数与实际参数范围不同 形式参数变量是属于被调函数的局部变量,实际参数变量是属于主调函数的局部变量。3 局部变量可以同名 允许在不同的函数中使用相同的变量名,它们代表不同的对象,分配不同的单元,互不干扰,也不会发生混淆。就是形式参数和实际参数的变量同名也是允许的。【例9-10】(见课本),9.3.

13、2 全局变量 全局变量也称为外部变量。在一个文件中,定义在函数之外的变量称为全局变量。它不属于哪一个函数,它属于一个源程序文件。其作用域是:从定义它的那一点直到文件末尾。整个源程序。在函数中使用全局变量,一般应作全局变量说明。只有在函数内经过说明的全局变量才能使用。全局变量的说明符为extern。但 在一个函数之前定义的全局变量,在该函数内使用可不再加以说明。外部变量定义必须在所有的函数之外,且只能定义一次。其一般形式为:extern 类型说明符 变量名,变量名,.;外部变量说明出现在要使用该外部变量的各个函数内。在整个程序内,可能出现多次,外部变量说明的一般形式为:extern 类型说明符

14、变量名,变量名,.;全局变量在编译时分配存储空间。,1 外部变量的值具有继承性 如果在一个函数中改变了外部变量的值,则其后引用该变量时,得到的是改变了的值。因此,可以使用外部变量在不同的函数间传递数据。2 静态外部变量 它允许本文件使用的外部变量。它可以使不同文件之间同名的外部变量互不干扰。其说明格式为:static 类型 变量名=初值 初值默认为0。3 外部变量在文件内作用范围的扩展 可以使用extern命令,把作用范围扩展到从extern命令开始。,4 外部变量在文件外的扩张 可以把外部变量的作用范围扩展到后来运行的、有extern命令的文件中。5 外部变量的副作用 外部变量建立了函数之间

15、的另外一条数据交换渠道(正常的渠道是传递参数及得到返回值)。这样,很可能形成某个外部变量与多个函数(甚至文件)的关联。若其中一个模块异常,都可能引起此外部变量的异常。而此外部变量的异常,又会引起其它模块的异常,造成“牵一发而动全身”,是问题扩大化与复杂化。这会给程序的调试与运行带来不便。为避免此问题,建议尽量使用静态外部变量,把它控制在你所编写的程序内。【例9-11】(见课本)【例9-12】(见课本)【例9-13】(见课本),9.4 变量的存储类型,变量是程序中数据的传递者,变量具有两种属性:操作属性和存储属性。操作属性就是指数据类型,存储属性就是指数据的存储位置与时间。9.4.1 概说1 变

16、量可用的存储空间 可以用来存放变量的存储空间是内存和寄存器。内存大家已经了解。寄存器是CPU中的一个数据临时存储区,其容量有限(一般都比内存小的多),但系统对寄存器中数据的读写操作的速度则较快。,2 变量生存周期 就是变量存在的时期。根据其存在时期的长短,可以把变量分为以下两种:(1)静态变量 在程序执行的整个过程中都存在,并有固定的存储空间。,(2)动态变量 只在程序执行的一段时间内存在,没有固定的存储空间。变量按存储方式可分为“静态存储”和“动态存储”两种。静态存储变量通常是在变量定义时就分定存储单元并一直保持不变,直至整个程序结束。动态存储变量是在程序执行过程中,使用它时才分配存储单元,

17、使用完毕立即释放。典型的例子是函数的形式参数,在函数定义时并不给形式参数分配存储单元,只是在函数被调用时,才予以分配,调用函数完毕立即释放。如果一个函数被多次调用,则反复地分配、释放形式参数变量的存储单元。静态存储变量是一直存在的,而动态存储变量则时而存在时而消失。这种由于变量存储方式不同而产生的特性就是变量的生存周 期。生存周期表示了变量存在的时间。生存期和作用域是从时间 和空间这两个不同的角度来描述变量的特性,这两者既有联系,又有区别。,3 变量的可用性(1)全局可用(2)局部可用9.4.2 动态变量 动态变量可用分为自动变量和寄存器变量两大类。1 自动变量 由系统自动建立和撤消的变量。自

18、动变量用时建、用完撤。从使用时间来看,具有招之即来、挥之即去的特点。自动变量在每次使用时才分配存储单元,用完清除存储单元。下次用时再分配新的存储单元(可能不是上次所用的存储单元)。从存储空间来看,具有“打一枪换一个地方”的特点。,(1)定义格式 自动变量的定义格式如下:auto 数据类型 变量名=初始表达式 以上格式中内的内容可以省略。以下对格式中的各项加以解释:数据类型 表明变量的数据类型。量名 变量名字,可以与其它程序中变量的名字相同。初始表达式 用来给变量赋初值。若不给变量赋初值,则变量的初始不确定(初始值取决于分配给此变量的存储单元中存储的当前值)。也可以在程序段中用赋值语句来赋给初始

19、值。但是,只能赋给一次初始值,不可重复。,(2)自动变量的局部性 自动变量是局部变量,仅仅在定义它的那个局部有效。(3)值不继承 自动变量的值没有继承性,也就是说,函数调用自动变量时,自动变量现有的值不保留,而是以现赋的初始值替代原值。【例9-14】(见课本)【例9-15】(见课本)【例9-16】(见课本),2 寄存器变量 寄存器变量存放在CPU的寄存器中。使用时,不需要访问内存,而直接从寄存器中读写,有较高的读写效率。通常用于循环次数较多的循环控制变量及循环体内反复使用的变量。要定义寄存器变量,可采用如下格式:register 数据类型 变量名=初值表达式 寄存器变量的性质与自动变量的性质完

20、全相同,只是放的位置不同。若硬件中闲置的寄存器中不足容纳所定义的寄存器变量,则系统自动把寄存器变量转换为自动变量。应该把变量按照操作情况排序,尽量把使用频繁的变量设置为寄存器变量。在实际应用中,因为机器硬件所限,寄存器变量使用不是很多。【例9-17】(见课本),9.4.3 静态变量1 静态变量的定义格式 要定义静态变量,可采用如下格式:static 数据类型 变量名=初值表达式 静态变量具有如下特点:静态变量在程序运行期间固定不变。它在编译时就分配存储空间,程序一开始执行就建立,直到程序结束一直存在;静态变量的初始化在编译时进行,默认的初始值为0或0.0;只能使用常数或常数表达式赋给初值,不能

21、用含变量的表达式赋初值;静态变量可以从其作用域分为静态局部变量和静态全局变量。,2 静态局部变量 在局部变量的说明前再加上static说明符就构成静态局部变量。例如:static int a,b;static float array5=1,2,3,4,5;静态局部变量属于静态存储方式,它具有以下特点。(1)生命期为程序运行期 静态局部变量虽然在函数内定义,但不象自动变量那样,当调用时就存在,退出函数时就消失。静态局部变量始终存在着,也就是说它的生存期为整个源程序运行期。,(2)作用的范围只是定义它的函数内 静态局部变量的生存期虽然为整个源程序,但是其作用域仍与自动变量相同,即只能在定义该变量的

22、函数内使用该变量。退出该函数后,尽管该变量还继续存在,但不能使用它。也就是说,静态局部变量只能在本函数中使用,具有“从一而终”的特点。(3)值可继承 静态局部变量的值具有可继承性。下次调用时,上次的结果值还在。也就是说,只在第一次调用时初始化。当多次调用一个函数且要求在各次调用之间保留某些变量的值时,可考虑采用静态局部变量。虽然用全局变量也可以达到上述目的,但全局变量有时会造成意外的副作用,因此仍以采用局部静态变量为宜。【例9-18】(见课本),3静态全局变量 全局变量(外部变量)的说明之前加上static就构成了静态的全局变量。全局变量与静态全局变量的区别在于:非静态全局变量的作用域是整个源

23、程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它,可以避免在其它源文件中引起错误。,9.5 内部函数和外部函数,函数一旦定义后就可被本文件的其它函数调用,但函数能否被其它源文件中的函数调用则取决于函数的性质。从这一角度,把函数分为内部函数与外部函数。9.5.1 内部函数 在一个源文件中定义的函数只能被本文件中的函数调用,而不能被同一源程序其它文件中的函数调用,这种函数称为内部函数。定义内部函数的一般形式是:static 类型说明符 函数名(形式参数表)例如:static int f(int a,int b)内部函数也称为静态函数。但此处静态static的含义已不是指存储方式,而是指对函数的调用范围只局限于本文件。因此在不同的源文件中定义同名的静态函数不会引起混淆。,9.5.2 外部函数 外部函数在整个源程序中都有效,其定义的一般形式为:extern 类型说明符 函数名(形式参数表)例如:extern int f(int a,int b)如在函数定义中没有说明extern或static则默认为extern。在一个源文件的函数中调用其它源文件中定义的外部函数时,应用extern说明被调函数为外部函数。【例9-19】(见课本),

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号