程序的内存及标识符的存储属性(一)

内存单元的可以分为系统区(操作系统使用)与用户区(用户程序使用)两部分,用户区可分为代码区(code area,存放程序的二进制代码)和数据区(存放程序数据)。

数据区是我们研究的重点,其中数据区又可以分为静态数据区(静态区,有最长生存期)和动态数据区(动态区,有较短生存期)。

静态区中有全局数据区(data area),和文字常量区

动态区又细分为堆区(heap area),栈区(stack area)。

给它们一个总结:

                                                              虚线内容是在实际内存中时的内容

下面是各个不同内存区的特点
1,程序代码区(code area)--存放函数体的二进制代码。

2,全局数据区(data area)--存放的是全局变量和静态变量(常指静态局部变量),初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在(有时初始化区和未初始化区不一定相邻)另一块区域,将初始化为0(字符与字符串初始化并不不相同)。在编译时分配,结束时由系统释放。

3,文字常量区(位于静态数据区)--字符串常量(是一种字面值常量,上一篇有提到)放在这里。 程序结束后由系统释放。

4,栈区(stack area)--存放的是局部变量,函数参数,调用函数的状态,返回地址等。自高地址向低地址扩展。由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈(只有一个方向能插入与删除,即栈顶)。

5,堆区(heap area)--存放程序员自动申请内存,由程序员自己释放, 若程序员不释放,程序结束时可能由操作系统回收 。

来自网上的例子

//main.cpp
int a = 0; //a:
全局初始化区

char *p1; //p1:
全局未初始化区
main()
{
       int b; //b:

       char s[] = "abc"; //s[4]:
栈 ,"abc":在栈区上,因为是s[4]字符数组,便位于栈区
       char *p2; //p2:
栈, 
       char *p3 = "123456";// p3:栈上,"123456":
在常量区
       static int c =0; //c:
全局(静态)初始化区
       p1 = (char *)malloc(10);//p1:堆区 
       p2 = (char *)malloc(20);//p2:堆区 
 
       strcpy(p1, "123456"); 123456
放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
}


变量及函数的存储属性
关键词:auto(自动的),static(静态的),extern(外部的),register(寄存器的)

使用方法:存储属性(auto/static/extern/register)  类型名  变量名 = 初始值;

auto(自动的)变量
只有局部变量才能才能定义为auto类别的变量,成为局部自动变量,定义方法为
auto typeName varName = 初始值;
auto类别变量在函数调用时分配存储空间,存储在栈区内,函数结束时自动释放其内存空间。
应该注意,函数局部变量定义时默认为自动的,即在函数内typeName variaName = 初始值;等同于上一句定义。自动变量无编译初值,若没有初始化,其值保持原来内存的随机值,若已经初始化了,每次调用所在函数时,每次定义与初始化都起作用,原因是上一次调用的内存已经释放。

static(静态的)类别
1)局部变量可以被定义为static类别的,static typeName varName = 初始值;
这样的变量称为局部静态变量,存放在全局数据区,静态变量有编译初值,若无初始化,系统将其初始为0(字符初始化不同)。
2)另外,全局变量与函数亦可以用static修饰,但其于局部静态变量有区别。
全局变量的作用域是文件的(定义处到文件结束),默认为其它文件可以使用,当有static关键词时,表示不可以被其它源程序文件调用,作用域被局限于本文件内。
当函数前有static修饰时,其功能与全局变量一样,表示其作用域只限定与本文件,不能被其它源程序文件调用。

extern(外部的)类别
全局变量与函数可以被extern修饰,但不能在定义时使用,作用是在本源程序文件使用其它文件允许使用的全局变量和函数,用extern可以看做是对作用域的扩充。
全局变量与函数定义都默认是外部的,允许其它文件使用,若想它们不被其它文件使用可以定义为static类别的,表示作用域限定在本文件,当想使用其它文件的全局变量或函数时,必须使用extern表明。

register(寄存器的)类别
寄存器是读写最快的存储器,直接与CPU打交道,有时为了提高变量的读写速度,和减少重复写入寄存器的频率,可以将变量定义为register类别,但寄存器变量有数量限制,只能有一两个,并且由操作系统分配,若无空间时,寄存器变量只能作普通变量使用。

另,变量的存储属性还有const(不可变的)volatile(易变的)类别的,前者修饰的标识符成为常量,后者是变量的默认形式。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值