《C语言程序设计第9章.ppt》由会员分享,可在线阅读,更多相关《C语言程序设计第9章.ppt(35页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、第第9 9章章 函数与变量函数与变量9.1 函数定义函数定义9.2 函数定义与使用函数定义与使用9.3 变量的作用域变量的作用域9.4 变量的存储类型变量的存储类型9.5 内部函数和外部函数内部函数和外部函数退出退出9.1 函数定义函数定义 C源源程程序序是是由由函函数数组组成成的的。虽虽然然在在前前面面的的示示例例程程序序中中都都只只有有一一个个主主函函数数main(),但但在在实实际际编编程程中中往往往往有有多多个个函函数数组组成成。函函数数是是C源源程程序序最最基基本本的的模模块块,相相当当于于其其它它高高级级语语言言的的子子程程序序。C语语言言提提供供了了极极为为丰丰富富的的库库函函数
2、数,库库函函数数相相当当于于标标准准程程序序。编编写写程程序序就就是是编写函数以及使用库函数。各个函数之间为模块化关系。编写函数以及使用库函数。各个函数之间为模块化关系。可从不同的角度对函数分类。可从不同的角度对函数分类。9.1.1 9.1.1 9.1.1 9.1.1 根据来源定义根据来源定义根据来源定义根据来源定义 从定义的角度把函数分为库函数和用户定义函数。从定义的角度把函数分为库函数和用户定义函数。1 库函数库函数 库库函函数数由由系系统统提提供供,无无须须用用户户定定义义,也也不不必必在在程程序序中中作作类类型型说说明,但必须在程序最前面使用包含有该函数原型的头文件。明,但必须在程序最
3、前面使用包含有该函数原型的头文件。库库函函数数如如:printf、scanf、getchar、putchar、gets、puts。2 用户定义函数用户定义函数 由由用用户户自自己己编编写写的的函函数数。它它不不仅仅要要在在程程序序中中定定义义,而而且且必必须须在调用它的函数模块中进行类型说明。在调用它的函数模块中进行类型说明。9.1.2 9.1.2 9.1.2 9.1.2 根据返回情况定义根据返回情况定义根据返回情况定义根据返回情况定义 把函数分为有返回值函数和无返回值函数两种。把函数分为有返回值函数和无返回值函数两种。1 有返回值函数有返回值函数 函函数数被被调调用用执执行行完完后后将将向向
4、调调用用者者返返回回一一个个执执行行结结果果,称称为为函函数数返返回回值值。如如数数学学函函数数即即属属于于此此类类函函数数。用用户户定定义义的的有有返返回回值值的的函函数,必须在函数定义和函数说明中明确返回值的类型。数,必须在函数定义和函数说明中明确返回值的类型。2 无返回值函数无返回值函数 执执行行完完成成后后不不向向调调用用者者返返回回函函数数值值。这这类类函函数数类类似似于于其其它它语语言言的的过过程程。由由于于函函数数无无返返回回值值,在在定定义义时时可可指指定定它它为为“空空类类型型”,空类型的说明符为空类型的说明符为“void”。9.1.3 9.1.3 9.1.3 9.1.3 根
5、据参数传递定义根据参数传递定义根据参数传递定义根据参数传递定义 从从主主调调函函数数和和被被调调函函数数之之间间数数据据传传送送的的角角度度可可分分为为无无参参函函数数和有参函数两种。和有参函数两种。1 无参函数无参函数 调调用用函函数数与与被被调调函函数数之之间间没没有有数数据据传传送送。则则此此类类函函数数在在定定义义、说明及调用中均不带参数。说明及调用中均不带参数。2 有参函数有参函数 调用函数与被调函数之间有数据传送。则此类函数在定义、调用函数与被调函数之间有数据传送。则此类函数在定义、说明及调用中均带参数。说明及调用中均带参数。函数是函数是C语言的核心,而所有的函数在定义时是平等关系
6、语言的核心,而所有的函数在定义时是平等关系(包括主函数(包括主函数main在内在内),所谓平等是指:在一个函数的函数体,所谓平等是指:在一个函数的函数体内,不能再定义另一个函数,即不能嵌套定义。这与其它语言的内,不能再定义另一个函数,即不能嵌套定义。这与其它语言的子程序关系十分不同。这叫做子程序关系十分不同。这叫做“函数定义的外部性函数定义的外部性”。函数之间允许调用,也允许嵌套调用。甚至可以自己调用自函数之间允许调用,也允许嵌套调用。甚至可以自己调用自己己(称为递归调用称为递归调用)。但是,对主函数。但是,对主函数main函数而言,可以调用其函数而言,可以调用其它函数,而不能被其它函数调用。
7、程序的执行总是从它函数,而不能被其它函数调用。程序的执行总是从main函数函数开始,完成对其它函数调用后再返回到开始,完成对其它函数调用后再返回到main函数,最后由函数,最后由main函函数结束整个程序。一个源程序必须有、也只能有一个主函数数结束整个程序。一个源程序必须有、也只能有一个主函数main。习惯上把调用者称为主调函数。被调用者称为被调函数。习惯上把调用者称为主调函数。被调用者称为被调函数。9.2 函数定义与使用函数定义与使用9.2.1 9.2.1 9.2.1 9.2.1 无参函数定义的一般形式无参函数定义的一般形式无参函数定义的一般形式无参函数定义的一般形式 无参函数定义通常采用如
8、下形式:无参函数定义通常采用如下形式:类型说明符类型说明符类型说明符类型说明符 函数名函数名函数名函数名()()函数内部变量类型说明函数内部变量类型说明函数内部变量类型说明函数内部变量类型说明;语句序列语句序列语句序列语句序列;类类型型说说明明符符和和函函数数名名称称为为函函数数头头。类类型型说说明明符符指指明明了了本本函函数数的的类类型型,就就是是函函数数返返回回值值的的类类型型。函函数数名名是是由由用用户户定定义义的的标标识识符符。中的内容称为函数体,这是函数的核心。中的内容称为函数体,这是函数的核心。函数体中的类型说明用来说明函数体内部所用变量的类型。函数体中的类型说明用来说明函数体内部
9、所用变量的类型。若不要求无参函数有返回值,则函数类型符可以写为若不要求无参函数有返回值,则函数类型符可以写为void。【例【例9-1】(见课本)见课本)9.2.2 9.2.2 9.2.2 9.2.2 有参函数定义的一般形式有参函数定义的一般形式有参函数定义的一般形式有参函数定义的一般形式 有参函数定义通常采用如下形式:有参函数定义通常采用如下形式:类型说明符类型说明符类型说明符类型说明符 函数名函数名函数名函数名(形式参数列表形式参数列表形式参数列表形式参数列表)函数内部变量类型说明函数内部变量类型说明函数内部变量类型说明函数内部变量类型说明;语句序列语句序列语句序列语句序列;1 函数类型函数
10、类型 就是函数返回值的类型。系统默认为就是函数返回值的类型。系统默认为int,故对,故对int或或char型可型可以不定义类型。以不定义类型。对于不需要返回值的类型,则应定义为空函数,即函数类型对于不需要返回值的类型,则应定义为空函数,即函数类型为:为:void。2 函数名函数名 函数的标识,即给不同的函数起不同的名字。函数名应符合函数的标识,即给不同的函数起不同的名字。函数名应符合C语言对标识符的规定。语言对标识符的规定。3 形式参数列表形式参数列表 形形式式参参数数列列表表逐逐一一列列出出形形式式参参数数的的类类型型与与名名称称,之之间间用用逗逗号号隔开。如:隔开。如:int a,doub
11、le x int a,double x 形式参数的类型决定函数可以接受的数据类型。形式参数的类型决定函数可以接受的数据类型。形形式式参参数数实实际际上上是是一一种种替替身身,代代替替实实际际参参数数在在函函数数中中先先占占位位置。它有点像代数式中的变量置。它有点像代数式中的变量xy。4 函数体函数体 是函数中最独特的部分,实际上它决定了函数的功能。是函数中最独特的部分,实际上它决定了函数的功能。函数体可以是空的,此函数就是空函数,什么也不做。函数体可以是空的,此函数就是空函数,什么也不做。5 类型说明类型说明 形式参数既然作为变量应有类型说明。形式参数既然作为变量应有类型说明。6 函数的返回函
12、数的返回 返返回回就就是是函函数数执执行行结结束束,返返回回到到调调用用它它的的函函数数。有有返返回回值值则则代回,也可以没有返回值。代回,也可以没有返回值。通常用通常用return语句来实现返回。语句来实现返回。return语句可以包含表达式。此时,则返回表达式的值。语句可以包含表达式。此时,则返回表达式的值。若若return语语句句不不包包含含表表达达式式,则则返返回回一一个个不不确确定定的的值值。为为避避免可能引起的问题,此时应指定函数的类型为免可能引起的问题,此时应指定函数的类型为void。函函数数可可以以有有多多个个出出口口,即即可可以以有有多多个个return语语句句。但但是是,每
13、每 个个return语句中的表达式的类型应相同。语句中的表达式的类型应相同。7 函数定义的位置无关性函数定义的位置无关性 函函数数的的定定义义可可以以放放在在任任意意位位置置,既既可可放放在在主主函函数数main之之前前,也可放在也可放在main之后。之后。总之,函数主要由三要素组成:输入、过程及输出。总之,函数主要由三要素组成:输入、过程及输出。【例【例9-2】(见课本)见课本)【例【例9-3】(见课本)见课本)9.2.3 9.2.3 9.2.3 9.2.3 函数声明函数声明函数声明函数声明 对对本本函函数数要要定定义义的的函函数数作作一一个个声声明明,以以便便编编译译系系统统对对函函数数进
14、进行行检检查查。主主要要声声明明函函数数的的输输入入信信息息:函函数数名名,函函数数类类型型,形形式式参参数数的类型、个数及次序。的类型、个数及次序。格式如下:格式如下:函数类型函数类型函数类型函数类型 函数名函数名函数名函数名(形式参数列表形式参数列表形式参数列表形式参数列表););注意格式末尾的分号不可缺少。注意格式末尾的分号不可缺少。在在实实际际使使用用中中,最最好好在在文文件件程程序序对对本本程程序序所所使使用用的的函函数数逐逐一一、全部、集中声明。全部、集中声明。在以下几种情况下,可以不做声明:在以下几种情况下,可以不做声明:l函数的返回值是整形或字符型时;函数的返回值是整形或字符型
15、时;l被调用函数的定义位置在主函数位置之前时;被调用函数的定义位置在主函数位置之前时;l在所有函数定义之前、在文件的开头已经说明了时;在所有函数定义之前、在文件的开头已经说明了时;【例【例9-4】(见课本)见课本)9.2.4 9.2.4 9.2.4 9.2.4 函数调用函数调用函数调用函数调用 调调用用函函数数就就是是使使用用已已经经定定义义了了的的函函数数,通通常常通通过过对对函函数数的的调调用用来来执执行行函函数数体体,其其过过程程与与其其它它语语言言的的子子程程序序调调用用相相似似。函函数数调调用用 的一般形式为:的一般形式为:函数名函数名函数名函数名(实际参数列表实际参数列表实际参数列
16、表实际参数列表)实实际际参参数数表表中中的的参参数数可可以以是是常常数数,变变量量或或其其它它构构造造类类型型数数据据及及表达式。表达式。各实际参数之间用逗号分隔。各实际参数之间用逗号分隔。对无参函数调用时则无实际参数表。其格式为:对无参函数调用时则无实际参数表。其格式为:函数名函数名函数名函数名 在在C语言中,可以用多种方式调用函数。以下简述之。语言中,可以用多种方式调用函数。以下简述之。1 函数表达式函数表达式 函函数数作作为为表表达达式式中中的的一一项项出出现现在在表表达达式式中中,以以函函数数返返回回值值参参与表达式的运算。这种方式要求函数是有返回值的。例如:与表达式的运算。这种方式要
17、求函数是有返回值的。例如:z=max(x,y)z=max(x,y)这是一个赋值表达式,把这是一个赋值表达式,把max的返回值赋予变量的返回值赋予变量z。2 2 函数语句函数语句 把函数作为一个语句,即一般形式加上分号。例如:把函数作为一个语句,即一般形式加上分号。例如:printf(%D,a);printf(%D,a);scanf(%d,&b);scanf(%d,&b);都是以函数语句的方式调用函数。都是以函数语句的方式调用函数。3 3 函数实际参数函数实际参数 函函数数作作为为另另一一个个函函数数调调用用的的实实际际参参数数出出现现。这这种种情情况况是是把把该该函函数数的的返返回回值值作作为
18、为实实际际参参数数进进行行传传送送,因因此此要要求求该该函函数数必必须须是是有有返回值的。例如:返回值的。例如:printf(%d,max(x,y);printf(%d,max(x,y);即即是是把把max调调用用的的返返回回值值又又作作为为printf函函数数的的实实际际参参数数来来使使用用的。的。【例【例9-5】(见课本)见课本)9.2.5 9.2.5 9.2.5 9.2.5 函数调用的类型函数调用的类型函数调用的类型函数调用的类型 函函数数调调用用的的方方式式主主要要有有以以下下几几种种。这这些些调调用用方方式式极极大大地地增增强强了了函函数数的的作作用用。其其功功能能强强大大,但但使使
19、用用中中也也应应细细心心,否否则则造造成成的的问问题也严重。题也严重。1 传值调用传值调用 调调用用时时,把把实实际际参参数数的的值值传传递递给给形形式式参参数数,再再执执行行函函数数。可可以有返回值,也可以没有返回值而只是执行某种操作。以有返回值,也可以没有返回值而只是执行某种操作。实实际际参参数数是是调调用用函函数数中中的的变变量量,形形式式参参数数是是被被调调用用函函数数中中的的变变量。在存储方面有以下特点:量。在存储方面有以下特点:l形式参数与实际参数各占独立的存储空间;形式参数与实际参数各占独立的存储空间;l形式参数的存储空间是调用时才分配的;形式参数的存储空间是调用时才分配的;l调
20、用结束时,撤消分配给形式参数的临时存储区;调用结束时,撤消分配给形式参数的临时存储区;l实实际际参参数数可可以以是是常常量量、变变量量、表表达达式式、函函数数等等,无无论论实实际际参参数数是是何何种种类类型型的的量量,在在进进行行函函数数调调用用时时,它它们们都都必必须须具具有有确确定定的的值值,以便把这些值传送给形式参数;以便把这些值传送给形式参数;l实际参数和形式参数的数量、类型、顺序应严格一致;实际参数和形式参数的数量、类型、顺序应严格一致;l函函数数调调用用中中发发生生的的数数据据传传送送是是单单向向的的。即即只只能能把把实实际际参参数数的的值值传传送送给给形形式式参参数数,而而不不能
21、能把把形形式式参参数数的的值值反反向向地地传传送送给给实实际际参参数数。因因此此在在函函数数调调用用过过程程中中,形形式式参参数数的的值值发发生生改改变变,而而实实际际参参数数中中的值不会变化;的值不会变化;【例【例9-6】(见课本)见课本)2 嵌套调用嵌套调用 嵌套调用就是在被调用的函数中再调用其它函数。嵌套调用就是在被调用的函数中再调用其它函数。【例【例9-7】(见课本)见课本)3 递归调用递归调用 直直接接或或间间接接地地调调用用函函数数本本身身。此此时时应应特特别别注注意意递递归归的的结结束束条条件件,仔仔细细推推敲敲它它是是否否真真正正有有效效,必必要要时时可可人人为为设设置置递递归
22、归终终止止条条件件(如控制调用次数如控制调用次数)。【例【例9-8】(见课本)见课本)9.3 变量的作用域变量的作用域 变变量量有有效效的的范范围围称称为为变变量量的的作作用用域域。语语言言中中的的变变量量,按按作作用用域范围可分为两种,域范围可分为两种,即局部变量和全局变量。即局部变量和全局变量。9.3.1 9.3.1 9.3.1 9.3.1 局部变量局部变量局部变量局部变量 局局部部变变量量也也称称为为内内部部变变量量。局局部部变变量量是是在在函函数数内内作作定定义义说说明明的的。其作用域仅限于函数内,离开该函数后再使用这种变量是非法的。其作用域仅限于函数内,离开该函数后再使用这种变量是非
23、法的。【例【例9-9】(见课本)见课本)1 主函数的变量只能用于主函数中主函数的变量只能用于主函数中 主主函函数数中中定定义义的的变变量量也也只只能能在在主主函函数数中中使使用用,不不能能在在其其它它函函数数中中使使用用。同同时时,主主函函数数中中也也不不能能使使用用其其它它函函数数中中定定义义的的变变量量。因因为为主主函函数数也也是是一一个个函函数数,它它与与其其它它函函数数是是平平行行关关系系。这这一一点点是是与与其它语言不同的,应予以注意。其它语言不同的,应予以注意。2形式参数与实际参数范围不同形式参数与实际参数范围不同 形形式式参参数数变变量量是是属属于于被被调调函函数数的的局局部部变
24、变量量,实实际际参参数数变变量量是是属属于主调函数的局部变量。于主调函数的局部变量。3 局部变量可以同名局部变量可以同名 允允许许在在不不同同的的函函数数中中使使用用相相同同的的变变量量名名,它它们们代代表表不不同同的的对对象象,分配不同的单元,互不干扰,也不会发生混淆。分配不同的单元,互不干扰,也不会发生混淆。就是形式参数和实际参数的变量同名也是允许的。就是形式参数和实际参数的变量同名也是允许的。【例【例9-10】(见课本)见课本)9.3.2 9.3.2 9.3.2 9.3.2 全局变量全局变量全局变量全局变量 全全局局变变量量也也称称为为外外部部变变量量。在在一一个个文文件件中中,定定义义
25、在在函函数数之之外外的的变变量量称称为为全全局局变变量量。它它不不属属于于哪哪一一个个函函数数,它它属属于于一一个个源源程程序序文文件件。其其作作用用域域是是:从从定定义义它它的的那那一一点点直直到到文文件件末末尾尾。整整个个源源程程序序。在在函函数数中中使使用用全全局局变变量量,一一般般应应作作全全局局变变量量说说明明。只只有有在在函函数数内内经经过过说说明明的的全全局局变变量量才才能能使使用用。全全局局变变量量的的说说明明符符为为extern。但但 在在一一个个函函数数之之前前定定义义的的全全局局变变量量,在在该该函函数数内内使使用用可可不不再再加加以以说说明。明。外外部部变变量量定定义义
26、必必须须在在所所有有的的函函数数之之外外,且且只只能能定定义义一一次次。其其一一般形式为:般形式为:extern extern 类型说明符类型说明符类型说明符类型说明符 变量名变量名变量名变量名,变量名变量名变量名变量名,.;,.;外外部部变变量量说说明明出出现现在在要要使使用用该该外外部部变变量量的的各各个个函函数数内内。在在整整个个程序内,可能出现多次,外部变量说明的一般形式为:程序内,可能出现多次,外部变量说明的一般形式为:extern extern 类型说明符类型说明符类型说明符类型说明符 变量名,变量名,变量名,变量名,变量名,变量名,变量名,变量名,.;.;全局变量在编译时分配存储
27、空间。全局变量在编译时分配存储空间。1 外部变量的值具有继承性外部变量的值具有继承性 如如果果在在一一个个函函数数中中改改变变了了外外部部变变量量的的值值,则则其其后后引引用用该该变变量量时时,得得到到的的是是改改变变了了的的值值。因因此此,可可以以使使用用外外部部变变量量在在不不同同的的函函数间传递数据。数间传递数据。2 静态外部变量静态外部变量 它它允允许许本本文文件件使使用用的的外外部部变变量量。它它可可以以使使不不同同文文件件之之间间同同名名的外部变量互不干扰。其说明格式为:的外部变量互不干扰。其说明格式为:static static 类型类型类型类型 变量名变量名变量名变量名=初值初
28、值初值初值 初值默认为初值默认为0。3 外部变量在文件内作用范围的扩展外部变量在文件内作用范围的扩展 可以使用可以使用extern命令,把作用范围扩展到从命令,把作用范围扩展到从extern命令开始。命令开始。4 外部变量在文件外的扩张外部变量在文件外的扩张 可可以以把把外外部部变变量量的的作作用用范范围围扩扩展展到到后后来来运运行行的的、有有extern命命令令的文件中。的文件中。5 外部变量的副作用外部变量的副作用 外外部部变变量量建建立立了了函函数数之之间间的的另另外外一一条条数数据据交交换换渠渠道道(正正常常的的渠渠道道是是传传递递参参数数及及得得到到返返回回值值)。这这样样,很很可可
29、能能形形成成某某个个外外部部变变量量与与多多个个函函数数(甚甚至至文文件件)的的关关联联。若若其其中中一一个个模模块块异异常常,都都可可能能引引起起此此外外部部变变量量的的异异常常。而而此此外外部部变变量量的的异异常常,又又会会引引起起其其它它模模块块的的异异常常,造造成成“牵牵一一发发而而动动全全身身”,是是问问题题扩扩大大化化与与复复杂杂化化。这这会会给给程程序序的的调调试试与与运运行行带带来来不不便便。为为避避免免此此问问题题,建建议议尽尽量量使使用静态外部变量,把它控制在你所编写的程序内。用静态外部变量,把它控制在你所编写的程序内。【例【例9-11】(见课本)见课本)【例【例9-12】
30、(见课本)见课本)【例【例9-13】(见课本)见课本)9.4 变量的存储类型变量的存储类型 变变量量是是程程序序中中数数据据的的传传递递者者,变变量量具具有有两两种种属属性性:操操作作属属性性和和存存储储属属性性。操操作作属属性性就就是是指指数数据据类类型型,存存储储属属性性就就是是指指数数据据的的存存储位置与时间。储位置与时间。9.4.1 9.4.1 9.4.1 9.4.1 概说概说概说概说1 变量可用的存储空间变量可用的存储空间 可可以以用用来来存存放放变变量量的的存存储储空空间间是是内内存存和和寄寄存存器器。内内存存大大家家已已经经了了解解。寄寄存存器器是是CPU中中的的一一个个数数据据
31、临临时时存存储储区区,其其容容量量有有限限(一一般般都都比比内内存存小小的的多多),但但系系统统对对寄寄存存器器中中数数据据的的读读写写操操作作的的速速度度则较快。则较快。2 变量生存周期变量生存周期 就就是是变变量量存存在在的的时时期期。根根据据其其存存在在时时期期的的长长短短,可可以以把把变变量量分分为以下两种:为以下两种:(1)(1)静态变量静态变量 在程序执行的整个过程中都存在,并有固定的存储空间。在程序执行的整个过程中都存在,并有固定的存储空间。(2)(2)动态变量动态变量 只在程序执行的一段时间内存在,没有固定的存储空间。只在程序执行的一段时间内存在,没有固定的存储空间。变量按存储
32、方式可分为变量按存储方式可分为“静态存储静态存储”和和“动态存储动态存储”两种。两种。静态存储变量通常是在变量定义时就分定存储单元并一直保持不静态存储变量通常是在变量定义时就分定存储单元并一直保持不变,直至整个程序结束。动态存储变量是在程序执行过程中,使变,直至整个程序结束。动态存储变量是在程序执行过程中,使用它时才分配存储单元,使用完毕立即释放。典型的例子是函数用它时才分配存储单元,使用完毕立即释放。典型的例子是函数的形式参数,在函数定义时并不给形式参数分配存储单元,只是的形式参数,在函数定义时并不给形式参数分配存储单元,只是在函数被调用时,才予以分配,调用函数完毕立即释放。如果一在函数被调
33、用时,才予以分配,调用函数完毕立即释放。如果一个函数被多次调用,则反复地分配、释放形式参数变量的存储单个函数被多次调用,则反复地分配、释放形式参数变量的存储单元。元。静态存储变量是一直存在的,而动态存储变量则时而存在时静态存储变量是一直存在的,而动态存储变量则时而存在时而消失。这种由于变量存储方式不同而产生的特性就是变量的生而消失。这种由于变量存储方式不同而产生的特性就是变量的生存周存周 期。生存周期表示了变量存在的时间。生存期和作用域是从期。生存周期表示了变量存在的时间。生存期和作用域是从时间时间 和空间这两个不同的角度来描述变量的特性,这两者既有联和空间这两个不同的角度来描述变量的特性,这
34、两者既有联系,系,又有区别。又有区别。3 3 变量的可用性变量的可用性 (1)(1)全局可用全局可用 (2)(2)局部可用局部可用9.4.2 9.4.2 9.4.2 9.4.2 动态变量动态变量动态变量动态变量 动态变量可用分为自动变量和寄存器变量两大类。动态变量可用分为自动变量和寄存器变量两大类。1 自动变量自动变量 由由系系统统自自动动建建立立和和撤撤消消的的变变量量。自自动动变变量量用用时时建建、用用完完撤撤。从从使用时间来看,具有招之即来、挥之即去的特点。使用时间来看,具有招之即来、挥之即去的特点。自自动动变变量量在在每每次次使使用用时时才才分分配配存存储储单单元元,用用完完清清除除存
35、存储储单单元元。下下次次用用时时再再分分配配新新的的存存储储单单元元(可可能能不不是是上上次次所所用用的的存存储储单单元元)。从存储空间来看,具有从存储空间来看,具有“打一枪换一个地方打一枪换一个地方”的特点。的特点。(1)(1)定义格式定义格式 自动变量的定义格式如下:自动变量的定义格式如下:auto auto 数据类型数据类型数据类型数据类型 变量名变量名变量名变量名=初始表达式初始表达式初始表达式初始表达式 以上格式中以上格式中内的内容可以省略。以下对格式中的各项加以内的内容可以省略。以下对格式中的各项加以解释:解释:数据类型数据类型 表明变量的数据类型。表明变量的数据类型。量名量名 变
36、量名字,可以与其它程序中变量的名字相同。变量名字,可以与其它程序中变量的名字相同。初始表达式初始表达式 用来给变量赋初值。若不给变量赋初值,则变量的初始不确用来给变量赋初值。若不给变量赋初值,则变量的初始不确定定(初始值取决于分配给此变量的存储单元中存储的当前值初始值取决于分配给此变量的存储单元中存储的当前值)。也。也可以在程序段中用赋值语句来赋给初始值。但是,只能赋给一次可以在程序段中用赋值语句来赋给初始值。但是,只能赋给一次初始值,不可重复。初始值,不可重复。(2)(2)自动变量的局部性自动变量的局部性 自动变量是局部变量,仅仅在定义它的那个局部有效。自动变量是局部变量,仅仅在定义它的那个
37、局部有效。(3)(3)值不继承值不继承 自自动动变变量量的的值值没没有有继继承承性性,也也就就是是说说,函函数数调调用用自自动动变变量量时时,自动变量现有的值不保留,而是以现赋的初始值替代原值。自动变量现有的值不保留,而是以现赋的初始值替代原值。【例【例9-14】(见课本)见课本)【例【例9-15】(见课本)见课本)【例【例9-16】(见课本)见课本)2 寄存器变量寄存器变量 寄寄存存器器变变量量存存放放在在CPU的的寄寄存存器器中中。使使用用时时,不不需需要要访访问问内内存存,而而直直接接从从寄寄存存器器中中读读写写,有有较较高高的的读读写写效效率率。通通常常用用于于循循环环次次数数较多的循
38、环控制变量及循环体内反复使用的变量。较多的循环控制变量及循环体内反复使用的变量。要定义寄存器变量,可采用如下格式:要定义寄存器变量,可采用如下格式:register register 数据类型数据类型数据类型数据类型 变量名变量名变量名变量名=初值表达式初值表达式初值表达式初值表达式 寄寄存存器器变变量量的的性性质质与与自自动动变变量量的的性性质质完完全全相相同同,只只是是放放的的位位置不同。置不同。若若硬硬件件中中闲闲置置的的寄寄存存器器中中不不足足容容纳纳所所定定义义的的寄寄存存器器变变量量,则则系系统自动把寄存器变量转换为自动变量。统自动把寄存器变量转换为自动变量。应应该该把把变变量量按
39、按照照操操作作情情况况排排序序,尽尽量量把把使使用用频频繁繁的的变变量量设设置置为为寄寄存器变量。存器变量。在在实实际际应应用用中中,因因为为机机器器硬硬件件所所限限,寄寄存存器器变变量量使使用用不不是是很很多。多。【例【例9-17】(见课本)见课本)9.4.3 9.4.3 9.4.3 9.4.3 静态变量静态变量静态变量静态变量1 静态变量的定义格式静态变量的定义格式 要定义静态变量,可采用如下格式:要定义静态变量,可采用如下格式:static static 数据类型数据类型数据类型数据类型 变量名变量名变量名变量名=初值表达式初值表达式初值表达式初值表达式 静态变量具有如下特点:静态变量具
40、有如下特点:l静静态态变变量量在在程程序序运运行行期期间间固固定定不不变变。它它在在编编译译时时就就分分配配存存储储空空间间,程序一开始执行就建立,直到程序结束一直存在;程序一开始执行就建立,直到程序结束一直存在;l静态变量的初始化在编译时进行,默认的初始值为静态变量的初始化在编译时进行,默认的初始值为0或或0.0;l只只能能使使用用常常数数或或常常数数表表达达式式赋赋给给初初值值,不不能能用用含含变变量量的的表表达达式式赋赋初值;初值;静态变量可以从其作用域分为静态局部变量和静态全局变量。静态变量可以从其作用域分为静态局部变量和静态全局变量。2 静态局部变量静态局部变量 在局部变量的说明前再
41、加上在局部变量的说明前再加上static说明符就构成静态局部变量。说明符就构成静态局部变量。例如:例如:static int a,b;static int a,b;static float array5=1,2,3,4,5 static float array5=1,2,3,4,5;静态局部变量属于静态存储方式,它具有以下特点。静态局部变量属于静态存储方式,它具有以下特点。(1)(1)生命期为程序运行期生命期为程序运行期 静态局部变量虽然在函数内定义,但不象自动变量那样,当静态局部变量虽然在函数内定义,但不象自动变量那样,当调用时就存在,退出函数时就消失。静态局部变量始终存在着,调用时就存在,
42、退出函数时就消失。静态局部变量始终存在着,也就是说它的生存期为整个源程序运行期。也就是说它的生存期为整个源程序运行期。(2)(2)作用的范围只是定义它的函数内作用的范围只是定义它的函数内 静态局部变量的生存期虽然为整个源程序,但是其作用域仍静态局部变量的生存期虽然为整个源程序,但是其作用域仍与自动变量相同,即只能在定义该变量的函数内使用该变量。退与自动变量相同,即只能在定义该变量的函数内使用该变量。退出该函数后,出该函数后,尽管该变量还继续存在,但不能使用它。尽管该变量还继续存在,但不能使用它。也就是说,静态局部变量只能在本函数中使用,具有也就是说,静态局部变量只能在本函数中使用,具有“从一从
43、一而终而终”的特点。的特点。(3)(3)值可继承值可继承 静态局部变量的值具有可继承性。下次调用时,上次的结果静态局部变量的值具有可继承性。下次调用时,上次的结果值还在。也就是说,只在第一次调用时初始化。当多次调用一个值还在。也就是说,只在第一次调用时初始化。当多次调用一个函数且要求在各次调用之间保留某些变量的值时,可考虑采用静函数且要求在各次调用之间保留某些变量的值时,可考虑采用静态局部变量。虽然用全局变量也可以达到上述目的,但全局变量态局部变量。虽然用全局变量也可以达到上述目的,但全局变量有时会造成意外的副作用,因此仍以采用局部静态变量为宜。有时会造成意外的副作用,因此仍以采用局部静态变量
44、为宜。【例【例9-18】(见课本)见课本)3静态全局变量静态全局变量 全局变量全局变量(外部变量外部变量)的说明之前加上的说明之前加上static就构成了静态的全就构成了静态的全局变量。全局变量与静态全局变量的区别在于:非静态全局变量局变量。全局变量与静态全局变量的区别在于:非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。而静态全局变量则静态的全局变量在各个源文件中都是有效的。而静态全局变量则只在定义该变量的源文件内有效,在同一源程序的其它源文件中只在定义该变量的源文件内有效,
45、在同一源程序的其它源文件中不能使用它,可以避免在其它源文件中引起错误。不能使用它,可以避免在其它源文件中引起错误。9.5 内部函数和外部函数内部函数和外部函数 函数一旦定义后就可被本文件的其它函数调用,但函数能否函数一旦定义后就可被本文件的其它函数调用,但函数能否被其它源文件中的函数调用则取决于函数的性质。从这一角度,被其它源文件中的函数调用则取决于函数的性质。从这一角度,把函数分为内部函数与外部函数。把函数分为内部函数与外部函数。9.5.1 9.5.1 9.5.1 9.5.1 内部函数内部函数内部函数内部函数 在一个源文件中定义的函数只能被本文件中的函数调用,而在一个源文件中定义的函数只能被
46、本文件中的函数调用,而不能被同一源程序其它文件中的函数调用,这种函数称为内部函不能被同一源程序其它文件中的函数调用,这种函数称为内部函数。定义内部函数的一般形式是:数。定义内部函数的一般形式是:static static 类型说明符类型说明符类型说明符类型说明符 函数名函数名函数名函数名(形式参数表形式参数表形式参数表形式参数表)例如:例如:static int f(int a,int b)static int f(int a,int b)内部函数也称为静态函数。但此处静态内部函数也称为静态函数。但此处静态static的含义已不是指的含义已不是指存储方式,而是指对函数的调用范围只局限于本文件。
47、因此在不存储方式,而是指对函数的调用范围只局限于本文件。因此在不同的源文件中定义同名的静态函数不会引起混淆。同的源文件中定义同名的静态函数不会引起混淆。9.5.2 9.5.2 9.5.2 9.5.2 外部函数外部函数外部函数外部函数 外部函数在整个源程序中都有效,其定义的一般形式为:外部函数在整个源程序中都有效,其定义的一般形式为:extern extern 类型说明符类型说明符类型说明符类型说明符 函数名函数名函数名函数名(形式参数表形式参数表形式参数表形式参数表)例如:例如:extern int f(int a,int b)extern int f(int a,int b)如在函数定义中没有说明如在函数定义中没有说明extern或或static则默认为则默认为extern。在一个源文件的函数中调用其它源文件中定义的外部函数时,在一个源文件的函数中调用其它源文件中定义的外部函数时,应用应用extern说明被调函数为外部函数。说明被调函数为外部函数。【例【例9-19】(见课本)见课本)