欢迎来到三一文库! | 帮助中心 三一文库31doc.com 一个上传文档投稿赚钱的网站
三一文库
全部分类
  • 研究报告>
  • 工作总结>
  • 合同范本>
  • 心得体会>
  • 工作报告>
  • 党团相关>
  • 幼儿/小学教育>
  • 高等教育>
  • 经济/贸易/财会>
  • 建筑/环境>
  • 金融/证券>
  • 医学/心理学>
  • ImageVerifierCode 换一换
    首页 三一文库 > 资源分类 > PPT文档下载
     

    六章运行时存储空间的组织和管理.ppt

    • 资源ID:2338208       资源大小:1.34MB        全文页数:150页
    • 资源格式: PPT        下载积分:10
    快捷下载 游客一键下载
    会员登录下载
    微信登录下载
    三方登录下载: 微信开放平台登录 QQ登录   微博登录  
    二维码
    微信扫一扫登录
    下载资源需要10
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    六章运行时存储空间的组织和管理.ppt

    第六章 运行时存储空间的组织和管理 术语 过程的活动 过程的一次执行称为过程的一次活动 活动记录 过程的活动需要可执行代码和存放所需信息的存 储空间,后者称为活动记录 本章内容 讨论一个活动记录中的数据布局 程序执行过程中,所有活动记录的组织方式 第六章 运行时存储空间的组织和管理 影响存储分配策略的语言特征 过程能否递归 当控制从过程的活动返回时,局部变量的值是否 要保留 过程能否访问非局部变量 过程调用的参数传递方式 过程能否作为参数被传递 过程能否作为结果值传递 存储块能否在程序控制下动态地分配 存储块是否必须显式地释放 6.1 局部存储分配 6.1.1 过程 语言概念: 过程定义、过程调用、形式参数、实在参 数、活动的生存期 6.1 局部存储分配 6.1.2 名字的作用域和绑定 1、名字的作用域 一个声明起作用的程序部分称为该声明的作 用域 即使一个名字在程序中只声明一次,该名字 在程序运行时也可能表示不同的数据对象 6.1 局部存储分配 2、环境和状态 环境把名字映射到左值,而状态把左值映射 到右值(即名字到值有两步映射) 赋值改变状态,但不改变环境 过程调用改变环境 如果环境将名字x映射到存储单元s,则说x被 绑定到s 名字存储单元 状态 值 环境 6.1 局部存储分配 3、静态概念和动态概念的对应 静 态 概 念 动 态 对 应 过程的定义 过程的活动 6.1 局部存储分配 3、静态概念和动态概念的对应 静 态 概 念 动 态 对 应 过程的定义 过程的活动 名字的声明 名字的绑定 6.1 局部存储分配 3、静态概念和动态概念的对应 静 态 概 念 动 态 对 应 过程的定义 过程的活动 名字的声明 名字的绑定 声明的作用域 绑定的生存期 6.1 局部存储分配 6.1.3 活动记录 活动记录的常见布局 临 时 数 据 参 数 局 部 数 据 机 器 状 态 访 问 链 控 制 链 返 回 值 6.1 局部存储分配 6.1.4 局部数据的布局 字节是可编址内存的最小单位 变量所需的存储空间可以根据其类型而静态 确定 一个过程所声明的局部变量,按这些变量声 明时出现的次序,在局部数据域中依次分配 空间 局部数据的地址可以用相对于活动记录中某 个位置的地址来表示 数据对象的存储布局还有一个对齐问题 6.1 局部存储分配 例 在SPARC/Solaris工作站上下面两个结构 体的size分别是24和16,为什么不一样? typedef struct _atypedef struct _b char c1; char c1; long i; char c2; char c2; long i; double f; double f; a; b; 对齐:char : 1, long : 4, double : 8 6.1 局部存储分配 例 在SPARC/Solaris工作站上下面两个结构 体的size分别是24和16,为什么不一样? typedef struct _atypedef struct _b char c1;0 char c1; 0 long i;4 char c2; 1 char c2;8 long i; 4 double f; 16 double f; 8 a; b; 对齐:char : 1, long : 4, double : 8 6.1 局部存储分配 例 在X86/Linux机器的结果和SPARC/Solaris 工作站不一样,是20和16。 typedef struct _atypedef struct _b char c1;0 char c1; 0 long i;4 char c2; 1 char c2;8 long i; 4 double f; 12 double f; 8 a; b; 对齐:char : 1, long : 4, double : 4 6.1 局部存储分配 6.1.5 程序块 本身含有局部变量声明的语句 可以嵌套 最接近的嵌套作用域规则 并列程序块不会同时活跃 并列程序块的变量可以重叠分配 6.1 局部存储分配 main() / 例 / / begin of B0 / int a = 0; int b = 0; / begin of B1 / int b = 1; / begin of B2 / int a = 2; / end of B2 / / begin of B3 / int b = 3; / end of B3 / / end of B1 / / end of B0 / 6.1 局部存储分配 main() / 例 / / begin of B0 / int a = 0; int b = 0; / begin of B1 / int b = 1; / begin of B2 / int a = 2; / end of B2 / / begin of B3 / int b = 3; / end of B3 / / end of B1 / / end of B0 / 声 明 作 用 域 int a = 0; B0 B2 int b = 0; B0 B1 int b = 1; B1 B3 int a = 2;B2 int b = 3; B3 a0 b0 b1 a2, b3 重叠分配存储单元 6.2 全局栈式存储分配 本节介绍 介绍程序运行时所需的各个活动记录在存储 空间的分配策略 描述过程的目标代码怎样访问绑定到局部名 字的存储单元 介绍三种分配策略 静态分配策略 栈式分配策略 堆式分配策略 6.2 全局栈式存储分配 6.2.1 运行时内存的划分 代 码 静 态 数 据 堆 栈 6.2 全局栈式存储分配 1、静态分配 名字在程序被编译时绑定到存储单元,不需 要运行时的任何支持 绑定的生存期是程序的整个运行期间 6.2 全局栈式存储分配 2、静态分配给语言带来限制 递归过程不被允许 数据对象的长度和它在内存中位置的限制, 必须是在编译时可以知道的 数据结构不能动态建立 6.2 全局栈式存储分配 例 C程序的外部变量、静态局部变量以及程 序中出现的常量都可以静态分配 声明在函数外面 外部变量- 静态分配 静态外部变量- 静态分配 声明在函数里面 静态局部变量- 也是静态分配 自动变量- 不能静态分配 6.2 全局栈式存储分配 6.2.2 活动树和运行栈 1、活动树 用树来描绘控制进入和离开活动的方式 m q(1,9)r p(1,9) q(1,3) q(1,0) p(1,3)q(2,3) q(2,1) q(3,3)p(2,3) q(5,9) q(5,5) p(5,9)q(7,9) q(7,7) q(9,9)p(7,9) 6.2 全局栈式存储分配 活动树的特点 每个结点代表某过程的一个活动 根结点代表主程序的活动 结点a是结点b的父结点,当且仅当控制流从a的 活动进入b的活动 结点a处于结点b的左边,当且仅当a的生存期先 于b的生存期 m q(1,9)r p(1,9) q(1,3) . . . . q(5,9) . . . . 6.2 全局栈式存储分配 当前活跃着的过程活动可以保存在一个栈中 例 控制栈的内容:m, q (1, 9), q (1, 3), q (2, 3) m q(1,9)r p(1,9) q(1,3) q(1,0) p(1,3)q(2,3) q(2,1) q(3,3)p(2,3) q(5,9) q(5,5) p(5,9)q(7,9) q(7,7) q(9,9)p(7,9) 6.2 全局栈式存储分配 2、运行栈:把控制栈中的信息拓广到包括过程 活动所需的所有局部信息(即活动记录) 6.2 全局栈式存储分配 2、运行栈:把控制栈中的信息拓广到包括过程 活动所需的所有局部信息(即活动记录) main 栈 main 函数调用关系树 6.2 全局栈式存储分配 2、运行栈:把控制栈中的信息拓广到包括过程 活动所需的所有局部信息(即活动记录) main r 函数调用关系树 main int i r ( ) 栈 6.2 全局栈式存储分配 2、运行栈:把控制栈中的信息拓广到包括过程 活动所需的所有局部信息(即活动记录) main q(1,9)r 函数调用关系树 main int i q (1, 9) int m, n 栈 6.2 全局栈式存储分配 2、运行栈:把控制栈中的信息拓广到包括过程 活动所需的所有局部信息(即活动记录) main q(1,9)r p(1,9)q(1,3) main int i q (1, 9) int m, n int i q (1, 3) int m, n 栈 函数调用关系树 6.2 全局栈式存储分配 2、运行栈:把控制栈中的信息拓广到包括过程 活动所需的所有局部信息(即活动记录) main q(1,9)r p(1,9)q(1,3) q(1,0) p(1,3) main int i q (1, 9) int m, n int i q (1, 3) int m, n int i q (1, 0) int m, n 栈 函数调用关系树 6.2 全局栈式存储分配 6.2.3 调用序列 过程调用和过程返回都需要执行一些代码来 管理活动记录栈,保存或恢复机器状态等 过程调用序列 过程调用时执行的分配活动记录,把信息填入它的 域中,使被调用过程可以开始执行的代码 过程返回序列 被调用过程返回时执行的恢复机器状态,释放被调 用过程活动记录,使调用过程能够继续执行的代码 调用序列和返回序列常常都分成两部分,分 处于调用过程和被调用过程中 6.2 全局栈式存储分配 即使是同一种语言,过程调用序列、返回序 列和活动记录中各域的排放次序,也会因实 现而异 设计这些序列和活动记录 的一些原则 以活动记录中间的某个 位置作为基地址 长度能较早确定的域放在 活动记录的中间 临 时 数 据 参 数 局 部 数 据 机 器 状 态 访 问 链 控 制 链 返 回 值 6.2 全局栈式存储分配 即使是同一种语言,过程调用序列、返回序 列和活动记录中各域的排放次序,也会因实 现而异 设计这些序列和活动记录 的一些原则 一般把临时数据域放在 局部数据域的后面 把参数域和可能有的返回 值域放在紧靠调用者活动 记录的地方 临 时 数 据 参 数 局 部 数 据 机 器 状 态 访 问 链 控 制 链 返 回 值 6.2 全局栈式存储分配 即使是同一种语言,过程调用序列、返回序 列和活动记录中各域的排放次序,也会因实 现而异 设计这些序列和活动记录 的一些原则 用同样的代码来执行各个 活动的保存和恢复 临 时 数 据 参 数 局 部 数 据 机 器 状 态 访 问 链 控 制 链 返 回 值 6.2 全局栈式存储分配 1、过程p调用过程q的调用序列 返回值和参数 top_sp base_sp 临时数据局部数据 控制链 和保存的机器状态 6.2 全局栈式存储分配 1、过程p调用过程q的调用序列 (1) p计算实参,依 次放入栈顶,并在 栈顶留出放返回值 的空间。top_sp的 值在此过程中被改 变 返回值和参数 top_sp base_sp 临时数据局部数据 控制链 和保存的机器状态 返回值和参数 top_sp 6.2 全局栈式存储分配 1、过程p调用过程q的调用序列 (2) p把返回地址和 当前base_sp的值 存入q的活动记录 中,建立q的访问 链,增加base_sp 的值 返回值和参数 top_sp base_sp 临时数据局部数据 控制链 和保存的机器状态 返回值和参数 控制链和返回地址 base_sp top_sp 6.2 全局栈式存储分配 1、过程p调用过程q的调用序列 (3) q保存寄存器的 值和其它机器状态 信息 返回值和参数 top_sp base_sp 临时数据局部数据 控制链 和保存的机器状态 返回值和参数 控制链 和保存的机器状态 6.2 全局栈式存储分配 1、过程p调用过程q的调用序列 (4) q根据局部数据 域和临时数据域的 大小增加top_sp的 值,初始化它的局 部数据,并开始执 行过程体 临时数据局部数据 返回值和参数 返回值和参数 控制链 和保存的机器状态 top_sp base_sp 临时数据局部数据 控制链 和保存的机器状态 6.2 全局栈式存储分配 调用者p和被调用者q之间的任务划分 被调用者q的责任 调用者p的责任 调用者p的 活动记录 被调用者q 的活动记录 临时数据局部数据 返回值和参数 返回值和参数 控制链 和保存的机器状态 top_sp base_sp 栈 增 长 方 向 临时数据局部数据 控制链 和保存的机器状态 6.2 全局栈式存储分配 2、过程p调用过程q的返回序列 临时数据局部数据 返回值和参数 返回值和参数 控制链 和保存的机器状态 top_sp base_sp 栈 增 长 方 向 临时数据局部数据 控制链 和保存的机器状态 6.2 全局栈式存储分配 2、过程p调用过程q的返回序列 临时数据局部数据 返回值和参数 返回值和参数 控制链 和保存的机器状态 top_sp base_sp 栈 增 长 方 向 临时数据局部数据 控制链 和保存的机器状态 (1) q把返回值置入 邻近p的活动记录 的地方 参数个数可变场 合难以确定存放返 回值的位置,因此 通常用寄存器传递 返回值 6.2 全局栈式存储分配 2、过程p调用过程q的返回序列 (2) q对应调用序列 的步骤(4),减小 top_sp的值 返回值和参数 top_sp base_sp 临时数据局部数据 控制链 和保存的机器状态 返回值和参数 控制链 和保存的机器状态 6.2 全局栈式存储分配 2、过程p调用过程q的返回序列 (3) q恢复寄存器(包 括base_sp)和机器 状态,返回p 返回值和参数 top_sp base_sp 临时数据局部数据 控制链 和保存的机器状态 返回值和参数 6.2 全局栈式存储分配 2、过程p调用过程q的返回序列 返回值和参数 top_sp base_sp 临时数据局部数据 控制链 和保存的机器状态 (4) p根据参数个数 与类型和返回值类 型调整top_sp,然 后取出返回值 6.2 全局栈式存储分配 3、过程的参数个数可变的情况 临时数据局部数据 参 数 参 数 控制链 和保存的机器状态 top_sp base_sp 栈 增 长 方 向 临时数据局部数据 控制链 和保存的机器状态 (1) 函数返回值改 成用寄存器传递 6.2 全局栈式存储分配 3、过程的参数个数可变的情况 临时数据局部数据 参数1, , 参数n 参数1, ,参数m 控制链 和保存的机器状态 top_sp base_sp 栈 增 长 方 向 临时数据局部数据 控制链 和保存的机器状态 (2) 编译器产生将 实参表达式逆序计 算并将结果进栈的 代码 自上而下依次 是参数1, , 参数 n 6.2 全局栈式存储分配 3、过程的参数个数可变的情况 临时数据局部数据 参数1, , 参数n 参数1, ,参数m 控制链 和保存的机器状态 top_sp base_sp 栈 增 长 方 向 临时数据局部数据 控制链 和保存的机器状态 (3) 被调用函数能 准确地知道第一个 参数的位置 6.2 全局栈式存储分配 3、过程的参数个数可变的情况 临时数据局部数据 参数1, , 参数n 参数1, ,参数m 控制链 和保存的机器状态 top_sp base_sp 栈 增 长 方 向 临时数据局部数据 控制链 和保存的机器状态 (4) 被调用函数根 据第一个参数到栈 中取第二、第三个 参数等等 6.2 全局栈式存储分配 3、过程的参数个数可变的情况 临时数据局部数据 参数1, , 参数n 参数1, ,参数m 控制链 和保存的机器状态 top_sp base_sp 栈 增 长 方 向 临时数据局部数据 控制链 和保存的机器状态 C语言的printf函 数就是按此方式, 用C语言编写的 下面语句的输出? printf(“%d, %d, %dn”); 6.2 全局栈式存储分配 6.2.4 栈上可变长数据 活动记录的长度在编译时不能确定的情况 例:局部数组的大小要等到过程激活时才能 确定 备注: Java语言的实现是将它们分配在堆上 6.2 全局栈式存储分配 访问动态分配的数组 控制链 数组A的指针 数组B的指针 top_sp base_sp . . . . . . . . . 栈 (1) 编译时, 在活动记录中 为这样的数组 分配存放数组 指针的单元 6.2 全局栈式存储分配 访问动态分配的数组 (2) 运行时, 这些指针指向 分配在栈顶的 数组存储空间 控制链 数组A的指针 数组B的指针 top_sp base_sp . . . . . . . . . 栈 数组A 数组B 6.2 全局栈式存储分配 访问动态分配的数组 (3) 运行时, 对数组A和B 的访问都要通 过相应指针来 间接访问 控制链 数组A的指针 数组B的指针 top_sp base_sp . . . . . . . . . 栈 数组A 数组B 6.2 全局栈式存储分配 访问动态分配的数组 q的数组 q的活动记录 p的数组 p的活动记录 控制链 top_sp base_sp 数组A的指针 数组B的指针 数组A 数组B 控制链 . . . . . . . . . 栈 6.2 全局栈式存储分配 6.2.5 悬空引用 悬空引用:引用某个已被释放的存储单元 6.2 全局栈式存储分配 6.2.5 悬空引用 悬空引用:引用某个已被释放的存储单元 例:main中引用p指向的对象 main( ) |int dangle ( ) int q;|int j = 20; q = dangle ( ); |return | 6.3 非局部名字的访问 本节介绍 无过程嵌套的静态作用域(C语言) 有过程嵌套的静态作用域(Pascal语言) 动态作用域(Lisp语言) 6.3 非局部名字的访问 6.3.1 无过程嵌套的静态作用域 过程体中的非局部引用可以直接使用静态确 定的地址(非局部数据此时就是全局数据) 局部变量在栈顶的活动记录中,可以通过 base_sp指针来访问 无须深入栈中取数据,无须访问链 过程可以作为参数来传递,也可以作为结果 来返回 6.3 非局部名字的访问 6.3.2 有过程嵌套的静态作用域 sort readarray exchange quicksort partition 6.3 非局部名字的访问 6.3.2 有过程嵌套的静态作用域 过程嵌套深度 sort1 readarray2 exchange2 quicksort2 partition3 变量的嵌套深度:它的声明所在过程的嵌套 深度作为该名字的嵌套深度 访问链 用来寻找非局部 名字的存储单元 s a, x q (1, 9) k, v 访问链 s a, x q (1, 3) k, v 访问链 q (1, 9) k, v 访问链 s a, x q (1, 3) k, v 访问链 q (1, 9) k, v 访问链 p (1, 3) i, j 访问链 e (1, 3) 访问链 s a, x q (1, 3) k, v 访问链 q (1, 9) k, v 访问链 p (1, 3) i, j 访问链 6.3 非局部名字的访问 6.3 非局部名字的访问 访问非局部名字的存储单元 假定过程p的嵌套深度为np,它引用嵌套深度为na 的变量a,na np,如何访问a的存储单元 sort1 readarray2 exchange2 quicksort2 partition3 s a, x q (1, 3) k, v 访问链 q (1, 9) k, v 访问链 6.3 非局部名字的访问 访问非局部名字的存储单元 假定过程p的嵌套深度为np,它引用嵌套深度为na 的变量a,na np,如何访问a的存储单元 从栈顶的活动记录开始,追踪访问链np na次 到达a的声明所在过程的活动记录 访问链的追踪用间接操作就可完成 sort1 readarray2 exchange2 quicksort2 partition3 s a, x q (1, 3) k, v 访问链 q (1, 9) k, v 访问链 访问非局部名字的存储单元 sort readarray exchange quicksort partition s a, x q (1, 9) k, v 访问链 s a, x q (1, 3) k, v 访问链 q (1, 9) k, v 访问链 s a, x q (1, 3) k, v 访问链 q (1, 9) k, v 访问链 p (1, 3) i, j 访问链 e (1, 3) 访问链 s a, x q (1, 3) k, v 访问链 q (1, 9) k, v 访问链 p (1, 3) i, j 访问链 6.3 非局部名字的访问 6.3 非局部名字的访问 过程p对变量a访问时,a的地址由下面的二元 组表示: (np na,a在活动记录中的偏移) 6.3 非局部名字的访问 建立访问链 假定嵌套深度为np的过程p调用嵌套深度为nx的 过程x (1) np 6.3 非局部名字的访问 program param(input, output);(过程作为参数) procedure b(function h( begin writeln(h(2) end ; procedure c; var m: integer; function f(n: integer) begin f := m+n end f; begin m := 0; b(f) end c; begin c end. f作为参数传递时, 它的起始地址连同它 的访问链一起传递 访 问 链 访 问 链 param c m b 6.3 非局部名字的访问 program param(input, output);(过程作为参数) procedure b(function h( begin writeln(h(2) end ; procedure c; var m: integer; function f(n: integer) begin f := m+n end f; begin m := 0; b(f) end c; begin c end. b调用f时,用传递 过来的访问链来建立f 的访问链 访 问 链 访 问 链 param c m b 访 问 链 b 6.3 非局部名字的访问 program ret (input, output);(过程作为返回值) var f: function (integer): integer; function a: function (integer): integer; var m: integer; function addm (n: integer): integer; begin return m+n end; begin m:= 0; return addm end; procedure b (g: function (integer): integer); begin writeln (g(2) end; begin f := a; b(f) end. a ret b addm 6.3 非局部名字的访问 program ret (input, output);(过程作为返回值) var f: function (integer): integer; function a: function (integer): integer; var m: integer; function addm (n: integer): integer; begin return m+n end; begin m:= 0; return addm end; procedure b (g: function (integer): integer); begin writeln (g(2) end; begin f := a; b(f) end. a ret b addm 执行addm时,a 的活动记录已不存 在,取不到m的值 6.3 非局部名字的访问 C语言的函数声明不能嵌套,函数不论在什么 情况下激活,要访问的数据分成两种情况 非静态局部变量(包括形式参数),它们分配在 活动记录栈顶的那个活动记录中 外部变量(包括定义在其它源文件之中的外部变 量)和静态的局部变量,它们都分配在静态数据 区 因此C语言允许函数(的指针)作为返回值 6.3 非局部名字的访问 6.3.3 动态作用域 被调用过程的非局部名字a和它在调用过程中 引用的是同样的存储单元 基于运行时的调用关系 而不是基于静态作用域来确定 新的绑定仅为被调用过程的局部名字建立, 这些名字在被调用过程的活动记录中占用存 储单元 这一点与静态作用域没有区别 6.3 非局部名字的访问 program dynamic(input, output); var r: real; procedure show; begin write(r: 5: 3) end; procedure small; var r: real; begin r := 0.125; show end; begin r := 0.25; show; small; writeln; show; small; writeln end. dynamic showsmallsmall show showshow 6.3 非局部名字的访问 program dynamic(input, output); var r: real; procedure show; begin write(r: 5: 3) end; procedure small; var r: real; begin r := 0.125; show end; begin静态作用域 r := 0.25;0.250 0.250 show; small; writeln;0.250 0.250 show; small; writeln end. dynamic showsmallsmall show showshow 6.3 非局部名字的访问 program dynamic(input, output); var r: real; procedure show; begin write(r: 5: 3) end; procedure small; var r: real; begin r := 0.125; show end; begin动态作用域 r := 0.25;0.250 0.125 show; small; writeln;0.250 0.125 show; small; writeln end. dynamic showsmallsmall show showshow 6.3 非局部名字的访问 实现动态作用域的方法 深访问 用控制链搜索运行栈,寻找包含该非局部名字 的第一个活动记录 浅访问 为每个名字在静态分配的存储空间中保存它的当 前值 当过程p的新活动出现时,p的局部名字n使用在 静态数据区分配给n的存储单元。n的先前值保存 在p的活动记录中,当p的活动结束时再恢复 6.3 非局部名字的访问 program dynamic(input, output); var r: real; procedure show; begin write(r: 5: 3) end; procedure small; var r: real; begin r := 0.125; show end; begin (绿色表示已执行部分) r := 0.25; show; small; writeln; show; small; writeln end. dynamic showsmallsmall show showshow ? r 静态区 使用值的地方 栈区 暂存值的地方 dynamic r ? 6.3 非局部名字的访问 program dynamic(input, output); var r: real; procedure show; begin write(r: 5: 3) end; procedure small; var r: real; begin r := 0.125; show end; begin (绿色表示已执行部分) r := 0.25; show; small; writeln; show; small; writeln end. dynamic showsmallsmall show showshow 0.25 r dynamic r ? 静态区 使用值的地方 栈区 暂存值的地方 6.3 非局部名字的访问 program dynamic(input, output); var r: real; procedure show; begin write(r: 5: 3) end; procedure small; var r: real; begin r := 0.125; show end; begin (绿色表示已执行部分) r := 0.25; show; small; writeln; show; small; writeln end. dynamic showsmallsmall show showshow 0.25 r dynamic r ? show 静态区 使用值的地方 栈区 暂存值的地方 6.3 非局部名字的访问 program dynamic(input, output); var r: real; procedure show; begin write(r: 5: 3) end; procedure small; var r: real; begin r := 0.125; show end; begin (绿色表示已执行部分) r := 0.25; show; small; writeln; show; small; writeln end. dynamic showsmallsmall show showshow 0.25 r dynamic r ? small r0.25 静态区 使用值的地方 栈区 暂存值的地方 6.3 非局部名字的访问 program dynamic(input, output); var r: real; procedure show; begin write(r: 5: 3) end; procedure small; var r: real; begin r := 0.125; show end; begin (绿色表示已执行部分) r := 0.25; show; small; writeln; show; small; writeln end. dynamic showsmallsmall show showshow 0.125 r dynamic r ? small r0.25 静态区 使用值的地方 栈区 暂存值的地方 6.3 非局部名字的访问 program dynamic(input, output); var r: real; procedure show; begin write(r: 5: 3) end; procedure small; var r: real; begin r := 0.125; show end; begin (绿色表示已执行部分) r := 0.25; show; small; writeln; show; small; writeln end. dynamic showsmallsmall show showshow 0.25 r dynamic r ? 静态区 使用值的地方 栈区 暂存值的地方 6.4 参 数 传 递 6.4.1 值调用 实参的右值传给被调用过程 值调用可以如下实现 把形参当作所在过程的局部名看待,形参的存储 单元在该过程的活动记录中 调用过程计算实参,并把其右值放入被调用过程 形参的存储单元中 6.4 参 数 传 递 6.4.2 引用调用 实参的左值传给被调用过程 引用调用可以如下实现: 把形参当作所在过程的局部名看待,形参的存储 单元在该过程的活动记录中 调用过程计算实参,把实参的左值放入被调用过 程形参的存储单元 在被调用过程的目标代码中,任何对形参的引用 都是通过传给该过程的指针来间接引用实参 6.4 参 数 传 递 6.4.3 换名调用 从概念上说,每次调用时,用实参表达式对 形参进行正文替换,然后再执行 procedure swap(var x, y: integer); var temp: integer; begin temp := x; x := y; y := temp end 6.4 参 数 传 递 6.4.3 换名调用 从概念上说,每次调用时,用实参表达式对 形参进行正文替换,然后再执行 procedure swap(var x, y: integer); var temp: integer;例如:调用swap(i, ai) begin temp := x; x := y; y := temp end 6.4 参 数 传 递 6.4.3 换名调用 从概念上说,每次调用时,用实参表达式对 形参进行正文替换,然后再执行 procedure swap(var x, y: integer); var temp: integer;例如:调用swap(i, ai) begin 替换结果: temp := i; temp := x; i := ai; x := y; ai := temp y := temp end 6.4 参 数 传 递 6.4.3 换名调用 从概念上说,每次调用时,用实参表达式对 形参进行正文替换,然后再执行 procedure swap(var x, y: integer); var temp: integer;例如:调用swap(i, ai) begin 替换结果: temp := i; temp := x; i := ai; x := y; ai := temp y := temp 交换两个数据的程序 end并非总是正确 6.5 堆 管 理 堆式分配 堆用来存放生存期不确定的数据 C+和Java允许程序员用new创建对象,它们的 生存期没有被约束在创建它们的过程活动的生成 期之内 实现内存回收是内存管理器的责任 堆空间的回收有两种不同方式 程序显式释放空间:free(C)或delete(C+) 垃圾收集器自动收集(Java)。11.3节介绍垃圾 收集算法,本课程不做介绍 6.5 堆 管 理 6.5.1 内存管理器 内存管理器把握的基本信息是堆中空闲空间 分配函数 回

    注意事项

    本文(六章运行时存储空间的组织和管理.ppt)为本站会员(本田雅阁)主动上传,三一文库仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知三一文库(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    经营许可证编号:宁ICP备18001539号-1

    三一文库
    收起
    展开