第5章作用域与存储类型.ppt
第5章 作用域和存储类型,5.1 作用域5.2 变量的存储类型5.3 编译预处理,5.1.1 作用域,作用域是变量在程序中可引用的区域。作用域共分成块作用域、文件作用域、函数声明(原型)作用域、函数作用域、类作用域五种。1块作用域 复合语句是一个块。复合语句中定义的变量,作用域仅在该复合语句中。,5.1.1 作用域,【例5.1】输入两数,按从大到小的顺序保存,并输出结果。#includevoid main()int a,b;/a、b具有函数作用域 coutab;cout=a)int t;/t具有块作用域 t=a;a=b;b=t;/交换a,b的值 couta=atb=bendl;/t已经无效,5.1.1 作用域,2文件作用域 文件作用域也称全局作用域。定义在所有函数之外的变量,具有文件作用域,作用域为从定义处到整个源文件结束。文件中定义的全局变量和函数都具有文件作用域。3函数声明作用域 函数声明不是定义函数,在作函数声明时,其中的形参作用域只在声明中,即作用域结束于右括号。正是由于形参不能被程序的其他地方引用,所以通常只要声明形参个数和类型,形参名可省略。,5.1.1 作用域,4函数作用域 函数中定义的变量,包括形参和函数体中定义的局部变量,作用域都在该函数内,也称作函数域。5类作用域 在介绍类和对象时,可知类作用域是指类定义范围(包括类的声明部分和相应成员函数实现整个范围)。在该范围内,类的成员函数对数据成员有无限访问权限。,5.1.2 局部变量与全局变量,一、局部变量,下列变量是局部变量:1、在一个函数内部定义的变量;2、函数的形式参数;3、在某个复合语句中定义的变量;,float f1(int a)int b,c;Void main()int m,n;,b,c有效,m,n有效,a有效,main()int a,b,c;int d;d=a+b;,d有效,5.1.2 局部变量与全局变量,一、局部变量,说明:、局部变量只在自己范围内有效;2、如果局部变量的有效范围有重叠,则有效范围小的优先;,main()int a,b,c;int c;c=a+b;,局部优先,C有效,二、全局变量,5.1.2 局部变量与全局变量,在函数之外定义的变量(外部变量)是全局变量,全局变量的有效范围是:从定义变量的位置开始到源文件结束,7.7 局部变量与全局变量,二、全局变量,例:编写一个函数实现同时返回10个数的最大和最小值,分析:用一个函数返回两个数据,除了用函数值外,可以借助于全局变量,可见,全局变量可以减少函数的参数,5.1.2 局部变量与全局变量,#include#include#include int min;/全局变量minint find()int max,x;x=rand()%101+100;/产生一个100,200之间的随机数x printf(“%d”,x);max=x;min=x;/设定最大数和最小数 for(int i=1;i max)max=x;/若新产生的随机数大于最大数,则进行替换 if(x min)min=x;/若新产生的随机数小于最小数,则进行替换 return max;,void main()int m=find();printf(“n最大数:%d,最小数:%dn“,max,min);,7.7 局部变量与全局变量,二、全局变量,说明:,、利用全局变量可以在函数间传递参数。、应尽量少用全局变量、如果全局变量与局部变量同名,则局部变量优先,5.1.3 动态变量与静态变量,全局变量和局部变量:变量的作用域,静态存储变量和动态存储变量:变量的存储类别,即生存期,内存中供用户使用的存储空间包括:程序区 静态存储区:编译时分配空间动态存储区:执行时分配空间,变量或函数的属性:,作业:,P90:四、3、4P108:一、2,5.2 变量的存储类别,1、自动类型:存储在动态存储区,用auto说明,如:int func1(int a)auto int b,c=3;,通常auto可以省略,形参a,变量b、c都是自动变量调用该函数时,系统给它们分配存储空间,函数调用结束时自动释放存储空间。,自动类型、寄存器类型的变量属于动态变量;静态类型、外部类型的变量属于静态变量。,5.2 变量的存储类别,1、自动类型:,【例5.5】使用自动变量的示例。#include void main()int x=5,y=10;/自动变量x,y for(int k=1;k=2;k+)auto int m=0,n=0;/自动变量m,n m=m+1;n=n+x+y;printf(m=%dtn=%dn“,m,n);,5.2 变量的存储类别,2、寄存器类型(register),计算机中的寄存器的个数是有限的 寄存器变量对寄存器的占用是动态的 有的系统将寄存器变量转化为自动变量处理,而有的系统会自动设置寄存器变量,5.2 变量的存储类别,3、静态类型(static),静态局部变量属于静态存储类别,在程序整个运行期间都不释放存储空间。静态局部变量在编译时赋初值(仅赋一次值)如果定义静态局部变量时没有赋初值,编译时会自动赋初值 静态局部变量只能在定义它的函数内被引用(它存在但不能被其它函数使用),打印1到5的阶乘,(1)静态局部变量,5.2 变量的存储类别,【例5.6】自动变量与静态局部变量的区别。#include void f()int x=0;/初始化多次,栈中分配、相当于auto int x=0;static int y=3;/静态局部变量,仅初始化一次,静态区分配 x=x+1;y=y+1;printf(“%dt%dn”,x,y);void main()int i;for(i=0;i3;i+)f();,5.2 变量的存储类别,【例5.7】用自动变量与静态局部变量求三个整数的和。#include void f(int x,int y)int m=0;/自动变量 static int n=0;/静态局部变量,此处也可static int n;m=m+x+y;n=n+x+y;printf(m=%dtn=%dn“,m,n);void main()int i=5,j=10,k;for(k=1;k=3;k+)f(i,j);,5.2 变量的存储类别,(2)静态全局变量,在定义全局变量时也加说明符static。程序由一个源程序文件实现,一个全局变量和一个静态全局变量是没区别的。在多文件组成的程序中,一个全局变量和一个静态全局变量在使用上是不同的,其他文件通过外部变量声明可以使用一个全局变量,但却无法使用静态全局变量,静态全局变量只能被定义它的文件所独享。,特点:1)与全局变量基本相同,只是其作用范围(即作用域)是定义它的程序文件,而不是整个程序。(2)静态全局变量属于静态存储类别的变量,所以它在程序一开始运行时,就被分配固定的存储单元,所以其生存期是整个程序运行期间。(3)使用静态全局变量的好处是同一程序的两个不同的源程序文件中可以使用相同名称的变量名,而互不干扰。,5.2 变量的存储类别,(2)静态全局变量,【例5.8】编写一个含两个源程序文件程序(多文件程序见5.4节)。在file2.c文件中定义静态全局变量n,在含有main函数的file1.c文件中又定义全局变量n,分析两者是否有联系?,/file1.c#includeint n;void fn();void main()n=20;printf(“%dn”,n);fn();,/file2.c#include/不能省略static int n;/定义静态全局变量nvoid fn()n=n+1;printf(“%dn”,n);,5.2 变量的存储类别,4、外部类型(extern),定义格式:extern 类型 变量名;在由多个源程序文件组成的程序中,如果一个文件要使用另一个文件中定义的全局变量,这些源程序文件之间通过外部类型的变量进行沟通。在一个文件中定义的全局变量缺省为外部的,即其作用域可以延伸到程序的其他文件中。但其他文件如果要使用这个文件中定义的全局变量,必须在使用前用“extern”作外部声明,外部声明通常放在文件的开头。,5.2 变量的存储类别,4、外部类型(extern),【例5.9】将另一文件中的全局变量a,b定义为本文件外部变量的示例。第一个文件内容如下:,/*文件名:exemple5_9_1.c*/int a=20,b=7;/全局变量a,bint max(int x,int y)return xy?x:y;,第二个文件内容如下:/*文件名:exemple5_9_2.c*/#include extern int a,b;/外部变量a,bextern int max(int x,int y);void main()int c;c=max(a,b);printf(max=%dn“,c);,5.2 存储类别小结,1、变量的定义方法,存储类别 数据类型变量名,2、变量的划分,5.3 编译预处理,C语言提供的预处理功能主要有以下3种:(1)宏定义命令(2)文件包含命令(3)条件编译命令 为了与一般C语句相区别,这些命令以符号“#”开头,而且末尾不包含分号。预处理命令可放在程序开头、中间和末尾,主要由需要而定。习惯上预编译命令都是放在程序的开头。,5.3.1 宏定义,宏定义命令是将一个标识符定义为一个字符串,该标识符被称为宏名,被定义的字符串称为替换文本。宏定义命令有两种格式:简单的宏定义 带参数的宏定义1宏定义的一般形式为:#define 宏名 字符串如:#define PI 3.1415926,注意:(1)#define、宏名和字符串之间一定要有空格。(2)宏名一般用大写字母表示,以区别于普通标识符。(3)宏被定义以后,一般不能再重新定义。但可以用#undef来终止宏定义。(4)一个定义过的宏名可以用来定义其他新的宏,但要注意其中的括号。如:#define A 20#define B(A+10),5.3.1 宏定义,2有带参数的宏定义如:#define MAX(a,b)(a)(b)?(a):(b)如果在程序中出现如下语句:S=MAX(4,6);则被替换为:S=46?4:6;,5.3.2 文件包含命令,所谓“文件包含”是指将另一个源文件的内容合并到当前程序中。文件包含命令的一般形式为:#include#include 文件名 文件名一般是以.h为扩展名,因而称它为“头文件”,将文件名用“”括起来,用来包含那些由C语言系统提供的并放在指定子目录中头文件 将文件名用双引号括起来的,用来包含用户自己定义的放在当前目录或其他目录下的头文件或其他源文件。,5.3.2 文件包含命令,5.3.2 文件包含命令,文件包含中“头文件”是指存放与标准函数相关信息的文件。或者存放着符号常量、类型定义、类和其他复杂类型的定义以及与程序环境相关信息,该文件名的后缀是h文件。头文件有系统提供的,stdio.h是系统提供的有关输入输出操作信息的头文件。头文件也可以由用户根据需要自己编写。注意:1文件包含命令都被放在程序最前端,后面程序对它们的引用。2一条#include命令只能包含一个文件。,