收藏 分享(赏)

C语言进阶:重点、难点与疑点解析.pdf

上传人:HR专家 文档编号:6235201 上传时间:2019-04-03 格式:PDF 页数:114 大小:2.81MB
下载 相关 举报
C语言进阶:重点、难点与疑点解析.pdf_第1页
第1页 / 共114页
C语言进阶:重点、难点与疑点解析.pdf_第2页
第2页 / 共114页
C语言进阶:重点、难点与疑点解析.pdf_第3页
第3页 / 共114页
C语言进阶:重点、难点与疑点解析.pdf_第4页
第4页 / 共114页
C语言进阶:重点、难点与疑点解析.pdf_第5页
第5页 / 共114页
点击查看更多>>
资源描述

1、C 语 言 进 阶 : 重 点 、 难 点 与 疑 点 解 析 牟 海 军 著C 语 言 是 编 程 语 言 中 的 一 朵 奇 葩 , 虽 已 垂 垂 老 矣 , 但 却 屹 立 不 倒 , 诞 生 了 数 十 年 , 仍 然 是 最 流 行 的 编 程 语 言 之 一 。C 语 言 看 似 简 单 , 却 不 易 吃 透 , 想 要 运 用 好 , 更 是 需 要 积 淀 。 本 书 是 一 本 修 炼 C 程 序 设 计 能 力 的 进 阶 之 作 , 它 没 有 系 统 地 去 讲 解 C 语 言 的 语 法 和 编 程 方 法 , 而 是 只 对 C 语 言 中 不 容 易 被 初

2、学 者 理 解 的 重 点 、 难 点 和 疑 点 进 行 了 细 致 而 深 入 的 解 读 , 揭 露 了 C 语 言 中 那 些 鲜 为 普 通 开 发 者 所 知 的 秘 密 , 旨 在 让 读 者 真 正 掌 握 C 语 言 , 从 而 编 写 出 更 高 质 量 的 C 程 序 代 码 。 全 书 一 共 11 章 : 第 1 章 重 点 阐 述 了 C 语 言 中 不 易 被 理 解 的 多 个 核 心 概 念 , 很 多 初 学 者 在 理 解 这 些 概 念 时 都 会 存 在 误 区 ; 第 28 章 对 预 处 理 、 选 择 结 构 和 循 环 结 构 的 程 序 设

3、计 、 数 组 、 指 针 、 数 据 结 构 、 函 数 和 文 件 等 知 识 点 的 核 心 问 题 和 注 意 事 项 进 行 了 讲 解 ; 第 9 章 介 绍 了 调 试 和 异 常 处 理 的 方 法 及 注 意 事 项 ; 第 10 章 对 C 语 言 中 的 若 干 容 易 让 开 发 者 误 解 误 用 的 陷 阱 知 识 点 进 行 了 剖 析 ; 第 11 章 则 对 所 有 程 序 员 必 须 掌 握 的 几 种 算 法 进 行 了 详 细 的 讲 解 ; 附 录 经 验 性 地 总 结 了 如 何 养 成 良 好 的 编 码 习 惯 , 这 对 所 有 开 发 者

4、都 尤 为 重 要 。 封 底 无 防 伪 标 均 为 盗 版 版 权 所 有 , 侵 权 必 究 本 书 法 律 顾 问 北 京 市 展 达 律 师 事 务 所 图 书 在 版 编 目 (CIP ) 数 据 C 语 言 进 阶 : 重 点 、 难 点 与 疑 点 解 析 / 牟 海 军 著 . 北 京 : 机 械 工 业 出 版 社 ,2012.6 ISBN 978-7-111-38861-6 I. C II. 牟 III. C 语 言 程 序 设 计 IV. TP312 中 国 版 本 图 书 馆 CIP 数 据 核 字 (2012 ) 第 131103 号 机 械 工 业 出 版 社 (

5、 北 京 市 西 城 区 百 万 庄 大 街 22 号 邮 政 编 码 100037 ) 责 任 编 辑 : 王 海 霞印 刷 2012 年 7 月 第 1 版 第 1 次 印 刷 186mm240mm 22.5 印 张 标 准 书 号 : ISBN 978-7-111-38861-6 定 价 : 59.00 元 凡 购 本 书 , 如 有 缺 页 、 倒 页 、 脱 页 , 由 本 社 发 行 部 调 换 客 服 热 线 : (010 )88378991 ; 88361066 购 书 热 线 : (010 )68326294 ; 88379649 ; 68995259 投 稿 热 线 : (

6、010 )88379604 读 者 信 箱 : 前 言 为 什 么 要 写 这 本 书 或 许 绝 大 多 数 人 都 有 这 样 的 经 历 , 最 初 学 习 C 语 言 的 目 的 是 为 了 应 付 考 试 , 所 以 对 于 C 语 言 只 能 算 是 一 知 半 解 。 真 正 运 用 C 语 言 进 行 编 程 时 会 出 现 很 多 问 题 , 让 人 措 手 不 及 , 这 时 才 发 现 自 己 只 能 理 解 C 语 言 的 皮 毛 , 虽 能 看 懂 简 单 的 代 码 , 却 写 不 出 程 序 来 , 对 于 那 些 稍 微 复 杂 的 代 码 就 更 是 望 尘

