1、变量的作用域与生存期,作用域与生存期概述 变量的作用域(空间特性) 变量的作用域也称为可见性,指变量能够被访问的范围 分为局部变量和全局变量两类:局部变量的范围较窄,限定在程序中的部分区域;全局变量的范围较宽,可以是整个文件甚至是整个程序 变量的存储类别(时间特性) 除作用域(可见性)外的另外两个特性:变量存放在计算机何处,变量何时存在 存储类别 变量存在的位置:RAM 或 CPU寄存器 RAM 划分:代码区、静态存储区、动态存储区 存储类别:RAM:static、auto,CPU:register,void sub() int a,b;a = 6;b = 7;printf(“sub:a=%d
2、,b=%dn“,a,b); void main() int a,b;a = 3;b = 4;printf(“main:a=%d,b=%dn“,a,b);sub();printf(“main:a=%d,b=%dn“,a,b); ,#define N 5 void main() int i;int aN = 1,2,3,4,5;for(i=0;iN/2;i+) int temp;temp = ai;ai = aN-i-1;aN-i-1 = temp;for(i = 0;i N;i+)printf(“%d “,ai); ,例 不同函数中同名变量,例 复合语句中变量,运行结果:5 4 3 2 1,运行
3、结果: main:a=3,b=4 sub:a=6,b=7 main:a=3,b=4,自动变量 ( auto ) 格式:auto 类型 变量名列表; auto 可省略auto int a; 等价于 int a; 自动变量的生存期:自动变量存在于 RAM 中的动态存储区“栈”,并且仅当定义它的函数或复合语句被执行时,才创建该变量,执行结束后该变量自动被删除掉,释放占用的内存空间。 自动变量用的最多,不会永久占用内存空间。,寄存器变量 格式:register 类型 变量名列表;for(register int a=0; a1000000; a+) 寄存器变量存在于 cpu 内部的寄存器中,数量很少,
4、一般是将循环使用很多次的变量放在寄存器中,加快执行速度。 注意: 只有整型变量能放在寄存器中,包括:int、char、short、long等。 寄存器变量必须是 auto 类型的局部变量、形参,不能是全局变量或静态变量。由于寄存器数量很少,不能保证定义的寄存器变量总是能分配到寄存器,这时作为普通变量。 对于寄存器变量,不能做取地址( & )运算。,例 使用寄存器变量,int fac(int n) register int i, f = 1;for(i = 1;i = n;i+)f = f*i;return(f); void main() int i;for(i = 1;i = 1000;i+)
5、printf(“%d!=%dn”,i,fac(i); ,1、只有局部自动变量和 形式参数可以作为寄存器 变量 2、不能定义任意多个寄 存器变量 3、局部静态变量不能定义 为寄存器变量,静态内部变量 格式:static 类型 变量名列表;static int a; 形参不能是定义成 static。 内部变量定义成 static 后,作用域不变,但生存期变长,在整个程序执行前就存在,直到程序结束才清除掉,其生存期为整个程序的运行期。 使用注意: 静态变量只初始化一次。 静态变量的值具有“记忆”性。 尽管生存期变长,但作用域(可见性)仍然局限在定义它的局部范围内。,void main() int i
6、;for(i=0;i 3;i+)inc1();for(i=0;i 3;i+)inc2(); ,例 静态内部变量的生存期,#include void inc1() int x=0;x+;printf(“in inc1 x=%dn“,x); void inc2() static int x=0;x+;printf(“in inc2 x=%dn“,x); ,运行结果: in inc1 x=1 in inc1 x=1 in inc1 x=1 in inc2 x=1 in inc2 x=2 in inc2 x=3,外部变量-全局变量 定义:在函数外定义,可为本文件所有函数共用 作用域:从定义变量的位置开
7、始到本源文件结束,及有extern说明的其它源文件 生存期:整个程序运行期间,! 应尽量少使用全局变量,因为: 全局变量在程序全部执行过程中占用存储单元 降低了函数的通用性、可靠性,可移植性 降低程序清晰性,容易出错,定义 说明 次数: 只能1次 可说明多次 位置: 所有函数之外 函数内或函数外 分配内存: 分配内存,可初始化 不分配内存,不可初始化,用 extern 声明外部变量:extern 数据类型 变量表;,外部变量定义与外部变量说明(声明)不同,若外部变量与局部变量同名,则外部变量被屏蔽,外部变量可用存储类型:缺省 或 static,/*ch7_17.c*/ int a = 3, b
8、 = 5; int max(int a, int b) int c;c=ab?a:b;return(c); void main() int a = 8;printf(“max=%d“,max(a,b); ,例 外部变量与局部变量(同名的局部变量屏蔽外部变量),运行结果:max=8,float max, min; float average(float array, int n) int i; float sum = array0;max = min = array0;for (i=1; i max ) max = arrayi;else if( arrayi min) min = arrayi
9、;sum += arrayi;return (sum/n); void main() int i; float ave,score10;/*Input data to score 省略*/ ave = average(score,10);printf(“max=%6.2fnmin=%6.2fnaverage=%6.2fn“,max,min,ave); ,外部变量增加了函数间数据联系的渠道,extern char c1,c2;,extern char c1,c2;,用 extern 声明外部变量可以扩展外部变量的作用域,int add(int x,int y) int z;z=x+y;retur
10、n z; void main() extern int a,b;printf(“a+b=%dn“,add(a,b); int a=3, b=4;,例 用extern扩展外部变量作用域,运行结果: a+b=7,例 用extern将变量的作用域扩展到其它文件中,int x=10,y=10; extern void sub(); void add(void) int y =5;y = 10+x;x *= 2;printf(“add:y=%d:“,y); void main() x+=5;add();sub();printf(“main:x=%d,main:y=%dn“,x,y); ,extern i
11、nt x; void sub() int y=5;x -= y;printf(“sub:y=%d;“,y); ,file1.c,file2.c,运行结果: add:y=25;sub:y=5; main:x=25;main:y=10;,static int x=10; void add2() extern int y;x+=10;y+=2;printf(“in add2 x=%dn“,x); ,例 static 型外部变量的作用域受到限制,限制在本文件内使用,运行结果: in add1 x=4 in add2 x=20 in add1 x=6 in add2 x=30 x=6;y=13,stat
12、ic int x=2; int y=3; extern void add2(); void add1(); void main()add1();add2();add1();add2();printf(“x=%d;y=%dn“,x,y); void add1() x+=2;y+=3;printf(“in adda x=%dn“,x); ,int i; void main() void prt();for(i = 0;i 5;i+)prt(); void prt() for(i = 0;i 5;i+)printf(“%c”,*);printf(“n”); ,例 外部变量副作用,运行结果:*,例 文件file1.c int a; void main( ) .f2; .f1;. f1( ) auto int b;f2; f2( ) static int c; ,变量存储类型,局部变量默认为auto型 register型变量个数受限,且不能为long, double, float型 局部static变量具有全局寿命和局部可见性 局部static变量具有可继承性 extern不是变量定义,可扩展外部变量作用域,