pl004.asp
来自「ASPWeb数据库范例总览」· ASP 代码 · 共 792 行 · 第 1/3 页
ASP
792 行
号 的 优 先 顺 序 上 , 其 中 BASIC 的 / 其 优 先 顺 序 大 於 Mod, 所
以 结 果 等 於 10 Mod (6 / 2), 而 C 语 言 的 / 其 优 先 顺 序 与 % 相
同 , 所 以 运 算 结 果 等 於 (10 % 6) / 2。 </P>
<P>以 上 提 出 BASIC 及 C 语 言 的 差 异 , 并 不 是 要 您 去 熟 悉 所
有 程 式 语 言 在 运 算 元 上 的 优 先 顺 序 , 只 是 提 醒 您 在 数 学
运 算 式 中 应 该 注 意 这 件 事 , 而 最 保 险 的 方 法 是 利 用 (),
只 要 是 没 有 把 握 而 又 必 须 优 先 运 算 的 运 算 符 号 , 一 概 加
上 () 就 对 了 。 </P>
</UL>
<P><B><U><FONT COLOR="#000080"><FONT SIZE=+1>错 误 类 型 之 五 : 不 同
型 别 的 运 算 </FONT></FONT></U></B></P>
<UL>
<P>一 支 鸡 加 一 支 鸡 等 於 两 支 鸡 , 但 一 支 鸡 加 一 条 狗 等 於
什 麼 呢 ? 这 就 好 像 "ABC" 加 100 是 没 有 意 义 的 , 大
部 份 的 情 形 , 型 态 「 不 同 」 的 变 数 是 不 能 在 一 起 运 算 的
, 不 过 为 了 增 加 程 式 撰 写 上 的 弹 性 , 有 一 大 半 的 程 式 语
言 允 许 型 态 「 相 容 」 的 变 数 互 相 作 运 算 , 例 如 整 数 与 浮
点 数 的 加 减 , 有 时 候 这 的 确 很 方 便 , 但 这 个 方 便 之 门 也
开 启 了 bug 之 门 。 </P>
<P><FONT COLOR="#800000">错 误 实 例 之 一 :</FONT> </P>
<P>A 先 生 过 去 一 直 以 BASIC 开 发 程 式 , 最 近 因 工 作 需 要 改
用 C 语 言 , 他 将 一 「 计 算 平 均 数 」 的 程 式 段 直 接 由 BASIC
改 成 C 。 </P>
<UL>
<ADDRESS><FONT COLOR="#000080">' 原 BASIC 程 式 </FONT></ADDRESS>
<ADDRESS><FONT COLOR="#000080">Dim sum As Integer </FONT></ADDRESS>
<ADDRESS><FONT COLOR="#000080">Dim average As Single </FONT></ADDRESS>
<ADDRESS><FONT COLOR="#000080">sum = 0 </FONT></ADDRESS>
<ADDRESS><FONT COLOR="#000080">For i = 1 To 10 </FONT></ADDRESS>
<UL>
<ADDRESS><FONT COLOR="#000080">sum = sum + I </FONT></ADDRESS>
</UL>
<ADDRESS><FONT COLOR="#000080">Next </FONT></ADDRESS>
<ADDRESS><FONT COLOR="#000080">average = sum / 10 </FONT></ADDRESS>
</UL>
<P>// 转 换 成 C 以 後 的 程 式 </P>
<UL>
<ADDRESS><FONT COLOR="#000080">int sum; </FONT></ADDRESS>
<ADDRESS><FONT COLOR="#000080">float average; </FONT></ADDRESS>
<ADDRESS><FONT COLOR="#000080">sum = 0 ; </FONT></ADDRESS>
<ADDRESS><FONT COLOR="#000080">for( i = 1; i <= 10; i++) </FONT></ADDRESS>
<UL>
<ADDRESS><FONT COLOR="#000080">sum = sum + i ; </FONT></ADDRESS>
</UL>
<ADDRESS><FONT COLOR="#000080">average = sum / 10 ; </FONT></ADDRESS>
</UL>
<P><FONT COLOR="#800000">错 误 说 明 : </FONT></P>
<P>请 注 意 这 个 程 式 中 的 sum 是 整 数 , 而 average 是 浮 点 数 ,
一 般 来 说 , 浮 点 数 的 数 值 范 围 比 整 数 来 得 大 , 所 以 将 整
数 指 定 给 浮 点 数 并 不 會 有 什 麼 问 题 , 这 个 例 子 所 出 的 问
题 其 实 是 在 除 号 (/)上 面 , 对 於 BASIC 来 说 , 以 / 所 运 算 出
来 的 结 果 均 表 示 成 「 浮 点 数 」 , 所 以 「 sum / 10」 所 得 到
的 结 果 是 55.0 / 10 = 5.5, 至 於 C 语 言 则 會 先 检 查 / 号 两 边
的 资 料 型 态 , 然 後 再 选 择 数 值 范 围 较 大 的 资 料 型 别 作 为
运 算 的 根 據 , 以 「 sum / 10」 来 说 , 两 边 的 资 料 型 态 均 为
整 数 , 所 以 执 行 时 采 整 数 的 运 算 方 式 , 於 是 结 果 变 成 55
/ 10 = 5。 </P>
<P><FONT COLOR="#008000">注 : BASIC 的 另 一 个 运 算 符 号 \ 也 是 用
来 当 作 除 号 , 但 其 运 算 结 果 则 一 概 表 示 成 整 数 , 以 55 \
10 为 例 , 其 结 果 等 於 5, 而 55.0 \ 10 的 结 果 也 是 5。 </FONT></P>
<P>如 果 想 让 前 面 的 C 程 式 得 到 正 确 的 结 果 有 三 个 方 法 :
(1) 把 被 除 数 sum 的 资 料 型 态 改 成 浮 点 数 , (2) 在 被 除 数 sum
的 前 面 加 上 (float), 意 思 是 在 运 算 前 强 制 将 sum 转 成 浮 点
数 , (3) 把 除 数 10 改 成 浮 点 型 态 的 10.0。 </P>
<P><FONT COLOR="#800000">错 误 实 例 之 二 : </FONT></P>
<P>中 文 字 是 由 两 个 字 元 所 组 成 的 , 其 中 第 一 个 字 元 一 定
大 於 等 於 128( = 16 进 位 的 80) , 以 下 的 C 语 言 程 式 段 就 用
这 个 原 则 来 判 断 字 串 第 一 个 字 是 否 为 中 文 字 。 </P>
<UL>
<ADDRESS><FONT COLOR="#000080">char the_word[] = "我 是 中 文 字 ";
</FONT></ADDRESS>
<ADDRESS><FONT COLOR="#000080">if ( the_word[0] >= 128 ) </FONT></ADDRESS>
<UL>
<ADDRESS><FONT COLOR="#000080">printf("%s 的 第 一 个 字 是 中 文
", the_word) ; </FONT></ADDRESS>
</UL>
</UL>
<P>结 果 printf() 并 没 有 被 执 行 , 这 表 示 the_word[0] >= 128 为
FALSE。 </P>
<P><FONT COLOR="#800000">错 误 说 明 : </FONT></P>
<P>「 我 」 是 中 文 字 , 所 以 它 的 第 一 个 字 元 一 定 大 於 128,
而 在 「 the_word[] = "我 是 中 文 字 ";」 的 设 定 之 後 ,
the_word[0] 变 成 了 「 我 」 的 第 一 个 字 元 , 所 以 the_word[0] >=
128 应 该 为 TRUE。 </P>
<P>问 题 点 就 出 在 the_word 的 资 料 型 态 上 , 由 於 它 被 宣 告 成
char, 而 C 语 言 中 char 是 含 有 正 负 值 的 1 byte 资 料 , 其 数 值
范 围 是 -128 到 127, 因 此 「 我 」 的 第 一 个 字 元 在 指 定 给 the_word[0]
之 後 , 便 由 >= 128 的 数 值 变 成 <= 127 的 数 值 , 所 以 if
(the_word[0] >= 128 ) 只 能 得 到 FALSE 值 了 。 </P>
<P>解 决 这 个 问 题 的 方 法 是 把 the_word 的 宣 告 改 成 : 「 unsigned
char」 型 态 , 使 其 数 值 范 围 变 成 0 到 255, 这 样 子 在 「 the_word[]
= "我 是 中 文 字 ";」 的 设 定 之 後 , 就 不 至 於 有 数 值
被 强 制 转 变 的 现 象 。 </P>
<P><FONT COLOR="#800000">不 同 型 别 运 算 的 错 误 避 免 之 道 : </FONT></P>
<P>以 上 所 举 的 只 是 不 同 型 别 运 算 後 产 生 错 误 的 两 个 代 表
性 的 例 子 , 欲 避 免 所 有 的 错 误 , 以 下 是 笔 者 的 建 议 : </P>
<UL>
<P>· 检 查 各 种 运 算 符 号 ( + 、 - 、 × 、 ÷ 、 = 、 > 、 <
等 ) 两 边 的 资 料 型 别 是 否 相 同 , 若 不 同 , 则 要 先 确 定 程
式 语 言 是 如 何 处 理 这 些 运 算 符 号 的 , , 如 果 不 能 确 定 ,
先 写 个 小 程 式 试 看 看 。 </P>
<P>· 不 要 假 设 同 一 种 运 算 符 号 在 不 同 程 式 语 言 之 间 會 有
相 同 的 处 理 结 果 , 例 如 除 号 (/)在 BASIC 及 C 语 言 中 就 有 不
同 的 处 理 方 式 。 </P>
</UL>
</UL>
<H2><A NAME="s2"></A><FONT COLOR="#0000FF">程 式 转 弯 处 </FONT></H2>
<UL>
<P>if...else、 goto、 for 回 圈 、 while 回 圈 、 exit、 return、 break
等 指 令 让 我 们 可 以 控 制 程 式 的 流 程 , 有 了 它 们 程 式 才 會
转 弯 , 也 因 此 可 以 执 行 出 许 多 不 同 的 结 果 , 而 bug 也 特 别
喜 欢 躲 在 这 些 转 弯 的 地 方 , 干 扰 程 式 的 执 行 结 果 。 </P>
</UL>
<P><B><U><FONT COLOR="#000080"><FONT SIZE=+1>goto 的 後 遗 症 </FONT></FONT></U></B></P>
<UL>
<P>大 家 都 知 道 滥 用 goto 将 使 程 式 的 结 构 变 得 不 好 , 影 响
程 式 的 可 维 护 性 , 不 过 那 并 不 表 示 任 何 情 况 都 不 要 使 用
goto, 举 个 例 子 来 说 , 在 以 下 的 多 层 回 圈 中 , 如 果 我 们 想
跳 出 所 有 的 回 圈 , 使 用 goto 是 最 简 单 明 白 的 方 法 。 </P>
</UL>
<UL>
<UL>
<ADDRESS><FONT COLOR="#000080">For i = 1 to M </FONT></ADDRESS>
<UL>
<ADDRESS><FONT COLOR="#000080">For k = 1 to N </FONT></ADDRESS>
<UL>
<ADDRESS><FONT COLOR="#000080">...</FONT></ADDRESS>
<ADDRESS><FONT COLOR="#000080">If cond Then goto outside </FONT></ADDRESS>
</UL>
<ADDRESS><FONT COLOR="#000080">Next </FONT></ADDRESS>
</UL>
<ADDRESS><FONT COLOR="#000080">Next </FONT></ADDRESS>
<ADDRESS><FONT COLOR="#000080">outside: </FONT></ADDRESS>
</UL>
<P>其 实 goto 与 return、 exit、 break、 continue 等 指 令 在 本 质 上
并 没 有 差 别 , 它 们 都 會 跳 过 一 段 程 式 , 虽 然 我 们 以 goto
作 为 讨 论 的 标 题 , 但 实 际 上 所 要 谈 的 是 「 跳 过 一 段 程 Α
可 能 衍 生 的 後 遗 症 」 。 </P>
<P>假 设 原 本 有 一 个 副 程 式 , 架 构 上 大 致 是 : </P>
<UL>
<ADDRESS><FONT COLOR="#000080">// C 程 式 </FONT></ADDRESS>
<ADDRESS><FONT COLOR="#000080">SubX () </FONT></ADDRESS>
<ADDRESS><FONT COLOR="#000080">{</FONT></ADDRESS>
<UL>
<ADDRESS><FONT COLOR="#000080">fp = fopen( somefile, "r"); </FONT></ADDRESS>
<ADDRESS><FONT COLOR="#000080">... </FONT></ADDRESS>
<ADDRESS><FONT COLOR="#000080">... </FONT></ADDRESS>
<ADDRESS><FONT COLOR="#000080">... </FONT></ADDRESS>
<ADDRESS><FONT COLOR="#000080">fclose( fp ); </FONT></ADDRESS>
</UL>
<ADDRESS><FONT COLOR="#000080">}</FONT></ADDRESS>
</UL>
<P>这 样 的 副 程 式 很 不 错 , 总 會 在 离 开 前 把 打 开 的 档 案 关
掉 , 後 来 我 们 修 改 程 式 让 它 在 某 种 状 况 之 下 直 接 跳 离 副
程 式 , 所 以 加 了 一 行 判 断 式 : </P>
<UL>
<P><FONT COLOR="#000080">if ( condition ) return;</FONT></P>
</UL>
<P>这 个 判 断 式 当 然 没 错 , 但 我 们 忘 了 在 return 之 前 「 关 档
」 了 。 </P>
<P>前 面 这 个 例 子 是 个 简 化 版 , fclose( fp ) 就 在 眼 前 , 所 以
很 容 易 看 到 这 样 的 错 误 , 但 实 际 上 一 个 副 程 式 可 能 多 达
数 页 , 在 我 们 加 上 跳 出 副 程 式 的 判 断 式 时 , 通 常 不 會 看
到 fclose( fp ), 加 上 您 可 能 急 著 把 程 式 跑 出 来 , 根 本 就 忘
了 关 档 那 一 回 事 了 。 </P>
<P>而 更 糟 的 是 , 忘 了 关 档 的 错 误 并 不 會 马 上 显 现 出 来 ,
它 只 會 让 程 式 的 可 开 档 案 数 越 来 越 少 , 但 程 式 还 是 可 以
正 常 执 行 , 这 样 的 错 误 必 须 在 不 退 掉 程 式 之 下 连 续 的 测
试 才 會 发 现 , 而 绝 大 多 的 人 总 以 为 测 过 两 三 次 就 OK 了 ,
於 是 这 个 bug 就 一 直 躲 藏 到 系 统 整 合 , 甚 至 软 体 交 付 到 客
户 的 手 上 才 被 发 现 。 </P>
<P>除 了 「 开 、 关 档 」 有 配 对 执 行 的 关 系 之 外 , 「 记 忆 体
的 配 置 、 释 放 」 、 「 系 统 资 源 的 配 置 、 释 放 」 等 也 有 相
似 的 性 质 , 在 「 跳 过 一 段 程 式 」 之 後 , 宜 防 只 执 行 了 「
头 」 ( 例 如 开 档 ) , 而 跳 过 「 尾 」 ( 例 如 关 档 ) 的 现 象
。 </P>
</UL>
<P><B><U><FONT COLOR="#000080"><FONT SIZE=+1>无 穷 回 圈 </FONT></FONT></U></B></P>
<UL>
<P>当 我 们 想 重 复 做 某 一 件 事 , 少 不 了 回 圈 的 帮 忙 , 但 如
果 控 制 不 良 , 可 能 造 成 程 式 一 直 在 回 圈 中 打 转 , 进 入 所
谓 的 「 无 穷 回 圈 」 。 一 旦 进 入 无 穷 回 圈 , 程 式 就 像 死 当
一 样 , 所 以 这 个 问 题 通 常 在 程 式 测 试 的 阶 段 就 會 被 发 现
。 </P>
<P>就 程 式 的 撰 写 习 惯 上 , 有 些 小 动 作 可 以 轻 易 地 避 免 无
穷 回 圈 的 发 生 , 举 个 例 子 来 说 : </P>
<UL>
<ADDRESS><FONT COLOR="#000080">Dim i as Integer </FONT></ADDRESS>
<ADDRESS><FONT COLOR="#000080">i = 1 </FONT></ADDRESS>
<ADDRESS><FONT COLOR="#000080">While i <> 10 </FONT></ADDRESS>
<UL>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?