存储类型

2.存储类型:是指变量占用内存空间的方式,也称为存储方式。变量占据内存空间的类型分为静态和动态两种。静态:程序开始执行时分配存储空间,直到程序运行结束收回其内存;动态:程序运行过程中用到时才分配内存空间,到其作用域之外时,收回其内存。


自动变量(auto)和寄存器变量(register)属于动态存储方式,外部变量(extern)和静态变量(static)属于静态存储方式。


自动变量:说明自动类型变量的关键字为auto,函数内凡是缺省说明的变量均作为自动变量。int i,j,k; 等价 auto int i,j,k;
自动变量的作用域仅限于定义改变量的块内,属于局部变量。自动变量无初始值的时候其值是不确定的。自动变量属于动态存储方式,只在该变量的作用域范围内才为它分配存储单元,出了作用域,就自动收回存储单元。
int kv(int a)
{
auto int x, y;
{
auto char c;
} //c的作用结束

} //a, x, y的作用结束


静态变量:静态变量的类型说明符是static,属于静态存储方式。
特点:具有缺省的初值0,有全局和局部之分。当static修饰的是局部变量的时候,说明该变量一直存在,但是该变量只能在该作用域内使用(静态变量的记忆功能)。
当static修饰的是全局变量的时候,表示该全局变量只能在本文件(源程序)中使用,其他文件是不允许引用被static修饰的全局变量的。一般的全局变量虽然不是静态变量,但像静态变量一样具有缺省的初值为0.静态数组变量同样具有缺省的初值为0,如static int a[10];则数组a的每个元素的值都为0.
静态局部变量和非局部变量的本质区别是存储类不同:静态局部变量分配在数据段/bss段上,而非静态局部变量分配在栈上。


外部变量:说明外部变量的关键字为extern,外部变量有两种情形:
1.本文件(源程序)中的全局变量先使用后说明的,使用前要说明为外部变量。
2.其他文件中未用static说明的全局变量。
特点:
外部变量一定是全局变量。
外部变量的存储类型是静态类型,具有缺省初值0.


寄存器变量:用关键字register说明的变量是寄存器类型变量。C++编译器江永寄存器类型变量的值存放在CPU的寄存器中,而不是存储器中,从而提高程序运行效率,常用语循环控制。
注意:
由于寄存器变量属于动态存储方式,故只有局部自动变量和形式参数才可以定义为寄存器变量。
凡需要采用静态存储方式的量不能定义为寄存器变量。
由于CPU中寄存器的个数是有限的,因此使用寄存器变量的个数也是有限的。
定义成寄存器类型的变量未必能按寄存器变量使用,还是当着一般变量来使用,这个取决于编译器。


3.生命周期:生命周期描述这个变量什么时候诞生(运行时分配内存空间给这个变量)以及什么时候死亡(运行时收回这个内存空间,伺候不能访问这个内存地址,或者访问这个内存地址已经和这个变量无关了)的。


4.连接属性:大家都知道程序从源代码到最终可执行程序,经历的过程:编译、链接。
编译阶段就是把源代码搞成.o目标文件,目标文件里面有很多符号和代码段、数据段、bss段等分段。符号就是编程中的变量名、函数名等。运行时变量名、函数名能够和相应的内存对应起来,靠符号来做链接的。
.o的目标文件链接生成最终可执行程序的时候,其实就是把符号和相对于的段给连接起来。
C语言中的符号有三种连接属性:外链接属性(该符号可以在整个程序范围内进行链接,可以跨文件,比如普通的函数和全局变量就是外链接)、内链接属性(不能被外链接,不能被当前C文件外面的其他文件进行访问,static四十的函数、全局变量属于内链接)、无链接属性(局部变量、静态局部变量都属于无链接,这些变量的符号本身不参与链接)。


5.内存映像:
代码段:对应着程序中的代码(函数),代码段在linux中又叫文本段(.text)。只读数据段就是在程序运行期间只能读不能写的数据,const修饰的常量有可能是存在只读数据段的(但是不一定,因为const常量的实现方法在不同平台是不一样的)。
数据段:显示初始化为非0的全局变量;显示初始化为非0的static局部变量。
bss段: 显示初始化为0或者未显示初始化的全局变量;显示初始化为0或未显示初始化的static局部变量。
堆:
C语言不会自动向堆中存放东西,堆的操作是程序员自己手工操作的,程序员根据需求自己判断要不要使用堆内存,用malloc申请,用free释放。
文件映射区:
就是进程打开了文件后,将这个文件的内容从硬盘读到进程的文件映射区,以后就直接在内存中操作这个文件,读写完了后在保存时再将内存中的文件写到硬盘中去。
栈:栈内存区,局部变量分配在栈上;函数调用传参过程也会用到栈。
内核映射区:内核映射区就是将操作系统内核映射到这个区域了。对于linux中的每一个进程来说,它都以为整个系统只有他自己和内核而已。它认为内存地址0xc0000000以下都是OS内核的活动空间。
每一个进程都活在自己独立的进程空间中,0-3G的空间每一个进程是不同的(因为用了虚拟地址技术),但是内核是唯一的。


C语言程序运行时对环境有一定的要求,意思是单独个人写的C语言程序没法直接在内存中运行,需要外部一定的协助,这段协助的代码叫加载运行代码(构建C运行时环境的代码,这段代码在操作系统下是别人写好的,会自动添加到我们写的程序上,这段代码的主要作用是:给全局变量赋值、清bss段。)


总结:在C89标准的编译器中,所有的局部变量必须先定义在最前面,在变量定义之前不能有一句执行代码。

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值