C语言变量的声明和空间的分配
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
无论用什么语言编制的程序,都是为让计算机完成某一特定功能而编写的文本文件。这些文本文件是不能直接在机器上运行的,它们必须经过系统软件(包括编辑器和编译器)的输入并编译或汇编后,转换成二进制的可执行代码,才是计算机可以识别的机器语言。此时,程序就是一个包含二进制可执行代码文件的模块。当内核把二进制的可执行代码装入内存后,它由三部分组成:代码段、数据段、堆栈段。在线性地址的低地址字段是代码段,存放程序经编译后的可执行代码(程序文本)。在操作系统中,代码段是只读的,不能修改,所以,代码段的长度是不会改变的。在程序文本(代码段)的上方是数据段,用来存放程序的变量、字符串和其它数据。它分为初始化静态数据(data)和未初始化静态数据(BSS。数据段的长
度是可以改变的。程序可以修改其中的变量。在程序设计中,将其值可以改变的量称为变量。每一个变量在内存中都要占据一定的存储单元,因此,每一个变量也就会具有一定的存储属性。
从变量的作用域(空间)的角度来考虑变量的属性,可将变量分为全局变量和局部变量。
局部变量
局部变量是指在一个函数内部定义的变量,它只中本函数范围内有效。
说明:
1、在主函数中定义的变量只在主函数中有效,且主函数也不能使用其他函数中定义的变量
2、在不同函数中可以使用相同名字的变量,它们代表不同的变量,互不干扰;
3、形参也是局部变量,也只在对应的函数中有效,其他函数不能使用
4、在一函数内部,可在复合语句(有一个{} 括起的一组语句)中定义变量,这些变量只在本复合语句中有效。
全局变量
程序的编译单位是源程序文件,一个源文件可以包含一个或若干个函数。在函数之外定义的变量称为外部变量(extern ), 也叫全局变量。全局变量的有效范围是从定义变量的位置开始到本源程序文件结束为止,其关键字extern 可以省略。
说明:
1、在一个函数中既可以使用本函数中的局部变量,又可以使用有效的全局变量。
2、设置全局变量的作用是增加函数间数据联系的渠道。由于同一文件中的若干函数均能引用全局变量
的值,因而若在一个函数中改变了全局变量的值,就能影响其他函数,相当于各函数有了直接的传递通道,即公共变量,从而可能从函数获得一个以上的返回值。
3、建议不在必要时不要使用全局变量,因为:
(1)全局变量在程序的整个执行过程中都占用存储单元;
(2)它将降低函数的通用性。因为函数执行时要依赖对应的全局变量
(3)降低了函数的独立性,从而降低了函数的内聚度,增加了函数间的耦合度。而结构化程序设计的基本原则是:应争取组成程序的各模块(在 C 语言中用函数实现)具有尽可能高的内聚度和尽可能低的耦合度。
(4)如果外部(全局变量)在文件开头定义,则其作用范围为整个文件;如果不在文件开头定义,则其作用范围为定义点到文件终了处。若在定义点前的函数想引用此外部变量,则应在该函数中用关键字extern 对外部变量作说明。
(5)如果在同一个源文件中,外部变量与局部变量同名,则在局部变量的作用范围内,外部变量不起作用。
变量的生存周期
从变量存在的时间(生存期)的角度来考虑变量的属性,则可将变量分为动态存储变量和静态存储变量。在 C 语言中,每一个变量和函数都具有两个属性:类型和存储类别。类型即int 、float 等,存储类别指的是数据在内存中存储的方式(属性)。存储方式分为静态存储和动态存储两大类,但具体有四种:自动型(auto ,即局部变量)、寄存器型(register)、静态型(static )、外部型(extern ,其它文件中定义过的全局变量), 其中,静态型和外部型变量为静态存储变量,自动型和寄存器型变量为动态存储变量。在定义变量时,应先说明存储类型,再说明数据类型,最后说明变量名。
因此,静态存储变量也分静态全局变量和静态局部变量,动态存储变量则都是局部的?静态
存储变量是指在程序运行期间占据固定的内存单元的变量, 包含全局(extern ,当然extern
可省)变量、静态全局变量(加static 的全局变量)和局部静态变量(冠以关键字static 的局部变量)。
1、对于全局变量,在程序开始执行时就给它分配内存单元,直到程序终结时才释放。它可由本文件和其它文件中的函数所引用。在其它文件中被引用时,应该在文件开头有一个extern 说明(注意,此说明在函数外),说明在引用该变量的文件中出现的变量是一个已在其他文件中定义过的全局(外部)变量,本文件不必再为它分配内存单元。本来外部变量的作用域是从它的定义点到文件结束,但可以用extern 说明将其作用域扩大到有extern 说明的其它文件。但使用这样的全局变量是应十分慎重,因为在执行一个文件中的函数时,可能会改变该全局变量的值,从而会影响到另一文件中函数的
执行结果。
2、对于静态外部(全局)变量,即冠以static 的全局变量,也在编译时分配在静态存储区,它只在本文件内有效,其它文件不能引用。(编译还是执行?)
3、对于局部静态变量,即在局部变量前冠以关键字static 的变量,在编译到它时分配存储单元,直到程序结束才释放。在程序的执行过程中它们占据固定的存储单元,而不是动态的分配和释放。当希望函数中的局部变量之值在函数调用结束后不消失而保留原值时,可定义为静态局部变量。这样,函数调用结束后,其占用的单元不释放,在下一次调用该函数时,变量保留上一次函数调用结束时的值。静态局部变量不能被其它函数访问。
注:当全局变量和静态局部变量未赋初值时,系统自动置为0。
动态存储变量
存储在动态存储区的变量叫动态存储变量。它们在程序执行的某一时刻被动态地建立并在另一时刻又被动态地撤消,即使用到时为其分配存储单元,使用完即释放。
在动态存储区存储的变量有:
1、函数的形参变量。在调用函数时给形参变量分配存储空间。
2、局部变量(未加static 说明的局部变量,即自动变量auto )。自动变量是在函数或复合语句内部定义的变量(即前面所说的局部变量)。当程序块执行时,为它定义的自动型变量分配内存单元,在程序执行完成后,便释放这些变量占用的内存单元。在定义自动型变量时,一般缺省存储类型名auto ;自动变量若未赋初值,则其初值不定(将分配给它的存储单元的当前值作为初值,这是和静态存储变量不同的地方)。
3、函数调用时的现场保护和返回地址等。
以上三种变量在函数调用开始时分配动态存储单元,函数结束时释放这些单元。在程序执行过程中,这种分配和释放是动态的,如果一个程序中多次调用同一函数,分配给此函数中局部变量的存储空间地址可能是不同的。如果一个程序包含若干个函数,每个函数中的局部变量的生存期并不等于整个程序的执行周期,而只是程序执行周期的一部分,并根据函数调用的需要,动态地分配存储空间。
寄存器变量
一般情况下,变量(包括静态存储方式和动态存储方式)的值都是存放在内存中的,当程序中用到哪一个变量的值时,同控制器发出指令将内存中该变量的值送到运算器中。经过运算器
进行运算。如果需要存数,再从运算器将数据送到内存存放。但如果有一些变量使用频繁,为了节省存取时间,提高执行效率,C语言允许将其值存放在运算器中的寄存器中,需要时