局部变量和全局变量
从变量的作用域来分析可以分为局部变量和全局变量。局部变量是只在某一个模块中使用。全局变量是在整个文件中会一直存在而且改变的变量。
变量的储存类和生存期
从变量值存在的时间(即生存期)来观察。
变量的存储方式有两种:静态存储方式和动态存储方式
静态存储方式是指在程序运行期间由系统分配固定的存储空间的方式。
动态存储方式是指在程序运行期间根据需要进行动态的分配存储空间的方式。
内存中的供用户使用的存储空间的情况,可以分为三部分:
(1) 程序区
(2) 静态存储区
(3) 动态存储区
数据分别放在静态存储区和动态存储区中。全局变量全部存放在静态存储区,在程序开始执行是给全局变量分配存储区,程序执行完毕就释放。在程序执行过程中他们占据固定的存储单元,而不是动态地进行分配和释放。
在动态区域中存放以下数据:
-
- 函数形式参数
- 函数中定义的没有用关键字static声明的变量,即自动变量
- 函数调用时的现场保护和返回地址
对于这些数据,在函数调用开始时分配动态存储空间,函数结束时释放这些空间。
这种分配和释放是动态的。 如果两次调用同一个函数,函数内部的局部变量调用时分配给这些局部变量的储存空间的地址可能是不同的。
数据类型和数据的存储类别
在定义和声明变量和函数时,一般会同时指定数据类型和数据的存储类别(如果用户不指定,系统会隐含的指定为某一种存储类别)
C的存储类别包括4种:自动的(auto)、静态的(static)、寄存器的(register)、外部的(extern)。根据存储类别可以知道变量的作用域和生存期。
局部变量的存储类别
1. 自动变量(auto)
函数中的局部变量,如果不专门声明为static(静态)存储类别,都是动态的分配存储空间的,数据存储在动态存储区中。函数中的形参和局部变量都属于这类。
在调用该函数时,系统会自动分配存储空间,结束时释放空间。
自动变量用关键字auto作存储类别的声明。例如:
int f(int a) //定义f函数,形参为a { auto int b,c = 3; //定义b,c为自动整型变量 }
其实捏,关键字auto可省略,不写auto则隐含指定为“自动存储类别”
2. 静态局部变量(static局部变量)
遇到希望函数中的局部变量的值在函数调用结束后不消失而继续保留原值,即其占用的存储单元不释放,下次调用该函数时,该变量已有值。用关键字static声明。
注意:
-
- 静态局部变量属于静态存储类别,在静态存储区内分配存储单元。
- 虽然函数调用结束后静态局部变量仍然存在,但是其他函数也不能引用该变量。因为他是局部变量,只能被本函数引用,而不能被其他函数引用。
3. 寄存器变量(register变量)
有这么一个变量其实是用来提高工作效率的。当存在众多变量的时候,避免重复依次查找,可以将调用频繁的变量放入在CPU中的寄存器中作为寄存器变量存在,这样可以降低查找成本,提高工作效率。用关键字register声明。
现如今呢,计算机速度越来越快,逐渐普及了自发判断选择可以放入寄存器的变量,不需要程序设计这指定。
全局变量的存储类别
全局变量它都是存放在静态存储区的,生存期是固定的,存在在程序的整个运行过程。但是对于全局变量来说有一个问题有待解决,就是他们的生命周期从什么时候开始什么时候结束呢?
一般来说,外部变量是在函数外定影的全局变量,他的作用域是从变量的定义出开始到本程序的末尾。所以在此区域内是全局变量的作用域。
啊,这个时候呢为了保证某些人想有向外扩展作用域的需求,总结了几种情况。
1.在一个文件内扩展外部变量的作用域
出于某种考虑,在定义点之前的函数需要引用该外部变量。就在引用该函数之前加上extern对该变量“外部变量声明”,表示把该外部变量的作用域扩展到该位置。
2.将外部变量的作用域扩展到其他文件
如果一个程序由多个源文件组成,想在一个文件中引用另一个文件已定义的外部变量,正确的做法是:
在任一个文件中定义外部变量,然后在另一个文件中用extern对其作“外部变量声明”(如 extern NUM)
3.将外部变量的作用域限制在本文件中
又是在程序设计中希望某些外部变量只限于在本文件中使用,因为有时候一个程序有多个人完成,可能会有同样的变量名,会出现意想不到的问题,这个时候就需要将本文件中的变量限制在本文件中,防止被其他文件误用。
这个时候可以在定义外部变量是加一个static声明。
这种加上static声明、只能用在本文件的外部变量称为静态外部变量。
注意!!:
不要误认为对外部变量加static声明后才采取静态存储方式,而不加static的是采取动态存储方式。
声明局部变量的存储类型和声明全局变量的储存类型的含义是不同的。
对于局部变量来说声明存储类型作用是指定变量存储的区域(生存期问题)
对于全局变量来说声明存储类型作用是变量作用域的扩展问题
存储类别总结!
对一个数据的定义,需要指定两种属性:数据类型和存储类别,分别使用两个关键字。例如:
static int a ; //静态局部整型变量或静态外部整型变量
auto float b ; //自动变量,在函数内定义
register int c ; //寄存器变量,在函数内定义
此外,可以用extern声明已经定义的外部变量,例如:
extern b; //将已经定义的外部变量的作用域扩展至此
可以从不同角度进行总结:
(1)从作用域角度分,有全局变量和局部变量。
(2)从变量存在的时间(生存期)来区分,有动态存储和静态存储两类。静态存储是程序整个运行时间都存在,冬天存储则是在调用函数时临时分配内存单元。
(3)从变量值存放的位置来区分,可分为: