【如何写出优美的 C 代码】
Sunday, July 3, 2016
11:02 AM
|
| | —- |
| Tags: #微博 |

IT程序猿
07/03/2016
【如何写出优美的 C 代码】面向对象的语言更接近人的思维方式,而且在很大程度上降低了代码的复杂性,同时提高了代码的可读性和可维护性,传统的C 代码同样可以设计出比较易读,易维护,复杂度较低的优美代码,本文将通过一个实际例子来说明这点。http://t.cn/Rbm51sb(来自: IBM developerWorks)
![计算机生成了可选文字: 本 文 来 自 : [BMdevelo rworks 版 权 归 届 原 作 者 如 何 写 出 优 美 的 c 代 码 @仃 程 厚 猿 & & 酷 勤 网 制 作 面 向 对 象 的 语 言 更 接 近 人 的 思 维 方 式 , 而 且 在 很 大 程 度 上 降 低 了 代 码 的 复 杂 性 , 同 时 提 高 了 代 码 的 可 读 性 和 可 维 沪 性 传 统 的 c 代 码 同 样 可 以 设 计 出 比 较 易 读 , 易 维 沪 , 复 杂 度 较 低 的 优 美 代 码 , 本 文 将 通 过 一 个 实 际 的 例 子 来 说 明 这 一 点 。 基 础 知 识 结 构 体 除 了 提 供 基 本 数 据 类 型 外 , c 语 言 还 提 供 给 户 自 己 定 制 数 据 类 型 的 能 力 , 那 就 是 结 构 体 , 在 c 语 言 中 , 你 可 以 结 构 体 来 表 亍 任 何 实 体 。 结 构 体 正 是 面 向 对 象 语 言 中 的 类 的 概 念 的 推 形 , 比 如 typedef structI 口 0 a t x; float y , 丨 P 0 i n t , 定 义 了 一 个 平 面 坐 标 系 中 的 一 个 点 , 点 中 有 叻 个 域 , x 坐 和 y 坐 。 结 构 体 中 的 域 称 为 结 构 体 的 成 员 。 结 构 体 中 的 数 据 类 型 可 以 是 简 单 数 据 类 型 , 也 可 以 是 其 他 的 结 构 体 , 县 至 结 构 体 本 身 还 可 以 嵌 套 , 比 如 一 个 标 准 的 链 表 结 构 可 以 进 行 如 下 定 t y p e d e f s t r u c t no d e { void data 訕 指 针 int datal-ength Struct node _next 指 下 一 个 节 点 lNode 可 以 看 到 , 纟 士 构 体 node 中 的 next 俨 针 的 类 型 又 是 node 函 數 指 针 指 针 是 c 语 言 的 灵 谀 , 是 c 比 其 他 语 言 更 灵 活 , 更 强 大 的 地 方 。 所 以 学 习 c 语 言 必 须 很 好 的 皇 握 指 针 。 函 数 指 针 即 指 向 函 数 在 内 存 映 射 中 的 苜 地 址 的 指 针 , 通 过 函 数 指 针 可 以 将 函 数 作 为 参 数 传 递 给 另 一 个 函 数 , 并 在 适 当 的 时 佞 调 , 从 而 实 觋 异 步 通 信 等 功 能 。 比 如 , UN[X/Linux 系 统 中 的 信 号 注 册 函 数 , 其 原 型 如 下 . v 0 i d ( s i g n a 1 0 n t s i no , v 0 i d ( fun 的 ( i n 0 的 0 n 0 使 的 时 佞 , 需 要 己 在 外 部 定 义 一 个 信 号 处 理 函 数 (signal handler), 然 后 使 Signal(sigNo, handler) 将 处 理 程 序 注 册 在 进 程 上 , 当 信 号 发 生 时 , 进 程 就 可 以 回 调 信 号 处 理 函 数 。 将 函 數 指 针 作 为 结 构 体 的 成 员 正 如 前 面 提 到 的 , 结 构 体 的 成 员 可 以 是 简 单 的 数 据 结 构 , 也 可 以 是 其 他 的 结 构 体 , 当 然 , 也 可 以 是 指 针 。 当 将 函 数 指 针 作 为 结 构 体 的 成 员 , 并 且 这 些 函 数 R 来 操 作 . 在 士 构 体 中 的 数 据 时 , 可 以 十 成 一 个 伸 立 的 实 体 , 这 个 实 体 中 既 有 数 据 , 也 有 对 数 据 的 操 作 , 这 样 然 就 可 以 引 出 类 ( class ) 的 面 向 对 象 语 言 的 特 性 一 般 而 言 , 继 承 , 装 和 多 态 被 认 为 是 面 向 对 象 语 言 所 必 须 支 時 的 三 种 特 征 , 也 正 是 通 过 这 三 种 特 征 才 可 以 体 觋 出 面 向 对 象 在 哪 些 方 面 优 于 面 向 过 程 由 于 语 言 开 发 商 的 宣 传 或 其 他 的 各 种 原 因 , 使 的 表 面 上 面 向 对 象 的 思 想 要 通 过 语 言 为 载 体 而 得 以 实 觋 , 然 而 实 际 上 , 面 向 对 象 是 一 种 软 件 设 计 思 想 完 全 是 可 以 与 具 体 实 现 无 关 的 。 虽 然 如 此 , 但 是 不 可 否 认 , 这 些 所 诓 的 纯 面 向 对 象 的 语 言 在 其 代 码 的 可 读 性 以 及 与 人 的 然 思 维 的 匹 配 方 面 , 比 面 向 过 程 的 语 言 要 好 的 多 。 语 言 层 次 的 面 向 对 象 我 们 一 般 要 描 述 一 个 对 象 , 一 般 需 要 描 述 这 个 对 象 的 一 些 届 性 , 比 如 盒 子 ( b 。 x ) 罡 一 个 实 体 , 它 有 6 个 面 , 有 色 , 重 量 , 罡 否 为 仝 等 性 , 且 可 以 成 东 西 进 去 , 可 以 东 西 出 来 。 在 面 向 对 象 的 语 言 中 , 通 常 将 这 样 的 对 象 抽 象 成 一 个 (class) c I a s s 0 戛 { c 10 [ r co 1 0 r [ n t 可 e i h t , boolean empty, put(something) , S 0111 e t h i n e t 0 对 盒 子 进 行 操 作 时 可 以 做 一 下 动 作 Bo 戛 put(cake) Poo 戛 e t 0 , 取 到 某 个 东 西 , 从 点 子 中 。 而 面 向 过 程 的 语 言 中 , 通 常 是 将 实 体 传 递 给 一 个 贯 穿 全 局 的 函 数 来 进 行 的 , 同 样 以 Box 为 例 , 对 Box 进 行 操 作 时 , 往 往 是 这 样 put(Box, cake) 将 一 个 煮 子 中 Get(Box) , 从 煮 子 中 取 出 某 个 东 西 来 而 显 然 , 第 一 种 代 码 十 式 更 符 合 常 理 , 所 以 面 向 对 象 的 语 言 大 都 提 供 这 种 语 言 层 面 的 细 节 的 支 時 , 使 得 代 码 的 可 读 性 可 理 解 性 大 大 增 加 。 c 语 言 , 作 为 一 个 灵 活 而 简 单 的 语 , 我 们 完 全 可 以 通 过 c 提 供 的 简 单 机 制 , 实 觋 这 样 的 比 较 优 美 的 代 码 形 式 。 c 语 言 的 面 向 对 象 如 前 所 说 , 面 向 对 象 是 一 种 软 件 设 计 的 思 想 , 是 语 言 无 关 的 。 在 本 节 中 , 我 举 一 个 链 表 山 st ) 的 例 子 来 说 明 如 何 在 C 语 言 中 的 设 计 出 有 面 向 对 象 风 格 的 代 码 。 定 义 接 口 接 口 是 面 向 对 象 语 言 中 的 一 个 比 较 重 要 的 概 念 , 接 口 R 对 外 部 承 诺 实 觋 该 唼 口 的 实 体 可 以 完 成 什 么 样 的 功 能 , 但 是 不 暴 露 实 现 的 方 式 。 这 样 的 好 处 是 , 实 现 者 可 以 在 不 唼 触 接 口 使 者 的 代 码 的 情 兄 下 , 对 实 觋 进 行 调 整 。 我 们 来 看 看 链 表 的 接 口 定 义 清 单 1 . 链 表 的 接 口 定 义 # i d e [ 1 凵 S T H # d e 0 n e 1 凵 S T 日 定 义 韦 中 的 节 点 结 构 t y p e d e f s t ru c t no d e { void _data Struct node _next lNode 定 义 表 结 构 t y p e d e f s t ru c t ] i s t { S t ru C t 1 i S t t h i S Node head 1 n t S 1 e v 0 i d ( i n s e r 0 ( v 0 i d no d e ) void (_drop) ( void _node) “ i d ( “ 性 “ ) 0 i n t ( “ t s i “ ) 0 v 0 i d ( e 0 ( i n t index) “ i d ( “ i n 0 0 丨 L i s t , void insert(VOid _node) void drop( void _node) v 0 i d c [ e a r 0 i n t e t s i Z e 0 V 0 i d e t ( i n t index) v 0 i d p r i n t 0 # e n d i [ / 丨 凵 S T 日 / 山 st 接 口 中 可 以 清 晰 的 看 到 , 对 于 一 个 list 实 体 ( 也 就 是 对 象 ) 来 说 , 可 以 在 其 进 行 insert, drop, clear, , get(index) 以 及 print 等 操 作 list—>head list—>drop 1 i S t 一 冫 S i z e 1 i S t 一 冫 e t getSlze Node L i S t void void void _node 1 i S t 接 口 的 实 现 清 单 2 . 构 造 方 法 = NULL = NULL insert(void node) drop( void _node) 回 e “ 0 , i n t e t s i Z e 0 v 0 i d p r i n t 0 V 0 i d e t ( i n t index) L i S t L i S t c on S t ru C t i on 0 { 1 i S t ] i S t 一 将 ( L i s t ) m a 1 10 c ( s i z e 0 f ( L i s t 的 (Node)malloc (sizeof (Node)) , 1 n S e r t 1 S e r t 1 i s t 一 冫 c ] e a r 1 n S e r t 函 实 册 在 实 体 上 1 i S t drop 1 i S t 一 冫 e t S i e e t S i e list—>print print ] i s t 一 冫 t h i s 1 i S t 指 针 将 本 身 保 存 起 来 t h i S 1 i S t r e t u rn ( L i S t I i S t 需 要 注 意 的 是 此 处 的 this 俨 针 , this 指 针 可 以 保 证 外 对 list 的 操 作 映 射 到 对 _this 的 操 作 上 , 从 而 使 得 代 码 得 到 简 化 。 清 单 3 . 插 入 及 删 除 将 一 个 是 入 到 一 个 象 上 I i S t v 0 i d i n s e r t ( v 0 i d *no d e Node _current current—>data Cu r r e n t 一 冫 n e 戛 t (Node)malloc (sizeof (Node)) , list—> this—>head—>next, list—> this—>head—>next ( 1 i s t 一 冫 t h i s 一 冫 s i e ) + + 除 一 个 指 定 的 节 点 node void drop( void node)l Node _t Node _d for (i list—> this—>head = NULL 1 i s t 一 冫 t h i s 一 冫 s i z e , i + + ) { list—> this—>head—>next, if(d->data ((Node)node)->data)l list—> this—>head—>next d—>next, f r e e ( d ) , ( 1 i s t 一 冫 t h i s 一 冫 s i z e ) 一 break, 跹 I “ { list—> this—>head list—> this—>head list—> this—>head—>next, 其 他 的 实 觋 代 码 可 以 参 看 下 载 部 分 , 这 里 限 于 篇 幅 就 不 再 意 义 列 举 出 来 。 测 试 测 试 代 码 好 了 , 前 面 做 的 一 切 工 作 都 是 为 了 保 证 我 们 的 暴 露 给 使 者 的 API 可 以 尽 量 的 简 ; 吉 , 优 美 , 现 在 到 测 试 的 时 佞 了 清 单 4 . 测 试 代 码 int argC, char* argV) { ( L i s t L i s t C on s t ru c t i on 0 L i S t 1 i S t 构 蔭 一 个 新 的 泌 表 入 一 些 值 帥 i 芤 1 i s t 一 冫 i n s e r t ( “App 1 e “ ) , list—>insert(“porland”) 1 i S t 一 冫 i n S e r t ( “c i S CO “ ) 1 i S t 一 冫 i n S e r t ( 1 i S t 一 冫 i n S e r t ( ] i S t 一 冫 i n S e r t ( 1 i s t 一 冫 i n s e r t ( “ G00 1 e “ ) —>print() , ] i S t 打 印 个 列 羡 p r i n t f ( 0 i s t “D e 凵 0 F 1 e c t ro 1 ux “FireFox”) , i s t 一 冫 e 吓 i ‘ e 0 ) %dn” Node node node. data F [ e c t ro 1 ux = NULL list—>drop(&node) 一 个 节 点 node. data “C i S CO node.next = NULL list—>drop(&node) 一 个 节 点 ] i s t 一 冫 p r i n t 0 胄 次 打 印 p r i n t f ( 0 i s t s i e I i s t 一 冫 c 1 e a r 0 %dn” , [ i s t 一 冫 e 吓 i ‘ e 0 ) 窒 列 韦 r e t u rn 0 [ 色 49 9 9 8 ] [ 色 49 Q DZ ] [ 色 49 A ] [ 色 49 9 ] [ 色 49 1 ] [ 色 49 9 9 Eg ] [ 色 49 9 9 BZ ] is t S iZ e [ 色 49 9 9 8 ] [ 色 49 Q DZ ] [ 色 49 9 ] [ 色 49 9 9 Eg ] [ 色 49 9 9 BZ ] is t S iZ e 图 1 . 运 行 结 果 {Google} { P 》 。 e PO x} { E le c t po lux} { C is c o 〉 { Bo r Ian d} {Google} { P 》 。 e PO x} { Bo r Ian d} 结 束 语 c 语 言 所 诞 生 的 “ 0 半 台 提 倡 这 样 一 种 设 计 哲 学 : 尽 量 进 行 简 单 的 设 计 , 让 使 者 如 同 褡 积 木 一 样 的 将 这 些 简 单 的 工 具 连 接 成 强 大 的 , 完 整 的 应 。 应 该 说 , c 比 较 好 的 继 承 了 这 一 点 , c 语 言 非 常 简 吉 , 非 常 强 大 , 而 由 于 c 语 言 诞 生 的 比 较 早 , 当 时 的 面 向 对 象 的 思 想 还 不 成 熟 , 所 以 出 觋 了 大 量 的 过 程 式 的 c 应 , 从 而 给 人 们 一 种 c 语 言 是 面 向 过 程 的 语 言 的 错 觉 其 实 c R 是 提 供 了 一 些 简 单 , 强 大 而 通 的 能 力 至 于 你 想 将 其 褡 成 什 么 样 的 积 木 , 则 全 靠 你 自 己 了 。 来 自 http://t.cn/amKnQQ
查看源微博
已使用 Microsoft OneNote 2016 创建。
