原创 C语言变量的存储类别专题讲座-学C者必看

2009-10-27 21:48 4949 8 9 分类: 软件与OS

1、局部变量和全局变量<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />


       从变量的作用域(即从空间)角度可以将变量分为局部变量和全局变量。


(1) 局部变量


       在一个函数内部定义的变量是内部变量,它只在本函数范围内有效,也就是说只有在本函数内才能使用它们,在此函数外是不能使用这些变量的,这就称为“局部变量”。


       (2) 全局变量


       程序的编译单位是源程序文件,一个源程序文件可以包含一个或多个函数。在函数内定义的变量是局部变量,而在函数之外定义的变量称为全局变量,全局变量可以在本文件中为其它函数所共用,它的有效范围为从定义变量的位置开始到本源文件结束。


       为了便于区分全局变量和局部变量,一般将全局变量名的第一个字母用大写表示。


       (3) 不建议使用全局变量的原因


?           全局变量在程序的全部执行中都占用存储单元,而不是仅在需要时才开辟单元;


?           它使函数的通用性降低了,因为函数在执行时要依赖于其所在的外部变量;


?           使用全局变量过多,会降低程序的清晰性,人们往往难以清楚地判断出每个瞬时各个外部变量的值。


?           如果在同一个源文件中,外部变量与局部变量同名,则在局部变量的作用范围内,外部变量会被“屏蔽”,即它不起作用。


2、变量的存储类别


       (1) 动态存储方式和静态存储方式


从变量值存在的时间(即生命期)角度可以将变量分为静态存储变量和动态存储变量,简称静态变量和动态变量。


所谓静态存储方式是指在程序运行期间分配固定的存储空间的方式,而动态存储方式则是指在程序运行期间根据需要进行动态分配存储空间的方式。


供用户使用的存储空间可以分为程序区、静态存储区和动态存储区,数据分别存放在静态存储区和动态存储区。全局变量全部存放在静态存储区,在程序开始执行时给全局变量分配存储区,程序执行完毕就释放。在程序执行过程中它们占据固定的存储单元,而不是动态地进行分配和释放。


在动态存储区中存放以下数据:函数形参、自动变量(未加static声明的局部变量)以及函数调用时的现场保护和返回地址等。


(3) 变量和函数的属性


C语言中每一个变量和函数都有两个属性:数据类型和数据的存储类别。数据类型就是大家熟知的整型、字符型、实型等;存储类别指的是数据在内存中存储的方式。存储方式分为两大类:静态存储类和动态存储类,具体包括四种:自动的(auto)、静态的(static)、寄存器的(register),外部的(extern)。根据变量的存储类别,可以知道变量的作用域和生存期。


(4) auto变量


函数中的局部变量,如不专门声明为static存储类别,都是动态分配存储空间的,数据存储在动态存储区中。函数中的形参和在函数中定义的变量都属此类,在调用这些函数时系统会给它们分配存储空间,在函数调用结束时就自动释放这些存储空间,因此这类局部变量称为自动变量。自动变量用关键字auto作存储类别的声明。


实际上,关键字“auto”可以省略,auto不写则隐含确定为“自动存储类别”,它属于动态存储方式。


(5) static声明局部变量


有时希望函数中的局部变量的值在函数调用结束后不消失而保留原值,即其占用的存储单元不释放,在下一次该函数调用时,该变量已有值,就是上一次函数调用结束时的值,这时就应该指定局部变量为“静态局部变量”,用关键字static进行声明。


对静态局部变量的说明:


?           静态局部变量属于静态存储类型,在静态存储区为其分配存储单元。


?           静态局部变量是在编译时赋初值的,即只赋初值一次,在程序运行时它已有初值。以后在每次调用函数时不再重新赋初值而是保留上次函数调用结束时的值。而对自动变量赋初值不是在编译时进行的,而是在函数调用时进行的,每调用一次函数就重新给其赋一次初值,相当于执行一次赋值语句。


