C 语言中常用的变量类型包括以下几类: 局部变量(自动变量)、外部变量(全局变量)、静态变量和寄存器变量(寄存器变量不常用,因此不做整理)。
1 局部变量
局部变量也称为自动变量,是在函数内或程序块内定义的变量,是一种“临时”的变量,随着函数(或程序块)的执行而生成,随着函数(或程序块)的退出而消失。局部变量的作用域仅限于定义它的函数或者程序块。
例1:在函数内定义的局部变量
void function(void)
{
int x; /* 变量x的作用域仅限于funciton函数 */
}
例2:在程序段内定义的局部变量
while(1)
{
int x; /* 变量x的作用域仅限于while语句 */
}
2 外部变量
外部变量也称为全局变量,是定义于所有函数之外的变量,其作用域是其定义(或声明)之后的所有函数。函数可以访问外部变量的前提是在该外部变量的定义(或声明)在该函数定义或声明之前。外部变量的定义与普通变量一样,不同之处是:外部变量只能初始化一次!外部变量通过关键字extern声明。
例3:外部变量定义及使用
int x = 0; /* 定义并初始化外部变量x */
void function1(void)
{
extern int x; /* 声明外部变量,由于x的定义在function函数之前,
因此此处extern声明可以省略 */
/* funciton1 函数中可以使用变量x */
}
外部变量的一个常用用法是,在某个文件中定义并初始化;在其他文件中通过extern声明来使用该外部变量。而这一过程通常是通过.c和.h文件来实现的。这样做的好处是方便程序代码的管理和软件的模块化。
例4:file1中定义外部变量,file2通过extern声明使用外部变量
file :
int x = 0; /* 定义并初始化外部变量x */
***************文件其他内容*******************
:
extern int x; /* 声明外部变量x */
***************文件其他内容*******************
file :
#include “” /* 通过include 包含 */
**********中其他变量和函数的声明**************
file
#include “” /* 通过include 包含 */
由于中已经头包含了,因此通过头包含也就同时头包含了,这样在文件中就可以使用 中定义的外部变量x了。
3 静态变量
静态变量是指通过static关键词声明的变量。由于static 不仅可以用于声明变量,也可以用于声明函数,因此我们统一称static声明的对象。Static声明的作用是限定其对象的作用域,这样可以起到隐藏对象的作用。具体又分为以下3种情况:
1) static作用于外部变量
当static作用于外部变量时,将其作用域限定在被编译原文件(头文件不会被编译的,而是在编译前将其中内容复制到原文件对应处)的剩余部分,阻止其他文件中函数使用该变量。对其他文件中函数来说,该外部变量似乎不存在。这就起到“隐藏”的作用。
例5:static 声明静态外部变量
:
static int x;
:
static int x = 0;
:
#include “”
:
#include “”
该例中,静态变量x的定义只在file1中,因此虽然file2通过头包含对变量x进行了声明,但不可用,因为x的作用域仅限于定义它的源文件中。(如果中也有句“static int x = 0;”会怎么样?这个问题我也没考虑清楚,没有编程验证)
2) static 作用于局部变量
当static作用于局部变量时,将其作用域限定于定义该变量的函数体内。这样,对于其他函数来说该变量不可用。实际上,局部变量本身的作用于就是限定在定义它的函数体内的。但是,通过static声明的局部变量(静态局部变量)与普通局部变量的区别在于:静态局部变量会一直存在,即一直占有存储空间,而不是像普通局部变量那样,随着函数的调用而生成;随着函数的推出而消失。
3) static作用于函数
当static作用于函数时,将其作用于限定为被编译文件的剩余部分,而在其他文件中不可用,起到隐藏该函数的功能。举例如下:
:
void function1(void);
static void function2(void);
:
void function1(void)
{
function1 函数体
}
static void function2(void)
{
Function2 函数体
}
:
#include “”
:
#include “”
尽管file2通过头包含已经有了function1和function2的函数声明,但function2由于是静态函数,因此只能在file1中使用;而finction1既可以在file1中使用,也可以在file2中使用。
注:与静态全局变量情况类似,如果中也有函数定义语句“static void function2(void)”,即函数function2既在file1中有定义,也在file2种有定义,或者说即在file1和file2都定义了一个函数名为function2的函数。那么结果究竟会怎样?
如果往底层考虑,即无论是函数还是变量,都是存储在存储器某个位置的二进制数,而其访问是通过对应存储位置的地址来访问的。因此,虽然file1和file2中都有相同名字的变量或者函数,但是编译后其实是分别为它们分配了不同的存储位置(即地址不同)的,因此也就无所谓变量名或者函数名相同了,实际上它们是不同的变量(或函数)。