一、自动变量(auto)
函数中的局部变量,动态的分配存储空间,数据存储在动态存储区(栈区)中。在调用函数时,系统会自动的给这些变量分配存储空间,在函数调用结束时就自动释放这些存储空间。因此,这类局部变量成为自动变量,用关键字auto作为存储类别的声明。
关键字auto可以省略,不写则隐含为自动存储类别。
即 int a = 10;
等价于
auto int a = 10;
二、静态变量(static)
static关键字修饰的变量称为静态变量。
1.static修饰局部变量
static修饰局部变量时,改变了它的存储区域——存储在静态区,使得该变量的生命周期发生了变化:该变量不随函数调用结束而释放,只要程序还在运行,都不释放;但没有改变其作用域,该变量还是只能在定义该变量的域内部使用,不能被其它函数调用。
//统计一个函数被调用了多少次
void fun()
{
static int count = 0;
count++;
printf("第%d次调用fun函数\n", count);
}
int main()
{
int i = 4;
while (i--)
{
fun();
}
system("pause");
return 0;
}
通过上面的例子我们发现函数fun内部定义static修饰的变量时同时进行了初始化,第二次以后调用fun函数count都只++,并没有重新初始化。
静态局部变量是在编译时赋初值的,所以只赋初值一次,在程序运行期间它已有初值,每次调用函数时不再重新赋值而是保留上次调用结束时的值。如果在定义静态局部变量时不赋初值的话,编译时会自动赋初值0或空字符‘\0’。
而对局部变量来说,实在函数调用时赋初值的,所以每次调用都重新定义且赋初值一次。如果自动变量不赋初值的话,它的值是一个随机值。
2.static修饰全局变量
全局变量都是存放在静态存储区的,它们的生命周期是程序的整个过程,作用域是从定义该全局变量的开始到文件结束。当全局变量被static修饰时,该变量就不能被其它文件所使用。改变了该变量的连接属性,从外部链接变成了内部链接。
三、寄存器变量(register)
一般情况下,变量的值是存放在内存中的。当程序中用到那个变量时,由控制器发出指令将内存中的数据送到运算器中。通过运算器进行运算,如果需要存数,再从运算器将数据运到内存中存放。
如果有一些变量使用频繁,则为存取变量的值要花不少时间,为提高CPU的执行效率,编译器会将这些经常使用的局部变量的值放在CPU的寄存器中,寄存器的存取速度远高于内存的存取速度,这样就提高了执行效率。这样,这样被存放在寄存器中的变量叫做寄存器变量,用关键字register声明。
eg 、 register int a;//声明寄存器变量
现在,编译器可以总动识别使用频繁的变量,会自动将它优化进寄存器中,不需要程序员声明。
四、外部变量(extern)
外部变量是在函数外部定义的变量,也就是全局变量。作用域是从变量定义开始到文件结束,也就是说在定义该外部变量前以及文件外部,函数不能使用该变量,那么要想使用怎么办呢?使用extern扩展作用域!
1.在一个文件内部扩展作用域
在定义点之前的函数要想使用该外部变量,则应该在引用前,用extern对该变量做外部变量声明,表示把外部变量的作用域扩展到此位置。例如:
int main()
{
int max(int, int);
extern int a, b; //把外部变量的作用域扩展到从此处开始
a = 10;
b = 20;
int lager = max(a, b);
system("pause");
return 0;
}
int a, b; //定义外部变量
int max(int a, int b)
{
return a > b ? a : b;
}
2.将外部变量的作用域扩展到其它文件
如果程序有多个源程序文件组成,那么在一个文件中想引用另一个文件的外部变量,怎么做呢?