printf(“%d\\n”,f(a)); return 0; }
int f(int a)
{ auto int b=0; static c=3; b=b+1; c=c+1;
return(a+b+c); }
在编译时赋初值 在函数调用时赋初值
例7.16 考察静态局部变量的值。 #include
{ int f(int); int a=2,i; for(i=0;i<3;i++)
printf(“%d\\n”,f(a)); return 0; }
int f(int a)
{ auto int b=0; static c=3; b=b+1; c=c+1;
return(a+b+c); }
若不赋初值,是0 若不赋初值,不确定
例7.16 考察静态局部变量的值。 #include
{ int f(int); int a=2,i; for(i=0;i<3;i++)
printf(“%d\\n”,f(a)); return 0; }
int f(int a)
{ auto int b=0; static c=3; b=b+1; c=c+1;
return(a+b+c); }
仅在本函数内有效
例7.17 输出1到5的阶乘值。
解题思路:可以编一个函数用来进行连乘,如第1次调用时进行1乘1,第2次调用时再乘以2,第3次调用时再乘以3,依此规律进行下去。 #include
{ int fac(int n); int i;
for(i=1;i<=5;i++)
printf(“%d!=%d\\n”,i,fac(i)); return 0; }
int fac(int n) { static int f=1; f=f*n;
return(f); }
若非必要,不要多用静态局部变量 3. 寄存器变量(register变量)
一般情况下,变量(包括静态存储方式和动态存储方式)的值是存放在内存中的 寄存器变量允许将局部变量的值放在CPU中的寄存器中 现在的计算机能够识别使用频繁的变量,从而自动地将这些变量放在寄存器中,而不需要程序设计者指定
7.9.3 全局变量的存储类别
全局变量都是存放在静态存储区中的。因此它们的生存期是固定的,存在于程序的整个运行过程
一般来说,外部变量是在函数的外部定义的全局变量,它的作用域是从变量的定义处开始,到本程序文件的末尾。在此作用域内,全局变量可以为程序中各个函数所引用。 1. 在一个文件内扩展外部变量的作用域
外部变量有效的作用范围只限于定义处到本文件结束。 如果用关键字extern对某变量作“外部变量声明”,则可以从“声明”处起,合法地使用该外部变量
例7.18 调用函数,求3个整数中的大者。
解题思路:用extern声明外部变量,扩展外部变量在程序文件中的作用域。 #include
{ int max( );
extern int A,B,C;
scanf(“%d %d %d”,&A,&B,&C); printf(\ return 0; }
int A ,B ,C; int max( ) { int m;
m=A>B?A:B; if (C>m) m=C; return(m); }
2. 将外部变量的作用域扩展到其他文件
如果一个程序包含两个文件,在两个文件中都要用到同一个外部变量Num,不能分别在两个文件中各自定义一个外部变量Num 应在任一个文件中定义外部变量Num,而在另一文件中用extern对Num作“外部变量声明” 在编译和连接时,系统会由此知道Num有“外部链接”,可以从别处找到已定义的外部变量Num,并将在另一文件中定义的外部变量num的作用域扩展到本文件 例7.19 给定b的值,输入a和m,求a*b和am的值。 解题思路:
分别编写两个文件模块,其中文件file1包含主函数,另一个文件file2包含求am的函数。 在file1文件中定义外部变量A,在file2中用extern声明外部变量A,把A的作用域扩展到file2文件。 文件file1.c: #include
int main() { int power(int);
int b=3,c,d,m; scanf(\ c=A*b;
printf(\ d=power(m);
printf(\ return 0; }
文件file2.c: extern A; int power(int n) { int i,y=1;
for(i=1;i<=n;i++) y*=A; return(y); }
编译和运行包括多个文件的程序,可参考《C程序设计学习辅导》一书的“C语言上机指南”部分
3.将外部变量的作用域限制在本文件中
有时在程序设计中希望某些外部变量只限于被本文件引用。这时可以在定义外部变量时加一个static声明。 file1.c
static int A; int main ( ) {
…… }
file2.c
extern A; void fun (int n) { …… A=A*n; …… }
只能用于本文件 本文件仍然不能用 说明:
不要误认为对外部变量加static声明后才采取静态存储方式,而不加static的是采取动态存储
声明局部变量的存储类型和声明全局变量的存储类型的含义是不同的 对于局部变量来说,声明存储类型的作用是指定变量存储的区域以及由此产生的生存期的问题,而对于全局变量来说,声明存储类型的作用是变量作用域的扩展问题 用static 声明一个变量的作用是:?
(1) 对局部变量用static声明,把它分配在静态存储区,该变量在整个程序执行期间不释放,其所分配的空间始终存在。?
(2) 对全局变量用static声明,则该变量的作用域只限于本文件模块(即被声明的文件中)。 注意:用auto、register、static声明变量时,是在定义变量的基础上加上这些关键字,而不能单独使用。 下面用法不对: int a; ? static a;
编译时会被认为“重新定义”。? 7.9.4 存储类别小结
对一个数据的定义,需要指定两种属性: 数据类型和存储类别,分别使用两个关键字 例如:
static int a; ? auto char c; ? register int d;
可以用extern声明已定义的外部变量 例如: extern b;
静态局部整型变量或静态外部整型变量 自动变量,在函数内定义 寄存器变量,在函数内定义
将已定义的外部变量b的作用域扩展至此
(1)从作用域角度分,有局部变量和全局变量。它们采用的存储类别如下:
按作用域角度分 局部变量 全局变量 自动变量 静态局部变量 寄存器变量 静态外部变量 外部变量
形式参数可以定义为自动变量或寄存器变量
(2)从变量存在的时间区分,有动态存储和静态存储两种类型。静态存储是程序整个运行时间都存在,而动态存储则是在调用函数时临时分配单元 按生存期分 动态存储 静态存储 自动变量 寄存器变量 静态局部变量 外部变量 形式参数 静态外部变量
(3)从变量值存放的位置来区分,可分为: 按变量值存放的位置分 内存中静态存储区 内存中动态存储区 静态局部变量 静态外部变量
自动变量和形式参数 寄存器变量 外部变量
CPU中的寄存器
(4) 关于作用域和生存期的概念
对一个变量的属性可以从两个方面分析:
作用域:如果一个变量在某个文件或函数范围内是有效的,就称该范围为该变量的作用域 生存期:如果一个变量值在某一时刻是存在的,则认为这一时刻属于该变量的生存期 作用域是从空间的角度,生存期是从时间的角度 二者有联系但不是同一回事 int a;
int main( )
{ …f2( );…f1( );… } void f1( ) { auto int b;
… f2( ); … }