4.6 变量的存储类别
在程序中经常会使用到变量,在C程序中可以选择变量的不同存储形式,存储类型分别为静态存储和动态存储。可以通过存储类修饰符来告诉编译器要处理什么样的类型变量,具体有以下4种:自动(auto)、寄存器(register)、静态(static)及外部(extern)。
4.6.1 动态存储与静态存储
内存中供用户使用的存储空间分为代码区与数据区两个部分。变量存储在数据区,数据区又可分为静态存储区与动态存储区。
静态存储是指在程序运行期间给变量分配固定存储空间的方式。如全局变量存放在静态存储区中,程序运行时分配空间,程序运行完释放。
动态存储是指在程序运行时根据实际需要动态分配存储空间的方式。如形式参数存放在动态存储区中,在函数调用时分配空间,调用完成释放。
对于静态存储方式的变量可在编译时初始化,默认初值为0或空字符。对动态存储方式的变量如不赋初值,则它的值是一个不确定的值。
静态存储类别与外部存储类别变量存放在静态存储区,自动存储类别变量存放在动态存储区,寄存器存储类别直接送寄存器。
4.6.2 自动(auto)变量
函数中定义的变量,如不专门声明为static存储类别,都是动态地分配存储空间的,数据存储在动态存储区中。函数中的形参和在函数中定义的变量(包括在复合语句中定义的变量),在调用该函数时系统会给它们分配存储空间,在函数调用结束时就自动释放这些存储空间。这类局部变量称为自动变量。自动变量用关键字auto作存储类别的声明。
例如:
int f(int a) // 定义f函数,a为参数 { auto int b,c=3; // 定义b,c自动变量 …… }
该例中,a是形参,b、c是自动变量,对c赋初值3。执行完f函数后,自动释放a、b、c所占的存储单元。
提示
关键字auto可以省略,auto不写则隐含定义为“自动存储类别”,属于动态存储方式。
【例4-15】编写程序,使用auto变量进行定义。(源代码\ch04\4-15)
运行上述程序,结果如图4-30所示。
图4-30 使用auto变量
【代码解析】
本例用于演示使用自动变量。首先在函数fun中定义一个auto型变量add,在其中对变量进行加1操作。之后在主函数main中通过显示的提示语句,可以看到调用两次fun函数的输出,从结果中可以看到fun函数中定义整型变量时系统会为其分配内存空间,在函数调用结束时自动释放这些存储空间。
4.6.3 静态(static)变量
static变量为静态变量,将函数的内部和外部声明成static变量的意义是不一样的。不过对于局部变量来说,static变量是和auto变量相对而言的。两者作用域仅限于声明变量函数中,语句块执行期间,static变量将始终保持它的值。
【例4-00316】编写程序,使用static变量进行定义。(源代码\ch04\4-16)
运行上述程序,结果如图4-31所示。
图4-31 使用static变量
【代码解析】
本例用于演示使用静态变量。在函数fun中定义一个static型的整型变量add,在其中对变量加1操作。之后在主函数main中通过显示的提示语句,可以看到调用两次add函数的输出,从结果中可以发现static变量的值保持不变。
4.6.4 寄存器(register)变量
为了提高效率,C语言允许将局部变量的值放在CPU中的寄存器中,这种变量叫“寄存器变量”,用关键字register作声明。
【例4-17】编写程序,使用register变量修饰整型变量。(源代码\ch04\4-17)
运行上述程序,结果如图4-32所示。
图4-32 使用register变量
【代码解析】
本例用于演示寄存器存储类变量的使用方法。在代码中首先定义一个register型的寄存器存储类变量a,然后赋值并打印输出。
注意:
(1)只有局部自动变量和形式参数可以作为寄存器变量。
(2)一个计算机系统中的寄存器数目有限,不能定义任意多个寄存器变量。
(3)局部静态变量不能定义为寄存器变量。
4.6.5 外部(extern)变量
外部变量(即全局变量)是在函数的外部定义的,它的作用域为从变量定义处开始,到本程序文件的末尾。如果外部变量不在文件的开头定义,其有效的作用范围只限于定义处到文件终了。如果在定义点之前的函数想引用该外部变量,则应该在引用之前用关键字extern对该变量作“外部变量声明”,表示该变量是一个已经定义的外部变量。有了此声明,就可以从“声明”处起,合法地使用该外部变量。
【例4-18】编写程序,用extern声明外部变量,扩展程序文件中的作用域。(源代码\ch04\4-18)
运行上述程序,结果如图4-33所示。
图4-33 使用extern变量
【代码解析】
本例用于演示使用外部存储变量。在代码中的最后1行定义了外部变量A、B,但由于外部变量定义的位置在主函数main之后,因此本来在main函数中不能引用外部变量A、B。现在我们在main函数中用extern对A和B进行“外部变量声明”,就可以从“声明”处起,合法地使用该外部变量A和B。