1. 局部变量
局部变景是指在程序中只在特定过程或函数中可以访问的变量。
作用范围
- 主函数中定义的变量只在主函数中有效, 并不因为在主函数中定义而在整个文件或程序中有效, 主函数也不能使用其他函数中定义的变量;
- 不同函数中可以使用同名的变量, 它们代表不同的对象, 互不干扰;
- 形式参数也是局部变景, 其他函数可以调用某函数, 但不能直接引用该函数的形参;
- 在一个函数内部, 可以在复合语句中定义变量, 这些变量只在本复合语句中有效, 这种复合语句也称为“分程序”或“程序块”。
2. 全局变量
在函数之外定义的变量称为外部变量, 外部变量是全局变量( 也称全程变量)。
作用范围
- 全局变量可以为本文件中其他函数所共用。
- 它的有效范围为从定义变量的位置开始到本源文件结朿。
由于同一文件中的所有函数都能引用全局变量的值, 因此如果在一个函数中改变了全局变量的值, 就能影响到其他函数中全局变量的值。 相当于各个函数间有直接的传递通道。
由于函数的调用只能带回一个函数返回值, 因此有时可以利用全局变量来对增加函数间的联系渠道, 通过函数调用能得到一个以上的值。
建议:不在必要时不要使用全局变量
- 全局变量在程序的全部执行过程中都占用存储单元, 而不是仅在需要时才开辟单元。
- 它使函数的通用性降低了, 因为如果在函数中引用了全局变景, 那么执行情况会受到有关的外部变量的影响, 降低了程序的可靠性和通用性。
- 使用全局变量过多, 会降低程序的清晰性, 人们往往难以清楚地判断出每个瞬时各个外部变景的值。
- 由于在各个函数执行时都可能改变外部变量的值, 程序容易出错。
3.存储方式
变量的存储有两种不同的方式:
- 静态存储方式是指在程序运行期间由系统分配固定的存储空间的方式;
- 动态存储方式则是在程序运行期间根据需要进行动态的分配存储空间的方式。
存储空间:
- 程序区
- 静态存储区
- 动态存储区
静态存储区
全局变量全部存放在静态存储区中, 在程序开始执行时给全局变量分配存储区, 程序执行完毕就释放。
在程序执行过程中它们占据固定的存储单元, 而不是动态地进行分配和释放。
动态存储区
- 函数形式参数。 在调用函数时给形参分配存储空间。
- 函数中定义的没有用关键字 static 声明的变量, 即自动变量。
- 函数调用时的现场保护和返回地址等。
对以上这些数据, 在函数调用开始时分配动态存储空间, 函数结束时释放这些空间。
在程序执行过程中, 这种分配和释放是动态的,如果在一个程序中两次调用同一函数, 而在此函数中定义了局部变量, 在两次调用时分配给这些局部变景的存储空间的地址可能是不相同的。
4.存储类别
在 C 语言中, 每一个变量和函数都有两个属性: 数据类型和数据的存储类别。
存储类别指的是数据在内存中存储的方式( 如静态存储和动态存储)。
在定义和声明变量和函数时, 一般应同时指定其数据类型和存储类别, 也可以采用默认方式指定(即如果用户不指定, 系统会隐含地指定为某一种存储类别)。
存储类别:
- 自动的 (auto)
- 静态的( static)
- 寄存器的( register)
- 外部的( extern )
根据变量的存储类别, 可以知道变量的作用域和生存周期 。
局部变量的存储类别
- auto 局部变量
局部变最, 如果不专门声明为某种存储类别,系统会给这些变量分配存储空间 - static 局部变量
希望局部变量的值在函数调用结束后不消失而继续保留原值, 即其占用的存储单元不释放, 在下一次再调用该函数时, 该变最己有值( 是指上一次函数调用结束时的值)。 这时就应该指定该局部变量为“静态局部变量”, 用关键字 static 进行声明。
注意:
- 如果在定义局部变量时不赋初值的话, 则对静态局部变量来说, 编译时自动赋初值 0 (对数值型变量)或空字符’ \0’ ( 对字符变量)。
- 而对auto变量来说, 它的值是一个不确定的值。 这是由于每次函数调用结束后存储单元己释放, 下次调用时又重新另分配存储单元, 而所分配的单元中的内容是不可知的。
- register 变量
有一些变量使用频繁( 例如, 在一个函数中执行 10000 次循环, 每次循环中都要引用某局部变量), 则为存取变最的值要花费不少时间。 为提高执行效率, 允许将局部变景的值放在 CPU 中的寄存器中, 需要用时直接从寄存器取出参加运算, 不必再到内存中去存取。 由于对寄存器的存取速度远高于对内存的存取速度, 因此这 样做可以提高执行效率。 这种变量叫做寄存器变量, 用关键字 register 作声明。
全局变量的存储类别
外部变量是在函数的外部定义的全局变景, 它的作用域是从变量的定义处开始, 到本程序文件的末尾。 在此作用域内, 全局变量可以为程序中各个函数所引用。
有时程序设计人员希望能扩展外部变量的作用域:
-
在一个文件内扩展外部变量的作用域
如果外部变量不在文件的开头定义, 其有效的作用范围只限于定义处到文件结束。 在定义点之前的函数不能
引用该外部变量。 如果由于某种考虑, 在定义点之前的函数需要引用该外部变量, 则应该在引用之前用关键字extern 对该变量作“外部变量声明”, 表示把该外部变量的作用域扩展到此位置。 有了此声明, 就可以从“ 声明”处起, 合法地使用该外部变量。 -
将外部变量的作用域扩展到其他文件
如果程序由多个源程序文件组成, 那么在一个文件中想引用另一个文件中己定义的外部变量, 应该在一个文件中定义外部变量 ,而在另一文件中用 extern 对该变量作“外部变量声明“ -
将外部变量的作用域限制在本文件中
有时在程序设计中希望某些外部变量只限于被本文件引用, 而不能被其他文件引用。 这时可以在定义外部变量时加一个 static 声明 。
用 static 声明变量的作用
- 对局部变景用 static 声明, 把它分配在静态存储区, 该变量在整个程序执行期间不释放, 其所分配的空间始终存在。
- 对全局变量用 static 声明, 则该变量的作用域只限于本文件模块( 即被声明的文件中)
注意:
不要误认为对外部变量加 static 声明后才采取静态存储方式( 存放在静态存储区中), 而不加 static 的是采取动态存储( 存放在动态存储区)。
- 声明局部变量的存储类型和声明全局变量的存储类型的含义是不同的:
对于局部变量来说, 声明存储类型的作用是指定变量存储的区域( 静态存储区或动态存储区) 以及由此产生的生存期的问题,- 而对于全局变量来说, 由于都是在编译时分配内存的, 都存放在静态存储区, 声明存储类型的作用是变量作用域的扩展问题。
5.小结
- 从作用域角度分,有局部变量和全局变量。它们采用的存储类别如下:
-
从变量存在的时间(生存期)来区分,有动态存储和静态存储两种类型。静态存储是程序整个运行时间都存在,而动态存储则是在调用函数时临时分配单元。
-
从变量值存放的位置来区分,可分为:
-
关于作用域和生存期的概念
对一个变量的属性可以从两个方面分析,一是变量的作用域,一是变量值存在时间的长短,即生命周期。
前者是从空间的角度,后者是从时间的角度。二者有联系但并不相同。