一、静态储存方式与动态储存方式
1、静态储存
a)全局变量全部存储在静态储存区中,在程序开始运行时给全局变量分配存储区,程序执行完毕就释放。
2、动态储存
a)函数形式参数
b)自动变量(未加static声明的局部变量)
c)函数调用时的现场保护和返回地址等
二、四种储存方法
1、auto变量
函数中的局部变量,如不专门声明为static储存类型,都是动态地分配储存空间的,数据储存在动态储存区中。
2、static声明局部变量
static声明的局部变量的值在函数调用结束后不消失而保留原值,即其占用的储存单元不释放,在下一次改函数调用时,改变量已有值,就是上一次函数调用结束时的值。
#include<stdio.h>
void f( int a){
auto int b=0;
static int c=3;
b+=1;
c+=1;
return (a+b+c);
}
void main(){
int a=2,i;
for(i=0;i<3;i++)
printf("%d ",f(a));
}
运行结果为 7 8 9
c只有第一次的定义初始化有效,后面的无效,都是保留了原值。
说明:
a)静态局部变量属于静态储存类型,在静态储存区内分配储存单元。
b)对静态局部变量是在编译时赋初值一次,在程序运行时它已有初值。
c)如在定义局部变量是不赋初值的话,则对静态局部变量来说,编译时自动赋初值0或者空字符。
d)虽然静态局部变量在函数调用结束后任然存在,单其他函数是不能引用它的。
在什么情况下需要有那个局部静态变量
a)需要保留函数上一次调用结束的值。
b)如果初始化后,变量只被引用而不改变其值,则这时用静态局部变量比较方便,以免每次调用时重复赋值。
3、register变量
一般情况下,变量的值是存放在内存中的,当程序中用到哪一个变量的值时,有控制器发出指令将内存中该变量的值送到运算器中。经过运算器进行运算,如果需要存数,再从运算器将数据送到内存存放。如果需要频繁的存放,可以把局部变量的值放在CPU中的寄存器中。
说明:
a)只有局部自动变量和形式参数可以作为寄存器变量,其他(如全局变量)不行。
b)一个计算机系统中的寄存器数目是有限的,不能定义任意多个寄存器变量。
c)局部静态变量不能定义为寄存器变量。不能写成register static int a;不能把变量a既放在静态存储区,又放在寄存器中,二者只能居其一。对一个变量只能声明为一个储存类别。
4、extern声明的外部变量
外部变量(全局变量)是在函数的外部定义的,它的作用域为从变量的定义处开始,到本程序文件的末尾。在此作用域内,全局变量可以为程序中各个函数所引用。编译时讲外部变量分配在静态存储区。有需要时用extern来声明外部变量,以扩展外部变量的作用域。
a)在一个文件内声明外部变量。
如果外部变量不在文件的开头定义,其有效的作用范围只限于定义出到文件终了。如果在定义点之前的函数想引用该外部变量,则应该在引用之前用关键字extern对该变量做“外部变量声明”。表示该变量是一个已经定义的外部变量。有了此声明,就可以从“声明”处起,合法地使用该外部变量。
b)在多文件的程序中声明外部变量
一个C程序可以包含多个源程序文件,可以通过extern声明,引用定义在任一个文件的变量。
5、用static声明外部变量
有如果希望外部变量只限于被本文应用,而不能被其他文件引用,这是可以在定义外部变量时加一个static声明。
外部变量都是静态存储的,加了static声明后,只是作用范围不同而已,都是在编译时分配内存的。
三、变量的声明和定义
变量声明部分有2中情况:
1、需要建立储存空间的(定义性声明,定义),比如int a
2、不需要简历储存空间的(引用性声明),比如extrern a
广义地说,声明包括定义,但并非所有的声明都是定义。对于int a而言,既是声明,又是定义。extern a是声明,而不是定义。
一般为了叙述方便,把建立储存空间的声明称定义,而把不需要建立储存空间的声明成为声明。
四、内部函数和外部函数
1、内部函数
如果一个函数值能被本文件中其他函数调用,成为内部函数(静态函数)。
static 类型标识符 函数名(形参表)
2、外部函数
a)在定义函数时,如果在函数首部的最左端冠以关键字extern,则表示该函数是外部函数,可以供其他文件调用。C语言中规定,如果定义函数时省略extern,则隐含为外部函数。
b)在需要调用次函数的文件中,用extern声明所用的函数是外部函数。