?           如在定义局部变量时不赋初值的话,则对于静态局部变量来说,编译时自动赋初值0(对数值型变量)或空字符(对字符变量),而对自动变量来说,如果不赋初值则它的值是一个不确定的值。


?           虽然静态局部变量是在函数调用结束后仍然存在,但其它函数是不能引用它的。


什么时候需要使用局部静态变量呢?


?           需要保留函数上一次调用结束时的值。


?           如果初始化后,变量只被引用而不改变其值,则这时用静态局部变量比较方便,以免每次调用时重新赋值。


(6) register变量


一般情况下,变量(包括静态存储方式和动态存储方式)的值是存放在内存中的,当程序中用到哪一个变量的值时,由控制器发出指令将内存中该变量的值送到运算器中。经过运算器进行运算,如果需要存数,再从运算器将数据送到内存中。


如果有一些变量使用频繁(例如在一个函数中执行10000次循环,每次循环都要引用某局部变量),则为存取变量的值要花不少时间。为提高执行效率,C语言允许将局部变量的值放在CPU中的寄存器中,需要用时直接从寄存器中取出参加运算,不必再到内存中去读取。由于对寄存器的存取速度远高于对内存的存取速度,因此这样做可以提高执行效率。这种变量叫做“寄存器变量”,用关键字register做声明。


关于寄存器变量的说明:


?           只有局部自动变量和形参可以作为寄存器变量,其它(如全局变量)不行。


?           一个计算机系统中的寄存器数目是有限的,不能定义任意多个寄存器变量。


?           局部静态变量不能定义为寄存器变量。


(7) extern声明外部变量


外部变量(即全局变量)是在函数的外部定义的,它的作用域为从变量的定义处开始,到本程序文件的末尾。在此作用域内,全局变量可以为程序中各个函数所引用。编译时将外部变量分配在静态存储区。有时需要用extern来声明外部变量以扩展外部变量的作用域。


?           在一个文件内声明外部变量


如果外部变量不在文件的开头定义,其有效的作用范围只限于定义处到文件终了。如果在定义点之前的函数想引用该外部变量,则应该在引用前用关键字extern对该变量做“外部变量声明”,表示该变量是一个已经定义的外部变量。有了该声明,就可以从声明处起,合法地使用该外部变量。换句话说,就是先使用该全局变量(使用前要用extern声明),然后才定义该全局变量(如在文件末尾处而不是文件开始处定义)


extern声明外部变量时,类型名可以写也可以不写。


?           在多文件的程序中声明外部变量


一个C程序可以由一个或多个源程序文件组成。如果程序由多个源程序文件组成,那么在一个文件中想引用另一个文件中已定义的外部变量应该怎么办呢?


方法就是一个文件(任一个都可以)中定义该外部变量,当另一文件要引用该外部变量时,只需在该文件中用extern对该外部变量进行声明即可。


需要注意的是,需要慎用这样的全局变量,因为在执行一个文件中函数时可能会改变该全局变量的值,它会影响到其它文件中函数的执行结果。


(8) static声明外部变量


有时在程序设计中希望某些外部变量只限于被本文件引用,而不能被其他文件引用,这时可以在定义外部变量时加一个static声明。这种加上static声明、只能用于本文件的外部变量(全局变量)称为静态外部变量。


需要指出的是,对外部变量加static声明并不意味着这时才是静态存储,而不加static的是动态存储,两种形式的外部变量都是静态存储方式,只是作用范围不同而已,都是在编译时分配内存的。


(9) 关于变量的声明和定义


广义地说,声明包括定义,但并非所有的生命都是定义。在声明部分出现的变量有两种情况:一种是需要建立存储空间的(如:int a;);另一种是不需要建立存储空间的(如:extern a;)。前者称为“定义性声明”,或称定义;后者称为“引用性声明”。对“int a;”而言,它既是声明,又是定义;而对“extern a;”而言,它是声明而不是定义。一般为了叙述方便,把建立存储空间的声明称为定义,而把不需要建立存储空间的声明称为声明。显然这里的声明是狭义的,即非定义性声明。