7、莫 及 了 。 为 了 摆 脱 对 C 语 言 知 其 然 不 知 其 所 以 然 的 状 态 , 本 书 将 带 领 读 者 重 启 C 语 言 学 习 之 旅 , 这 次 不 再 是 为 了 考 试 , 而 是 出 于 真 正 的 使 用 需 要 , 所 以 有 针 对 性 地 给 出 了 C 语 言 学 习 中 的 重 点 、 难 点 与 疑 点 解 析 , 希 望 能 够 帮 助 更 多 的 C 语 言 爱 好 者 走 出 困 境 , 真 正 理 解 C 语 言 , 真 正 做 到 学 以 致 用 。 为 了 让 读 者 能 够 真 正 地 理 解 C 语 言 学 习 中 的 重 点

8、、 难 点 与 疑 点 , 以 及 体 现 本 书 学 以 致 用 的 特 色 , 全 书 没 有 采 用 枯 燥 的 文 字 描 述 来 讲 解 C 语 言 相 关 的 知 识 点 , 而 是 采 用 知 识 点 与 代 码 结 合 的 方 式 , 同 时 对 于 代 码 展 开 相 应 的 分 析 , 这 就 避 免 了 部 分 读 者 在 学 习 了 相 关 知 识 点 之 后 仍 然 不 知 道 如 何 使 用 该 知 识 点 的 弊 端 , 使 读 者 可 以 通 过 代 码 来 加 深 对 相 关 知 识 点 的 理 解 。 全 书 在 结 构 安 排 上 都 是 围 绕 C 语

9、言 学 习 中 的 重 点 、 难 点 与 疑 点 进 行 讲 解 , 如 第 1 章 并 没 有 从 讲 解 C 语 言 中 的 基 础 知 识 点 开 始 , 而 是 先 列 举 了 C 语 言 学 习 中 易 混 淆 的 核 心 概 念 , 使 读 者 清 晰 地 区 分 这 些 核 心 概 念 后 再 开 始 相 应 知 识 点 的 学 习 。 本 书 对 基 础 知 识 点 也 并 非 概 念 性 地 讲 解 , 而 是 重 点 讲 解 了 使 用 中 的 要 点 , 同 时 重 点 讲 解 了 C 语 言 中 的 一 些 调 试 和 异 常 处 理 的 方 IV 法 , 以 及 误

10、 区 和 陷 阱 知 识 点 。 最 后 一 章 讲 解 了 编 程 中 必 须 掌 握 的 一 些 常 用 算 法 。 总 之 , 本 书 能 够 使 读 者 在 现 有 基 础 上 进 一 步 提 高 自 己 的 C 语 言 编 程 能 力 , 更 清 晰 地 认 识 和 理 解 C 语 言 。 本 书 读 者 对 象 本 书 适 合 以 下 读 者 : C 语 言 爱 好 者 嵌 入 式 开 发 人 员 初 、 中 级 C 语 言 程 序 员 参 加 C 语 言 培 训 的 学 员 如 何 阅 读 本 书 本 书 共 11 章 , 第 1 章 主 要 针 对 C 语 言 学 习 中 一

11、些 容 易 混 淆 的 核 心 概 念 进 行 具 体 讲 解 , 内 容 跨 度 比 较 大 , 初 学 者 学 起 来 可 能 有 些 吃 力 , 所 以 建 议 在 遇 到 不 懂 的 知 识 点 时 暂 时 跳 过 , 待 学 习 了 后 面 的 相 关 知 识 点 后 再 进 行 相 应 的 学 习 ; 第 28 章 有 针 对 性 地 讲 解 了 C 语 言 中 的 相 应 知 识 点 , 同 时 有 针 对 性 地 对 其 中 的 要 点 部 分 进 行 具 体 讲 解 , 读 者 可 以 通 过 这 几 章 的 学 习 夯 实 每 个 知 识 点 的 基 础 ; 第 9 章 重

12、 点 讲 解 了 在 C 语 言 编 程 中 进 行 调 试 和 异 常 处 理 的 一 些 常 见 方 法 和 技 巧 ; 第 10 章 重 点 讲 解 了 C 语 言 编 程 中 的 一 些 陷 阱 知 识 点 , 通 过 本 章 的 学 习 读 者 可 以 知 道 如 何 在 以 后 编 程 时 绕 开 陷 阱 ; 第 11 章 讲 解 了 一 些 编 程 中 的 常 用 算 法 , 这 是 编 程 中 必 然 会 遇 到 的 , 因 此 读 者 有 必 要 掌 握 这 些 常 见 的 算 法 。 最 后 在 附 录 部 分 给 出 了 养 成 良 好 编 程 习 惯 的 建 议 。 本

13、 书 针 对 每 个 知 识 点 都 提 供 了 相 应 的 代 码 , 建 议 读 者 在 学 习 的 过 程 中 自 己 动 手 编 写 , 这 样 才 会 发 现 自 己 在 C 语 言 学 习 方 面 的 缺 陷 , 进 而 快 速 提 升 自 己 的 编 程 能 力 。 勘 误 和 支 持 除 署 名 作 者 外 , 参 与 本 书 材 料 整 理 和 代 码 测 试 工 作 的 还 有 项 俊 、 马 晓 路 、 刘 倩 、 罗 艳 、 胡 开 云 、 余 路 、 张 涛 、 张 晓 咏 、 时 翔 、 秦 萤 雪 等 。 由 于 作 者 的 水 平 有 限 , 书 中 难 免 会

14、 出 现 一 些 错 误 或 者 不 准 确 的 地 方 , 恳 请 读 者 批 评 指 正 。 读 者 遇 到 任 何 问 题 都 可 以 发 邮 件 到 , 我 会 尽 力 为 读 者 提 供 最 满 意 的 解 答 。 书 中 的 全 部 源 文 件 除 可 以 从 华 章 网 站 ( ) 下 载 外 , 还 可 以 发 邮 件 向 我 索 取 。 如 果 你 有 更 多 的 宝 贵 意 见 , 也 欢 迎 发 邮 件 与 我 交 流 , 期 待 得 到 你 们 的 真 挚 反 馈 。 致 谢 本 书 得 以 出 版 要 感 谢 很 多 人 , 首 先 要 感 谢 我 的 导 师 侯

15、建 华 教 授 , 无 论 是 在 科 研 还 是 平 时 V 的 学 习 和 生 活 中 , 都 得 到 您 严 格 的 指 导 和 无 微 不 至 的 关 怀 , 在 此 向 您 表 示 最 真 诚 的 敬 意 和 衷 心 的 感 谢 ! 其 次 要 感 谢 我 的 好 朋 友 们 , 他 们 是 刘 倩 、 马 晓 路 、 胡 开 云 、 时 翔 、 张 晓 咏 、 余 路 、 张 涛 , 有 你 们 的 陪 伴 , 我 每 天 都 过 得 很 开 心 , 感 谢 你 们 在 生 活 中 给 予 我 的 关 心 和 体 贴 。 同 时 也 感 谢 实 验 室 的 项 俊 、 梁 娟 、

16、左 坚 、 罗 艳 、 严 明 君 、 李 思 , 谢 谢 你 们 平 时 给 予 的 帮 助 。 感 谢 机 械 工 业 出 版 社 华 章 公 司 的 编 辑 杨 福 川 和 姜 影 , 你 们 在 这 一 年 多 的 时 间 中 始 终 支 持 我 的 写 作 , 你 们 的 鼓 励 和 帮 助 指 引 我 顺 利 地 完 成 全 部 书 稿 。 最 后 要 感 谢 我 的 家 人 , 没 有 你 们 的 鼓 励 和 支 持 , 就 没 有 我 今 天 的 成 绩 。 在 此 要 特 别 感 谢 我 的 父 亲 , 您 多 年 来 对 我 的 悉 心 教 导 , 我 都 铭 记 在 心

17、。 谨 以 此 书 献 给 众 多 热 爱 C 语 言 的 朋 友 们 ! 牟 海 军 (bigloomy ) 2012 年 4 月 于 中 国 武 汉目 录 前 言 第 1 章 必 须 厘 清 的 核 心 概 念 / 1 1.1 堆 栈 /2 1.2 全 局 变 量 和 局 部 变 量 /5 1.3 生 存 期 和 作 用 域 /7 1.3.1 生 存 期 /7 1.3.2 作 用 域 /10 1.4 内 部 函 数 和 外 部 函 数 /11 1.5 指 针 变 量 /14 1.6 指 针 数 组 和 数 组 指 针 /17 1.7 指 针 函 数 和 函 数 指 针 /20 1.8 传

