文档介绍:第4章存储
存储对象是程序对象在计算机中的实现
程序对象不一一对应为存储对象
x:=0; x,0是两程序对象
只有一个存储对象x加指令清零
初值常量也不作为单独存储对象
程序变量的时空特性
引用和指针
计算对象有地址非固定地址, 因时而变, 相对地址虚存空间
P指针是地址变量*P是P所指的内容, 也有左值和右值
*P左值是P所指地址值,即P的值
*P右值是所指地址内的内容值
引用是常指针是变量的别名, 但实现是不一样的
递引用 dereference
通过指针变量引用变量的值为递引用
*P1右值即递引用
有些语言显式递引用算符如FORTH的@
1 13 VARIABLE xx (声明变量xx并赋初值13)
2 0 VARIABLE Y (声明变量Y并赋初值0)
3 xx @ 2 * Y ! (相当于Y=xx*2)
如果只写xx 2 * 则为将xx的地址乘以2放在Y之中
变量的时态
分配/未分配/除分配
分配: 为程序对象创建—存储对象
编译时分配叫静态分配 allocate
运行时分配叫动态分配如声明指针p, 执new才分配
未分配: 声明了未分配运行时分配
除分配: 取消存储对象(程序对象) delete操作显式
自动除配: 无用单元收集Garbage collection
动态语言有,静态可有Ada可没有C
续
4
3
?
?
a b c d e f
声明和定义:定义必然声明;反之不然
声明的两个作用:给出对象, 该对象的时间有效性
出了声明的作用域该对象失去定义。在声明的作用
域内显式删除也失去定义
定义/未定义/失去定义
只要分配存储对象必然有残值, 无意义即未定义赋值或初值变量得以定义
a,b:分配且有定义
c,d:分配未定义或失去定义
e,f:未分配或除配
存储模型
基元类型值仅除数组
记录、构造、表不可更新其中一元素
函数抽象, ——ML重过程
变量引用
可存储值Storable:指最小的可直接访问的可存储单元中的值
Pascal可存储值:集合不选择更新某一元素是可存储值,Pascal, C ,Ada数组可选择更新, 不是可存储值。
引用非可存储(C++可存储), 过程和函数名也非可存储
ML几乎都是可存储值, 也带来毛病:每次更新结构数据都要重来。它们是:
( if exp then sin else cos ) (x) 得sin(x)|cos(x)
可存储值
全局变量和引用程序寿命一样长
局部变量和程序中的一个模块寿命一样长
持久变量比程序寿命长除非显式撤销文件变量
瞬间变量(transient)持久变量的逆
每个存储对象都有创建(生), 可用(活着),撤销(死)的生命期。按生命期长短分:
静态存储对象
编译时分配存储对象, 近代语言类属对象直到装入后确立(elaboration)之时才定下存储对象叫静态分配
一旦执行不再改动其存储,直至所在存储单元无效叫静态(Static)存储对象
全局变量均为隐式的静态对象, COBOL,BASIC全
静态,ALGOL,C是显示声明静态,Pascal除全局,Ada 不能。
C语言的静态变量是既私有又不随所在声明块中消逝, 全局于所在文件。auto是静态分配动态装入不叫静态对象。Extern是静态对象。
extern
static
auto
把寿命特长的(如文件,全局量)排出来归到栈底的某一组,把寿命特
短的(如循环控制变量)另立嵌套组,这个问题也就解决。
块5
块66
块1
块2
块3
块4
5
4
6
6
5
4
6
寿
命
动态存储对象
二叉树其大小由输入值定在运行中确立。内存开辟堆(heap)随生成随堆放动态存储对象。指针(即堆变量)所指程序对象用堆存放
问题:多次重分,内存成了小洞
解决办法:按寿命分组寿命最长的放在较低(按其所在块生命期)。
重复使用
无法再分