外部变量的定义和声明其含义是不同的,外部变量的定义只能有一次,它的位置在所有函数之外,而同一个文件中的外部变量的声明可以有多次,它的位置可以在函数之内(哪个函数要用就在哪个函数中声明)也可以在函数之外(在外部变量的定义点之前)。对外部变量的初始化只能在“定义”时进行,而不能在“声明”中进行。所谓“声明”,其作用就是声明该变量是一个已在后面定义过的外部变量,仅仅是为了“提前”引用该变量而做的“声明”。


(10) 总结


?           对一个数据的定义,需要指出两种属性:数据类型和存储类别,分别使用两个关键字。


?           从作用域角度分,有局部变量和全局变量,它们采用的存储类别如下:1) 局部变量:自动变量、静态局部变量、寄存器变量、形参;2) 全局变量:静态外部变量、外部变量。


?           从变量存在的时间来区分,有动态存储方式和静态存储方式两种类型。静态存储是程序整个运行时间都存在,而动态存储则是在调用函数时临时分配单元。1) 动态存储:自动变量、寄存器变量、形参;2) 静态存储:静态局部变量、静态外部变量、外部变量。


?           从变量值存放的位置来区分,可分为:1) 内存中静态存储区:静态局部变量、静态外部变量、外部变量;2) 内存中动态存储区:自动变量、形参;3) CPU中的寄存器:寄存器变量


?           static对局部变量和全局变量的作用不同,对局部变量来说,它使变量由动态存储方式改变为静态存储方式,而对全局变量来说,它使变量局部化(局限于本文件),但仍为静态存储方式。从作用域角度看,凡是static声明的,其作用域都是局限的,或者是局限于本函数内(静态局部变量),或者局限于本文件内(静态外部变量)

文章评论1条评论)

登录后参与讨论

用户377235 2013-5-27 23:51

太感谢了

用户377235 2013-1-5 15:48

Thanks for your passage,it helps me know more about C

用户575872 2011-7-27 16:59

有没有MSP430的呢

用户225660 2009-12-11 22:19

支持反反复反复
相关推荐阅读
gujunyi1_407560534 2011-03-22 16:43
NP0,X5R,X7R,Y5V释义及其用途
这个是按美国电工协会(EIA)标准,根据不同介质材料而分类。这类参数描述了电容采用的电介质材料类别,温度特性以及误差等参数,不同的值也对应着一定的电容容量的范围。具体来说,就是:X7R常用于容量为33...
gujunyi1_407560534 2011-03-22 16:29
转贴:电容的选型
从电子产品的设计到采购来看,无源元件只是一个配角,其在整个电子产品中所占的物料成本仅约一成,但电子产品中的无源元件数量却是最多的。以电容为例,从2G发展到3G,仅一部手机中的MLCC数量就从平均165...
gujunyi1_407560534 2011-01-28 12:34
手把手将你用PADS Layout 2007.2生成Gerber文件
        本文主要讲述如何利用PADS 2007.2 Layout生成Gerber文件,由于内容较多,所以不再一一列出,这里仅贴出里面第一页的内容,总共14页。需要的博友们可以下载后观看,如有问...
gujunyi1_407560534 2011-01-12 16:10
DxDesigner的两个使用技巧-你一定用得着,而且很有帮助
...
gujunyi1_407560534 2010-11-22 13:47
VCC、VDD、VEE、VSS释疑汇总
在电子电路中,常可以看到VCC、VDD和VSS三种不同的符号,它们有什么区别呢?1、解释VCC:C=Circuit 表示电路的意思,即接入电路的电压;VDD:D=Device 表示器件的意思,即器件内...
gujunyi1_407560534 2010-11-17 12:23
晶体振荡器专题介绍
1、晶振的作用       晶振是晶体振荡器的简称,分为有源晶振和无源晶振两种,有源晶振无需外接匹配电容,只要加电即可输出一定频率的周期波形,所以有源晶振一般是四个引脚;无源晶振严格来说不能叫晶振,只...
我要评论
1
8
关闭 站长推荐上一条 /2 下一条