18、值 和 传 址 /22 1.9 递 归 和 嵌 套 /25 1.10 结 构 体 /29 1.11 共 用 体 /32 1.12 枚 举 /37 VII 1.13 位 域 /39 第 2 章 预 处 理 / 4 7 2.1 文 件 的 包 含 方 式 /48 2.2 宏 定 义 /50 2.2.1 简 单 宏 替 换 /50 2.2.2 带 参 数 的 宏 替 换 /52 2.2.3 嵌 套 宏 替 换 /56 2.3 宏 定 义 常 见 错 误 解 析 /56 2.3.1 不 带 参 数 的 宏 /56 2.3.2 带 参 数 的 宏 /59 2.4 条 件 编 译 指 令 的 使 用 /6

19、2 2.5 #pragma 指 令 的 使 用 /65 第 3 章 选 择 结 构 和 循 环 结 构 的 程 序 设 计 / 6 9 3.1 if 语 句 及 其 易 错 点 解 析 /70 3.2 条 件 表 达 式 的 使 用 /76 3.3 switch 语 句 的 使 用 及 注 意 事 项 /78 3.4 goto 语 句 的 使 用 及 注 意 事 项 /85 3.5 for 语 句 的 使 用 及 注 意 事 项 /87 3.6 while 循 环 与 do while 循 环 的 使 用 及 区 别 /92 3.7 循 环 结 构 中 break 、continue 、got

20、o 、return 和 exit 的 区 别 /98 第 4 章 数 组 / 1 0 3 4.1 一 维 数 组 的 定 义 及 引 用 /104 4.2 二 维 数 组 的 定 义 及 引 用 /110 4.3 多 维 数 组 的 定 义 及 引 用 /117 4.4 字 符 数 组 的 定 义 及 引 用 /119 4.5 数 组 作 为 函 数 参 数 的 易 错 点 解 析 /124 4.6 动 态 数 组 的 创 建 及 引 用 /130 VIII 第 5 章 指 针 / 1 3 9 5.1 不 同 类 型 指 针 之 间 的 区 别 和 联 系 /140 5.2 指 针 的 一 般

21、 性 用 法 及 注 意 事 项 /144 5.3 指 针 与 地 址 之 间 的 关 系 /148 5.4 指 针 与 数 组 之 间 的 关 系 /153 5.5 指 针 与 字 符 串 之 间 的 关 系 /161 5.6 指 针 与 函 数 之 间 的 关 系 /163 5.7 指 针 与 指 针 之 间 的 关 系 /169 第 6 章 数 据 结 构 / 1 7 2 6.1 枚 举 类 型 的 使 用 及 注 意 事 项 /173 6.2 结 构 体 变 量 的 初 始 化 方 法 及 引 用 /177 6.2.1 结 构 体 的 初 始 化 /177 6.2.2 结 构 体 的

22、引 用 /180 6.3 结 构 体 字 节 对 齐 详 解 /184 6.4 共 用 体 变 量 的 初 始 化 方 法 及 成 员 的 引 用 /193 6.5 传 统 链 表 的 实 现 方 法 及 注 意 事 项 /196 6.6 颠 覆 传 统 链 表 的 实 现 方 法 /214 6.6.1 头 结 点 的 创 建 /214 6.6.2 结 点 的 添 加 /215 6.6.3 结 点 的 删 除 /217 6.6.4 结 点 位 置 的 调 整 /219 6.6.5 检 测 链 表 是 否 为 空 /221 6.6.6 链 表 的 合 成 /222 6.6.7 宿 主 结 构 指

23、 针 /225 6.6.8 链 表 的 遍 历 /225 第 7 章 函 数 / 2 3 0 7.1 函 数 参 数 /231 7.2 变 参 函 数 的 实 现 方 法 /235 7.3 函 数 指 针 的 使 用 方 法 /241 7.4 函 数 之 间 的 调 用 关 系 /245 IX 7.5 函 数 的 调 用 方 式 及 返 回 值 /251 第 8 章 文 件 / 2 5 5 8.1 文 件 及 文 件 指 针 /256 8.2 EOF 和 FEOF 的 区 别 /259 8.3 读 写 函 数 的 选 用 原 则 /264 8.4 位 置 指 针 对 文 件 的 定 位 /27

24、0 8.5 文 件 中 的 出 错 检 测 /275 第 9 章 调 试 和 异 常 处 理 / 2 7 9 9.1 assert 宏 的 使 用 及 注 意 事 项 /280 9.2 如 何 设 计 一 种 灵 活 的 断 言 /283 9.3 如 何 实 现 异 常 处 理 /287 9.4 如 何 处 理 段 错 误 /293 第 1 0 章 陷 阱 知 识 点 解 剖 / 2 9 9 10.1 strlen 和 sizeof 的 区 别 /300 10.2 const 修 饰 符 /301 10.3 volatile 修 饰 符 /305 10.4 void 和 void* 的 区 别

25、 /311 10.5 #define 和 typedef 的 本 质 区 别 /314 10.6 条 件 语 句 的 选 用 /317 10.7 函 数 realloc 、malloc 和 calloc 的 区 别 /319 10.8 函 数 和 宏 /322 10.9 运 算 符 = 、= 和 ! = 的 区 别 /323 10.10 类 型 转 换 /324 第 1 1 章 必 须 掌 握 的 常 用 算 法 / 3 2 6 11.1 时 间 复 杂 度 /327 11.2 冒 泡 法 排 序 /329 11.3 选 择 法 排 序 /332 X 11.4 快 速 排 序 /334 11.

26、5 归 并 排 序 /337 11.6 顺 序 查 找 /340 11.7 二 分 查 找 /341 附 录 如 何 养 成 良 好 的 编 程 习 惯 / 3 4 4第 1 章 必 须 厘 清 的 核 心 概 念 1.1 堆 栈 1.2 全 局 变 量 和 局 部 变 量 1.3 生 存 期 和 作 用 域 1.4 内 部 函 数 和 外 部 函 数 1.5 指 针 变 量 1.6 指 针 数 组 和 数 组 指 针 1.7 指 针 函 数 和 函 数 指 针 1.8 传 值 和 传 址 1.9 递 归 和 嵌 套 1.10 结 构 体 1.11 共 用 体 1.12 枚 举 1.13 位

27、域2 C 语 言 进 阶 : 重 点 、 难 点 与 疑 点 解 析 人 或 多 或 少 都 有 一 点 惰 性 和 急 功 近 利 , 我 就 是 这 样 , 在 一 开 始 学 习 编 程 的 时 候 不 喜 欢 阅 读 那 些 枯 燥 的 文 字 , 喜 欢 直 接 去 阅 读 代 码 。 但 是 渐 渐 地 , 我 发 现 一 个 问 题 , 那 就 是 编 程 时 经 常 会 犯 一 些 低 级 的 错 误 。 通 过 总 结 才 明 白 , 这 些 错 误 源 于 自 己 对 C 语 言 中 的 基 本 概 念 一 知 半 解 , 知 其 然 , 不 知 其 所 以 然 , 发 现

28、 问 题 后 才 意 识 到 那 些 枯 燥 的 文 字 对 掌 握 并 熟 练 使 用 C 语 言 非 常 重 要 。 为 了 让 读 者 少 走 一 些 弯 路 , 本 书 的 第 1 章 先 来 介 绍 C 语 言 中 的 核 心 概 念 。 开 始 本 章 的 学 习 之 前 , 先 向 读 者 交 代 一 下 , 由 于 本 章 涉 及 的 知 识 范 围 较 广 , 有 些 初 学 者 理 解 起 来 会 有 些 吃 力 , 因 此 建 议 读 者 有 选 择 地 阅 读 , 遇 到 陌 生 知 识 点 可 以 暂 时 跳 过 , 待 学 习 了 后 面 章 节 的 内 容 后 再

29、 回 过 头 来 阅 读 这 一 章 的 相 关 内 容 。 当 然 , 学 习 代 码 的 最 佳 方 法 是 动 手 , 所 以 本 章 在 讲 解 C 语 言 的 一 些 基 本 概 念 的 同 时 , 为 了 便 于 读 者 理 解 , 有 针 对 性 地 列 举 了 一 些 代 码 , 读 者 也 可 以 通 过 这 些 代 码 来 验 证 所 学 的 概 念 , 体 会 学 习 的 乐 趣 , 以 避 免 单 纯 通 过 阅 读 文 字 来 枯 燥 地 学 习 概 念 。 1.1 堆 栈 不 少 人 可 能 对 堆 栈 的 概 念 并 不 清 楚 , 甚 至 部 分 从 事 计 算

30、 机 专 业 的 人 也 没 有 理 解 通 常 所 说 的 堆 栈 其 实 是 两 种 数 据 结 构 。 那 么 究 竟 什 么 是 堆 , 什 么 又 是 栈 呢 ? 接 下 来 , 我 们 就 来 看 看 它 们 各 自 的 概 念 。 栈 , 是 硬 件 , 主 要 作 用 表 现 为 一 种 数 据 结 构 , 是 只 能 在 一 端 插 入 和 删 除 数 据 的 特 殊 线 性 表 。 允 许 进 行 插 入 和 删 除 操 作 的 一 端 称 为 栈 顶 , 另 一 端 为 栈 底 。 栈 按 照 后 进 先 出 的 原 则 存 储 数 据 , 最 先 进 入 的 数 据 被

