什么是变量的存储类型
存储类型决定了系统将在哪一个数据存储区为变量分配存储空间。auto型将在堆栈区分配存储空间;static型将在静态数据区分配存储空间;register型将在CPU内部的寄存器中分配存储空间;而extern将不为变量分配存储空间,extern声明该变量在别的地方已经分配了存储空间。
变量存储类型关键字只需加在变量定义语句类型关键字前面即可。
char ch1;/*定义了一个char型变量ch1,其存储类型默认为自动型(必须是内部变量)*/
static char ch2;/*定义了一个char型变量ch2,其存储类型指定为静态型*/
注意:以上auto型是对内部变量而言,对于外部变量不存在自动型的问题。内部变量自动在堆栈区分配空间。事实上,内部变量默认为自动型,所以auto限定词没有任何用处。
1.自动型变量
定义一个内部变量时,如果将auto加在定义语句前面,则该变量是自动型变量;定义内部变量时,如果没有加任何存储类型限定,该变量默认为自动型变量。
auto只能修饰内部变量,不能修饰外部变量。也就是说只有内部变量可以定义为自动型变量,外部变量不能定义为自动型变量。
事实上,auto没有什么实际用处。内部变量已经默认为自动型变量。
2.静态型变量
外部变量和内部变量都可以定义为静态型变量。
如果在定义一个内部变量时,在定义语句最前面加上static存储类型限定词,那么该变量将是一个静态型变量。该变量将在静态数据区分配存储空间。这种变量作用域虽然只在函数内部,但是该变量将一直在静态数据区占据存储空间,直到程序运行结束。
定义外部变量时,如果不加存储类型限定词,它将在静态数据区分配存储空间。它的作用域除了本文件以外,其他文件通过extern语句声明后也可访问。
但是,如果在定义一个外部变量时,加上static限定词,其作用域将变窄,该变量只在本文件中可见,在其他文件中将不可见,此时在其他文件中即使用extern声明也不能扩展其作用域。这是一个外部静态型变量,也在静态数据区分配存储空间。
注意:对于函数的作用域也是这样,如果在函数定义时加上了static限定词,那么该函数也只在其定义文件内可见(“可见”的意思就是在在该范围内可以使用)。在其他文件中即使声明了也不可以调用。另外,对于函数声明而言可以省略extern关键字。
一个文件中加了static的同名外部变量将隐藏其他文件中定义的未加static的外部变量。也就是说,static变量能够屏蔽其他文件中的同名外部变量,这功能有点像函数的内部变量能够屏蔽同名的外部变量一样。但是,不同文件中如具有未加static的多个同名外部变量则是非法的。
static限定词常用于外部变量,也可用于函数。正常情况下,函数名字是全局的,对程序的任何部分都是可见的。如果在定义一个函数时用static限定,该函数将在其定义文件以外不可见。
static限定词同样能够应用于内部变量。此时,该变量将是一个内部静态型变量。内部静态型变量就像自动变量一样是属于某个特定函数的内部变量。但是,同自动型变量不同,它们一直在内存中存在,而不是随着函数的每次调用而存在,随着函数调用结束而消失。这意味着内部静态型变量提供了单个函数内部私有的、持久的存储。也就是说内部静态型变量只在函数被调用时起作用,但是它将在程序的整个运行时间内一直占据内存空间。
3.寄存器型变量
register限定词通知编译器--程序中的变量将频繁使用。它的意思是建议编译器将程序中用register限定的变量放置在计算机的内部寄存其中,这样可能得到更小更快的程序。但是,编译器将根据实际情况考虑是否采纳该建议--是否将register变量处理为寄存器变量最终决定权还是在编译器。
如下使用register:
register int x;/*x必须是内部变量*/
register char ch;/*ch必须是内部变量*/
register只能用于限定自动型变量和函数的形式参数。也就是说register只对内部变量起作用,而且只能限定内部非静态型变量,不能限定内部静态型变量。
register也可以应用于形式参数,格式如下:
f(register unsigned m,register long n) /*register应用于形式参数*/
{
register int i; /* register应用于内部变量*/
}
在传统C中,register变量的使用有诸多限制,它决定于硬件的实现方式。在每一个函数中只有少数几个变量可以保存在寄存器中,而且也只有特定的类型才行。过量的register变量看起来是无害的,但是超量以后,编译器将忽略新的register变量。另外不管register变量实际上是否被编译器设置为寄存器型变量,都不可能取得该变量的地址。寄存器型变量的类型和数量的多少随计算机不同而异。register变量一般只能够设置几个。传统C的register类型限定于char、int等类型。像float、double、数组等是不可以设定为register型变量的。但是,在最新C99标准中,任何类型都可以定义为register变量,register声明的目的只是告诉编译器以尽快的速度处理该变量,编译器不见得非把它处理为register变量。
4.外部型变量
如extern用于变量定义语句前面,那么该语句就只能是一个声明语句了,他不再是一个变量定义语句。它仅仅是一个声明--声明该变量已经在别的地方定义,只是告诉编译器该变量的类型。
extern int sp;/* sp在别的地方定义,并分配存储单元,本语句只是声明它已经定义过*/
该语句声明了sp在别的地方已经定义,并分配了存储空间,本语句只是说明sp已经定义过的类型为int,并不再为它分配内存空间。这样声明以后,在本文件余下部分就可以使用sp了。
2023-08-15 广告
量有4种存储类型,分别是auto(自动型)、static(静态型)、register(寄存器型)和extern(外部型)。在定义或说明一个变量时可以加上存储类型关键字,以限定其存储类别。
存储类型决定了系统将在哪一个数据存储区为变量分配存储空间。
变量来源于数学,是计算机语言中能储存计算结果或能表示值抽象概念。变量可以通过变量名访问。在指令式语言中,变量通常是可变的;但在纯函数式语言(如Haskell)中,变量可能是不可变(immutable)的。在一些语言中,变量可能被明确为是能表示可变状态、具有存储空间的抽象(如在Java和Visual Basic中)。
由于变量让你能够把程序中准备使用的每一段数据都赋给一个简短、易于记忆的名字,因此它们十分有用。变量可以保存程序运行时用户输入的数据(如使用InputBox函数在屏幕上显示一个对话框,然后把用户键入的文本保存到变量中)、特定运算的结果以及要在窗体上显示的一段数据等。
如果在定义一个内部变量时,在定义语句最前面加上static存储类型限定词,那么该变量将是一个静态型变量。该变量将在静态数据区分配存储空间。这种变量作用域虽然只在函数内部,但是该变量将一直在静态数据区占据存储空间,直到程序运行结束。
auto static extern register
下面分别来介绍。
一、auto
auto称为自动变量。
局部变量是指在函数内部说明的变量(有时也称为自动变量)。用关键字auto进
行说明, 当auto省略时, 所有的非全程变量都被认为是局部变量, 所以auto实际上
从来不用。
局部变量在函数调用时自动产生, 但不会自动初始化, 随函数调用的结束, 这
个变量也就自动消失了, 下次调用此函数时再自动产生, 还要再赋值, 退出时又自
动消失。
二、static
static称为静态变量。根据变量的类型可以分为静态局部变量和静态全程变量。
1. 静态局部变量
它与局部变量的区别在于: 在函数退出时, 这个变量始终存在, 但不能被其它
函数使用, 当再次进入该函数时, 将保存上次的结果。其它与局部变量一样。
2. 静态全程变量
Turbo C2.0允许将大型程序分成若干独立模块文件分别编译, 然后将所有模块
的目标文件连接在一起, 从而提高编译速度, 同时也便于软件的管理和维护。静态
全程变量就是指只在定义它的源文件中可见而在其它源文件中不可见的变量。它与
全程变量的区别是: 全程变量可以再说明为外部变量(extern), 被其它源文件使用,
而静态全程变量却不能再被说明为外部的, 即只能被所在的源文件使用。
三、extern
extern称为外部变量。为了使变量除了在定义它的源文件中可以使用外, 还要
被其它文件使用。因此, 必须将全程变量通知每一个程序模块文件, 此时可用
extern来说明。
四、register
register称为寄存器变量。它只能用于整型和字符型变量。定义符register说
明的变量被Turbo C2.0存储在CPU的寄存器中, 而不是象普通的变量那样存储在内
存中, 这样可以提高运算速度。但是Turbo C2.0只允许同时定义两个寄存器变量,
一旦超过两个, 编译程序会自动地将超过限制数目的寄存器变量当作非寄存器变量
来处理。因此, 寄存器变量常用在同一变量名频繁出现的地方。
另外, 寄存器变量只适用于局部变量和函数的形式参数, 它属于auto型变量,
因此, 不能用作全程变量。定义一个整型寄存器变量可写成:
register int a;
对于以上所介绍的变量类型和变量存储类型将会在以后的学习中, 通过例行程
序中的定义、使用来逐渐加深理解。
存储类决定了两件事, 第一, 它控制哪些函数可以访问一个变量,第二, 存储类决定了变量在内存中的时间。