版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、第九章第九章 函数函数第九章第九章 函数函数9.1 模块化程序设计与函数模块化程序设计与函数n在在C程序设计中,子程序的作用是用函数来完程序设计中,子程序的作用是用函数来完成的。一个成的。一个C程序一般由多个函数组成,其中必程序一般由多个函数组成,其中必须有一个且仅有一个名为须有一个且仅有一个名为main的主函数,其余的主函数,其余为被为被main函数或其它函数调用的函数,无论函数或其它函数调用的函数,无论main函数位于程序中什么位置,函数位于程序中什么位置, C程序总是从程序总是从main函数开始执行。函数开始执行。main函数可调用其它函数函数可调用其它函数来实现所需的功能。来实现所需的
2、功能。 第九章第九章 函数函数例例9.1定义一个函数,用于求两个数中的大数。定义一个函数,用于求两个数中的大数。main()int max(int n1,int n2); /*声明声明max()函数函数*/ int num,num1,num2; printf(Input two integer numbers:n); scanf(%d,%d,&num1,&num2); num=max(num1,num2); /*调用调用max()函数函数*/ printf(max=%dn, num); int max(int n1,int n2) /*定义定义max()函数函数*/ retur
3、n (n1n2?n1:n2);程序运行情况如下程序运行情况如下:Input two integer numbers: 12 ,34 max=349.1 模块化程序设计与函数模块化程序设计与函数第九章第九章 函数函数例例9.2输出一个文本信息框。输出一个文本信息框。void fun1 ( ) /*定义定义fun1()函数函数*/ printf(* * * * * * * * * * * * * *n); void fun2 ( ) /*定义定义fun2()函数函数*/ printf(* How do you do! *n); main() fun1(); /*调用调用fun1()函数函数*/ f
4、un2(); /*调用调用fun2()函数函数*/ fun1(); /*再次调用再次调用fun1()函数函数*/ 程序运行结果如下:程序运行结果如下: * * * * * * * * * * * * * * * How do you do! * * * * * * * * * * * * * * * 9.1 模块化程序设计与函数模块化程序设计与函数第九章第九章 函数函数9.2 函数的定义与调用函数的定义与调用一、函数的定义一、函数的定义 1无参函数定义的一般形式:无参函数定义的一般形式: 类型名类型名 函数名函数名( ) 声明部分;声明部分; 执行部分;执行部分; 无参函数没有参数,因此,函数
5、首部的无参函数没有参数,因此,函数首部的“参数定义表参数定义表”可以缺省可以缺省(但括号不能缺但括号不能缺省省)。第九章第九章 函数函数 2有参函数定义的一般形式:有参函数定义的一般形式: 类型名类型名 函数名函数名(类型名类型名 参数名参数名1,类型名类型名 参参数名数名2,.,) 说明部分;说明部分; 执行部分;执行部分; 有参函数在其参数定义表中定义了所需有参函数在其参数定义表中定义了所需的每一个参数的类型和名称。每一个参数的每一个参数的类型和名称。每一个参数单独定义,参数定义之间用逗号隔开。单独定义,参数定义之间用逗号隔开。9.2 函数的定义与调用函数的定义与调用一、函数的定义一、函数
6、的定义第九章第九章 函数函数n自定义函数说明部分定义的参数称为形式自定义函数说明部分定义的参数称为形式参数,简称形参。参数,简称形参。n主调函数提供的参数称为实际参数,简称主调函数提供的参数称为实际参数,简称实参。实参。n函数若无返回值,则其首部的类型标识符函数若无返回值,则其首部的类型标识符用用“void”表示。表示。9.2 函数的定义与调用函数的定义与调用一、函数的定义一、函数的定义第九章第九章 函数函数说明:说明:(1) 除除main()函数外,函数名和形参名都是由函数外,函数名和形参名都是由用户命名的标识符,要求符合标识符的命名规则。用户命名的标识符,要求符合标识符的命名规则。(2)
7、函数定义不允许嵌套。在语言中,所有函数定义不允许嵌套。在语言中,所有函数函数(包括主函数包括主函数main( )都是平行的。在一个函都是平行的。在一个函数的函数体内,不能再定义另一个函数,即不能数的函数体内,不能再定义另一个函数,即不能嵌套定义。嵌套定义。(3) 可以定义空函数。所谓空函数,是指既无可以定义空函数。所谓空函数,是指既无参数又无函数体的函数。参数又无函数体的函数。 9.2 函数的定义与调用函数的定义与调用一、函数的定义一、函数的定义第九章第九章 函数函数其一般形式为:其一般形式为:void 函数名函数名( ) (4) 在旧版本的语言中,参数定义表允许放在在旧版本的语言中,参数定义
8、表允许放在函数首部的第二行单独指定。函数首部的第二行单独指定。(5) 当一个源程序由多个函数构成时,必须有当一个源程序由多个函数构成时,必须有一个唯一的一个唯一的main()函数。函数。main()函数在源程序函数在源程序中的位置可以任意,程序的执行总是从中的位置可以任意,程序的执行总是从main()函数开始,最终从函数开始,最终从main()函数结束。函数结束。 9.2 函数的定义与调用函数的定义与调用一、函数的定义一、函数的定义第九章第九章 函数函数1形参与实参的参数传递形参与实参的参数传递形参在函数首部定义,必须是变量形式,形参在函数首部定义,必须是变量形式,只能在该函数体内使用。只能在
9、该函数体内使用。实参在函数调用表达式中提供,可以是实参在函数调用表达式中提供,可以是表达式形式。表达式形式。 函数调用时,主调函数把实参的值复制函数调用时,主调函数把实参的值复制一份,传送给被调用函数的形参变量,从一份,传送给被调用函数的形参变量,从而实现主调函数向被调用函数的参数传递。而实现主调函数向被调用函数的参数传递。 9.2 函数的定义与调用函数的定义与调用二、函数的参数与函数的返回值二、函数的参数与函数的返回值第九章第九章 函数函数9.2 函数的定义与调用函数的定义与调用二、函数的参数与函数的返回值二、函数的参数与函数的返回值例例9.3求两数中值较大的一个数。求两数中值较大的一个数。
10、 int max(int x, int y) if(xy) return x; else return y; main( ) int a, b, c; scanf(“%d%d”,&a,&b); c=max(a,b); printf(“max=%dn”,c); 运行结果:运行结果:23 45max=45第九章第九章 函数函数 关于形参与实参的说明:关于形参与实参的说明: (1) 实参可以是常量、变量、表达式、函数等。无论实实参可以是常量、变量、表达式、函数等。无论实参是何种类型的量,在进行函数调用时,它们都必须具参是何种类型的量,在进行函数调用时,它们都必须具有确定的值,以便把这
11、些值传送给形参。因此,应预先有确定的值,以便把这些值传送给形参。因此,应预先用赋值、输入等方法,使实参获得确定的值。用赋值、输入等方法,使实参获得确定的值。 (2) 形参变量只有在被调用时,才分配存储单元,调形参变量只有在被调用时,才分配存储单元,调用结束后,即刻释放所分配的存储单元。因此,形参只用结束后,即刻释放所分配的存储单元。因此,形参只有在该函数内有效。调用结束,返回主调函数后,则不有在该函数内有效。调用结束,返回主调函数后,则不能再使用该形参变量。能再使用该形参变量。 (3) 实参对形参的数据传送是单向的值传递,即只能实参对形参的数据传送是单向的值传递,即只能把实参的值传送给形参,而
12、不能把形参的值反向地传送把实参的值传送给形参,而不能把形参的值反向地传送给实参。给实参。9.2 函数的定义与调用函数的定义与调用二、函数的参数与函数的返回值二、函数的参数与函数的返回值第九章第九章 函数函数例例9.4分析以下程序能否交换主函数中分析以下程序能否交换主函数中 a 与与 b 的的值。值。void swap(int x, int y) int t; t=x; x=y; y=t; main() int a=10; b=20; swap(a,b); printf(a=%d,b=%dn,a,b); 程序运行结果如下:程序运行结果如下:a=10, b=209.2 函数的定义与调用函数的定义与
13、调用二、函数的参数与函数的返回值二、函数的参数与函数的返回值第九章第九章 函数函数 2函数的返回值与函数类型函数的返回值与函数类型 函数的返回值就是调用函数求得的函数值。函数的返回值就是调用函数求得的函数值。 1)函数返回值与)函数返回值与return语句语句 函数的返回值是通过函数中的函数的返回值是通过函数中的return语句来获语句来获得的。得的。 格式:格式:return 表达式;表达式; 或或 return (表达式表达式); 或或 return ; 功能:返回主调函数,并将功能:返回主调函数,并将“表达式表达式”的值带回的值带回给主调函数。给主调函数。 9.2 函数的定义与调用函数的
14、定义与调用二、函数的参数与函数的返回值二、函数的参数与函数的返回值第九章第九章 函数函数 2)函数类型)函数类型 函数类型就是函数定义首部的类型名所定义的函数类型就是函数定义首部的类型名所定义的类型,也就是函数返回值的类型。因此,在定义类型,也就是函数返回值的类型。因此,在定义函数时,无返回值函数的类型定义为函数时,无返回值函数的类型定义为void,有,有返回值函数的类型应与返回值函数的类型应与return语句中返回值表达语句中返回值表达式的类型一致。式的类型一致。 当有返回值函数的类型定义与当有返回值函数的类型定义与ruturn语句中表语句中表达式的类型不一致时,则以函数类型定义为准。达式的
15、类型不一致时,则以函数类型定义为准。对于数值型数据,系统能自动进行类型转换,否对于数值型数据,系统能自动进行类型转换,否则,按出错处理。如果缺省函数类型定义,则系则,按出错处理。如果缺省函数类型定义,则系统一律按整型处理。统一律按整型处理。9.2 函数的定义与调用函数的定义与调用二、函数的参数与函数的返回值二、函数的参数与函数的返回值第九章第九章 函数函数1函数调用的一般形式函数调用的一般形式函数调用的一般形式为:函数调用的一般形式为:函数名函数名( 实际参数表实际参数表) 调用无参函数时,缺省实际参数表,但圆括调用无参函数时,缺省实际参数表,但圆括号不能省略。号不能省略。实际参数表中的参数可
16、以是常量、变量或表实际参数表中的参数可以是常量、变量或表达式。如果实参不止一个,则相邻实参之间用逗达式。如果实参不止一个,则相邻实参之间用逗号分隔。实参的个数、类型和顺序,应该与被调号分隔。实参的个数、类型和顺序,应该与被调用函数的形参所要求的个数、类型和顺序一致。用函数的形参所要求的个数、类型和顺序一致。 9.2 函数的定义与调用函数的定义与调用三、函数的调用三、函数的调用第九章第九章 函数函数2函数调用的方式函数调用的方式(1)当为)当为void类型时,其调用只能单独类型时,其调用只能单独作为一个语句出现;作为一个语句出现;(2)当函数类型不为)当函数类型不为void型时,函数的型时,函数
17、的调用可以出现在同类型常量可以出现的任调用可以出现在同类型常量可以出现的任何地方,如:表达式,输出表,实参表中何地方,如:表达式,输出表,实参表中等。但不能出现在输入表和形参表中。等。但不能出现在输入表和形参表中。9.2 函数的定义与调用函数的定义与调用三、函数的调用三、函数的调用第九章第九章 函数函数例例9.5求两数中较大数。求两数中较大数。int max(int x, int y) if(xy) return x; else return y;main( ) int a, b, c; scanf(“%d%d”,&a,&b); c=max(a,b); /*printf(“ma
18、x=%dn”,max(a,b);*/ /*调用语句在表达式调用语句在表达式,或输出表中或输出表中*/ printf(“max=%dn”,c);9.2 函数的定义与调用函数的定义与调用三、函数的调用三、函数的调用第九章第九章 函数函数例例9.6求三个数中较大数。求三个数中较大数。int max(int x, int y) if(xy) return x; else return y;main( ) int a, b, c,d; scanf(“%d%d%d”,&a,&b,&c); d=max(max(a,b),c); /*调用语句在实参表中调用语句在实参表中*/ print
19、f(“max=%dn”,d);9.2 函数的定义与调用函数的定义与调用三、函数的调用三、函数的调用第九章第九章 函数函数 3对被调用函数的声明对被调用函数的声明 1)对被调用函数的声明对被调用函数的声明 C程序中的一个函数要调用另一个函数时必须程序中的一个函数要调用另一个函数时必须具备以下两个条件:具备以下两个条件: a)被调用函数已经存在。若是库函数,系统已被调用函数已经存在。若是库函数,系统已经定义,否则需要用户自己定义。经定义,否则需要用户自己定义。 b)在主调函数中对被调用函数先声明,然后才在主调函数中对被调用函数先声明,然后才能调用。能调用。9.2 函数的定义与调用函数的定义与调用三
20、、函数的调用三、函数的调用第九章第九章 函数函数 2)函数的声明方式函数的声明方式 类型声明的一般形式为:类型声明的一般形式为: 类型名类型名 函数名函数名(类型名,类型名类型名,类型名); 类型名类型名 函数名函数名(类型名类型名 参数名参数名 ,类型名,类型名 参参数名数名2); 其中,参数的其中,参数的“参数名参数名”可以缺省。可以缺省。函数原型与函数定义的首部是一致的,各参函数原型与函数定义的首部是一致的,各参数的顺序也必须与函数首部定义的一致。但函数的顺序也必须与函数首部定义的一致。但函数声明是单独作为一条说明语句,因此其末尾数声明是单独作为一条说明语句,因此其末尾必须有分号必须有分
21、号(;)。9.2 函数的定义与调用函数的定义与调用三、函数的调用三、函数的调用第九章第九章 函数函数说明:说明:(1)语言规定,在以下三种情况下,可以省去语言规定,在以下三种情况下,可以省去对被调用函数的声明:对被调用函数的声明: 如果函数的值是整型或字符型,可以不必声如果函数的值是整型或字符型,可以不必声明。明。 当对被调用函数的定义出现在主调函数之前时,当对被调用函数的定义出现在主调函数之前时,可以缺省对被调用函数的声明。可以缺省对被调用函数的声明。 如果在所有函数定义之前,在函数外部如果在所有函数定义之前,在函数外部(例如例如源文件开始处源文件开始处)预先对各个被调用函数进行了声预先对各
22、个被调用函数进行了声明,则在主调函数中可缺省对被调用函数的声明,则在主调函数中可缺省对被调用函数的声明。明。9.2 函数的定义与调用函数的定义与调用三、函数的调用三、函数的调用第九章第九章 函数函数 (2) 函数定义和函数声明是两个不同的概念。函数定义和函数声明是两个不同的概念。 函数定义是对函数功能的确立,包括定义函函数定义是对函数功能的确立,包括定义函数名、函数值的类型、函数参数及其函数体等,数名、函数值的类型、函数参数及其函数体等,它是一个完整的、独立的函数单位。在一个程它是一个完整的、独立的函数单位。在一个程序中,一个函数只能被定义一次,而且是在其序中,一个函数只能被定义一次,而且是在
23、其他任何函数之外进行的。他任何函数之外进行的。 函数声明则是把函数的名称、函数值的类型、函数声明则是把函数的名称、函数值的类型、参数的个数、类型和顺序通知编译系统,以便参数的个数、类型和顺序通知编译系统,以便在调用该函数时系统对函数名称正确与否、参在调用该函数时系统对函数名称正确与否、参数的类型、个数及顺序是否一致等进行对照检数的类型、个数及顺序是否一致等进行对照检查。查。 9.2 函数的定义与调用函数的定义与调用三、函数的调用三、函数的调用第九章第九章 函数函数 (3) 对库函数的调用不需要声明,但必须对库函数的调用不需要声明,但必须把该库函数的头文件用把该库函数的头文件用 #include
24、 命令包命令包含在源文件开始处。含在源文件开始处。9.2 函数的定义与调用函数的定义与调用三、函数的调用三、函数的调用第九章第九章 函数函数例例9.7由键盘输入三个整数,输出绝对值最大者由键盘输入三个整数,输出绝对值最大者#include “math.h”main( ) int a, b, c, max; scanf(“%d,%d,%d”,&a,&b,&c); max=find(a,b,c); printf(“max=%dn”,max); find( int x, int y, int z ) int max; max=x; if( abs(max) abs(y) )
25、max=y; if( abs(max) abs(z) ) max=z; return max; 运行结果:运行结果:12,34,9max=349.2 函数的定义与调用函数的定义与调用三、函数的调用三、函数的调用第九章第九章 函数函数例例9.8编写程序,计算编写程序,计算1!2!3!10!的值。的值。程序如下:程序如下:long fact(int n) int i; long s=1; for (i=1; i=n; i) s=s*i; return s; main( ) long s=0; int k,n; printf(“Input a number:”); scanf(%d,&n);
26、 for (k=1; k= e ) pi=pit; n=n2; s=s; t=s/n; return pi*4;运行结果运行结果:pi=3.1415949.2 函数的定义与调用函数的定义与调用三、函数的调用三、函数的调用第九章第九章 函数函数例例9.10求求100200之间的全部素数之和之间的全部素数之和#include “math.h”main( ) int m, s=0; for(m=101; m200; m=2) s=sum(m); printf(“s=%dn”,s); sum(int m ) int i, k; k=sqrt(m); for( i=2; i=k; i) if(m%i=0
27、) return 0; return m; 运行结果如下:运行结果如下:s=31679.2 函数的定义与调用函数的定义与调用三、函数的调用三、函数的调用第九章第九章 函数函数1函数的嵌套调用函数的嵌套调用在一个函数的执行过程中又调用另一个函数在一个函数的执行过程中又调用另一个函数的调用方式称为函数的嵌套调用。的调用方式称为函数的嵌套调用。2说明说明(1) C语言不允许函数嵌套定义,但允许在一语言不允许函数嵌套定义,但允许在一个函数的函数体中出现对另一个函数的调用。个函数的函数体中出现对另一个函数的调用。所谓函数的嵌套调用,是指在执行被调用函数所谓函数的嵌套调用,是指在执行被调用函数时,被调用函
28、数又调用了其他函数。时,被调用函数又调用了其他函数。 9.3 函数的嵌套调用与递归调用函数的嵌套调用与递归调用一、函数的嵌套调用一、函数的嵌套调用第九章第九章 函数函数调用调用f2()函数函数后续语句后续语句main( )函数函数调用调用f1()函数后函数后续语句续语句结束结束f1函数函数返回返回f2函数函数返回返回9.3 函数的嵌套调用与递归调用函数的嵌套调用与递归调用一、函数的嵌套调用一、函数的嵌套调用(2) 图中表示了两层嵌套的情形。其执行过程是:执行图中表示了两层嵌套的情形。其执行过程是:执行main()函数中调用函数中调用f1()函数的语句时,即转去执行函数的语句时,即转去执行f1(
29、)函数;函数;在在f1()函数中调用函数中调用f2()函数时,又转去执行函数时,又转去执行f2()函数;函数;f2()函函数执行完毕,返回数执行完毕,返回f1()函数的断点,继续执行其后续语句;函数的断点,继续执行其后续语句;f1()函数执行完毕,返回函数执行完毕,返回main()函数的断点,继续执行后续函数的断点,继续执行后续语句。语句。第九章第九章 函数函数例例9.11求求1!2!3!4!.20! main() float sum(int); float add; add=sum(20); printf(“add=%e”,add);float sum(int n) float fac(in
30、t); int i; float s=0; for(i=1;i=n;i) s=fact(i); return s;float fac(int i) float t=1; int n=1; do t=t*n; n;while(n1) c=fac(n1)*n; else f=1; return f; main() int n; long y;printf(“Input a integer number: ”); scanf(“%d”,&n); y=fac(n); printf(%d!=%ldn,n,y);程序运行情况如下:程序运行情况如下:Input a integer number:5
31、5!=1209.3 函数的嵌套调用与递归调用函数的嵌套调用与递归调用二、函数的递归调用二、函数的递归调用第九章第九章 函数函数 说明说明 (1) 递归函数既是主调函数,同时又是被调用函递归函数既是主调函数,同时又是被调用函数。执行递归函数将反复调用其自身,每调用数。执行递归函数将反复调用其自身,每调用一次就进入新的一层。下图中,函数一次就进入新的一层。下图中,函数f()为直接为直接递归函数,函数递归函数,函数f1()和函数和函数f2()为间接递归函数。为间接递归函数。调用调用f函数函数调用调用f2函数函数f函数函数f1函数函数f2函数函数调用调用f1函数函数9.3 函数的嵌套调用与递归调用函数
32、的嵌套调用与递归调用二、函数的递归调用二、函数的递归调用第九章第九章 函数函数(2) 如果递归函数无休止地调用其自身,这当然如果递归函数无休止地调用其自身,这当然是不正确的。为了防止递归调用无终止地进行,是不正确的。为了防止递归调用无终止地进行,必须在函数内有终止递归调用的手段。常用的必须在函数内有终止递归调用的手段。常用的办法是加条件判断,满足某种条件后就不再作办法是加条件判断,满足某种条件后就不再作递归调用,然后逐层返回。这个条件称为递归递归调用,然后逐层返回。这个条件称为递归结束条件。结束条件。(3) 递归算法一般也可以用递归算法一般也可以用“递推递推”的循环结构的循环结构来代替。也可以
33、用递推法编程。递推法比递归来代替。也可以用递推法编程。递推法比递归法更容易理解和实现。但是有些问题只能用递法更容易理解和实现。但是有些问题只能用递归算法才能实现。归算法才能实现。 9.3 函数的嵌套调用与递归调用函数的嵌套调用与递归调用二、函数的递归调用二、函数的递归调用第九章第九章 函数函数例例9.13用递归法将十进制整数转换为二进制整数。用递归法将十进制整数转换为二进制整数。void fun(int n) if (n/2) fun(n/2); printf(%d,n%2); main() int a; printf(Input a integer number:); scanf(“%d”,
34、&a); fun(a); printf(n); 程序运行情况如下程序运行情况如下:Input a integer number::345 1010110019.3 函数的嵌套调用与递归调用函数的嵌套调用与递归调用二、函数的递归调用二、函数的递归调用第九章第九章 函数函数1局部变量的概念和定义局部变量的概念和定义在一个函数在一个函数(包括包括main()函数函数)内部或复合句内内部或复合句内部定义的变量称为局部变量。部定义的变量称为局部变量。函数的形参属于局部变量。局部变量只在该函数的形参属于局部变量。局部变量只在该函数范围内或该复合句范围内有效。函数范围内或该复合句范围内有效。2说明说
35、明(1) 主函数主函数main()中定义的局部变量,只能在主中定义的局部变量,只能在主函数中使用,其他函数不能使用。同时,主函函数中使用,其他函数不能使用。同时,主函数中也不能使用其他函数中定义的局部变量。数中也不能使用其他函数中定义的局部变量。因为主函数也是一个函数,与其他函数是平行因为主函数也是一个函数,与其他函数是平行关系。关系。9.4 变量的作用域变量的作用域一、局部变量一、局部变量第九章第九章 函数函数9.4 变量的作用域变量的作用域一、局部变量一、局部变量int f1(int x) int y,z; main()int x,y;int z;z=x+y;.f1内部内部,x,y,z作用
36、域作用域z 的作用域的作用域main中中x,y的作用域的作用域第九章第九章 函数函数 (2) 形参变量也是局部变量,属于被调用函数;形参变量也是局部变量,属于被调用函数;实参变量则是主调函数的局部变量。实参变量则是主调函数的局部变量。 (3) C语言允许在不同的函数中使用相同的变量语言允许在不同的函数中使用相同的变量名,它们代表不同的对象,分配不同的存储单元,名,它们代表不同的对象,分配不同的存储单元,互不干扰,也不会发生混淆。互不干扰,也不会发生混淆。 (4) 在复合句中也可定义变量,其作用域只在复在复合句中也可定义变量,其作用域只在复合句范围内。合句范围内。 9.4 变量的作用域变量的作用
37、域一、局部变量一、局部变量第九章第九章 函数函数1全局变量的概念和定义全局变量的概念和定义在函数外部定义的变量称为全局变量。全局在函数外部定义的变量称为全局变量。全局变量不属于任何一个函数,其作用域是:从全局变量不属于任何一个函数,其作用域是:从全局变量的定义位置开始,到本源文件结束为止。全变量的定义位置开始,到本源文件结束为止。全局变量可被作用域内的所有函数直接引用。局变量可被作用域内的所有函数直接引用。 9.4 变量的作用域变量的作用域二、全局变量二、全局变量int p=1,q=5;int f1(int x) int y,z; char c1,c2;main() int x,y;c1,c2
38、的作用域的作用域p,q 的作用域的作用域第九章第九章 函数函数2说明说明(1) 全局变量可加强函数模块之间的数据联系,全局变量可加强函数模块之间的数据联系,但又使这些函数依赖于这些全局变量,因而使但又使这些函数依赖于这些全局变量,因而使得这些函数的独立性降低。从模块化程序设计得这些函数的独立性降低。从模块化程序设计的观点来看,这是不利的,因此不是非用不可的观点来看,这是不利的,因此不是非用不可时,不提倡使用全局变量。时,不提倡使用全局变量。(2) 在同一源文件中,允许全局变量和内部变量在同一源文件中,允许全局变量和内部变量同名。同名时在内部变量的作用域内,全局变同名。同名时在内部变量的作用域内
39、,全局变量将被屏蔽而不起作用。量将被屏蔽而不起作用。9.4 变量的作用域变量的作用域二、全局变量二、全局变量第九章第九章 函数函数例例9.14全局变量与内部变量同名举例。全局变量与内部变量同名举例。int a=3,b=5;int max(int a,int b) int c; c=ab?a:b; return c; main() int a=8; printf(“max=%dn”,max(a,b); 程序运行结果如下:程序运行结果如下: max=89.4 变量的作用域变量的作用域二、全局变量二、全局变量第九章第九章 函数函数(3) 全局变量的作用域是从定义点开始到全局变量的作用域是从定义点开始
40、到本源文件结束为止的。如果定义点之前的本源文件结束为止的。如果定义点之前的函数需要引用这些全局变量,则需要在函函数需要引用这些全局变量,则需要在函数内对被引用的全局变量进行声明。数内对被引用的全局变量进行声明。全局变量声明的一般形式为全局变量声明的一般形式为 extern 类型名类型名 全局变量全局变量1 ,全局变量全局变量2;9.4 变量的作用域变量的作用域二、全局变量二、全局变量第九章第九章 函数函数n存储类型是指变量在内存中存储的方式。各存储类型是指变量在内存中存储的方式。各种变量的作用域不同,就其本质来说是因为变种变量的作用域不同,就其本质来说是因为变量的存储类型不同。量的存储类型不同
41、。n变量的存储类型分为静态存储和动态存储两变量的存储类型分为静态存储和动态存储两大类。大类。n静态存储变量通常是在变量定义时就分配存静态存储变量通常是在变量定义时就分配存储单元,并一直保持不释放,直至整个程序运储单元,并一直保持不释放,直至整个程序运行结束才释放。行结束才释放。 n动态存储变量是在程序执行过程中,使用它动态存储变量是在程序执行过程中,使用它时才分配存储单元,使用完毕立即释放。时才分配存储单元,使用完毕立即释放。 9.5 变量的存储类别变量的存储类别一、动态存储与静态存储的概念一、动态存储与静态存储的概念第九章第九章 函数函数n对变量的存储类型定义有以下四种:自动变量(auto)
42、、寄存器变量(register)、全局变量(extern)和静态内部变量(static)。n自动变量和寄存器变量属于动态存储方式,全局变量和静态内部变量属于静态存储方式。 9.5 变量的存储类别变量的存储类别一、动态存储与静态存储的概念一、动态存储与静态存储的概念第九章第九章 函数函数1静态存储静态存储静态局部变量静态局部变量静态局部变量的定义格式如下:静态局部变量的定义格式如下: static 数据类型数据类型 局部变量表;局部变量表;存储特点:存储特点:(1) 静态局部变量属于静态存储,是在编译时为其分配存静态局部变量属于静态存储,是在编译时为其分配存储单元的,其生存期为整个程序执行期间。
43、在程序执行储单元的,其生存期为整个程序执行期间。在程序执行过程中,即使所在函数被调用结束也不释放,一直存在。过程中,即使所在函数被调用结束也不释放,一直存在。但其他函数不能引用它们。但其他函数不能引用它们。(2) 静态局部变量是在编译时赋初值的,若定义而不初始静态局部变量是在编译时赋初值的,若定义而不初始化,则自动赋以化,则自动赋以0。每次调用静态局部变量所在的函数时,。每次调用静态局部变量所在的函数时,不再重新赋初值,只是保留上次调用结束时的值,如下不再重新赋初值,只是保留上次调用结束时的值,如下例所示。例所示。9.5 变量的存储类别变量的存储类别二、局部变量的存储方式二、局部变量的存储方式
44、第九章第九章 函数函数例例9.15void f(int c) int a=0; static int b=0; a;b; printf(“%d: a=%d,b=%dn”,c,a,b);main() int i; for( i=1; i=2; i) f (i ); 9.5 变量的存储类别变量的存储类别二、局部变量的存储方式二、局部变量的存储方式第九章第九章 函数函数说明:说明:(1)当需要保留函数上一次调用结束时的值时,应当需要保留函数上一次调用结束时的值时,应使用静态局部变量,使用静态局部变量,(2)当变量定义并初始化后只被引用而不改变其值当变量定义并初始化后只被引用而不改变其值时也可以使用静
45、态局部变量,以避免每次调用时也可以使用静态局部变量,以避免每次调用时重新赋值。时重新赋值。(3) 由于静态局部变量的作用域与生存期不一致,由于静态局部变量的作用域与生存期不一致,降低了程序的可读性,因此,除非对程序的执降低了程序的可读性,因此,除非对程序的执行效率有很大提高外,一般不提倡使用静态变行效率有很大提高外,一般不提倡使用静态变量。量。9.5 变量的存储类别变量的存储类别二、局部变量的存储方式二、局部变量的存储方式第九章第九章 函数函数2动态存储动态存储自动局部变量自动局部变量(又称自动变量又称自动变量)自动变量的定义格式如下:自动变量的定义格式如下: auto 数据类型数据类型 自动
46、变量表;自动变量表; 存储特点:存储特点:(1) 自动变量属于动态存储方式。是在函数被调自动变量属于动态存储方式。是在函数被调用时为其分配存储单元的,其生存期为函数被调用时为其分配存储单元的,其生存期为函数被调用期间,调用结束就释放。函数的形参也属于此用期间,调用结束就释放。函数的形参也属于此类变量。类变量。在复合语句中定义的自动变量,其生存期为在复合语句中定义的自动变量,其生存期为该复合句被执行期间。该复合句被执行期间。9.5 变量的存储类别变量的存储类别二、局部变量的存储方式二、局部变量的存储方式第九章第九章 函数函数(2) 定义而不初始化时,自动变量的值是不确定定义而不初始化时,自动变量
47、的值是不确定的。如果定义并初始化,则赋初值操作是在函的。如果定义并初始化,则赋初值操作是在函数被调用时进行的,且每次调用都要重新赋一数被调用时进行的,且每次调用都要重新赋一次初值。次初值。(3) 由于自动变量的作用域和生存期都局限于定由于自动变量的作用域和生存期都局限于定义它的个体内义它的个体内(函数或复合句函数或复合句),因此,不同的,因此,不同的个体中允许使用同名的变量而不会混淆。即使个体中允许使用同名的变量而不会混淆。即使在函数内定义的自动变量,也可与该函数内部在函数内定义的自动变量,也可与该函数内部的复合句中定义的自动变量同名。的复合句中定义的自动变量同名。注意注意:系统不会混淆,并不
48、意味着人也不会混淆,:系统不会混淆,并不意味着人也不会混淆,所以尽量少用同名自动变量。所以尽量少用同名自动变量。 9.5 变量的存储类别变量的存储类别二、局部变量的存储方式二、局部变量的存储方式第九章第九章 函数函数3寄存器存储寄存器存储寄存器变量寄存器变量一般情况下,变量的值都是存储在内存中的。一般情况下,变量的值都是存储在内存中的。为提高执行效率,语言允许将内部变量的值存为提高执行效率,语言允许将内部变量的值存放到寄存器中,这种变量称为寄存器变量。放到寄存器中,这种变量称为寄存器变量。定义格式如下:定义格式如下: register 数据类型数据类型 变量表;变量表;说明:说明:(1)只有内
49、部变量和形参变量才能定义为寄存器只有内部变量和形参变量才能定义为寄存器变量,全局变量则不行。变量,全局变量则不行。 9.5 变量的存储类别变量的存储类别二、局部变量的存储方式二、局部变量的存储方式第九章第九章 函数函数(2)对寄存器变量的实际处理,随系统而异。对寄存器变量的实际处理,随系统而异。(3)允许使用的寄存器数目是有限的,不能允许使用的寄存器数目是有限的,不能定义任意多个寄存器变量。一般将函数中定义任意多个寄存器变量。一般将函数中使用频率最高的变量定义为寄存器变量,使用频率最高的变量定义为寄存器变量,以此提高程序的执行效率。以此提高程序的执行效率。9.5 变量的存储类别变量的存储类别二
50、、局部变量的存储方式二、局部变量的存储方式第九章第九章 函数函数全局变量分为两种:全局变量分为两种:静态全局变量:静态全局变量:只允许被本源文件中的函数引用。只允许被本源文件中的函数引用。定义格式:定义格式:static 数据类型数据类型 全局变量表;全局变量表;非静态全局变量:非静态全局变量:允许被其他源文件中的函数引用。允许被其他源文件中的函数引用。定义时缺省定义时缺省static关键字的全局变量,即为非静态全局关键字的全局变量,即为非静态全局变量。其他源文件中的函数引用非静态全局变量时,需变量。其他源文件中的函数引用非静态全局变量时,需要在引用函数所在的源文件中进行如下声明:要在引用函数所在的源文件中进行如下声明: extern 数据类型数据类型 全局变量表;全局变量表; 在函数内的在函数内的extern变量声明,表示引用本源文件中的变量声明,表示引用本源文件中的全局变量,而函数外全局变量,而函数外(通常在文件开头通常在文件开头)的的extern变
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 绿色无公害虫害防治技术手册
- 快递分拣与配送服务手册
- 原材料采购与质量控制手册
- 农业试验作物生长动态监测工作手册
- 汽车发动机缸盖加工工艺与质量手册
- 叉车制动系统检查调试安全操作工作手册
- 销售岗位绩效管理规范执行手册
- 公交运营与调度管理手册
- 期末练习(试题)-六年级上册数学人教版 (二)
- 2027年四川省达州市高职单招职业技能考试模拟试卷及参考答案详解【培优A卷】
- 国家职业技术技能标准 4-03-02-06 营养配餐员 人社厅发202226号
- 2024年广西电力行业职工职业技能大赛(电力交易员赛项)理论考试题库-上(单选题)
- 小岛经济学(中文版)
- 2024版人教版英语初一上单词表
- 《浙江省建筑垃圾资源化利用技术导则》
- 装饰装修工程拟投入的主要施工机械设备表
- 高中伴随状语解析
- 智库咨询报告框架
- 新能源材料与器件PPT完整全套教学课件
- 2内经选读上古天真论
- GB/T 18589-2001焦化产品蒸馏试验的气压补正方法
评论
0/150
提交评论