31、 压 入 栈 底 , 最 后 进 入 的 数 据 在 栈 顶 , 需 要 读 数 据 时 从 栈 顶 开 始 弹 出 数 据 。 栈 底 固 定 , 而 栈 顶 浮 动 。 栈 中 元 素 个 数 为 零 时 称 为 空 栈 。 插 入 一 般 称 为 进 栈 (push ) , 删 除 则 称 为 出 栈 (pop ) 。 栈 也 被 称 为 先 进 后 出 表 , 在 函 数 调 用 的 时 候 用 于 存 储 断 点 , 在 递 归 时 也 要 用 到 栈 。 在 计 算 机 系 统 中 , 栈 则 是 一 个 具 有 以 上 属 性 的 动 态 内 存 区 域 。 程 序 可 以 将

32、数 据 压 入 栈 中 , 也 可 以 将 数 据 从 栈 顶 弹 出 。 在 i386 机 器 中 , 栈 顶 由 称 为 esp 的 寄 存 器 进 行 定 位 。 压 栈 的 操 作 使 栈 顶 的 地 址 减 小 , 弹 出 的 操 作 使 栈 顶 的 地 址 增 大 。 栈 在 程 序 的 运 行 中 有 着 举 足 轻 重 的 作 用 。 最 重 要 的 是 , 栈 保 存 了 一 个 函 数 调 用 时 所 需 要 的 维 护 信 息 , 这 常 常 被 称 为 堆 栈 帧 。 栈 一 般 包 含 以 下 两 方 面 的 信 息 : 1 ) 函 数 的 返 回 地 址 和 参 数

33、 。 2 ) 临 时 变 量 : 包 括 函 数 的 非 静 态 局 部 变 量 及 编 译 器 自 动 生 成 的 其 他 临 时 变 量 。 堆 , 是 一 种 动 态 存 储 结 构 , 实 际 上 就 是 数 据 段 中 的 自 由 存 储 区 , 它 是 C 语 言 中 使 用 的 一 种 名 称 , 常 常 用 于 存 储 、 分 配 动 态 数 据 。 堆 中 存 入 的 数 据 地 址 向 增 加 方 向 变 动 。 堆 可 以 不 断 进 行 分 配 直 到 没 有 堆 空 间 为 止 , 也 可 以 随 时 进 行 释 放 、 再 分 配 , 不 存 在 顺 序 问 题 。

34、 堆 内 存 的 分 配 常 通 过 malloc() 、calloc() 、realloc() 三 个 函 数 来 实 现 。 而 堆 内 存 的 释 放 则 使 用 free() 函 数 。第 1 章 必 须 厘 清 的 核 心 概 念 3 堆 和 栈 在 使 用 时“ 生 长” 方 向 相 反 , 栈 向 低 地 址 方 向“ 生 长” , 而 堆 向 高 地 址 方 向“ 生 长” 。 我 们 对 于 堆 的 理 解 可 能 要 直 观 些 , 而 仅 从 概 念 上 理 解 栈 会 让 读 者 感 到 有 些 模 糊 。 为 了 加 深 读 者 对 于 栈 的 理 解 , 我 们 来

35、 看 一 个 C 语 言 题 目 。 这 个 题 目 要 求 在 不 传 递 参 数 的 情 况 下 , 在 print() 函 数 中 打 印 出 main() 函 数 中 arr 数 组 中 的 各 个 元 素 。 #include void print() / 填充代码 int main() int a=1;int b=2;char c=c;int arr=11,12,13,14,15,16,17;print();return 0; 注 意 如 无 特 殊 说 明 , 本 书 代 码 均 通 过 VC+6.0 来 编 译 运 行 。 看 看 上 面 的 代 码 和 相 关 要 求 , 可

36、 能 会 让 很 多 读 者 束 手 无 策 , 如 果 能 联 系 前 面 的 知 识 点 , 就 应 该 想 到 用 栈 。 那 么 我 们 该 如 何 来 解 决 问 题 呢 ? 先 别 急 , 在 讲 解 之 前 , 我 们 先 来 回 顾 几 个 知 识 点 。 1 )push 操 作 先 移 动 栈 顶 指 针 , 之 后 将 信 息 入 栈 。 2 )esp 为 堆 栈 指 针 , 栈 顶 由 esp 寄 存 器 来 定 位 。 压 栈 的 操 作 使 栈 顶 的 地 址 减 小 , 弹 出 的 操 作 使 栈 顶 的 地 址 增 大 。 3 ) ebp 是 32 位 的 bp

