📄 45.asp
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<TITLE>VB 程式设计内功讲座(三)</TITLE>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=big5">
<META NAME="Generator" CONTENT="Microsoft Word 97">
<META NAME="Template" CONTENT="C:\PROGRAM FILES\OFFICE97\OFFICE\html.dot">
<META NAME="GENERATOR" CONTENT="Mozilla/3.01Gold (Win95; I) [Netscape]">
</HEAD>
<BODY TEXT="#000000" BGCOLOR="#FFFFFF" LINK="#0000FF" VLINK="#800080" ALINK="#FF0000">
<P>VB 程 式 设 计 内 功 讲 座 (三) - 王 国 荣 </P>
<H1>除 错 ─ 增 加 内 功 必 经 之 道</H1>
<P>
<HR WIDTH="100%">几 乎 所 有 角 色 扮 演 的 电 动 都 有 一 个 共 通 的
特 点 , 那 就 是 主 角 一 开 始 都 很 弱 , 但 随 著 打 败 的 敌 人 越
来 越 多 , 主 角 的 功 力 也 會 越 来 越 强 , 程 式 设 计 的 道 理 也
是 相 同 的 , 再 多 的 理 论 都 比 不 上 动 手 去 写 程 式 , 而 写 程
式 所 面 临 的 主 要 敌 人 就 是 bug, 同 样 的 随 著 除 过 的 bug 越 来
越 多 , 程 式 设 计 者 的 功 力 也 會 越 来 越 强 。 </P>
<P> </P>
<P>Bug 是 什 麼 ? 有 一 句 名 言 最 能 诠 释 bug 的 意 义 :「电 脑 是
按 照 指 令 行 事 , 而 不 是 人 的 意 志」, 当 人 将 其 意 志 转 化 成
指 令 下 给 电 脑 之 後 , 而 电 脑 执 行 的 结 果 与 人 的 意 志 不 符
时 , 便 是 bug。 </P>
<P> </P>
<P>怎 样 下 指 令 给 电 脑 呢 ? 若 是 一 般 的 使 用 者 , 使 用 的 是
作 业 系 统 所 提 供 的 指 令 (例 如 copy 指 令 )或 应 用 程 式 所 提 供
的 操 作 介 面 (当 使 用 者 操 作 应 用 程 式 时 , 应 用 程 式 即 已 代
替 使 用 者 下 指 令 给 电 脑 了 )。 </P>
<P> </P>
<P>然 而 对 程 式 设 计 人 员 而 言 , 下 指 令 给 电 脑 的 过 程 就 比
较 复 杂 了 , 首 先 必 须 选 取 适 当 的 程 式 语 言 , 然 後 将 自 己
期 望 电 脑 做 的 事 情 表 示 成 程 式 语 言 , 接 著 再 利 用 程 式 开
发 工 具 编 译 成 执 行 档 , 最 後 才 经 由 作 业 系 统 所 提 供 的 指
令 载 入 执 行 档 , 由 电 脑 开 始 执 行 , 理 论 上 , 以 上 的 每 一
个 过 程 都 可 能 发 生 错 误 , 例 如 程 式 语 言 选 错 了 、 程 式 写
错 了 、 编 译 器 有 bug 而 编 译 出 错 误 的 执 行 档 、 作 业 系 统 有
bug… , 想 一 想 还 真 可 怕 , 到 处 都 可 能 有 bug, 这 也 莫 怪 有
人 要 说「软 体 是 高 风 险 的 事 业」。 </P>
<P> </P>
<P>不 过 本 文 所 讨 论 的 范 围 仅 局 限 於「程 式 写 错」的 部 分 ,
首 先 我 们 只 能 假 设 编 译 器 是 没 有 错 的 , 作 业 系 统 是 没 有
错 的 , 这 就 好 像 我 们 搭 飞 机 以 前 必 须 假 设 飞 机 是 不 會 出
事 的 一 样 , 如 果 您 十 分 在 乎 飞 机 、 编 译 器 、 作 业 系 统 的
极 少 数 出 错 情 况 , 那 麼 笔 者 只 能 说 , 别 搭 飞 机 , 也 别 当
个 程 式 设 计 人 员 。 </P>
<P> </P>
<P>有 句 话 说 :「人 非 圣 贤 , 孰 能 无 过」, 而 笔 者 想 说 的 是「程
式 设 计 无 圣 贤」, 从 开 始 写 第 一 行 程 式 就 不 會 出 错 , 笔 者
未 曾 听 过 啊 ! 知 错 能 改 , 乃 程 式 设 计 之 根 本 大 法 也 。 记
得 以 前 在 学 校 的 时 候 , 老 师 总 喜 欢 讲「知 错 能 改 , 善 莫 大
焉」, 当 老 师 者 焉 知 数 学 题 作 错 了 , 就 是 不 懂 啊 ! 不 懂 者
又 如 何 知 错 , 又 如 何 能 改 呢 ? 对 程 式 设 计 来 说 , 道 理 也
是 相 同 的 ,「知 错 能 改」说 得 简 单 , 做 起 来 却 十 分 困 难 ,
笔 者 写 了 十 几 年 的 程 式 , 还 是 必 须 面 临 bug 上 身 的 问 题 ,
不 过 也 正 因 为 如 此 , 本 期 要 与 您 谈 一 谈 除 错 的 方 法 ! </P>
<P> </P>
<H1>肉 眼 除 错 法 </H1>
<P> </P>
<P>肉 眼 除 错 指 的 是 将 程 式 印 出 来 或 是 盯 著 萤 幕 一 行 一 行
检 查 , 这 听 起 来 有 点 不 太 入 流 , 主 要 的 缺 点 是 这 个 方 法
的 除 错 效 率 不 高 , 尤 其 对 於 自 己 写 的 程 式 , 总 认 为 程 式「应
该」按 照 自 己 的 意 思 执 行 , 而 没 有 看 出 程 式「实 际 上」是 怎
麼 执 行 的 。 </P>
<P> </P>
<P>肉 眼 所 观 察 出 来 的 错 误 , 通 常 都 还 不 是 十 分 肯 定 , 因
此 接 下 来 是 修 改 程 式 、 编 译 、 联 结 、 测 试 , 然 後 才 能 确
定 是 否 找 到 了 错 误 , 如 果 肉 眼 除 错 一 直 无 法 找 出 错 误 ,
那 麼「侦 错 、 修 改 程 式 、 编 译 、 联 结 、 测 试」等 动 作 就 得
一 再 重 来 , 非 常 浪 费 时 间 。 </P>
<P> </P>
<P>肉 眼 除 错 与 程 式 设 计 人 员 对 程 式 语 言 的 瞭 解 也 有 极 大
的 关 系 , 笔 者 并 不 全 然 反 对 这 个 方 法 , 因 为 在 侦 错 的 过
程 中 , 程 式 员 通 常 會 去 思 索 程 式 为 什 麼 错 了 , 这 对 程 式
语 言 的 瞭 解 颇 有 帮 助 , 而 且 也 可 以 训 练 程 式 员 对 於 错 误
的 敏 锐 性 , 不 过 就 像 前 面 所 说 的 , 这 个 方 法 的 效 率 不 高
, 除 了 给 自 己 这 方 面 的 训 练 之 外 , 别 忘 了「时 程 控 制」在
程 式 开 发 中 也 是 非 常 重 要 的 一 件 事 , 因 此 请 再 参 考 以 下
更 有 效 率 的 除 错 技 巧 。 </P>
<P> </P>
<H1>使 用 VB 的 侦 错 功 能 </H1>
<P> </P>
<P>VB 所 提 供 的 侦 错 功 能 相 当 丰 富 , 值 得 一 试 。 </P>
<P> </P>
<H2>侦 测 的 对 象 与 侦 测 的 工 具 </H2>
<P> </P>
<P>程 式 错 了 , 侦 测 的 对 象 不 外 乎 程 式 码 或 资 料 (变 数 及 物
件 ), 而 这 两 者 的 关 系 是 : 程 式 码 是「因」、 资 料 是「果」,
虽 然 说 我 们 要 找 出 错 误 的 因 , 但 是 在 侦 测 的 过 程 中 , 却
必 须 从 果 来 著 手 , 因 为 果 比 因 来 得 容 易 观 察 , 直 到 发 现
某 一 资 料 的 结 果 错 误 时 , 再 逐 步 清 查 错 误 原 因 。 </P>
<P> </P>
<P>在 检 视「果」(资 料 )的 功 能 中 , VB 所 提 供 的 有 : </P>
<P> </P>
<DIR>
<P>◇ 即 时 运 算 视 窗 : 即 时 运 算 视 窗 是 一 个 BASIC 语 言 的 编
译 器 , 我 们 在 里 面 所 输 入 的 指 令 将 會 立 刻 被 执 行 , 因 此
当 我 们 怀 疑 某 个 变 数 可 能 有 错 时 , 只 要 利 用「? 变 数 名 称」即
可 加 以 检 验 , 此 外 , 它 也 可 以 用 来 执 行 副 程 式 、 函 数 、
及 合 法 的 VB 叙 述 。 </P>
<P> </P>
<P>◇ 区 域 变 数 视 窗 : 当 我 们 将 程 式 中 断 於 某 一 个 程 序 (包
含 副 程 式 、 函 数 、 及 事 件 程 序 )时 , 区 域 变 数 视 窗 就 會 显
示 该 程 序 的 所 有 区 域 变 数 , 如 此 一 来 , 不 必 在 即 时 运 算
视 窗 输 入「? 变 数 名 称」即 可 以 看 到 区 域 变 数 的 内 容 。 区 域
变 数 视 窗 除 了 會 显 示 某 一 程 序 的 区 域 变 数 之 外 , 也 會 显
示 该 程 序 所 在 模 组 的 全 域 变 数 。 </P>
<P> </P>
<P>◇ 监 看 视 窗 : 区 域 变 数 视 窗 會 显 示 所 有 区 域 变 数 的 内
容 , 但 如 果 变 数 过 多 , 便 不 容 易 观 察 , 监 看 视 窗 则 只 显
示 特 别 观 察 的 变 数 。 </P>
<P> </P>
<P>◇ 程 式 视 窗 : 程 式 视 窗 是 检 测 程 式 码 执 行 过 程 的 视 窗
, 不 过 VB5 特 别 增 加 了 一 个 方 便 的 功 能 : 在 中 断 模 式 底 下
, 只 要 将 滑 鼠 游 标 移 到 变 数 的 上 面 , 程 式 视 窗 即 會 以 黄
色 条 块 显 示 该 变 数 的 内 容 。 </P>
<P> </P>
</DIR>
<P>以 上 的 功 能 座 落 在 功 能 表 的「检 视」栏 底 下 。 </P>
<P> </P>
<P>在 检 测「因」(程 式 码 )方 面 , VB 所 提 供 的 功 能 有 : </P>
<P> </P>
<DIR>
<P>◇ 设 定 中 断 点 : 可 将 某 一 行 叙 述 设 定 成 中 断 点 , 则 当
程 式 执 行 到 此 一 叙 述 时 , 程 式 即 會 进 入 中 断 模 式 , 而 只
有 在 中 断 模 式 底 下 , 我 们 才 能 够 利 用 即 时 运 算 视 窗 、 区
域 变 数 视 窗 、 监 看 视 窗 、 及 程 式 视 窗 检 视 变 数 的 内 容 。
</P>
<P> </P>
<P>◇ 逐 行 执 行 : 每 执 行 一 行 叙 述 程 式 即 进 入 中 断 模 式 ,
此 一 功 能 可 让 我 们 检 视 每 一 行 叙 述 执 行 前 後 的 结 果 。 </P>
<P> </P>
<P>◇ 逐 程 序 执 行 : 与 逐 行 执 行 类 似 , 但 遇 到 程 序 的 呼 叫
时 , 會 执 行 过 被 呼 叫 程 序 的 所 有 叙 述 , 才 中 断 於 呼 叫 程
序 端 的 下 一 行 叙 述 。 </P>
<P> </P>
<P>◇ 跳 出 程 序 : 当 程 式 中 断 於 某 一 个 程 序 , 而 我 们 不 想
再 逐 行 执 行 时 , 此 时 可 以 使 用 此 一 功 能 一 路 执 行 完 此 一
程 序 , 而 让 中 断 点 回 到 呼 叫 端 的 下 一 个 叙 述 。 (请 注 意 此
一 功 能 并 非 脱 离 程 序 不 执 行 )</P>
<P> </P>
<P>◇ 执 行 至 游 标 处 : 在 某 一 程 序 中 , 既 不 想 逐 行 执 行 ,
也 不 想 跳 出 程 序 , 可 以 先 将 输 入 游 标 设 定 於 某 一 叙 述 (在
叙 述 上 面 按 下 滑 鼠 ), 然 後 选 取 此 一 功 能 , 则 程 式 會 执 行
到 输 入 游 标 处 , 方 才 中 断 。 </P>
<P> </P>
<P>◇ 设 定 下 个 执 行 点 : 此 一 功 能 有 点 像 是 VB 的 Goto 叙 述
, 将 會 跳 过 (不 执 行 )中 间 的 所 有 叙 述 。 </P>
<P> </P>
<P>◇ 呼 叫 堆 叠 : 可 显 示 程 序 呼 叫 的 所 有 历 程 。 </P>
</DIR>
<P> </P>
<P>以 上 的 功 能 除 了「呼 叫 堆 叠」位 於 功 能 表 的「检 视」栏 底 下
之 外 , 其 他 功 能 则 座 落 在 功 能 表 的「侦 错」栏 底 下 。 </P>
<P> </P>
<H2>中 断 程 式 的 几 种 方 法 </H2>
<P> </P>
<P>程 式 执 行 时 是 无 法 侦 错 的 , 我 们 一 定 要 先 让 程 式 停 下
来 , 才 能 检 测 各 个 变 数 的 内 容 , 所 以 使 用 VB 侦 错 功 能 的
第 一 步 是 让 VB 程 式 能 够 停 下 来 , 而 以 下 是 中 断 程 式 方 法
: </P>
<P> </P>
<H3>设 定 中 断 点 </H3>
<P> </P>
<P>开 启 程 式 视 窗 , 在 我 们 希 望 中 断 的 叙 述 上 面 按 下 F9,
则 将 来 程 式 执 行 到 此 一 叙 述 时 , 即 會 进 入 中 断 模 式 , 此
时 我 们 可 以 使 用 各 种 检 视 变 数 的 功 能 来 检 查 截 至 此 一 叙
述 以 前 执 行 的 结 果 。 (特 别 注 意 : 所 谓 中 断 点 是 还 没 有 执
行 的 叙 述 , 不 是 已 经 执 行 而 停 下 来 的 叙 述 )</P>
<P> </P>
<P>设 定 中 断 点 的 另 一 个 方 法 是 使 用 Stop 叙 述 , 当 程 式 执
行 到 Stop 叙 述 时 , 也 會 进 入 中 断 模 式 。 使 用 Stop 叙 述 有 一
得 及 一 失 , 得 的 方 面 是 中 断 点 可 以 储 存 在 程 式 之 中 , 不
像 F9 所 设 定 的 中 断 点 , 在 专 案 结 束 时 即 告 消 失 , 失 的 方
面 则 是 含 有 Stop 叙 述 的 程 式 被 编 译 成 执 行 档 之 後 , 只 要
程 式 值 执 行 到 Stop 叙 述 即 會 结 束 执 行 , 这 使 得 我 们 在 程
式 编 译 成 执 行 档 之 前 必 须 把 所 有 的 Stop 叙 述 拿 掉 。 </P>
<P> </P>
<H3>发 生 了 可 处 理 错 误 </H3>
<P> </P>
<P>程 式 的 错 误 按 严 重 性 可 分 成「不 可 处 理」与「可 处 理」两 种
, 在 Windows 环 境 底 下 , 有 时 候 我 们 會 看 到 如 图 -1的 讯 息 窗
, 当 程 式 出 现 此 一 讯 息 窗 时 , 就 难 逃 被 踢 出 系 统 的 命 运
, 此 为 程 式 发 生 了 不 可 处 理 的 错 误 。 </P>
<P> </P>
<CENTER><P><IMG SRC="45-1.gif" HEIGHT=133 WIDTH=404></P></CENTER>
<CENTER><P>图 -1 不 可 处 理 的 错 误 所 显 示 的 讯 息 窗 </P></CENTER>
<P> </P>
<P>不 可 处 理 的 错 误 最 常 发 生 於 程 式 企 图 将 资 料 写 入 於 不
该 写 入 的 记 忆 体 之 中 , 一 般 而 言 , C/C++ 程 式 由 於 可 直 接
操 作 记 忆 体 的 位 址 , 最 容 易 发 生 这 种 事 情 , VB 程 式 则 由
於 无 法 直 接 操 作 记 忆 体 的 位 址 , 绝 少 发 生 类 似 於 C/C++ 的
错 误 , 因 此 本 文 只 讨 论 可 处 理 的 错 误 。 </P>
<P> </P>
<P>发 生 可 处 理 的 错 误 时 , VB 會 显 示 错 误 的 讯 息 窗 , 例 如
某 一 阵 列 X 的 注 标 范 围 是 0 到 3, 则 执 行「X(4) = 123」时 将 會
产 生 如 图 -2的 可 处 理 错 误 。 </P>
<P> </P>
<CENTER><P><IMG SRC="45-2.gif" HEIGHT=188 WIDTH=376></P></CENTER>
<CENTER><P>图 -2 VB 所 显 示 的 可 处 理 错 误 </P></CENTER>
<P> </P>
<P>此 时 我 们 若 按 下「侦 错」钮 , 即 可 使 程 式 进 入 中 断 模 式
, 而 此 时 中 断 点 将 停 留 在 发 生 错 误 的 叙 述 上 面 。 由 於 可
处 理 的 错 误 是 VB 侦 测 出 来 的 , 接 下 来 进 入 中 断 模 式 之 後
, 我 们 甚 至 可 以 把 错 误 的 叙 述 改 掉 , 然 後 继 续 执 行 程 式
。 </P>
<P> </P>
<H3>按 下 Ctrl + Break 键 </H3>
<P> </P>
<P>不 管 任 何 时 间 , 只 要 我 们 按 下 Ctrl+Break 键 , 则 VB 程 式
即 會 进 入 中 断 模 式 , 此 一 方 法 在 程 式 进 入 无 穷 回 圈 时 最
为 实 用 , 例 如 以 下 程 式 : </P>
<P> </P>
<DIR>
<P>Dim A As Single</P>
<P>A = 0</P>
<P>Do</P>
<P>A = A + 0.01</P>
<P>Loop Until A = 1</P>
<P> </P>
</DIR>
<P>乍 看 之 下 , 程 式 并 不 會 进 入 无 穷 回 圈 , 但 实 际 上 却 因
为 电 脑 处 理 小 数 点 时 會 有 些 微 的 误 差 , 以 致 A 不 會 刚 好
等 於 1, 而 使 得 程 式 进 入 了 无 穷 回 圈 , 当 程 式 进 入 无 穷 回
圈 时 , VB 可 以 说 是 动 弹 不 得 , 唯 独 Ctrl+Break 可 以 中 断 程
式 。 </P>
<P> </P>
<H3>以 F8 键 启 动 程 式 的 执 行 </H3>
<P> </P>
<P>在 VB 的 工 作 环 境 底 下 , 按 下 F5 执 行 程 式 是 最 普 遍 的 方
式 , 而 按 下 F5 执 行 程 式 必 须 采 用 上 述 的 方 法 才 能 够 中 断
程 式 , 如 果 我 们 一 开 始 就 按 下 F8, 也 可 以 执 行 程 式 , 但
将 来 只 要 执 行 一 行 叙 述 , 程 式 便 會 进 入 中 断 模 式 , 接 著
在 中 断 模 式 底 下 , 只 要 我 们 继 续 按 下 F8, 则 仍 然 维 持 一
次 执 行 一 行 叙 述 的 方 式 , 这 是 VB 所 提 供 的 逐 行 执 行 的 功
能 。 </P>
<P> </P>
<H2>侦 错 案 例 研 究 </H2>
<P> </P>
<P>VB 所 提 供 的 侦 错 功 能 的 确 不 少 , 当 我 们 进 行 程 式 的 侦
错 时 , 该 如 何 选 择 适 当 的 功 能 呢 ? 以 下 让 笔 者 以 实 例 的
案 例 来 说 明 。 </P>
<P> </P>
<H3>「逐 行 执 行」与「区 域 变 数 视 窗」的 搭 配 </H3>
<P> </P>
<P>对 於 刚 刚 写 好 而 又 没 有 呼 叫 其 他 自 定 程 序 的 程 式 而 言
, 使 用 逐 行 执 行 来 测 试 最 为 适 合 , 举 例 来 说 , 以 下 是 一
个 互 换 两 个 变 数 内 容 的 副 程 式 : </P>
<P> </P>
<DIR>
<DIR>
<P>Sub Swap(A, B)</P>
<DIR>
<P>Dim temp<BR>
temp = A<BR>
A = B<BR>
B = temp</P>
</DIR>
<P>End Sub</P>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -