变量的存储类别

在C语言指针中提到了每一个变量有两个物理意义,一个是它本身的内容,另一个是变量的地址。同时每个变量有两个属性,变量的数据类型和变量的存储类别。 一般在定义一个变量或数组时首先定义的是数据类型,但实际上还应该定义它的存储类别。变量的存储类别决定了变量的生存期及给它分配在哪个存储区。
变量定义的一般形式为:

存储类别标识符 数据类型说明符 变量1,变量2,…,变量n;

C语言中共有4种存储类别标识符:auto(自动的),static(静态的),register(寄存器的),extern(外部的)

在了解变量存储类别之前需要先搞清楚几个概念:
1.变量生存期:是指变量在内存中占据存储空间的时间
2.存储空间的分类:程序代码区、静态存储区、动态存储区
存放在不同存储空间内的变量的生存期不同。分配在静态存储区的变量在程序运行期间始终占据存储空间;分配在动态存储区或CPU寄存器中的变量,只在程序运行的某段时间占据存储空间。
同时还要区分作用域和生存期。

自动变量

在一般情况下使用最多的变量就是自动变量。自动变量用关键字auto作存储类别标识符。函数或分程序内定义的变量(包括形参)可以定义为自动变量,可以显示定义也可以隐式定义。如不存在指定存储类别,即隐式定义为自动变量。而一般在使用时,无特殊需要都不会定义存储类别,所以大多数的变量为自动变量。

auto int x,y;
int x,y; 

如上两行代码所示,都是定义了两个整型的自动变量,区别在于第一行是显式定义,第二行是隐式定义。
调用函数或执行分程序时,在动态存储区为自动变量分配存储单元,函数或分程序执行结束,所占内存空间即刻释放。定义变量时若没有给变量赋值,变量的初值不确定;如果赋初值,则每次函数被调用式执行一次赋初值操作。
在函数或分程序执行期间,自动变量占据存储单元。函数调用或分程序执行结束,所占存储单元即刻被释放。自动变量的作用域是它所在函数内或分程序内。

静态变量

静态变量用static作存储类别标识符。静态变量包括两种,一种是局部静态变量(内部静态变量),另一种是全局静态变量(外部静态变量)。

static int a;/*全局静态变量*/
f1()
{
	static int b=2;/*局部静态变量*/
	...
}

如上所示,a是全局静态变量,b是局部静态变量。其区别主要在变量定义的位置,若静态变量定义在所有函数外部则称为全局静态变量,作用域为全局;若静态变量定义在某个函数的内部则称为局部静态变量,作用域只在该函数内。
编译时,系统在内存的静态存储区为静态变量分配存储空间,程序运行结束释放其所占的存储空间。若定义时没有赋初值,在编译时,系统自动赋初值为0;若赋初值,则仅在编译时赋初值一次,程序运行后不再给变量赋初值。 对于局部静态变量,其存储单元中保留上次调用结束时的值。静态变量的生存期是整个程序的执行期间。
因为局部静态变量在程序执行期间始终保持在内存中,所以变量中的数据在函数调用结束后仍然存在。当再一次调用其所占函数时,该变量的值继续有效(该值为上一次函数调用保留的值)。局部静态变量的作用域与自动变量一样,只在它所在的函数或分程序内有效。全局静态变量的作用域是从定义处开始到源文件结束。

外部变量

在函数外部定义的变量若没有用static说明,则是外部变量。外部变量只能隐式定义为extern类别,不能显式定义,但在需要时可以用关键字extern声名其为外部变量类别。
编译时,系统把外部变量分配在静态存储区,程序运行结束释放该存储单元。若定义变量时未对外部变量赋初值,在编译时,系统自动赋初值为0。 外部变量的生存期是整个程序的执行期间。外部变量的作用域是从定义处开始到源文件结束。
既然外部变量只能隐式定义,那么在什么时候需要用到extern声名呢,例如

#include <stdio.h>
int x=2,y=2;/*定义外部变量x,y*/
float f1()
{
	extren char c1,c2;/*对外部变量c1,c2声名*/
	scanf("%c%c",&c1,c2);
}
char c1,c2;/*定义外部变量c1,c2*/
void main()
{
	int m,n;
	f1();
	printf("%c+%c=%d\n",c1,c2,x+y);
}

在上面的程序中,外部变量c1,c2是在f1函数之后定义的,它可以在其后的main函数中引用。若想在f1函数中引用它,必须要在f1函数中进行外部变量声明,使c1,c2的作用域扩展到f1函数中。
在多文件程序结构中,如果一个文件中的函数需要用到使用其他文件中定义的全局变量,也可以使用extern关键字声明所要使用的全局变量。

/*file1.c文件*/
#include <stdio.h>
int i;
void main()
{
	...
}
/*file2.c文件*/
#include <stdio.h>
extern int i;
void f1()
{
	...
}

如上两端代码所示,它们分别是两个不同的文件file1.c和file2.c。
在file1.c文件中定义了一个外部变量i,它在main函数中有效,而file2.c文件的开头有一个对外部变量i的声名语句,这使得file1.c文件中定义的外部变量i的作用域扩展到file2.c文件中,因而在file.2文件中的f1函数可以引用外部变量i。
对外部变量声名时,系统不分配存储空间,只是让编译系统知道该变量是一个已经定义过的外部变量,与函数声名类似。

寄存器变量

寄存器变量的值保存在CPU的寄存器中。由于CPU中寄存器的读/写速度快,因此,可以将程序中使用频率高的变量定义为寄存器变量,这样可以提高程序的执行速度。
寄存器变量只能是char、int和指针类型的变量。寄存器变量的生存期与自动变量相同。但随着计算机硬件性能的提高,寄存器变量使用的比较少。

总结

1.定义方式:
(1)自动变量:可以显式定义也可以隐式定义
(2)静态变量:显式定义
(3)外部变量:只能隐式定义,在需要时可以用关键字extern声名其为外部变量类别
如何识别3种变量:在函数内部定义没有存储类别标识符的或带有auto标识符变量的为自动变量;在函数外部定义没有static标识符的或带有extern标识符的变量是外部变量;有static标识符的是静态变量。
2.存储空间:
(1)自动变量:动态存储区
(2)静态变量:静态存储区
(3)外部变量:静态存储区
3.赋初值:
(1)自动变量:定义变量时若没有给变量赋值,变量的初值不确定;如果赋初值,则每次函数被调用式执行一次赋初值操作。
(2)静态变量:若定义时没有赋初值,在编译时,系统自动赋初值为0;若赋初值,则仅在编译时赋初值一次,程序运行后不再给变量赋初值。
(3)外部变量:若定义变量时未对外部变量赋初值,在编译时,系统自动赋初值为0。
4.生存期:
(1)自动变量:调用函数(执行分程序)开始到函数(分程序)结束。
(2)静态变量:整个程序的执行期间。
(3)外部变量:整个程序的执行期间。
5.作用域:
(1)自动变量:自动变量所在的函数内或分程序内。
(2)静态变量:局部静态变量的作用域是它所在的函数或分程序。全局静态变量的作用域是从定义处开始到本源文件结束。
(3)外部变量:从定义处开始到本源文件结束。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Tao'note

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值