37、, 是 基 址 指 针 。bp 为 基 指 针 寄 存 器 , 用 它 可 直 接 存 取 堆 栈 中 的 数 据 , 它 在 调 用 函 数 时 保 存 esp , 以 便 函 数 结 束 时 可 以 正 确 返 回 。 4 ) 默 认 的 函 数 内 部 变 量 的 压 栈 操 作 为 : 从 上 到 下 、 从 左 向 右 , 采 用 4 字 节 对 齐 。 数 组 压 栈 方 法 略 有 不 同 , 即 从 最 后 一 个 元 素 开 始 , 直 到 起 始 元 素 为 止 , 即 采 用 从 右 向 左 的 方 法 压 栈 。 现 在 看 一 下 以 上 代 码 的 汇 编 代 码

38、, 在 main() 函 数 的 return 语 句 处 按 F9 键 设 置 一 个 断 点 , 然 后 按 F5 键 运 行 代 码 , 代 码 运 行 到 断 点 时 把 光 标 移 动 到 断 点 处 , 右 击 选 择 Go to Disassembly , 就 可 以 看 到 上 面 那 段 代 码 的 汇 编 代 码 了 。 我 们 发 现 , 在 main() 函 数 和 print() 函 数 的 开 头 都 有 如 下 两 句 汇 编 指 令 : push ebp mov ebp,esp 为 了 使 读 者 易 于 理 解 , 在 此 通 过 图 1-1 来 分 析 说

39、明 。 根 据 图 上 的 标 注 , 函 数 开 头 部 分 的4 C 语 言 进 阶 : 重 点 、 难 点 与 疑 点 解 析 第 一 个 push 指 令 的 操 作 步 骤 是 , 首 先 移 动 栈 顶 指 针 esp , 然 后 将 ebp 内 容 压 栈 , 注 意 此 时 压 栈 的 ebp 的 值 为 上 一 个 函 数 的 esp 的 值 , 而 esp 恰 好 就 是 上 一 个 函 数 的 栈 底 , 所 以 每 个 函 数 一 开 始 的 push 指 令 就 是 保 存 上 一 个 函 数 的 栈 底 。 那 么 接 下 来 的 mov 指 令 有 什 么 作 用

40、 呢 ? 由 于 esp 是 当 前 的 栈 顶 指 针 , 所 以 该 指 令 的 作 用 就 是 保 存 当 前 栈 顶 指 针 的 值 。 由 此 就 可 以 分 析 出 ,ebp 存 放 的 是 此 刻 栈 顶 的 地 址 , 就 是 说 ,ebp 是 一 个 指 针 , 指 向 栈 顶 , 而 栈 顶 存 放 的 数 据 其 实 是 上 一 个 函 数 的 ebp 的 值 , 即 上 一 个 函 数 的 栈 底 。 图 1-1 函 数 调 用 过 程 中 的 压 栈 流 程 通 过 上 面 的 分 析 可 知 ,ebp 压 栈 后 , 接 着 就 是 函 数 中 临 时 变 量 的

41、压 栈 操 作 , 由 此 可 知 , 我 们 只 需 要 在 print() 函 数 中 得 到 main() 函 数 的 栈 底 , 就 可 以 取 出 数 组 中 的 每 个 元 素 了 , 看 看 下 面 的 实 现 方 法 。 #include void print() unsigned int _ebp;_asmmov _ebp,ebpint *p=(int *)(*(int *)_ebp-4-4-4-7*4);for(int i=0;i7;i+)printf(“%dt“,pi); int main() int a=1;int b=2;char c=a;int arr=11,12,

42、13,14,15,16,17;第 1 章 必 须 厘 清 的 核 心 概 念 5print();return 0; 运 行 结 果 为 : 11 12 13 14 15 16 17 在 没 有 传 递 任 何 参 数 的 情 况 下 , 成 功 地 在 print() 函 数 中 打 印 出 了 main() 函 数 中 arr 数 组 内 的 每 个 元 素 。 现 在 来 看 看 上 面 代 码 的 实 现 方 法 , 在 print() 函 数 中 定 义 了 一 个 _ebp 无 符 号 整 型 变 量 , 通 过 VC+ 6.0 内 嵌 汇 编 把 ebp 的 值 保 持 到 _eb

43、p 中 , 按 照 上 面 的 分 析 , 可 以 将 在 函 数 print() 中 通 过 这 条 内 嵌 汇 编 语 句 得 到 的 ebp 看 成 一 个 指 针 , 指 针 所 指 向 的 单 元 存 放 的 就 是 print() 函 数 的 上 一 个 函 数 的 栈 底 , 在 此 是 main() 函 数 的 栈 底 。 知 道 了 _ebp 的 作 用 后 , 我 们 来 分 析 下 代 码 , 通 过 (int*)_ebp 将 _ebp 转 换 为 一 个 整 型 指 针 , 然 后 通 过 *(int*)_ebp 即 可 得 到 main() 函 数 的 栈 底 地 址

44、 。 由 于 栈 的 压 栈 操 作 是 从 上 到 下 、 从 右 到 左 的 , 所 以 main() 函 数 中 的 变 量 a 先 压 栈 , 然 后 是 b 、 c , 最 后 是 arr 数 组 , 数 组 的 压 栈 顺 序 是 从 右 到 左 。 通 过“int *p=(int *)(*(int *)_ebp-4-4-4-7*4);” 即 可 得 到 数 组 元 素 的 首 地 址 。 接 下 来 , 根 据 首 地 址 就 可 以 取 出 数 组 中 的 每 个 元 素 了 。 有 的 读 者 可 能 会 有 一 个 疑 惑 ,main() 函 数 中 有 一 个 字 符 型

45、 变 量 , 是 不 是 在 求 数 组 元 素 的 首 地 址 时 应 该 把 其 中 的 减 4 改 为 减 1 呢 ? 因 为 它 只 占 用 了 一 个 字 节 ! 即 将“int *p=(int *)(*(int *)_ebp-4-4-4-7*4);” 修 改 为“int *p=(int *)(*(int *)_ebp-4-4-1- 7*4)” 。 我 们 暂 且 不 说 其 对 与 错 , 先 来 看 看 修 改 后 的 运 行 结 果 : 3072 3328 3584 3840 4096 4352 -859021056 我 们 发 现 这 样 的 运 行 结 果 是 错 误 的

46、, 为 什 么 呢 ? 细 心 的 读 者 可 能 发 现 了 本 章 一 开 始 回 顾 的 知 识 点 中 有 一 点 是 很 重 要 的 , 那 就 是 压 栈 操 作 为 4 字 节 对 齐 。 所 以 这 里 必 须 减 4 , 而 不 是 减 1 。 通 过 上 面 的 分 析 , 希 望 读 者 能 够 对 栈 有 更 加 深 入 的 理 解 , 而 对 于 堆 的 使 用 我 们 会 在 后 续 章 节 详 细 讲 解 。 1.2 全 局 变 量 和 局 部 变 量 全 局 变 量 , 也 称 外 部 变 量 , 在 函 数 体 外 定 义 , 不 是 哪 一 个 函 数 所

47、特 有 的 。 全 局 变 量 又 可 以 分 为 外 部 全 局 变 量 和 静 态 全 局 变 量 , 它 们 之 间 的 最 大 区 别 在 于 , 使 用 static 存 储 类 别 的 全 局 变 量 只 能 在 被 定 义 的 源 程 序 文 件 中 使 用 , 而 使 用 extern 存 储 类 别 的 全 局 变 量 不 仅 可 以 在 被 定 义 的 源 程 序 文 件 中 使 用 , 还 可 以 被 其 他 源 文 件 中 的 函 数 引 用 。 如 果 要 在 函 数 中 使 用 全 局 变 量 , 那 么 通 常 需 要 作 全 局 变 量 说 明 。 只 有 在

48、函 数 内 经 过 说 明 的 全 局 变 量 才 能 使 用 。 但 在 一 个 函 数 之 前 定 义 的 全 局 变 量 , 在 该 函 数 内 使 用 可 不 再 加 以 说 明 。 例 如 : #include 6 C 语 言 进 阶 : 重 点 、 难 点 与 疑 点 解 析 int a=0; void print(void) printf(“global variable a=%dn“, a); int main(void) print();return 0; 因 为 全 局 变 量 a 在 print() 函 数 之 前 定 义 , 所 以 在 print() 函 数 中 使

49、用 a 时 无 需 说 明 , 但 是 下 面 的 代 码 在 运 行 时 会 出 错 。 #include void print(void) printf(“global variable a=%dn“, a); int a=0; int main(void) print();return 0; 因 为 全 局 变 量 a 的 定 义 出 现 在 print() 函 数 之 后 , 所 以 在 print() 函 数 中 使 用 a 时 需 要 说 明 , 应 该 在 print() 函 数 的 printf 语 句 上 面 加 一 句“extern int a;” 来 说 明 , 这 样 才 可 以 使 用 全 局 变 量 。 局 部 变 量 是 相 对 于 全 局 变 量 而 言 的 , 即 在 函 数 中 定 义 的 变 量 称 为 局 部 变 量 。 当 然 , 由 于 形 参 相 当 于 在 函 数 中 定 义 的 变 量 , 所 以 形 参 也 是 一 种 局 部 变 量 。 我 们 可 以 通 过 图

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报