C语言教程

Size: px
Start display at page:

Download "C语言教程"

Transcription

1 1 C 语 言 概 述 C 语 言 的 发 展 过 程 当 代 最 优 秀 的 程 序 设 计 语 言 C 语 言 版 本 C 语 言 的 特 点 面 向 对 象 的 程 序 设 计 语 言 C 和 C 简 单 的 C 程 序 介 绍 输 入 和 输 出 函 数 C 源 程 序 的 结 构 特 点 书 写 程 序 时 应 遵 循 的 规 则 C 语 言 的 字 符 集 C 语 言 词 汇 Turbo C 2.0 集 成 开 发 环 境 的 使 用 Turbo C 2.0 简 介 和 启 动 Turbo C 2.0 集 成 开 发 环 境 File 菜 单 Edit 菜 单 Run 菜 单 Compile 菜 单 Project 菜 单 Options 菜 单 Debug 菜 单 Break/watch 菜 单 Turbo C 2.0 的 配 置 文 件 程 序 的 灵 魂 算 法 算 法 的 概 念 简 单 算 法 举 例 算 法 的 特 性 怎 样 表 示 一 个 算 法 用 自 然 语 言 表 示 算 法 用 流 程 图 表 示 算 法 三 种 基 本 结 构 和 改 进 的 流 程 图 用 N-S 流 程 图 表 示 算 法 用 伪 代 码 表 示 算 法 用 计 算 机 语 言 表 示 算 法 结 构 化 程 序 设 计 方 法 数 据 类 型 运 算 符 与 表 达 式 C 语 言 的 数 据 类 型 常 量 与 变 量 常 量 和 符 号 常 量 变 量 整 型 数 据 整 型 常 量 的 表 示 方 法 第 1 页

2 3.3.2 整 型 变 量 实 型 数 据 实 型 常 量 的 表 示 方 法 实 型 变 量 实 型 常 数 的 类 型 字 符 型 数 据 字 符 常 量 转 义 字 符 字 符 变 量 字 符 数 据 在 内 存 中 的 存 储 形 式 及 使 用 方 法 字 符 串 常 量 变 量 赋 初 值 各 类 数 值 型 数 据 之 间 的 混 合 运 算 算 术 运 算 符 和 算 术 表 达 式 C 运 算 符 简 介 算 术 运 算 符 和 算 术 表 达 式 赋 值 运 算 符 和 赋 值 表 达 式 逗 号 运 算 符 和 逗 号 表 达 式 小 结 C 的 数 据 类 型 基 本 类 型 的 分 类 及 特 点 常 量 后 缀 常 量 类 型 数 据 类 型 转 换 运 算 符 优 先 级 和 结 合 性 表 达 式 最 简 单 的 C 程 序 设 计 顺 序 程 序 设 计 C 语 句 概 述 赋 值 语 句 数 据 输 入 输 出 的 概 念 及 在 C 语 言 中 的 实 现 字 符 数 据 的 输 入 输 出 putchar 函 数 ( 字 符 输 出 函 数 ) getchar 函 数 ( 键 盘 输 入 函 数 ) 格 式 输 入 与 输 出 printf 函 数 ( 格 式 输 出 函 数 ) scanf 函 数 ( 格 式 输 入 函 数 ) 顺 序 结 构 程 序 设 计 举 例 分 支 结 构 程 序 关 系 运 算 符 和 表 达 式 关 系 运 算 符 及 其 优 先 次 序 关 系 表 达 式 逻 辑 运 算 符 和 表 达 式 逻 辑 运 算 符 极 其 优 先 次 序 逻 辑 运 算 的 值 第 2 页

3 5.2.3 逻 辑 表 达 式 if 语 句 if 语 句 的 三 种 形 式 if 语 句 的 嵌 套 条 件 运 算 符 和 条 件 表 达 式 switch 语 句 程 序 举 例 循 环 控 制 概 述 goto 语 句 以 及 用 goto 语 句 构 成 循 环 while 语 句 do-while 语 句 for 语 句 循 环 的 嵌 套 几 种 循 环 的 比 较 break 和 continue 语 句 break 语 句 continue 语 句 程 序 举 例 数 组 一 维 数 组 的 定 义 和 引 用 一 维 数 组 的 定 义 方 式 一 维 数 组 元 素 的 引 用 一 维 数 组 的 初 始 化 一 维 数 组 程 序 举 例 二 维 数 组 的 定 义 和 引 用 二 维 数 组 的 定 义 二 维 数 组 元 素 的 引 用 二 维 数 组 的 初 始 化 二 维 数 组 程 序 举 例 字 符 数 组 字 符 数 组 的 定 义 字 符 数 组 的 初 始 化 字 符 数 组 的 引 用 字 符 串 和 字 符 串 结 束 标 志 字 符 数 组 的 输 入 输 出 字 符 串 处 理 函 数 程 序 举 例 本 章 小 结 函 数 概 述 函 数 定 义 的 一 般 形 式 函 数 的 参 数 和 函 数 的 值 形 式 参 数 和 实 际 参 数 第 3 页

4 8.3.2 函 数 的 返 回 值 函 数 的 调 用 函 数 调 用 的 一 般 形 式 函 数 调 用 的 方 式 被 调 用 函 数 的 声 明 和 函 数 原 型 函 数 的 嵌 套 调 用 函 数 的 递 归 调 用 数 组 作 为 函 数 参 数 局 部 变 量 和 全 局 变 量 局 部 变 量 全 局 变 量 变 量 的 存 储 类 别 动 态 存 储 方 式 与 静 态 动 态 存 储 方 式 auto 变 量 用 static 声 明 局 部 变 量 register 变 量 用 extern 声 明 外 部 变 量 预 处 理 命 令 概 述 宏 定 义 无 参 宏 定 义 带 参 宏 定 义 文 件 包 含 条 件 编 译 本 章 小 结 指 针 地 址 指 针 的 基 本 概 念 变 量 的 指 针 和 指 向 变 量 的 指 针 变 量 定 义 一 个 指 针 变 量 指 针 变 量 的 引 用 指 针 变 量 作 为 函 数 参 数 指 针 变 量 几 个 问 题 的 进 一 步 说 明 数 组 指 针 和 指 向 数 组 的 指 针 变 量 指 向 数 组 元 素 的 指 针 通 过 指 针 引 用 数 组 元 素 数 组 名 作 函 数 参 数 指 向 多 维 数 组 的 指 针 和 指 针 变 量 字 符 串 的 指 针 指 向 字 符 串 的 针 指 变 量 字 符 串 的 表 示 形 式 使 用 字 符 串 指 针 变 量 与 字 符 数 组 的 区 别 函 数 指 针 变 量 指 针 型 函 数 指 针 数 组 和 指 向 指 针 的 指 针 指 针 数 组 的 概 念 第 4 页

5 指 向 指 针 的 指 针 main 函 数 的 参 数 有 关 指 针 的 数 据 类 型 和 指 针 运 算 的 小 结 有 关 指 针 的 数 据 类 型 的 小 结 指 针 运 算 的 小 结 void 指 针 类 型 结 构 体 与 共 用 体 定 义 一 个 结 构 的 一 般 形 式 结 构 类 型 变 量 的 说 明 结 构 变 量 成 员 的 表 示 方 法 结 构 变 量 的 赋 值 结 构 变 量 的 初 始 化 结 构 数 组 的 定 义 结 构 指 针 变 量 的 说 明 和 使 用 指 向 结 构 变 量 的 指 针 指 向 结 构 数 组 的 指 针 结 构 指 针 变 量 作 函 数 参 数 动 态 存 储 分 配 链 表 的 概 念 枚 举 类 型 枚 举 类 型 的 定 义 和 枚 举 变 量 的 说 明 枚 举 类 型 变 量 的 赋 值 和 使 用 类 型 定 义 符 typedef 位 运 算 位 运 算 符 C 语 言 提 供 了 六 种 位 运 算 符 : 按 位 与 运 算 按 位 或 运 算 按 位 异 或 运 算 求 反 运 算 左 移 运 算 右 移 运 算 位 域 ( 位 段 ) 本 章 小 结 文 件 C 文 件 概 述 文 件 指 针 文 件 的 打 开 与 关 闭 文 件 的 打 开 (fopen 函 数 ) 文 件 关 闭 函 数 (fclose 函 数 ) 文 件 的 读 写 字 符 读 写 函 数 fgetc 和 fputc 字 符 串 读 写 函 数 fgets 和 fputs 数 据 块 读 写 函 数 fread 和 fwtrite 格 式 化 读 写 函 数 fscanf 和 fprintf 第 5 页

6 13.5 文 件 的 随 机 读 写 文 件 定 位 文 件 的 随 机 读 写 文 件 检 测 函 数 文 件 结 束 检 测 函 数 feof 函 数 读 写 文 件 出 错 检 测 函 数 文 件 出 错 标 志 和 文 件 结 束 标 志 置 0 函 数 C 库 文 件 本 章 小 结 第 6 页

7 1 C 语 言 概 述 1.1 C 语 言 的 发 展 过 程 C 语 言 是 在 70 年 代 初 问 世 的 一 九 七 八 年 由 美 国 电 话 电 报 公 司 (AT&T) 贝 尔 实 验 室 正 式 发 表 了 C 语 言 同 时 由 B.W.Kernighan 和 D.M.Ritchit 合 著 了 著 名 的 THE C PROGRAMMING LANGUAGE 一 书 通 常 简 称 为 K&R, 也 有 人 称 之 为 K&R 标 准 但 是, 在 K&R 中 并 没 有 定 义 一 个 完 整 的 标 准 C 语 言, 后 来 由 美 国 国 家 标 准 协 会 (American National Standards Institute) 在 此 基 础 上 制 定 了 一 个 C 语 言 标 准, 于 一 九 八 三 年 发 表 通 常 称 之 为 ANSI C 1.2 当 代 最 优 秀 的 程 序 设 计 语 言 早 期 的 C 语 言 主 要 是 用 于 UNIX 系 统 由 于 C 语 言 的 强 大 功 能 和 各 方 面 的 优 点 逐 渐 为 人 们 认 识, 到 了 八 十 年 代,C 开 始 进 入 其 它 操 作 系 统, 并 很 快 在 各 类 大 中 小 和 微 型 计 算 机 上 得 到 了 广 泛 的 使 用, 成 为 当 代 最 优 秀 的 程 序 设 计 语 言 之 一 1.3 C 语 言 版 本 目 前 最 流 行 的 C 语 言 有 以 下 几 种 : Microsoft C 或 称 MS C Borland Turbo C 或 称 Turbo C AT&T C 这 些 C 语 言 版 本 不 仅 实 现 了 ANSI C 标 准, 而 且 在 此 基 础 上 各 自 作 了 一 些 扩 充, 使 之 更 加 方 便 完 美 1.4 C 语 言 的 特 点 1 C 语 言 简 洁 紧 凑, 使 用 方 便 灵 活 ANSI C 一 共 只 有 32 个 关 键 字 : auto break case char const continue default do double else enum extern float for goto if int long register return short signed static sizof struct switch typedef union unsigned void volatile while 9 种 控 制 语 句, 程 序 书 写 自 由, 主 要 用 小 写 字 母 表 示, 压 缩 了 一 切 不 必 要 的 成 分 Turbo C 扩 充 了 11 个 关 键 字 : asm _cs _ds _es _ss cdecl far huge interrupt near pascal 注 意 : 在 C 语 言 中, 关 键 字 都 是 小 写 的 2 运 算 符 丰 富 共 有 34 种 C 把 括 号 赋 值 逗 号 等 都 作 为 运 算 符 处 理 从 而 使 C 的 运 算 类 型 极 为 丰 富, 可 以 实 现 其 他 高 级 语 言 难 以 实 现 的 运 算 3 数 据 结 构 类 型 丰 富 第 7 页

8 4 具 有 结 构 化 的 控 制 语 句 5 语 法 限 制 不 太 严 格, 程 序 设 计 自 由 度 大 6 C 语 言 允 许 直 接 访 问 物 理 地 址, 能 进 行 位 (bit) 操 作, 能 实 现 汇 编 语 言 的 大 部 分 功 能, 可 以 直 接 对 硬 件 进 行 操 作 因 此 有 人 把 它 称 为 中 级 语 言 7 生 成 目 标 代 码 质 量 高, 程 序 执 行 效 率 高 8 与 汇 编 语 言 相 比, 用 C 语 言 写 的 程 序 可 移 植 性 好 但 是,C 语 言 对 程 序 员 要 求 也 高, 程 序 员 用 C 写 程 序 会 感 到 限 制 少 灵 活 性 大, 功 能 强, 但 较 其 他 高 级 语 言 在 学 习 上 要 困 难 一 些 1.5 面 向 对 象 的 程 序 设 计 语 言 在 C 的 基 础 上, 一 九 八 三 年 又 由 贝 尔 实 验 室 的 Bjarne Strou-strup 推 出 了 C++ C++ 进 一 步 扩 充 和 完 善 了 C 语 言, 成 为 一 种 面 向 对 象 的 程 序 设 计 语 言 C++ 目 前 流 行 的 最 新 版 本 是 Borland C++, Symantec C++ 和 Microsoft VisualC++ C++ 提 出 了 一 些 更 为 深 入 的 概 念, 它 所 支 持 的 这 些 面 向 对 象 的 概 念 容 易 将 问 题 空 间 直 接 地 映 射 到 程 序 空 间, 为 程 序 员 提 供 了 一 种 与 传 统 结 构 程 序 设 计 不 同 的 思 维 方 式 和 编 程 方 法 因 而 也 增 加 了 整 个 语 言 的 复 杂 性, 掌 握 起 来 有 一 定 难 度 1.6 C 和 C++ 但 是,C 是 C++ 的 基 础,C++ 语 言 和 C 语 言 在 很 多 方 面 是 兼 容 的 因 此, 掌 握 了 C 语 言, 再 进 一 步 学 习 C++ 就 能 以 一 种 熟 悉 的 语 法 来 学 习 面 向 对 象 的 语 言, 从 而 达 到 事 半 功 倍 的 目 的 1.7 简 单 的 C 程 序 介 绍 为 了 说 明 C 语 言 源 程 序 结 构 的 特 点, 先 看 以 下 几 个 程 序 这 几 个 程 序 由 简 到 难, 表 现 了 C 语 言 源 程 序 在 组 成 结 构 上 的 特 点 虽 然 有 关 内 容 还 未 介 绍, 但 可 从 这 些 例 子 中 了 解 到 组 成 一 个 C 源 程 序 的 基 本 部 分 和 书 写 格 式 例 1.1 main() printf(" 世 界, 您 好!\n"); main 是 主 函 数 的 函 数 名, 表 示 这 是 一 个 主 函 数 每 一 个 C 源 程 序 都 必 须 有, 且 只 能 有 一 个 主 函 数 (main 函 数 ) 函 数 调 用 语 句,printf 函 数 的 功 能 是 把 要 输 出 的 内 容 送 到 显 示 器 去 显 示 printf 函 数 是 一 个 由 系 统 定 义 的 标 准 函 数, 可 在 程 序 中 直 接 调 用 例 1.2 #include<math.h> #include<stdio.h> main() 第 8 页

9 double x,s; printf("input number:\n"); scanf("%lf",&x); s=sin(x); printf("sine of %lf is %lf\n",x,s); include 称 为 文 件 包 含 命 令 扩 展 名 为.h 的 文 件 称 为 头 文 件 定 义 两 个 实 数 变 量, 以 被 后 面 程 序 使 用 显 示 提 示 信 息 从 键 盘 获 得 一 个 实 数 x 求 x 的 正 弦, 并 把 它 赋 给 变 量 s 显 示 程 序 运 算 结 果 main 函 数 结 束 程 序 的 功 能 是 从 键 盘 输 入 一 个 数 x, 求 x 的 正 弦 值, 然 后 输 出 结 果 在 main() 之 前 的 两 行 称 为 预 处 理 命 令 ( 详 见 后 面 ) 预 处 理 命 令 还 有 其 它 几 种, 这 里 的 include 称 为 文 件 包 含 命 令, 其 意 义 是 把 尖 括 号 <> 或 引 号 "" 内 指 定 的 文 件 包 含 到 本 程 序 来, 成 为 本 程 序 的 一 部 分 被 包 含 的 文 件 通 常 是 由 系 统 提 供 的, 其 扩 展 名 为.h 因 此 也 称 为 头 文 件 或 首 部 文 件 C 语 言 的 头 文 件 中 包 括 了 各 个 标 准 库 函 数 的 函 数 原 型 因 此, 凡 是 在 程 序 中 调 用 一 个 库 函 数 时, 都 必 须 包 含 该 函 数 原 型 所 在 的 头 文 件 在 本 例 中, 使 用 了 三 个 库 函 数 : 输 入 函 数 scanf, 正 弦 函 数 sin, 输 出 函 数 printf sin 函 数 是 数 学 函 数, 其 头 文 件 为 math.h 文 件, 因 此 在 程 序 的 主 函 数 前 用 include 命 令 包 含 了 math.h scanf 和 printf 是 标 准 输 入 输 出 函 数, 其 头 文 件 为 stdio.h, 在 主 函 数 前 也 用 include 命 令 包 含 了 stdio.h 文 件 需 要 说 明 的 是,C 语 言 规 定 对 scanf 和 printf 这 两 个 函 数 可 以 省 去 对 其 头 文 件 的 包 含 命 令 所 以 在 本 例 中 也 可 以 删 去 第 二 行 的 包 含 命 令 #include<stdio.h> 同 样, 在 例 1.1 中 使 用 了 printf 函 数, 也 省 略 了 包 含 命 令 在 例 题 中 的 主 函 数 体 中 又 分 为 两 部 分, 一 部 分 为 说 明 部 分, 另 一 部 为 分 执 行 部 分 说 明 是 指 变 量 的 类 型 说 明 例 题 1.1 中 未 使 用 任 何 变 量, 因 此 无 说 明 部 分 C 语 言 规 定, 源 程 序 中 所 有 用 到 的 变 量 都 必 须 先 说 明, 后 使 用, 否 则 将 会 出 错 这 一 点 是 编 译 型 高 级 程 序 设 计 语 言 的 一 个 特 点, 与 解 释 型 的 BASIC 语 言 是 不 同 的 说 明 部 分 是 C 源 程 序 结 构 中 很 重 要 的 组 成 部 分 本 例 中 使 用 了 两 个 变 量 x,s, 用 来 表 示 输 入 的 自 变 量 和 sin 函 数 值 由 于 sin 函 数 要 求 这 两 个 量 必 须 是 双 精 度 浮 点 型, 故 用 类 型 说 明 符 double 来 说 明 这 两 个 变 量 说 明 部 分 后 的 四 行 为 执 行 部 分 或 称 为 执 行 语 句 部 分, 用 以 完 成 程 序 的 功 能 执 行 部 分 的 第 一 行 是 输 出 语 句, 调 用 printf 函 数 在 显 示 器 上 输 出 提 示 字 符 串, 请 操 作 人 员 输 入 自 变 量 x 的 值 第 二 行 为 输 入 语 句, 调 用 scanf 函 数, 接 受 键 盘 上 输 入 的 数 并 存 入 变 量 x 中 第 三 行 是 调 用 sin 函 数 并 把 函 数 值 送 到 变 量 s 中 第 四 行 是 用 printf 函 数 输 出 变 量 s 的 值, 即 x 的 正 弦 值 程 序 结 束 运 行 本 程 序 时, 首 先 在 显 示 器 屏 幕 上 给 出 提 示 串 input number, 这 是 由 执 行 部 分 的 第 一 行 完 成 的 用 户 在 提 示 下 从 键 盘 上 键 入 某 一 数, 如 5, 按 下 回 车 键, 接 着 在 屏 幕 上 给 出 计 算 结 果 1.8 输 入 和 输 出 函 数 在 前 两 个 例 子 中 用 到 了 输 入 和 输 出 函 数 scanf 和 printf, 在 以 后 要 详 细 介 绍 这 里 我 们 先 简 单 介 绍 一 下 它 们 的 格 式, 以 便 下 面 使 用 scanf 和 printf 这 两 个 函 数 分 别 称 为 格 式 输 入 函 数 和 格 式 输 出 函 数 其 意 义 是 按 指 定 的 格 式 输 入 输 出 值 因 此, 这 两 个 函 数 在 括 号 中 的 参 数 表 都 由 以 下 两 部 分 组 成 : 格 式 控 制 串, 参 数 表 第 9 页

10 格 式 控 制 串 是 一 个 字 符 串, 必 须 用 双 引 号 括 起 来, 它 表 示 了 输 入 输 出 量 的 数 据 类 型 各 种 类 型 的 格 式 表 示 法 可 参 阅 第 三 章 在 printf 函 数 中 还 可 以 在 格 式 控 制 串 内 出 现 非 格 式 控 制 字 符, 这 时 在 显 示 屏 幕 上 将 原 文 照 印 参 数 表 中 给 出 了 输 入 或 输 出 的 量 当 有 多 个 量 时, 用 逗 号 间 隔 例 如 : printf("sine of %lf is %lf\n",x,s); 其 中 %lf 为 格 式 字 符, 表 示 按 双 精 度 浮 点 数 处 理 它 在 格 式 串 中 两 次 现, 对 应 了 x 和 s 两 个 变 量 其 余 字 符 为 非 格 式 字 符 则 照 原 样 输 出 在 屏 幕 上 例 1.3 int max(int a,int b); /* 函 数 说 明 */ main() /* 主 函 数 */ int x,y,z; /* 变 量 说 明 */ int max(int a,int b); /* 函 数 说 明 */ printf("input two numbers:\n"); scanf("%d%d",&x,&y); /* 输 入 x,y 值 */ z=max(x,y); /* 调 用 max 函 数 */ printf("maxmum=%d",z); /* 输 出 */ int max(int a,int b) /* 定 义 max 函 数 */ if(a>b)return a;else return b; /* 把 结 果 返 回 主 调 函 数 */ 上 面 例 中 程 序 的 功 能 是 由 用 户 输 入 两 个 整 数, 程 序 执 行 后 输 出 其 中 较 大 的 数 本 程 序 由 两 个 函 数 组 成, 主 函 数 和 max 函 数 函 数 之 间 是 并 列 关 系 可 从 主 函 数 中 调 用 其 它 函 数 max 函 数 的 功 能 是 比 较 两 个 数, 然 后 把 较 大 的 数 返 回 给 主 函 数 max 函 数 是 一 个 用 户 自 定 义 函 数 因 此 在 主 函 数 中 要 给 出 说 明 ( 程 序 第 三 行 ) 可 见, 在 程 序 的 说 明 部 分 中, 不 仅 可 以 有 变 量 说 明, 还 可 以 有 函 数 说 明 关 于 函 数 的 详 细 内 容 将 在 以 后 第 五 章 介 绍 在 程 序 的 每 行 后 用 /* 和 */ 括 起 来 的 内 容 为 注 释 部 分, 程 序 不 执 行 注 释 部 分 上 例 中 程 序 的 执 行 过 程 是, 首 先 在 屏 幕 上 显 示 提 示 串, 请 用 户 输 入 两 个 数, 回 车 后 由 scanf 函 数 语 句 接 收 这 两 个 数 送 入 变 量 x,y 中, 然 后 调 用 max 函 数, 并 把 x,y 的 值 传 送 给 max 函 数 的 参 数 a,b 在 max 函 数 中 比 较 a,b 的 大 小, 把 大 者 返 回 给 主 函 数 的 变 量 z, 最 后 在 屏 幕 上 输 出 z 的 值 1.9 C 源 程 序 的 结 构 特 点 1. 一 个 C 语 言 源 程 序 可 以 由 一 个 或 多 个 源 文 件 组 成 2. 每 个 源 文 件 可 由 一 个 或 多 个 函 数 组 成 3. 一 个 源 程 序 不 论 由 多 少 个 文 件 组 成, 都 有 一 个 且 只 能 有 一 个 main 函 数, 即 主 函 数 4. 源 程 序 中 可 以 有 预 处 理 命 令 (include 命 令 仅 为 其 中 的 一 种 ), 预 处 理 命 令 通 常 应 放 在 源 文 件 或 源 程 序 的 最 前 面 5. 每 一 个 说 明, 每 一 个 语 句 都 必 须 以 分 号 结 尾 但 预 处 理 命 令, 函 数 头 和 花 括 号 之 后 不 能 加 分 号 6. 标 识 符, 关 键 字 之 间 必 须 至 少 加 一 个 空 格 以 示 间 隔 若 已 有 明 显 的 间 隔 符, 也 可 不 再 加 空 格 来 间 隔 第 10 页

11 1.10 书 写 程 序 时 应 遵 循 的 规 则 从 书 写 清 晰, 便 于 阅 读, 理 解, 维 护 的 角 度 出 发, 在 书 写 程 序 时 应 遵 循 以 下 规 则 : 1. 一 个 说 明 或 一 个 语 句 占 一 行 2. 用 括 起 来 的 部 分, 通 常 表 示 了 程 序 的 某 一 层 次 结 构 一 般 与 该 结 构 语 句 的 第 一 个 字 母 对 齐, 并 单 独 占 一 行 3. 低 一 层 次 的 语 句 或 说 明 可 比 高 一 层 次 的 语 句 或 说 明 缩 进 若 干 格 后 书 写 以 便 看 起 来 更 加 清 晰, 增 加 程 序 的 可 读 性 在 编 程 时 应 力 求 遵 循 这 些 规 则, 以 养 成 良 好 的 编 程 风 格 1.11 C 语 言 的 字 符 集 字 符 是 组 成 语 言 的 最 基 本 的 元 素 C 语 言 字 符 集 由 字 母, 数 字, 空 格, 标 点 和 特 殊 字 符 组 成 在 字 符 常 量, 字 符 串 常 量 和 注 释 中 还 可 以 使 用 汉 字 或 其 它 可 表 示 的 图 形 符 号 1. 字 母 小 写 字 母 a~z 共 26 个 大 写 字 母 A~Z 共 26 个 2. 数 字 0~9 共 10 个 3. 空 白 符 空 格 符 制 表 符 换 行 符 等 统 称 为 空 白 符 空 白 符 只 在 字 符 常 量 和 字 符 串 常 量 中 起 作 用 在 其 它 地 方 出 现 时, 只 起 间 隔 作 用, 编 译 程 序 对 它 们 忽 略 不 计 因 此 在 程 序 中 使 用 空 白 符 与 否, 对 程 序 的 编 译 不 发 生 影 响, 但 在 程 序 中 适 当 的 地 方 使 用 空 白 符 将 增 加 程 序 的 清 晰 性 和 可 读 性 4. 标 点 和 特 殊 字 符 1.12 C 语 言 词 汇 在 C 语 言 中 使 用 的 词 汇 分 为 六 类 : 标 识 符, 关 键 字, 运 算 符, 分 隔 符, 常 量, 注 释 符 等 1. 标 识 符 在 程 序 中 使 用 的 变 量 名 函 数 名 标 号 等 统 称 为 标 识 符 除 库 函 数 的 函 数 名 由 系 统 定 义 外, 其 余 都 由 用 户 自 定 义 C 规 定, 标 识 符 只 能 是 字 母 (A~Z,a~z) 数 字 (0~9) 下 划 线 (_) 组 成 的 字 符 串, 并 且 其 第 一 个 字 符 必 须 是 字 母 或 下 划 线 以 下 标 识 符 是 合 法 的 : a, x, x3, BOOK_1, sum5 以 下 标 识 符 是 非 法 的 : 3s 以 数 字 开 头 s*t 出 现 非 法 字 符 * -3x 以 减 号 开 头 bowy-1 出 现 非 法 字 符 -( 减 号 ) 在 使 用 标 识 符 时 还 必 须 注 意 以 下 几 点 : (1) 标 准 C 不 限 制 标 识 符 的 长 度, 但 它 受 各 种 版 本 的 C 语 言 编 译 系 统 限 制, 同 时 也 受 到 具 体 机 器 的 限 制 例 如 在 某 版 本 C 中 规 定 标 识 符 前 八 位 有 效, 当 两 个 标 识 符 前 八 位 相 同 时, 则 被 认 为 是 同 一 个 标 识 符 第 11 页

12 (2) 在 标 识 符 中, 大 小 写 是 有 区 别 的 例 如 BOOK 和 book 是 两 个 不 同 的 标 识 符 (3) 标 识 符 虽 然 可 由 程 序 员 随 意 定 义, 但 标 识 符 是 用 于 标 识 某 个 量 的 符 号 因 此, 命 名 应 尽 量 有 相 应 的 意 义, 以 便 于 阅 读 理 解, 作 到 顾 名 思 义 2. 关 键 字 关 键 字 是 由 C 语 言 规 定 的 具 有 特 定 意 义 的 字 符 串, 通 常 也 称 为 保 留 字 用 户 定 义 的 标 识 符 不 应 与 关 键 字 相 同 C 语 言 的 关 键 字 分 为 以 下 几 类 : (1) 类 型 说 明 符 用 于 定 义 说 明 变 量 函 数 或 其 它 数 据 结 构 的 类 型 如 前 面 例 题 中 用 到 的 int,double 等 (2) 语 句 定 义 符 用 于 表 示 一 个 语 句 的 功 能 如 例 1.3 中 用 到 的 if else 就 是 条 件 语 句 的 语 句 定 义 符 (3) 预 处 理 命 令 字 用 于 表 示 一 个 预 处 理 命 令 如 前 面 各 例 中 用 到 的 include 3. 运 算 符 C 语 言 中 含 有 相 当 丰 富 的 运 算 符 运 算 符 与 变 量, 函 数 一 起 组 成 表 达 式, 表 示 各 种 运 算 功 能 运 算 符 由 一 个 或 多 个 字 符 组 成 4. 分 隔 符 在 C 语 言 中 采 用 的 分 隔 符 有 逗 号 和 空 格 两 种 逗 号 主 要 用 在 类 型 说 明 和 函 数 参 数 表 中, 分 隔 各 个 变 量 空 格 多 用 于 语 句 各 单 词 之 间, 作 间 隔 符 在 关 键 字, 标 识 符 之 间 必 须 要 有 一 个 以 上 的 空 格 符 作 间 隔, 否 则 将 会 出 现 语 法 错 误, 例 如 把 int a; 写 成 inta;c 编 译 器 会 把 inta 当 成 一 个 标 识 符 处 理, 其 结 果 必 然 出 错 5. 常 量 C 语 言 中 使 用 的 常 量 可 分 为 数 字 常 量 字 符 常 量 字 符 串 常 量 符 号 常 量 转 义 字 符 等 多 种 在 后 面 章 节 中 将 专 门 给 予 介 绍 6. 注 释 符 C 语 言 的 注 释 符 是 以 /* 开 头 并 以 */ 结 尾 的 串 在 /* 和 */ 之 间 的 即 为 注 释 程 序 编 译 时, 不 对 注 释 作 任 何 处 理 注 释 可 出 现 在 程 序 中 的 任 何 位 置 注 释 用 来 向 用 户 提 示 或 解 释 程 序 的 意 义 在 调 试 程 序 中 对 暂 不 使 用 的 语 句 也 可 用 注 释 符 括 起 来, 使 翻 译 跳 过 不 作 处 理, 待 调 试 结 束 后 再 去 掉 注 释 符 1.13 Turbo C 2.0 集 成 开 发 环 境 的 使 用 Turbo C 2.0 简 介 和 启 动 我 们 上 机 实 习 和 将 来 考 试 都 是 使 用 Borland Turbo C 2.0 这 个 版 本 该 系 统 是 DOS 操 作 系 统 支 持 下 的 软 件, 在 windows 98 环 境 下, 可 以 在 DOS 窗 口 下 运 行 我 们 机 房 是 在 D 盘 根 目 录 下 建 立 一 个 TC 子 目 录 下 安 装 Turbo C 2.0 系 统 的 TC 下 还 建 立 了 两 个 了 目 录 LIB 和 INCLUDE, LIB 子 目 录 中 存 放 库 文 件, INCLUDE 子 目 录 中 存 放 所 有 头 文 件 在 DOS 环 境 下 或 在 windows 98 的 DOS 窗 口 下 运 行 运 行 Turbo C 2.0 时, 只 要 在 TC 子 目 录 下 键 入 TC 并 回 车 即 可 进 入 Turbo C 2. 0 集 成 开 发 环 境 在 windows 98 环 境 下, 也 可 以 选 运 行 菜 单, 然 后 键 入 d:\tc\tc 即 可, 也 可 以 在 tc 文 件 夹 找 到 tc.exe 文 件, 然 后 用 鼠 标 双 击 该 文 件 名 也 可 进 入 Turbo C 2. 0 集 成 开 发 环 境 Turbo C 是 美 国 Borland 公 司 的 产 品,Borland 公 司 是 一 家 专 门 从 事 软 件 开 发 研 制 的 大 公 司 该 公 司 相 继 推 出 了 一 套 Turbo 系 列 软 件, 如 Turbo BASIC, TurboPascal, Turbo Prolog, 这 些 软 件 很 受 用 户 欢 迎 该 公 司 在 1987 年 首 次 推 出 TurboC 1.0 产 品, 其 中 使 用 了 全 然 一 新 的 集 成 开 发 环 境, 即 使 用 了 一 系 列 下 拉 式 菜 单, 将 第 12 页

13 文 本 编 辑 程 序 编 译 连 接 以 及 程 序 运 行 一 体 化, 大 大 方 便 了 程 序 的 开 发 1988 年, Borland 公 司 又 推 出 Turbo C1.5 版 本, 增 加 了 图 形 库 和 文 本 窗 口 函 数 库 等, 而 Turbo C 2.0 则 是 该 公 司 1989 年 出 版 的 Turbo C2.0 在 原 来 集 成 开 发 环 境 的 基 础 上 增 加 了 查 错 功 能, 并 可 以 在 Tiny 模 式 下 直 接 生 成.COM ( 数 据 代 码 堆 栈 处 在 同 一 64K 内 存 中 ) 文 件 还 可 对 数 学 协 处 理 器 ( 支 持 8087/80287/80387 等 ) 进 行 仿 真 Borland 公 司 后 来 又 推 出 了 面 向 对 象 的 程 序 软 件 包 Turbo C++, 它 继 承 发 展 Turbo C 2.0 的 集 成 开 发 环 境, 并 包 含 了 面 向 对 象 的 基 本 思 想 和 设 计 方 法 1991 年 为 了 适 用 Microsoft 公 司 的 Windows 3.0 版 本, Borland 公 司 又 将 Turbo C++ 作 了 更 新, 即 Turbo C 的 新 一 代 产 品 Borlandc C++ 也 已 经 问 世 了 Turbo C 2.0 集 成 开 发 环 境 进 入 Turbo C 2.0 集 成 开 发 环 境 中 后, 屏 幕 上 显 示 : 其 中 顶 上 一 行 为 Turbo C 2.0 主 菜 单, 中 间 窗 口 为 编 辑 区, 接 下 来 是 信 息 窗 口, 最 底 下 一 行 为 参 考 行 这 四 个 窗 口 构 成 了 Turbo C 2.0 的 主 屏 幕, 以 后 的 编 程 编 译 调 试 以 及 运 行 都 将 在 这 个 主 屏 幕 中 进 行 主 菜 单 在 Turbo C 2.0 主 屏 幕 顶 上 一 行, 显 示 下 列 内 容 : File Edit Run Compile Project Options Debug Break/watch 除 Edit 外, 其 它 各 项 均 有 子 菜 单, 只 要 用 Alt 加 上 某 项 中 第 一 个 字 母, 就 可 进 入 该 项 的 子 菜 单 中 File 菜 单 按 Alt+F 可 进 入 File 菜 单, 如 图 : 第 13 页

14 File 菜 单 的 子 菜 单 共 有 9 项, 分 别 叙 述 如 下 : 1. Load: 装 入 一 个 文 件, 可 用 类 似 DOS 的 通 配 符 ( 如 *.C) 来 进 行 列 表 选 择 也 可 装 入 其 它 扩 展 名 的 文 件, 只 要 给 出 文 件 名 ( 或 只 给 路 径 ) 即 可 该 项 的 热 键 为 F3, 即 只 要 按 F3 即 可 进 入 该 项, 而 不 需 要 先 进 入 File 菜 单 再 选 此 项 2. Pick: 将 最 近 装 入 编 辑 窗 口 的 8 个 文 件 列 成 一 个 表 让 用 户 选 择, 选 择 后 将 该 程 序 装 入 编 辑 区, 并 将 光 标 置 在 上 次 修 改 过 的 地 方 其 热 健 为 Alt-F3 3. New: 新 建 文 件, 缺 省 文 件 名 为 NONAME.C, 存 盘 时 可 改 名 4. Save: 将 编 辑 区 中 的 文 件 存 盘, 若 文 件 名 是 NONAME.C 时, 将 询 问 是 否 更 改 文 件 名, 其 热 键 为 F2 5. Write to: 可 由 用 户 给 出 文 件 名 将 编 辑 区 中 的 文 件 存 盘, 若 该 文 件 已 存 在, 则 询 问 要 不 要 覆 盖 6. Directory: 显 示 目 录 及 目 录 中 的 文 件, 并 可 由 用 户 选 择 7. Change dir: 显 示 当 前 默 认 目 录, 用 户 可 以 改 变 默 认 目 录 8. Os shell: 暂 时 退 出 Turbo C 2.0 到 DOS 提 示 符 下, 此 时 可 以 运 行 DOS 命 令, 若 想 回 到 Turbo C 2.0 中, 只 要 在 DOS 状 态 下 键 入 EXIT 即 可 9. Quit: 退 出 Turbo C 2.0, 返 回 到 DOS 操 作 系 统 中, 其 热 键 为 Alt+X 说 明 : 以 上 各 项 可 用 光 标 键 移 动 色 棒 进 行 选 择, 回 车 则 执 行 也 可 用 每 一 项 的 第 一 个 大 写 字 母 直 接 选 择 若 要 退 到 主 菜 单 或 从 它 的 下 一 级 菜 单 列 表 框 退 回 均 可 用 Esc 键, Turbo C 2.0 所 有 菜 单 均 采 用 这 种 方 法 进 行 操 作, 以 下 不 再 说 明 Edit 菜 单 按 Alt+E 可 进 入 编 辑 菜 单, 若 再 回 车, 则 光 标 出 现 在 编 辑 窗 口, 此 时 用 户 可 以 进 行 文 本 编 辑 编 辑 方 法 基 本 与 wordstar 相 同, 可 用 F1 键 获 得 有 关 编 辑 方 法 的 帮 助 信 息 1. 与 编 辑 有 关 的 功 能 键 如 下 : F1 获 得 Turbo C 2.0 编 辑 命 令 的 帮 助 信 息 ; F5 扩 大 编 辑 窗 口 到 整 个 屏 幕 ; F6 在 编 辑 窗 口 与 信 息 窗 口 之 间 进 行 切 换 ; 第 14 页

15 F10 从 编 辑 窗 口 转 到 主 菜 单 2. 编 辑 命 令 简 介 : PageUp 向 前 翻 页 PageDn 向 后 翻 页 Home 将 光 标 移 到 所 在 行 的 开 始 End 将 光 标 移 到 所 在 行 的 结 尾 Ctrl+Y 删 除 光 标 所 在 的 一 行 Ctrl+T 删 除 光 标 所 在 处 的 一 个 词 Ctrl+KB 设 置 块 开 始 Ctrl+KK 设 置 块 结 尾 Ctrl+KV 块 移 动 Ctrl+KC 块 拷 贝 Ctrl+KY 块 删 除 Ctrl+KR 读 文 件 Ctrl+KW 存 文 件 Ctrl+KP 块 文 件 打 印 Ctrl+F1 如 果 光 标 所 在 处 为 Turbo C 2.0 库 函 数, 则 获 得 有 关 该 函 数 的 帮 助 信 息 Ctrl+Q[ 查 找 Turbo C 2.0 双 界 符 的 后 匹 配 符 Ctrl+Q] 查 找 Turbo C 2.0 双 界 符 的 前 匹 配 符 说 明 : 1) Turbo C 2.0 的 双 界 符 包 括 以 下 几 种 符 号 : a) 花 括 符 和 b) 尖 括 符 < 和 > c) 圆 括 符 ( 和 ) d) 方 括 符 [ 和 ] e) 注 释 符 /* 和 */ f) 双 引 号 " g) 单 引 号 ' 2) Turbo C 2.0 在 编 辑 文 件 时 还 有 一 种 功 能, 就 是 能 够 自 动 缩 进, 即 光 标 定 位 和 上 一 个 非 空 字 符 对 齐 在 编 辑 窗 口 中, Ctrl+OL 为 自 动 缩 进 开 关 的 控 制 键 Run 菜 单 按 Alt+R 可 进 入 Run 菜 单, 该 菜 单 有 以 下 各 项, 如 图 所 示 : 第 15 页

16 1. Run: 运 行 由 Project/Project name 项 指 定 的 文 件 名 或 当 前 编 辑 区 的 文 件 如 果 对 上 次 编 译 后 的 源 代 码 未 做 过 修 改, 则 直 接 运 行 到 下 一 个 断 点 ( 没 有 断 点 则 运 行 到 结 束 ) 否 则 先 进 行 编 译 连 接 后 才 运 行, 其 热 键 为 Ctrl+F9 2. Program reset: 中 止 当 前 的 调 试, 释 放 分 给 程 序 的 空 间, 其 热 键 为 Ctrl+F2 3. Go to cursor:: 调 试 程 序 时 使 用, 选 择 该 项 可 使 程 序 运 行 到 光 标 所 在 行 光 标 所 在 行 必 须 为 一 条 可 执 行 语 句, 否 则 提 示 错 误 其 热 键 为 F4 4. Trace into: 在 执 行 一 条 调 用 其 它 用 户 定 义 的 子 函 数 时, 若 用 Trace into 项, 则 执 行 长 条 将 跟 踪 到 该 子 函 数 内 部 去 执 行, 其 热 键 为 F7 5. Step over: 执 行 当 前 函 数 的 下 一 条 语 句, 即 使 用 户 函 数 调 用, 执 行 长 条 也 不 会 跟 踪 进 函 数 内 部, 其 热 键 为 F8 6. User screen: 显 示 程 序 运 行 时 在 屏 幕 上 显 示 的 结 果 其 热 键 为 Alt+F Compile 菜 单 按 Alt+C 可 进 入 Compile 菜 单, 该 菜 单 有 以 下 几 个 内 容, 如 图 所 示 : 第 16 页

17 1. Compile to OBJ: 将 一 个 C 源 文 件 编 译 生 成.OBJ 目 标 文 件, 同 时 显 示 生 成 的 文 件 名 其 热 键 为 Alt+F9 2. Make EXE file: 此 命 令 生 成 一 个.EXE 的 文 件, 并 显 示 生 成 的.EXE 文 件 名 其 中.EXE 文 件 名 是 下 面 几 项 之 一 : 1) 由 Project/Project name 说 明 的 项 目 文 件 名 2) 若 没 有 项 目 文 件 名, 则 由 Primary C file 说 明 的 源 文 件 3) 若 以 上 两 项 都 没 有 文 件 名, 则 为 当 前 窗 口 的 文 件 名 3. Link EXE file: 把 当 前.OBJ 文 件 及 库 文 件 连 接 在 一 起 生 成.EXE 文 件 4. Build all: 重 新 编 译 项 目 里 的 所 有 文 件, 并 进 行 装 配 生 成.EXE 文 件 该 命 令 不 作 过 时 检 查 ( 上 面 的 几 条 命 令 要 作 过 时 检 查, 即 如 果 目 前 项 目 里 源 文 件 的 日 期 和 时 间 与 目 标 文 件 相 同 或 更 早, 则 拒 绝 对 源 文 件 进 行 编 译 ) 5. Primary C file: 当 在 该 项 中 指 定 了 主 文 件 后, 在 以 后 的 编 译 中, 如 没 有 项 目 文 件 名 则 编 译 此 项 中 规 定 的 主 C 文 件, 如 果 编 译 中 有 错 误, 则 将 此 文 件 调 入 编 辑 窗 口, 不 管 目 前 窗 口 中 是 不 是 主 C 文 件 6. Get info: 获 得 有 关 当 前 路 径 源 文 件 名 源 文 件 字 节 大 小 编 译 中 的 错 误 数 目 可 用 空 间 等 信 息, 如 图 : 第 17 页

18 Project 菜 单 按 Alt+P 可 进 入 Project 菜 单, 该 菜 单 包 括 以 下 内 容, 如 图 所 示 : 1. Project name: 项 目 名 具 有.PRJ 的 扩 展 名, 其 中 包 括 将 要 编 译 连 接 的 文 件 名 例 如 有 一 个 程 序 由 file1.c, file2.c, file3.c 组 成, 要 将 这 3 个 文 件 编 译 装 配 成 一 个 file.exe 的 执 行 文 件, 可 以 先 建 立 一 个 file.prj 的 项 目 文 件, 其 内 容 如 下 : file1.c file2.c file3.c 此 时 将 file.prj 放 入 Project name 项 中, 以 后 进 行 编 译 时 将 自 动 对 项 目 文 件 中 规 定 的 三 个 源 文 件 分 别 进 行 编 译 然 后 连 接 成 file.exe 文 件 如 果 其 中 有 些 文 件 已 经 编 译 成.OBJ 文 件, 而 又 没 有 修 改 过, 可 直 接 写 上.OBJ 第 18 页

19 扩 展 名 此 时 将 不 再 编 译 而 只 进 行 连 接 例 如 : file1.obj file2.c file3.c 将 不 对 file1.c 进 行 编 译, 而 直 接 连 接 说 明 : 当 项 目 文 件 中 的 每 个 文 件 无 扩 展 名 时, 均 按 源 文 件 对 待, 另 外, 其 中 的 文 件 也 可 以 是 库 文 件, 但 必 须 写 上 扩 展 名.LIB 2. Break make on: 由 用 户 选 择 是 否 在 有 Warining Errors Fatal Errors 时 或 Link 之 前 退 出 Make 编 译 3. Auto dependencies: 当 开 关 置 为 on, 编 译 时 将 检 查 源 文 件 与 对 应 的.OBJ 文 件 日 期 和 时 间, 否 则 不 进 行 检 查 4. Clear project: 清 除 Project/Project name 中 的 项 目 文 件 名 5. Remove messages: 把 错 误 信 息 从 信 息 窗 口 中 清 除 掉 Options 菜 单 按 Alt+O 可 进 入 Options 菜 单, 该 菜 单 对 初 学 者 来 说 要 谨 慎 使 用, 该 菜 单 有 以 下 几 个 内 容, 如 图 所 示 : 1. Compiler: 本 项 选 择 又 有 许 多 子 菜 单, 可 以 让 用 户 选 择 硬 件 配 置 存 储 模 型 调 试 技 术 代 码 优 化 对 话 信 息 控 制 和 宏 定 义 这 些 子 菜 单 如 图 所 示 : 第 19 页

20 1) Model: 共 有 Tiny, small, medium, compact, large, huge 六 种 不 同 模 式 可 由 同 户 选 择 2) Define: 打 开 一 个 宏 定 义 框, 同 户 可 输 入 宏 定 义 多 重 定 义 可 同 分 号, 赋 值 可 用 等 号 3) Code generation: 它 又 有 许 多 任 选 项, 这 些 任 选 项 告 诉 编 译 器 产 生 什 么 样 的 目 标 代 码 Calling convention 可 选 择 C 或 Pascal 方 式 传 递 参 数 Instruction set 可 选 择 8088/8086 或 80186/80286 指 令 系 列 Floating point 可 选 择 仿 真 浮 点 数 学 协 处 理 器 浮 点 或 无 浮 点 运 算 Default char type 规 定 char 的 类 型 Alignonent 规 定 地 址 对 准 原 则 Merge duplicate strings 作 优 化 用, 将 重 复 的 字 符 串 合 并 在 一 起 Standard stack frame 产 生 一 个 标 准 的 栈 结 构 Test stack overflow 产 生 一 段 程 序 运 行 时 检 测 堆 栈 溢 出 的 代 码 Line number 在.OBJ 文 件 中 放 进 行 号 以 供 调 试 时 用 OBJ debug information 在.OBJ 文 件 中 产 生 调 试 信 息 4) Optimization: 它 又 有 许 多 任 选 项 Optimize for 选 择 是 对 程 序 小 型 化 还 是 对 程 序 速 度 进 行 优 化 处 理 Use register variable 用 来 选 择 是 否 允 许 使 用 寄 存 器 变 量 Register optimization 尽 可 能 使 用 寄 存 器 变 量 以 减 少 过 多 的 取 数 操 作 Jump optimization 通 过 去 除 多 余 的 跳 转 和 调 整 循 环 与 开 关 语 句 的 办 法, 压 缩 代 码 5) Source: 它 又 有 许 多 任 选 项 Indentifier length 说 明 标 识 符 有 效 字 符 的 个 数, 默 认 为 32 个 Nested comments 是 否 允 许 嵌 套 注 释 ANSI keywords only 是 只 允 许 ANSI 关 键 字 还 是 也 允 许 Turbo C2.0 关 键 字 6) Error Error stop after 多 少 个 错 误 时 停 止 编 译, 默 认 为 25 个 Warning stop after 多 少 个 警 告 错 误 时 停 止 编 译, 默 认 为 100 个 Display warning Portability warning 移 植 性 警 告 错 误 ANSI Violations 侵 犯 了 ANSI 关 键 字 的 警 告 错 误 第 20 页

21 Common error 常 见 的 警 告 错 误 Less common error 少 见 的 警 告 错 误 7) Names : 用 于 改 变 段 (segment) 组 (group) 和 类 (class) 的 名 字, 默 认 值 为 CODE, DATA, BSS 2. Linker: 本 菜 单 设 置 有 关 连 接 的 选 择 项, 它 有 以 下 内 容, 如 图 所 示 : 1) Map file menu 选 择 是 否 产 生.MAP 文 件 2) Initialize segments 是 否 在 连 接 时 初 始 化 没 有 初 始 化 的 段 3) Devault libraries 是 否 在 连 接 其 它 编 译 程 序 产 生 的 目 标 文 件 时 去 寻 找 其 缺 省 库 4) Graphics library 是 否 连 接 graphics 库 中 的 函 数 5) Warn duplicate symbols 当 有 重 复 符 号 时 产 生 警 告 信 息 6) Stack warinig 是 否 让 连 接 程 序 产 生 No stack 的 警 告 信 息 7) Case-sensitive link 是 否 区 分 大 小 写 字 3. Environment: 菜 单 规 定 是 否 对 某 些 文 件 自 动 存 盘 及 制 表 键 和 屏 幕 大 小 的 设 置, 它 有 以 下 内 容, 如 图 所 示 : 第 21 页

22 1) Message tracking: Current file 跟 踪 在 编 辑 窗 口 中 的 文 件 错 误 All files 跟 踪 所 有 文 件 错 误 Off 不 跟 踪 2) Keep message : 编 译 前 是 否 清 除 Message 窗 口 中 的 信 息 3) Config auto save: 选 on 时, 在 Run, Shell 或 退 出 集 成 开 发 环 境 之 前, 如 果 Turbo C 2.0 的 配 置 被 改 过, 则 所 做 的 改 动 将 存 入 配 置 文 件 中 选 off 时 不 存 4) Edit auto save: 是 否 在 Run 或 Shell 之 前, 自 动 存 储 编 辑 的 源 文 件 5) Backup file: 是 否 在 源 文 件 存 盘 时 产 生 后 备 文 件 (.BAK 文 件 ) 6) Tab size: 设 置 制 表 键 大 小, 默 认 为 8 7) Zoomed windows: 将 现 行 活 动 窗 口 放 大 到 整 个 屏 幕, 其 热 键 为 F5 8) Screen size 设 置 屏 幕 文 本 大 小 4. Directories: 规 定 编 译 连 接 所 需 文 件 的 路 径, 有 下 列 各 项, 如 图 所 示 : (1) Include directories: 包 含 文 件 的 路 径, 多 个 子 目 录 用 ";" 分 开 (2) Library directories: 库 文 件 路 径, 多 个 子 目 录 用 ";" 分 开 (3) Output directoried: 输 出 文 件 (.OBJ,.EXE,.MAP 文 件 ) 的 目 录 (4) Turbo C directoried:turbo C 所 在 的 目 录 (5) Pick file name: 定 义 加 载 的 pick 文 件 名, 如 不 定 义 则 从 currentpick file 中 取 5. Arguments: 允 许 用 户 使 用 命 令 行 参 数 6. Save options: 保 存 所 有 选 择 的 编 译 连 接 调 试 和 项 目 到 配 置 文 件 中, 缺 省 的 配 置 文 件 为 TCCONFIG.TC 7. Retrive options 装 入 一 个 配 置 文 件 到 TC 中, TC 将 使 用 该 文 件 的 选 择 项 Debug 菜 单 按 Alt+D 可 选 择 Debug 菜 单, 该 菜 单 主 要 用 于 查 错, 它 包 括 以 下 内 容, 如 图 所 示 : 第 22 页

23 1. Evaluate 1) Expression 要 计 算 结 果 的 表 达 式 2) Result 显 示 表 达 式 的 计 算 结 果 3) New value 赋 给 新 值 2. Call stack: 该 项 不 可 接 触 而 在 Turbo C debuger 时 用 于 检 查 堆 栈 情 况 3. Find function 在 运 行 Turbo C debugger 时 用 于 显 示 规 定 的 函 数 4. Refresh display 如 果 编 辑 窗 口 偶 然 被 用 户 窗 口 重 写 了 可 用 此 恢 复 编 辑 窗 口 的 内 容 Break/watch 菜 单 按 Alt+B 可 进 入 Break/watch 菜 单, 该 菜 单 有 以 下 内 容, 如 图 所 示 : 1. Add watch: 向 监 视 窗 口 插 入 一 监 视 表 达 式 第 23 页

24 2. Delete watch: 从 监 视 窗 口 中 删 除 当 前 的 监 视 表 达 式 3. Edit watch: 在 监 视 窗 口 中 编 辑 一 个 监 视 表 达 式 4. Remove all :watches 从 监 视 窗 口 中 删 除 所 有 的 监 视 表 达 式 5. Toggle breakpoint: 对 光 标 所 在 的 行 设 置 或 清 除 断 点 6. Clear all breakpoints: 清 除 所 有 断 点 7. View next breakpoint: 将 光 标 移 动 到 下 一 个 断 点 处 Turbo C 2.0 的 配 置 文 件 所 谓 配 置 文 件 是 包 含 Turbo C 2.0 有 关 信 息 的 文 件, 其 中 存 有 编 译 连 接 的 选 择 和 路 径 等 信 息 可 以 用 下 述 方 法 建 立 Turbo C 2.0 的 配 置 : 1. 建 立 用 户 自 命 名 的 配 置 文 件 : 可 以 从 Options 菜 单 中 选 择 Options/Save options 命 令, 将 当 前 集 成 开 发 环 境 的 所 有 配 置 存 入 一 个 由 用 户 命 名 的 配 置 文 件 中 下 次 启 动 TC 时 只 要 在 DOS 下 键 入 : tc/c< 用 户 命 名 的 配 置 文 件 名 > 就 会 按 这 个 配 置 文 件 中 的 内 容 作 为 Turbo C 2.0 的 选 择 2. 若 设 置 Options/Environment/Config auto save 为 on, 则 退 出 集 成 开 发 环 境 时, 当 前 的 设 置 会 自 动 存 放 到 Turbo C 2.0 配 置 文 件 TCCONFIG.TC 中 Turbo C 在 启 动 时 会 自 动 寻 找 这 个 配 置 文 件 3. 用 TCINST 设 置 Turbo C 的 有 关 配 置, 并 将 结 果 存 入 TC.EXE 中 Turbo C 在 启 动 时, 若 没 有 找 到 配 置 文 件, 则 取 TC.EXE 中 的 缺 省 值 2 程 序 的 灵 魂 算 法 一 个 程 序 应 包 括 : 对 数 据 的 描 述 在 程 序 中 要 指 定 数 据 的 类 型 和 数 据 的 组 织 形 式, 即 数 据 结 构 (data structure) 对 操 作 的 描 述 即 操 作 步 骤, 也 就 是 算 法 (algorithm) Nikiklaus Wirth 提 出 的 公 式 : 数 据 结 构 + 算 法 = 程 序 教 材 认 为 : 程 序 = 算 法 + 数 据 结 构 + 程 序 设 计 方 法 + 语 言 工 具 和 环 境 这 4 个 方 面 是 一 个 程 序 涉 及 人 员 所 应 具 备 的 知 识 本 课 程 的 目 的 是 使 同 学 知 道 怎 样 编 写 一 个 C 程 序, 进 行 编 写 程 序 的 初 步 训 练, 因 此, 只 介 绍 算 法 的 初 步 知 识 2.1 算 法 的 概 念 做 任 何 事 情 都 有 一 定 的 步 骤 为 解 决 一 个 问 题 而 采 取 的 方 法 和 步 骤, 就 称 为 算 法 计 算 机 算 法 : 计 算 机 能 够 执 行 的 算 法 计 算 机 算 法 可 分 为 两 大 类 : 数 值 运 算 算 法 : 求 解 数 值 ; 非 数 值 运 算 算 法 : 事 务 管 理 领 域 第 24 页

25 2.2 简 单 算 法 举 例 例 2.1 求 最 原 始 方 法 : 步 骤 1: 先 求 1 2, 得 到 结 果 2 步 骤 2: 将 步 骤 1 得 到 的 乘 积 2 乘 以 3, 得 到 结 果 6 步 骤 3: 将 6 再 乘 以 4, 得 24 步 骤 4: 将 24 再 乘 以 5, 得 120 这 样 的 算 法 虽 然 正 确, 但 太 繁 改 进 的 算 法 : S1: 使 t=1 S2: 使 i=2 S3: 使 t i, 乘 积 仍 然 放 在 在 变 量 t 中, 可 表 示 为 t i t S4: 使 i 的 值 +1, 即 i+1 i S5: 如 果 i 5, 返 回 重 新 执 行 步 骤 S3 以 及 其 后 的 S4 和 S5; 否 则, 算 法 结 束 如 果 计 算 100! 只 需 将 S5: 若 i 5 改 成 i 100 即 可 如 果 该 求 , 算 法 也 只 需 做 很 少 的 改 动 : S1: 1 t S2: 3 i S3: t i t S4: i+2 t S5: 若 i 11, 返 回 S3, 否 则, 结 束 该 算 法 不 仅 正 确, 而 且 是 计 算 机 较 好 的 算 法, 因 为 计 算 机 是 高 速 运 算 的 自 动 机 器, 实 现 循 环 轻 而 易 举 思 考 : 若 将 S5 写 成 :S5: 若 i<11, 返 回 S3; 否 则, 结 束 例 2.2 有 50 个 学 生, 要 求 将 他 们 之 中 成 绩 在 80 分 以 上 者 打 印 出 来 如 果,n 表 示 学 生 学 号,n i 表 示 第 个 学 生 学 号 ;g 表 示 学 生 成 绩,g i 表 示 第 个 学 生 成 绩 ; 则 算 法 可 表 示 如 下 : S1: 1 i S2: 如 果 g i 80, 则 打 印 n i 和 g i, 否 则 不 打 印 S3: i+1 i S4: 若 i 50, 返 回 S2, 否 则, 结 束 例 2.3 判 定 年 中 的 每 一 年 是 否 闰 年, 将 结 果 输 出 润 年 的 条 件 : 第 25 页

26 1) 能 被 4 整 除, 但 不 能 被 100 整 除 的 年 份 ; 2) 能 被 100 整 除, 又 能 被 400 整 除 的 年 份 ; 设 y 为 被 检 测 的 年 份, 则 算 法 可 表 示 如 下 : S1: 2000 y S2: 若 y 不 能 被 4 整 除, 则 输 出 y 不 是 闰 年, 然 后 转 到 S6 S3: 若 y 能 被 4 整 除, 不 能 被 100 整 除, 则 输 出 y 是 闰 年, 然 后 转 到 S6 S4: 若 y 能 被 100 整 除, 又 能 被 400 整 除, 输 出 y 是 闰 年 否 则 输 出 y 不 是 闰 年, 然 后 转 到 S6 S5: 输 出 y 不 是 闰 年 S6:y+1 y S7: 当 y 2500 时, 返 回 S2 继 续 执 行, 否 则, 结 束 例 2.4 求 算 法 可 表 示 如 下 : S1: sigh=1 S2: sum=1 S3: deno=2 S4: sigh=(-1) sigh S5: term= sigh (1/deno ) S6: term=sum+term S7: deno= deno +1 S8: 若 deno 100, 返 回 S4; 否 则, 结 束 第 26 页

27 例 2.5 对 一 个 大 于 或 等 于 3 的 正 整 数, 判 断 它 是 不 是 一 个 素 数 算 法 可 表 示 如 下 : S1: 输 入 n 的 值 S2: i=2 S3: n 被 i 除, 得 余 数 r S4: 如 果 r=0, 表 示 n 能 被 i 整 除, 则 打 印 n 不 是 素 数, 算 法 结 束 ; 否 则 执 行 S5 S5: i+1 i S6: 如 果 i n-1, 返 回 S3; 否 则 打 印 n 是 素 数 ; 然 后 算 法 结 束 改 进 : S6: 如 果 i n, 返 回 S3; 否 则 打 印 n 是 素 数 ; 然 后 算 法 结 束 2.3 算 法 的 特 性 有 穷 性 : 一 个 算 法 应 包 含 有 限 的 操 作 步 骤 而 不 能 是 无 限 的 确 定 性 : 算 法 中 每 一 个 步 骤 应 当 是 确 定 的, 而 不 能 应 当 是 含 糊 的 模 棱 两 可 的 有 零 个 或 多 个 输 入 有 一 个 或 多 个 输 出 有 效 性 : 算 法 中 每 一 个 步 骤 应 当 能 有 效 地 执 行, 并 得 到 确 定 的 结 果 对 于 程 序 设 计 人 员, 必 须 会 设 计 算 法, 并 根 据 算 法 写 出 程 序 2.4 怎 样 表 示 一 个 算 法 用 自 然 语 言 表 示 算 法 除 了 很 简 单 的 问 题, 一 般 不 用 自 然 语 言 表 示 算 法 用 流 程 图 表 示 算 法 流 程 图 表 示 算 法, 直 观 形 象, 易 于 理 解 第 27 页

28 例 2.6 将 例 2.1 求 5! 的 算 用 流 程 图 表 示 例 2.7 将 例 2.2 的 算 用 流 程 图 表 示 第 28 页

29 例 2.8 将 例 2.3 判 定 闰 年 的 算 用 流 程 图 表 示 第 29 页

30 例 2.9 将 例 2.4 求 的 算 用 流 程 图 表 示 一 个 流 程 图 包 括 : 1. 表 示 相 应 操 作 的 框 ; 2. 带 箭 头 的 流 程 线 ; 3. 框 内 外 必 要 的 文 字 说 明 第 30 页

31 2.4.3 三 种 基 本 结 构 和 改 进 的 流 程 图 1. 顺 序 结 构 : 2. 选 择 结 构 : 3. 循 环 结 构 第 31 页

32 三 种 基 本 结 构 的 共 同 特 点 : 只 有 一 个 入 口 ; 只 有 一 个 出 口 ; 结 构 内 的 每 一 部 分 都 有 机 会 被 执 行 到 ; 结 构 内 不 存 在 死 循 环 用 N-S 流 程 图 表 示 算 法 1973 年 美 国 学 者 提 出 了 一 种 新 型 流 程 图 :N-S 流 程 图 顺 序 结 构 : 第 32 页

33 选 择 结 构 : 循 环 结 构 : 用 伪 代 码 表 示 算 法 伪 代 码 使 用 介 于 自 然 语 言 和 计 算 机 语 言 之 间 的 文 字 和 符 号 来 描 述 算 法 第 33 页

34 2.4.6 用 计 算 机 语 言 表 示 算 法 我 们 的 任 务 是 用 计 算 机 解 题, 就 是 用 计 算 机 实 现 算 法 ; 用 计 算 机 语 言 表 示 算 法 必 须 严 格 遵 循 所 用 语 言 的 语 法 规 则 例 2.20 求 用 C 语 言 表 示 main() int i,t; t=1; i=2; while(i<=5) t=t*i; i=i+1; printf( %d,t); 例 2.21 求 级 数 的 值 main() int sigh=1; float deno=2.0,sum=1.0,term; while(deno<=100) sigh= -sigh; term= sigh/ deno; sum=sum+term; deno=deno+1; printf( %f,sum); 2.5 结 构 化 程 序 设 计 方 法 自 顶 向 下 ; 逐 步 细 化 ; 模 块 化 设 计 ; 结 构 化 编 码 第 34 页

35 3 数 据 类 型 运 算 符 与 表 达 式 3.1 C 语 言 的 数 据 类 型 在 第 一 章 中, 我 们 已 经 看 到 程 序 中 使 用 的 各 种 变 量 都 应 预 先 加 以 定 义, 即 先 定 义, 后 使 用 对 变 量 的 定 义 可 以 包 括 三 个 方 面 : 数 据 类 型 存 储 类 型 作 用 域 在 本 章 中, 我 们 只 介 绍 数 据 类 型 的 说 明 其 它 说 明 在 以 后 各 章 中 陆 续 介 绍 所 谓 数 据 类 型 是 按 被 定 义 变 量 的 性 质, 表 示 形 式, 占 据 存 储 空 间 的 多 少, 构 造 特 点 来 划 分 的 在 C 语 言 中, 数 据 类 型 可 分 为 : 基 本 数 据 类 型, 构 造 数 据 类 型, 指 针 类 型, 空 类 型 四 大 类 第 35 页

36 数 据 类 型 基 本 类 型 整 型 字 符 型 实 型 ( 浮 点 型 ) 单 精 度 型 双 精 度 型 枚 举 类 型 构 造 类 型 数 组 类 型 结 构 体 类 型 共 用 体 类 型 指 针 类 型 空 类 型 1. 基 本 数 据 类 型 : 基 本 数 据 类 型 最 主 要 的 特 点 是, 其 值 不 可 以 再 分 解 为 其 它 类 型 也 就 是 说, 基 本 数 据 类 型 是 自 我 说 明 的 2. 构 造 数 据 类 型 : 构 造 数 据 类 型 是 根 据 已 定 义 的 一 个 或 多 个 数 据 类 型 用 构 造 的 方 法 来 定 义 的 也 就 是 说, 一 个 构 造 类 型 的 值 可 以 分 解 成 若 干 个 成 员 或 元 素 每 个 成 员 都 是 一 个 基 本 数 据 类 型 或 又 是 一 个 构 造 类 型 在 C 语 言 中, 构 造 类 型 有 以 下 几 种 : 数 组 类 型 结 构 体 类 型 共 用 体 ( 联 合 ) 类 型 3. 指 针 类 型 : 指 针 是 一 种 特 殊 的, 同 时 又 是 具 有 重 要 作 用 的 数 据 类 型 其 值 用 来 表 示 某 个 变 量 在 内 存 储 器 中 的 地 址 虽 然 指 针 变 量 的 取 值 类 似 于 整 型 量, 但 这 是 两 个 类 型 完 全 不 同 的 量, 因 此 不 能 混 为 一 谈 第 36 页

37 4. 空 类 型 : 在 调 用 函 数 值 时, 通 常 应 向 调 用 者 返 回 一 个 函 数 值 这 个 返 回 的 函 数 值 是 具 有 一 定 的 数 据 类 型 的, 应 在 函 数 定 义 及 函 数 说 明 中 给 以 说 明, 例 如 在 例 题 中 给 出 的 max 函 数 定 义 中, 函 数 头 为 :int max(int a,int b); 其 中 int 类 型 说 明 符 即 表 示 该 函 数 的 返 回 值 为 整 型 量 又 如 在 例 题 中, 使 用 了 库 函 数 sin, 由 于 系 统 规 定 其 函 数 返 回 值 为 双 精 度 浮 点 型, 因 此 在 赋 值 语 句 s=sin (x); 中,s 也 必 须 是 双 精 度 浮 点 型, 以 便 与 sin 函 数 的 返 回 值 一 致 所 以 在 说 明 部 分, 把 s 说 明 为 双 精 度 浮 点 型 但 是, 也 有 一 类 函 数, 调 用 后 并 不 需 要 向 调 用 者 返 回 函 数 值, 这 种 函 数 可 以 定 义 为 空 类 型 其 类 型 说 明 符 为 void 在 后 面 函 数 中 还 要 详 细 介 绍 在 本 章 中, 我 们 先 介 绍 基 本 数 据 类 型 中 的 整 型 浮 点 型 和 字 符 型 其 余 类 型 在 以 后 各 章 中 陆 续 介 绍 3.2 常 量 与 变 量 对 于 基 本 数 据 类 型 量, 按 其 取 值 是 否 可 改 变 又 分 为 常 量 和 变 量 两 种 在 程 序 执 行 过 程 中, 其 值 不 发 生 改 变 的 量 称 为 常 量, 其 值 可 变 的 量 称 为 变 量 它 们 可 与 数 据 类 型 结 合 起 来 分 类 例 如, 可 分 为 整 型 常 量 整 型 变 量 浮 点 常 量 浮 点 变 量 字 符 常 量 字 符 变 量 枚 举 常 量 枚 举 变 量 在 程 序 中, 常 量 是 可 以 不 经 说 明 而 直 接 引 用 的, 而 变 量 则 必 须 先 定 义 后 使 用 整 型 量 包 括 整 型 常 量 整 型 变 量 常 量 和 符 号 常 量 在 程 序 执 行 过 程 中, 其 值 不 发 生 改 变 的 量 称 为 常 量 直 接 常 量 ( 字 面 常 量 ): 整 型 常 量 :12 0-3; 实 型 常 量 : ; 字 符 常 量 : a b 标 识 符 : 用 来 标 识 变 量 名 符 号 常 量 名 函 数 名 数 组 名 类 型 名 文 件 名 的 有 效 字 符 序 列 符 号 常 量 : 用 标 示 符 代 表 一 个 常 量 在 C 语 言 中, 可 以 用 一 个 标 识 符 来 表 示 一 个 常 量, 称 之 为 符 号 常 量 符 号 常 量 在 使 用 之 前 必 须 先 定 义, 其 一 般 形 式 为 : #define 标 识 符 常 量 其 中 #define 也 是 一 条 预 处 理 命 令 ( 预 处 理 命 令 都 以 "#" 开 头 ), 称 为 宏 定 义 命 令 ( 在 后 面 预 处 理 程 序 中 将 进 一 步 介 绍 ), 其 功 能 是 把 该 标 识 符 定 义 为 其 后 的 常 量 值 一 经 定 义, 以 后 在 程 序 中 所 有 出 现 该 标 识 符 的 地 方 均 代 之 以 该 常 量 值 习 惯 上 符 号 常 量 的 标 识 符 用 大 写 字 母, 变 量 标 识 符 用 小 写 字 母, 以 示 区 别 例 3.1 符 号 常 量 的 使 用 #define PRICE 30 main() int num,total; num=10; total=num* PRICE; printf( total=%d,total); 第 37 页

38 用 标 识 符 代 表 一 个 常 量, 称 为 符 号 常 量 符 号 常 量 与 变 量 不 同, 它 的 值 在 其 作 用 域 内 不 能 改 变, 也 不 能 再 被 赋 值 使 用 符 号 常 量 的 好 处 是 : 含 义 清 楚 ; 能 做 到 一 改 全 改 变 量 其 值 可 以 改 变 的 量 称 为 变 量 一 个 变 量 应 该 有 一 个 名 字, 在 内 存 中 占 据 一 定 的 存 储 单 元 变 量 定 义 必 须 放 在 变 量 使 用 之 前 一 般 放 在 函 数 体 的 开 头 部 分 要 区 分 变 量 名 和 变 量 值 是 两 个 不 同 的 概 念 a 3 变 量 名 变 量 值 存 储 单 元 3.3 整 型 数 据 整 型 常 量 的 表 示 方 法 整 型 常 量 就 是 整 常 数 在 C 语 言 中, 使 用 的 整 常 数 有 八 进 制 十 六 进 制 和 十 进 制 三 种 1) 十 进 制 整 常 数 : 十 进 制 整 常 数 没 有 前 缀 其 数 码 为 0~9 以 下 各 数 是 合 法 的 十 进 制 整 常 数 : ; 以 下 各 数 不 是 合 法 的 十 进 制 整 常 数 : 023 ( 不 能 有 前 导 0) 23D ( 含 有 非 十 进 制 数 码 ) 在 程 序 中 是 根 据 前 缀 来 区 分 各 种 进 制 数 的 因 此 在 书 写 常 数 时 不 要 把 前 缀 弄 错 造 成 结 果 不 正 确 2) 八 进 制 整 常 数 : 八 进 制 整 常 数 必 须 以 0 开 头, 即 以 0 作 为 八 进 制 数 的 前 缀 数 码 取 值 为 0~7 八 进 制 数 通 常 是 无 符 号 数 以 下 各 数 是 合 法 的 八 进 制 数 : 015( 十 进 制 为 13) 0101( 十 进 制 为 65) ( 十 进 制 为 65535); 以 下 各 数 不 是 合 法 的 八 进 制 数 : 256( 无 前 缀 0) 03A2( 包 含 了 非 八 进 制 数 码 ) -0127( 出 现 了 负 号 ) 3) 十 六 进 制 整 常 数 : 十 六 进 制 整 常 数 的 前 缀 为 0X 或 0x 其 数 码 取 值 为 0~9,A~F 或 a~f 以 下 各 数 是 合 法 的 十 六 进 制 整 常 数 : 0X2A( 十 进 制 为 42) 0XA0 ( 十 进 制 为 160) 0XFFFF ( 十 进 制 为 65535); 以 下 各 数 不 是 合 法 的 十 六 进 制 整 常 数 : 5A ( 无 前 缀 0X) 0X3H ( 含 有 非 十 六 进 制 数 码 ) 第 38 页

39 4) 整 型 常 数 的 后 缀 : 在 16 位 字 长 的 机 器 上, 基 本 整 型 的 长 度 也 为 16 位, 因 此 表 示 的 数 的 范 围 也 是 有 限 定 的 十 进 制 无 符 号 整 常 数 的 范 围 为 0~65535, 有 符 号 数 为 ~ 八 进 制 无 符 号 数 的 表 示 范 围 为 0~ 十 六 进 制 无 符 号 数 的 表 示 范 围 为 0X0~0XFFFF 或 0x0~0xFFFF 如 果 使 用 的 数 超 过 了 上 述 范 围, 就 必 须 用 长 整 型 数 来 表 示 长 整 型 数 是 用 后 缀 L 或 l 来 表 示 的 例 如 : 十 进 制 长 整 常 数 : 158L ( 十 进 制 为 158) L ( 十 进 制 为 ); 八 进 制 长 整 常 数 : 012L ( 十 进 制 为 10) 077L ( 十 进 制 为 63) L ( 十 进 制 为 65536); 十 六 进 制 长 整 常 数 : 0X15L ( 十 进 制 为 21) 0XA5L ( 十 进 制 为 165) 0X10000L ( 十 进 制 为 65536) 长 整 数 158L 和 基 本 整 常 数 158 在 数 值 上 并 无 区 别 但 对 158L, 因 为 是 长 整 型 量,C 编 译 系 统 将 为 它 分 配 4 个 字 节 存 储 空 间 而 对 158, 因 为 是 基 本 整 型, 只 分 配 2 个 字 节 的 存 储 空 间 因 此 在 运 算 和 输 出 格 式 上 要 予 以 注 意, 避 免 出 错 无 符 号 数 也 可 用 后 缀 表 示, 整 型 常 数 的 无 符 号 数 的 后 缀 为 U 或 u 例 如 : 358u,0x38Au,235Lu 均 为 无 符 号 数 前 缀, 后 缀 可 同 时 使 用 以 表 示 各 种 类 型 的 数 如 0XA5Lu 表 示 十 六 进 制 无 符 号 长 整 数 A5, 其 十 进 制 为 整 型 变 量 1. 整 型 数 据 在 内 存 中 的 存 放 形 式 如 果 定 义 了 一 个 整 型 变 量 i: int i; i=10; i 数 值 是 以 补 码 表 示 的 : 正 数 的 补 码 和 原 码 相 同 ; 负 数 的 补 码 : 将 该 数 的 绝 对 值 的 二 进 制 形 式 按 位 取 反 再 加 1 例 如 : 求 -10 的 补 码 : 10 的 原 码 : 取 反 : 再 加 1, 得 -10 的 补 码 : 第 39 页

40 由 此 可 知, 左 面 的 第 一 位 是 表 示 符 号 的 2. 整 型 变 量 的 分 类 1) 基 本 型 : 类 型 说 明 符 为 int, 在 内 存 中 占 2 个 字 节 2) 短 整 量 : 类 型 说 明 符 为 short int 或 short 所 占 字 节 和 取 值 范 围 均 与 基 本 型 相 同 3) 长 整 型 : 类 型 说 明 符 为 long int 或 long, 在 内 存 中 占 4 个 字 节 4) 无 符 号 型 : 类 型 说 明 符 为 unsigned 无 符 号 型 又 可 与 上 述 三 种 类 型 匹 配 而 构 成 : 无 符 号 基 本 型 : 类 型 说 明 符 为 unsigned int 或 unsigned 无 符 号 短 整 型 : 类 型 说 明 符 为 unsigned short 无 符 号 长 整 型 : 类 型 说 明 符 为 unsigned long 各 种 无 符 号 类 型 量 所 占 的 内 存 空 间 字 节 数 与 相 应 的 有 符 号 类 型 量 相 同 但 由 于 省 去 了 符 号 位, 故 不 能 表 示 负 数 有 符 号 整 型 变 量 : 最 大 表 示 无 符 号 整 型 变 量 : 最 大 表 示 下 表 列 出 了 Turbo C 中 各 类 整 型 量 所 分 配 的 内 存 字 节 数 及 数 的 表 示 范 围 类 型 说 明 符 数 的 范 围 字 节 数 int ~32767 即 ~(2 15-1) 2 unsigned int 0~65535 即 0~(2 16-1) 2 short int ~32767 即 ~(2 15-1) 2 unsigned short int 0~65535 即 0~(2 16-1) 2 long int ~ 即 ~(2 31-1) 4 unsigned long 0~ 即 0~(2 32-1) 4 以 13 为 例 : int 型 : short int 型 : long int 型 : unsigned int 型 : unsigned short int 型 : unsigned long int 型 : 整 型 变 量 的 定 义 变 量 定 义 的 一 般 形 式 为 : 第 40 页

41 类 型 说 明 符 变 量 名 标 识 符, 变 量 名 标 识 符,...; 例 如 : int a,b,c; (a,b,c 为 整 型 变 量 ) long x,y; (x,y 为 长 整 型 变 量 ) unsigned p,q; (p,q 为 无 符 号 整 型 变 量 ) 在 书 写 变 量 定 义 时, 应 注 意 以 下 几 点 : 允 许 在 一 个 类 型 说 明 符 后, 定 义 多 个 相 同 类 型 的 变 量 各 变 量 名 之 间 用 逗 号 间 隔 类 型 说 明 符 与 变 量 名 之 间 至 少 用 一 个 空 格 间 隔 最 后 一 个 变 量 名 之 后 必 须 以 ; 号 结 尾 变 量 定 义 必 须 放 在 变 量 使 用 之 前 一 般 放 在 函 数 体 的 开 头 部 分 例 3.2 整 型 变 量 的 定 义 与 使 用 main() int a,b,c,d; unsigned u; a=12;b=-24;u=10; c=a+u;d=b+u; printf( a+u=%d,b+u=%d\n,c,d); 4. 整 型 数 据 的 溢 出 例 3.3 整 型 数 据 的 溢 出 main() int a,b; a=32767; b=a+1; printf("%d,%d\n",a,b); 例 3.4 main() long x,y; int a,b,c,d; x=5; y=6; a=7; b=8; 32767: 第 41 页

42 c=x+a; d=y+b; printf("c=x+a=%d,d=y+b=%d\n",c,d); 从 程 序 中 可 以 看 到 :x, y 是 长 整 型 变 量,a, b 是 基 本 整 型 变 量 它 们 之 间 允 许 进 行 运 算, 运 算 结 果 为 长 整 型 但 c,d 被 定 义 为 基 本 整 型, 因 此 最 后 结 果 为 基 本 整 型 本 例 说 明, 不 同 类 型 的 量 可 以 参 与 运 算 并 相 互 赋 值 其 中 的 类 型 转 换 是 由 编 译 系 统 自 动 完 成 的 有 关 类 型 转 换 的 规 则 将 在 以 后 介 绍 3.4 实 型 数 据 实 型 常 量 的 表 示 方 法 实 型 也 称 为 浮 点 型 实 型 常 量 也 称 为 实 数 或 者 浮 点 数 在 C 语 言 中, 实 数 只 采 用 十 进 制 它 有 二 种 形 式 : 十 进 制 小 数 形 式, 指 数 形 式 1) 十 进 制 数 形 式 : 由 数 码 0~ 9 和 小 数 点 组 成 例 如 : 等 均 为 合 法 的 实 数 注 意, 必 须 有 小 数 点 2) 指 数 形 式 : 由 十 进 制 数, 加 阶 码 标 志 e 或 E 以 及 阶 码 ( 只 能 为 整 数, 可 以 带 符 号 ) 组 成 其 一 般 形 式 为 : a E n(a 为 十 进 制 数,n 为 十 进 制 整 数 ) 其 值 为 a*10 n 如 : 2.1E5 ( 等 于 2.1*10 5 ) 3.7E-2 ( 等 于 3.7*10-2 ) 0.5E7 ( 等 于 0.5*10 7 ) -2.8E-2 ( 等 于 -2.8*10-2 ) 以 下 不 是 合 法 的 实 数 : 345 ( 无 小 数 点 ) E7 ( 阶 码 标 志 E 之 前 无 数 字 ) -5 ( 无 阶 码 标 志 ) 53.-E3 ( 负 号 位 置 不 对 ) 2.7E ( 无 阶 码 ) 标 准 C 允 许 浮 点 数 使 用 后 缀 后 缀 为 f 或 F 即 表 示 该 数 为 浮 点 数 如 356f 和 356. 是 等 价 的 例 3.5 说 明 了 这 种 情 况 main() printf("%f\n ",356.); printf("%f\n ",356); printf("%f\n ",356f); 第 42 页

43 3.4.2 实 型 变 量 1. 实 型 数 据 在 内 存 中 的 存 放 形 式 实 型 数 据 一 般 占 4 个 字 节 (32 位 ) 内 存 空 间 按 指 数 形 式 存 储 实 数 在 内 存 中 的 存 放 形 式 如 下 : 数 符 小 数 部 分 指 数 小 数 部 分 占 的 位 (bit) 数 愈 多, 数 的 有 效 数 字 愈 多, 精 度 愈 高 指 数 部 分 占 的 位 数 愈 多, 则 能 表 示 的 数 值 范 围 愈 大 2. 实 型 变 量 的 分 类 实 型 变 量 分 为 : 单 精 度 (float 型 ) 双 精 度 (double 型 ) 和 长 双 精 度 (long double 型 ) 三 类 在 Turbo C 中 单 精 度 型 占 4 个 字 节 (32 位 ) 内 存 空 间, 其 数 值 范 围 为 3.4E-38~3.4E+38, 只 能 提 供 七 位 有 效 数 字 双 精 度 型 占 8 个 字 节 (64 位 ) 内 存 空 间, 其 数 值 范 围 为 1.7E-308~1.7E+308, 可 提 供 16 位 有 效 数 字 类 型 说 明 符 比 特 数 ( 字 节 数 ) 有 效 数 字 数 的 范 围 float 32(4) 6~ ~10 38 double 64(8) 15~ ~ long double 128(16) 18~ ~ 实 型 变 量 定 义 的 格 式 和 书 写 规 则 与 整 型 相 同 例 如 : float x,y; (x,y 为 单 精 度 实 型 量 ) double a,b,c; (a,b,c 为 双 精 度 实 型 量 ) 3. 实 型 数 据 的 舍 入 误 差 由 于 实 型 变 量 是 由 有 限 的 存 储 单 元 组 成 的, 因 此 能 提 供 的 有 效 数 字 总 是 有 限 的 如 下 例 例 3.6 实 型 数 据 的 舍 入 误 差 main() float a,b; a= e5; b=a+20 printf("%f\n",a); printf("%f\n",b); 注 意 :1.0/3*3 的 结 果 并 不 等 于 1 例 3.7 main() float a; double b; a= ; 第 43 页

44 b= ; printf("%f\n%f\n",a,b); 从 本 例 可 以 看 出, 由 于 a 是 单 精 度 浮 点 型, 有 效 位 数 只 有 七 位 而 整 数 已 占 五 位, 故 小 数 二 位 后 之 后 均 为 无 效 数 字 b 是 双 精 度 型, 有 效 位 为 十 六 位 但 Turbo C 规 定 小 数 后 最 多 保 留 六 位, 其 余 部 分 四 舍 五 入 实 型 常 数 的 类 型 实 型 常 数 不 分 单 双 精 度, 都 按 双 精 度 double 型 处 理 3.5 字 符 型 数 据 字 符 型 数 据 包 括 字 符 常 量 和 字 符 变 量 字 符 常 量 字 符 常 量 是 用 单 引 号 括 起 来 的 一 个 字 符 例 如 : 'a' 'b' '=' '+' '?' 都 是 合 法 字 符 常 量 在 C 语 言 中, 字 符 常 量 有 以 下 特 点 : 1) 字 符 常 量 只 能 用 单 引 号 括 起 来, 不 能 用 双 引 号 或 其 它 括 号 2) 字 符 常 量 只 能 是 单 个 字 符, 不 能 是 字 符 串 3) 字 符 可 以 是 字 符 集 中 任 意 字 符 但 数 字 被 定 义 为 字 符 型 之 后 就 不 能 参 与 数 值 运 算 如 '5' 和 5 是 不 同 的 '5' 是 字 符 常 量, 不 能 参 与 运 算 转 义 字 符 转 义 字 符 是 一 种 特 殊 的 字 符 常 量 转 义 字 符 以 反 斜 线 "\" 开 头, 后 跟 一 个 或 几 个 字 符 转 义 字 符 具 有 特 定 的 含 义, 不 同 于 字 符 原 有 的 意 义, 故 称 转 义 字 符 例 如, 在 前 面 各 例 题 printf 函 数 的 格 式 串 中 用 到 的 \n 就 是 一 个 转 义 字 符, 其 意 义 是 回 车 换 行 转 义 字 符 主 要 用 来 表 示 那 些 用 一 般 字 符 不 便 于 表 示 的 控 制 代 码 常 用 的 转 义 字 符 及 其 含 义 转 义 字 符 转 义 字 符 的 意 义 ASCII 代 码 \n 回 车 换 行 10 \t 横 向 跳 到 下 一 制 表 位 置 9 \b 退 格 8 \r 回 车 13 \f 走 纸 换 页 12 第 44 页

45 \\ 反 斜 线 符 "\" 92 \' 单 引 号 符 39 \ 双 引 号 符 34 \a 鸣 铃 7 \ddd 1~3 位 八 进 制 数 所 代 表 的 字 符 \xhh 1~2 位 十 六 进 制 数 所 代 表 的 字 符 广 义 地 讲,C 语 言 字 符 集 中 的 任 何 一 个 字 符 均 可 用 转 义 字 符 来 表 示 表 中 的 \ddd 和 \xhh 正 是 为 此 而 提 出 的 ddd 和 hh 分 别 为 八 进 制 和 十 六 进 制 的 ASCII 代 码 如 \101 表 示 字 母 "A",\102 表 示 字 母 "B",\134 表 示 反 斜 线,\XOA 表 示 换 行 等 例 3.8 转 义 字 符 的 使 用 main() int a,b,c; a=5; b=6; c=7; printf( ab c\tde\rf\n ); printf( hijk\tl\bm\n ); 字 符 变 量 字 符 变 量 用 来 存 储 字 符 常 量, 即 单 个 字 符 字 符 变 量 的 类 型 说 明 符 是 char 字 符 变 量 类 型 定 义 的 格 式 和 书 写 规 则 都 与 整 型 变 量 相 同 例 如 : char a,b; 字 符 数 据 在 内 存 中 的 存 储 形 式 及 使 用 方 法 每 个 字 符 变 量 被 分 配 一 个 字 节 的 内 存 空 间, 因 此 只 能 存 放 一 个 字 符 字 符 值 是 以 ASCII 码 的 形 式 存 放 在 变 量 的 内 存 单 元 之 中 的 如 x 的 十 进 制 ASCII 码 是 120,y 的 十 进 制 ASCII 码 是 121 对 字 符 变 量 a,b 赋 予 'x' 和 'y' 值 : a='x'; b='y'; 实 际 上 是 在 a,b 两 个 单 元 内 存 放 120 和 121 的 二 进 制 代 码 : a: b: 所 以 也 可 以 把 它 们 看 成 是 整 型 量 C 语 言 允 许 对 整 型 变 量 赋 以 字 符 值, 也 允 许 对 字 符 变 量 赋 以 整 型 值 在 输 出 时, 允 许 把 字 符 变 量 按 整 型 量 输 出, 也 允 许 把 整 型 量 按 字 符 量 输 出 整 型 量 为 二 字 节 量, 字 符 量 为 单 字 节 量, 当 整 型 量 按 字 符 型 量 处 理 时, 只 有 低 八 位 字 节 参 与 处 理 例 3.9 向 字 符 变 量 赋 以 整 数 第 45 页

46 main() char a,b; a=120; b=121; printf("%c,%c\n",a,b); printf("%d,%d\n",a,b); 本 程 序 中 定 义 a,b 为 字 符 型, 但 在 赋 值 语 句 中 赋 以 整 型 值 从 结 果 看,a,b 值 的 输 出 形 式 取 决 于 printf 函 数 格 式 串 中 的 格 式 符, 当 格 式 符 为 "c" 时, 对 应 输 出 的 变 量 值 为 字 符, 当 格 式 符 为 "d" 时, 对 应 输 出 的 变 量 值 为 整 数 例 3.10 main() char a,b; a='a'; b='b'; a=a-32; b=b-32; printf("%c,%c\n%d,%d\n",a,b,a,b); 本 例 中,a,b 被 说 明 为 字 符 变 量 并 赋 予 字 符 值,C 语 言 允 许 字 符 变 量 参 与 数 值 运 算, 即 用 字 符 的 ASCII 码 参 与 运 算 由 于 大 小 写 字 母 的 ASCII 码 相 差 32, 因 此 运 算 后 把 小 写 字 母 换 成 大 写 字 母 然 后 分 别 以 整 型 和 字 符 型 输 出 字 符 串 常 量 字 符 串 常 量 是 由 一 对 双 引 号 括 起 的 字 符 序 列 例 如 : "CHINA", C program, "$12.5" 等 都 是 合 法 的 字 符 串 常 量 字 符 串 常 量 和 字 符 常 量 是 不 同 的 量 它 们 之 间 主 要 有 以 下 区 别 : 1) 字 符 常 量 由 单 引 号 括 起 来, 字 符 串 常 量 由 双 引 号 括 起 来 2) 字 符 常 量 只 能 是 单 个 字 符, 字 符 串 常 量 则 可 以 含 一 个 或 多 个 字 符 3) 可 以 把 一 个 字 符 常 量 赋 予 一 个 字 符 变 量, 但 不 能 把 一 个 字 符 串 常 量 赋 予 一 个 字 符 变 量 在 C 语 言 中 没 有 相 应 的 字 符 串 变 量 这 是 与 BASIC 语 言 不 同 的 但 是 可 以 用 一 个 字 符 数 组 来 存 放 一 个 字 符 串 常 量 在 数 组 一 章 内 予 以 介 绍 4) 字 符 常 量 占 一 个 字 节 的 内 存 空 间 字 符 串 常 量 占 的 内 存 字 节 数 等 于 字 符 串 中 字 节 数 加 1 增 加 的 一 个 字 节 中 存 放 字 符 "\0" (ASCII 码 为 0) 这 是 字 符 串 结 束 的 标 志 例 如 : 字 符 串 "C program" 在 内 存 中 所 占 的 字 节 为 : C p r o g r a m \0 第 46 页

47 字 符 常 量 'a' 和 字 符 串 常 量 "a" 虽 然 都 只 有 一 个 字 符, 但 在 内 存 中 的 情 况 是 不 同 的 'a' 在 内 存 中 占 一 个 字 节, 可 表 示 为 : a "a" 在 内 存 中 占 二 个 字 节, 可 表 示 为 : a \0 3.6 变 量 赋 初 值 在 程 序 中 常 常 需 要 对 变 量 赋 初 值, 以 便 使 用 变 量 语 言 程 序 中 可 有 多 种 方 法 为 变 量 提 供 初 值 本 小 节 先 介 绍 在 作 变 量 定 义 的 同 时 给 变 量 赋 以 初 值 的 方 法 这 种 方 法 称 为 初 始 化 在 变 量 定 义 中 赋 初 值 的 一 般 形 式 为 : 类 型 说 明 符 变 量 1= 值 1, 变 量 2= 值 2, ; 例 如 : int a=3; int b,c=5; float x=3.2,y=3f,z=0.75; char ch1='k',ch2='p'; 应 注 意, 在 定 义 中 不 允 许 连 续 赋 值, 如 a=b=c=5 是 不 合 法 的 例 3.11 main() int a=3,b,c=5; b=a+c; printf("a=%d,b=%d,c=%d\n",a,b,c); 3.7 各 类 数 值 型 数 据 之 间 的 混 合 运 算 变 量 的 数 据 类 型 是 可 以 转 换 的 转 换 的 方 法 有 两 种, 一 种 是 自 动 转 换, 一 种 是 强 制 转 换 自 动 转 换 发 生 在 不 同 数 据 类 型 的 量 混 合 运 算 时, 由 编 译 系 统 自 动 完 成 自 动 转 换 遵 循 以 下 规 则 : 1) 若 参 与 运 算 量 的 类 型 不 同, 则 先 转 换 成 同 一 类 型, 然 后 进 行 运 算 2) 转 换 按 数 据 长 度 增 加 的 方 向 进 行, 以 保 证 精 度 不 降 低 如 int 型 和 long 型 运 算 时, 先 把 int 量 转 成 long 型 后 再 进 行 运 算 3) 所 有 的 浮 点 运 算 都 是 以 双 精 度 进 行 的, 即 使 仅 含 float 单 精 度 量 运 算 的 表 达 式, 也 要 先 转 换 成 double 型, 再 作 运 算 4) char 型 和 short 型 参 与 运 算 时, 必 须 先 转 换 成 int 型 5) 在 赋 值 运 算 中, 赋 值 号 两 边 量 的 数 据 类 型 不 同 时, 赋 值 号 右 边 量 的 类 型 将 转 换 为 左 边 量 的 类 型 如 果 右 边 量 的 数 据 类 型 长 度 左 边 长 时, 将 丢 失 一 部 分 数 据, 这 样 会 降 低 精 度, 丢 失 的 部 分 按 四 舍 五 入 向 前 舍 入 下 图 表 示 了 类 型 自 动 转 换 的 规 则 第 47 页

48 double long unsigned int char,short 例 3.12 main() float PI= ; int s,r=5; s=r*r*pi; printf("s=%d\n",s); 本 例 程 序 中,PI 为 实 型 ;s,r 为 整 型 在 执 行 s=r*r*pi 语 句 时,r 和 PI 都 转 换 成 double 型 计 算, 结 果 也 为 double 型 但 由 于 s 为 整 型, 故 赋 值 结 果 仍 为 整 型, 舍 去 了 小 数 部 分 强 制 类 型 转 换 强 制 类 型 转 换 是 通 过 类 型 转 换 运 算 来 实 现 的 其 一 般 形 式 为 : ( 类 型 说 明 符 ) ( 表 达 式 ) 其 功 能 是 把 表 达 式 的 运 算 结 果 强 制 转 换 成 类 型 说 明 符 所 表 示 的 类 型 例 如 : (float) a 把 a 转 换 为 实 型 (int)(x+y) 把 x+y 的 结 果 转 换 为 整 型 在 使 用 强 制 转 换 时 应 注 意 以 下 问 题 : 1) 类 型 说 明 符 和 表 达 式 都 必 须 加 括 号 ( 单 个 变 量 可 以 不 加 括 号 ), 如 把 (int)(x+y) 写 成 (int)x+y 则 成 了 把 x 转 换 成 int 型 之 后 再 与 y 相 加 了 2) 无 论 是 强 制 转 换 或 是 自 动 转 换, 都 只 是 为 了 本 次 运 算 的 需 要 而 对 变 量 的 数 据 长 度 进 行 的 临 时 性 转 换, 而 不 改 变 数 据 说 明 时 对 该 变 量 定 义 的 类 型 例 3.13 main() float f=5.75; printf("(int)f=%d,f=%f\n",(int)f,f); 第 48 页

49 本 例 表 明,f 虽 强 制 转 为 int 型, 但 只 在 运 算 中 起 作 用, 是 临 时 的, 而 f 本 身 的 类 型 并 不 改 变 因 此,(int)f 的 值 为 5( 删 去 了 小 数 ) 而 f 的 值 仍 为 算 术 运 算 符 和 算 术 表 达 式 C 语 言 中 运 算 符 和 表 达 式 数 量 之 多, 在 高 级 语 言 中 是 少 见 的 正 是 丰 富 的 运 算 符 和 表 达 式 使 C 语 言 功 能 十 分 完 善 这 也 是 C 语 言 的 主 要 特 点 之 一 C 语 言 的 运 算 符 不 仅 具 有 不 同 的 优 先 级, 而 且 还 有 一 个 特 点, 就 是 它 的 结 合 性 在 表 达 式 中, 各 运 算 量 参 与 运 算 的 先 后 顺 序 不 仅 要 遵 守 运 算 符 优 先 级 别 的 规 定, 还 要 受 运 算 符 结 合 性 的 制 约, 以 便 确 定 是 自 左 向 右 进 行 运 算 还 是 自 右 向 左 进 行 运 算 这 种 结 合 性 是 其 它 高 级 语 言 的 运 算 符 所 没 有 的, 因 此 也 增 加 了 C 语 言 的 复 杂 性 C 运 算 符 简 介 C 语 言 的 运 算 符 可 分 为 以 下 几 类 : 1. 算 术 运 算 符 : 用 于 各 类 数 值 运 算 包 括 加 (+) 减 (-) 乘 (*) 除 (/) 求 余 ( 或 称 模 运 算,%) 自 增 (++) 自 减 (--) 共 七 种 2. 关 系 运 算 符 : 用 于 比 较 运 算 包 括 大 于 (>) 小 于 (<) 等 于 (==) 大 于 等 于 (>=) 小 于 等 于 (<=) 和 不 等 于 (!=) 六 种 3. 逻 辑 运 算 符 : 用 于 逻 辑 运 算 包 括 与 (&&) 或 ( ) 非 (!) 三 种 4. 位 操 作 运 算 符 : 参 与 运 算 的 量, 按 二 进 制 位 进 行 运 算 包 括 位 与 (&) 位 或 ( ) 位 非 (~) 位 异 或 (^) 左 移 (<<) 右 移 (>>) 六 种 5. 赋 值 运 算 符 : 用 于 赋 值 运 算, 分 为 简 单 赋 值 (=) 复 合 算 术 赋 值 (+=,-=,*=,/=,%=) 和 复 合 位 运 算 赋 值 (&=, =,^=,>>=,<<=) 三 类 共 十 一 种 6. 条 件 运 算 符 : 这 是 一 个 三 目 运 算 符, 用 于 条 件 求 值 (?:) 7. 逗 号 运 算 符 : 用 于 把 若 干 表 达 式 组 合 成 一 个 表 达 式 (,) 8. 指 针 运 算 符 : 用 于 取 内 容 (*) 和 取 地 址 (&) 二 种 运 算 9. 求 字 节 数 运 算 符 : 用 于 计 算 数 据 类 型 所 占 的 字 节 数 (sizeof) 10. 特 殊 运 算 符 : 有 括 号 (), 下 标 [], 成 员 (,.) 等 几 种 算 术 运 算 符 和 算 术 表 达 式 1. 基 本 的 算 术 运 算 符 加 法 运 算 符 + : 加 法 运 算 符 为 双 目 运 算 符, 即 应 有 两 个 量 参 与 加 法 运 算 如 a+b,4+8 等 具 有 右 结 合 性 减 法 运 算 符 - : 减 法 运 算 符 为 双 目 运 算 符 但 - 也 可 作 负 值 运 算 符, 此 时 为 单 目 运 算, 如 -x,-5 等 具 有 左 结 合 性 乘 法 运 算 符 * : 双 目 运 算, 具 有 左 结 合 性 除 法 运 算 符 / : 双 目 运 算 具 有 左 结 合 性 参 与 运 算 量 均 为 整 型 时, 结 果 也 为 整 型, 舍 去 小 数 如 果 运 算 量 中 有 一 个 是 实 型, 则 结 果 为 双 精 度 实 型 第 49 页

50 例 3.14 main() printf("\n\n%d,%d\n",20/7,-20/7); printf("%f,%f\n",20.0/7,-20.0/7); 本 例 中,20/7,-20/7 的 结 果 均 为 整 型, 小 数 全 部 舍 去 而 20.0/7 和 -20.0/7 由 于 有 实 数 参 与 运 算, 因 此 结 果 也 为 实 型 求 余 运 算 符 ( 模 运 算 符 ) % : 双 目 运 算, 具 有 左 结 合 性 要 求 参 与 运 算 的 量 均 为 整 型 求 余 运 算 的 结 果 等 于 两 数 相 除 后 的 余 数 例 3.15 main() printf("%d\n",100%3); 本 例 输 出 100 除 以 3 所 得 的 余 数 1 2. 算 术 表 达 式 和 运 算 符 的 优 先 级 和 结 合 性 表 达 式 是 由 常 量 变 量 函 数 和 运 算 符 组 合 起 来 的 式 子 一 个 表 达 式 有 一 个 值 及 其 类 型, 它 们 等 于 计 算 表 达 式 所 得 结 果 的 值 和 类 型 表 达 式 求 值 按 运 算 符 的 优 先 级 和 结 合 性 规 定 的 顺 序 进 行 单 个 的 常 量 变 量 函 数 可 以 看 作 是 表 达 式 的 特 例 算 术 表 达 式 是 由 算 术 运 算 符 和 括 号 连 接 起 来 的 式 子 算 术 表 达 式 : 用 算 术 运 算 符 和 括 号 将 运 算 对 象 ( 也 称 操 作 数 ) 连 接 起 来 的 符 合 C 语 法 规 则 的 式 子 以 下 是 算 术 表 达 式 的 例 子 : a+b (a*2)/c (x+r)*8-(a+b)/7 ++I sin(x)+sin(y) (++i)-(j++)+(k--) 运 算 符 的 优 先 级 :C 语 言 中, 运 算 符 的 运 算 优 先 级 共 分 为 15 级 1 级 最 高,15 级 最 低 在 表 达 式 中, 优 先 级 较 高 的 先 于 优 先 级 较 低 的 进 行 运 算 而 在 一 个 运 算 量 两 侧 的 运 算 符 优 先 级 相 同 时, 则 按 运 算 符 的 结 合 性 所 规 定 的 结 合 方 向 处 理 运 算 符 的 结 合 性 :C 语 言 中 各 运 算 符 的 结 合 性 分 为 两 种, 即 左 结 合 性 ( 自 左 至 右 ) 和 右 结 合 性 ( 自 右 至 左 ) 例 如 算 术 运 算 符 的 结 合 性 是 自 左 至 右, 即 先 左 后 右 如 有 表 达 式 x-y+z 则 y 应 先 与 - 号 结 合, 执 行 x-y 运 算, 然 后 再 执 行 +z 的 运 算 这 种 自 左 至 右 的 结 合 方 向 就 称 为 左 结 合 性 而 自 右 至 左 的 结 合 方 向 称 为 右 结 合 性 最 典 型 的 右 结 合 性 运 算 符 是 赋 值 运 算 符 如 x=y=z, 由 于 = 的 右 结 合 性, 应 先 执 行 y=z 再 执 行 x=(y=z) 运 算 C 语 言 运 算 符 中 有 不 少 为 右 结 合 性, 应 注 意 区 别, 以 避 免 理 解 错 误 3. 强 制 类 型 转 换 运 算 符 其 一 般 形 式 为 : ( 类 型 说 明 符 ) ( 表 达 式 ) 其 功 能 是 把 表 达 式 的 运 算 结 果 强 制 转 换 成 类 型 说 明 符 所 表 示 的 类 型 例 如 : 第 50 页

51 (float) a 把 a 转 换 为 实 型 (int)(x+y) 把 x+y 的 结 果 转 换 为 整 型 4. 自 增 自 减 运 算 符 自 增 1, 自 减 1 运 算 符 : 自 增 1 运 算 符 记 为 ++, 其 功 能 是 使 变 量 的 值 自 增 1 自 减 1 运 算 符 记 为 --, 其 功 能 是 使 变 量 值 自 减 1 自 增 1, 自 减 1 运 算 符 均 为 单 目 运 算, 都 具 有 右 结 合 性 可 有 以 下 几 种 形 式 : ++i i 自 增 1 后 再 参 与 其 它 运 算 --i i 自 减 1 后 再 参 与 其 它 运 算 i++ i 参 与 运 算 后,i 的 值 再 自 增 1 i-- i 参 与 运 算 后,i 的 值 再 自 减 1 在 理 解 和 使 用 上 容 易 出 错 的 是 i++ 和 i-- 特 别 是 当 它 们 出 在 较 复 杂 的 表 达 式 或 语 句 中 时, 常 常 难 于 弄 清, 因 此 应 仔 细 分 析 例 3.16 main() int i=8; printf("%d\n",++i); printf("%d\n",--i); printf("%d\n",i++); printf("%d\n",i--); printf("%d\n",-i++); printf("%d\n",-i--); i 的 初 值 为 8, 第 2 行 i 加 1 后 输 出 故 为 9; 第 3 行 减 1 后 输 出 故 为 8; 第 4 行 输 出 i 为 8 之 后 再 加 1( 为 9); 第 5 行 输 出 i 为 9 之 后 再 减 1( 为 8) ; 第 6 行 输 出 -8 之 后 再 加 1( 为 9), 第 7 行 输 出 -9 之 后 再 减 1( 为 8) 例 3.17 main() int i=5,j=5,p,q; p=(i++)+(i++)+(i++); q=(++j)+(++j)+(++j); printf("%d,%d,%d,%d",p,q,i,j); 这 个 程 序 中, 对 P=(i++)+(i++)+(i++) 应 理 解 为 三 个 i 相 加, 故 P 值 为 15 然 后 i 再 自 增 1 三 次 相 当 于 加 3 故 i 的 最 后 值 为 8 而 对 于 q 的 值 则 不 然,q=(++j)+(++j)+(++j) 应 理 解 为 q 先 自 增 1, 再 参 与 运 算, 由 于 q 自 增 1 三 次 后 值 为 8, 三 个 8 相 加 的 和 为 24,j 的 最 后 值 仍 为 赋 值 运 算 符 和 赋 值 表 达 式 1. 赋 值 运 算 符 简 单 赋 值 运 算 符 和 表 达 式 : 简 单 赋 值 运 算 符 记 为 = 由 = 连 接 的 式 子 称 为 赋 值 表 达 式 其 一 般 形 式 为 : 第 51 页

52 变 量 = 表 达 式 例 如 : x=a+b w=sin(a)+sin(b) y=i+++--j 赋 值 表 达 式 的 功 能 是 计 算 表 达 式 的 值 再 赋 予 左 边 的 变 量 赋 值 运 算 符 具 有 右 结 合 性 因 此 a=b=c=5 可 理 解 为 a=(b=(c=5)) 在 其 它 高 级 语 言 中, 赋 值 构 成 了 一 个 语 句, 称 为 赋 值 语 句 而 在 C 中, 把 = 定 义 为 运 算 符, 从 而 组 成 赋 值 表 达 式 凡 是 表 达 式 可 以 出 现 的 地 方 均 可 出 现 赋 值 表 达 式 例 如, 式 子 : x=(a=5)+(b=8) 是 合 法 的 它 的 意 义 是 把 5 赋 予 a,8 赋 予 b, 再 把 a,b 相 加, 和 赋 予 x, 故 x 应 等 于 13 在 C 语 言 中 也 可 以 组 成 赋 值 语 句, 按 照 C 语 言 规 定, 任 何 表 达 式 在 其 未 尾 加 上 分 号 就 构 成 为 语 句 因 此 如 x=8;a=b=c=5; 都 是 赋 值 语 句, 在 前 面 各 例 中 我 们 已 大 量 使 用 过 了 2. 类 型 转 换 如 果 赋 值 运 算 符 两 边 的 数 据 类 型 不 相 同, 系 统 将 自 动 进 行 类 型 转 换, 即 把 赋 值 号 右 边 的 类 型 换 成 左 边 的 类 型 具 体 规 定 如 下 : 1) 实 型 赋 予 整 型, 舍 去 小 数 部 分 前 面 的 例 子 已 经 说 明 了 这 种 情 况 2) 整 型 赋 予 实 型, 数 值 不 变, 但 将 以 浮 点 形 式 存 放, 即 增 加 小 数 部 分 ( 小 数 部 分 的 值 为 0) 3) 字 符 型 赋 予 整 型, 由 于 字 符 型 为 一 个 字 节, 而 整 型 为 二 个 字 节, 故 将 字 符 的 ASCII 码 值 放 到 整 型 量 的 低 八 位 中, 高 八 位 为 0 整 型 赋 予 字 符 型, 只 把 低 八 位 赋 予 字 符 量 例 3.18 main() int a,b=322; float x,y=8.88; char c1='k',c2; a=y; x=b; a=c1; c2=b; printf("%d,%f,%d,%c",a,x,a,c2); 本 例 表 明 了 上 述 赋 值 运 算 中 类 型 转 换 的 规 则 a 为 整 型, 赋 予 实 型 量 y 值 8.88 后 只 取 整 数 8 x 为 实 型, 赋 予 整 型 量 b 值 322, 后 增 加 了 小 数 部 分 字 符 型 量 c1 赋 予 a 变 为 整 型, 整 型 量 b 赋 予 c2 后 取 其 低 八 位 成 为 字 符 型 (b 的 低 八 位 为 , 即 十 进 制 66, 按 ASCII 码 对 应 于 字 符 B) 3. 复 合 的 赋 值 运 算 符 在 赋 值 符 = 之 前 加 上 其 它 二 目 运 算 符 可 构 成 复 合 赋 值 符 如 +=,-=,*=,/=,%=,<<=,>>=,&=,^=, = 构 成 复 合 赋 值 表 达 式 的 一 般 形 式 为 : 第 52 页

53 变 量 双 目 运 算 符 = 表 达 式 它 等 效 于 变 量 = 变 量 运 算 符 表 达 式 例 如 : a+=5 等 价 于 a=a+5 x*=y+7 等 价 于 x=x*(y+7) r%=p 等 价 于 r=r%p 复 合 赋 值 符 这 种 写 法, 对 初 学 者 可 能 不 习 惯, 但 十 分 有 利 于 编 译 处 理, 能 提 高 编 译 效 率 并 产 生 质 量 较 高 的 目 标 代 码 3.10 逗 号 运 算 符 和 逗 号 表 达 式 在 C 语 言 中 逗 号, 也 是 一 种 运 算 符, 称 为 逗 号 运 算 符 其 功 能 是 把 两 个 表 达 式 连 接 起 来 组 成 一 个 表 达 式, 称 为 逗 号 表 达 式 其 一 般 形 式 为 : 表 达 式 1, 表 达 式 2 其 求 值 过 程 是 分 别 求 两 个 表 达 式 的 值, 并 以 表 达 式 2 的 值 作 为 整 个 逗 号 表 达 式 的 值 例 3.19 main() int a=2,b=4,c=6,x,y; y=(x=a+b),(b+c); printf("y=%d,x=%d",y,x); 本 例 中,y 等 于 整 个 逗 号 表 达 式 的 值, 也 就 是 表 达 式 2 的 值,x 是 第 一 个 表 达 式 的 值 对 于 逗 号 表 达 式 还 要 说 明 两 点 : 1) 逗 号 表 达 式 一 般 形 式 中 的 表 达 式 1 和 表 达 式 2 也 可 以 又 是 逗 号 表 达 式 例 如 : 表 达 式 1,( 表 达 式 2, 表 达 式 3) 形 成 了 嵌 套 情 形 因 此 可 以 把 逗 号 表 达 式 扩 展 为 以 下 形 式 : 表 达 式 1, 表 达 式 2, 表 达 式 n 整 个 逗 号 表 达 式 的 值 等 于 表 达 式 n 的 值 2) 程 序 中 使 用 逗 号 表 达 式, 通 常 是 要 分 别 求 逗 号 表 达 式 内 各 表 达 式 的 值, 并 不 一 定 要 求 整 个 逗 号 表 达 式 的 值 并 不 是 在 所 有 出 现 逗 号 的 地 方 都 组 成 逗 号 表 达 式, 如 在 变 量 说 明 中, 函 数 参 数 表 中 逗 号 只 是 用 作 各 变 量 之 间 的 间 隔 符 第 53 页

54 3.11 小 结 C 的 数 据 类 型 基 本 类 型, 构 造 类 型, 指 针 类 型, 空 类 型 基 本 类 型 的 分 类 及 特 点 类 型 说 明 符 字 节 数 值 范 围 字 符 型 char 1 C 字 符 集 基 本 整 型 int ~32767 短 整 型 short int ~32767 长 整 型 long int ~ 无 符 号 型 unsigned 2 0~65535 无 符 号 长 整 型 unsigned long 4 0~ 单 精 度 实 型 float 4 3/4E-38~3/4E+38 双 精 度 实 型 double 8 1/7E-308~1/7E 常 量 后 缀 L 或 l U 或 u F 或 f 长 整 型 无 符 号 数 浮 点 数 常 量 类 型 整 数, 长 整 数, 无 符 号 数, 浮 点 数, 字 符, 字 符 串, 符 号 常 数, 转 义 字 符 数 据 类 型 转 换 自 动 转 换 : 在 不 同 类 型 数 据 的 混 合 运 算 中, 由 系 统 自 动 实 现 转 换, 由 少 字 节 类 型 向 多 字 节 类 型 转 换 不 同 类 型 的 量 相 互 赋 值 时 也 由 系 统 自 动 进 行 转 换, 把 赋 值 号 右 边 的 类 型 转 换 为 左 边 的 类 型 强 制 转 换 : 由 强 制 转 换 运 算 符 完 成 转 换 运 算 符 优 先 级 和 结 合 性 一 般 而 言, 单 目 运 算 符 优 先 级 较 高, 赋 值 运 算 符 优 先 级 低 算 术 运 算 符 优 先 级 较 高, 关 系 和 逻 辑 运 算 符 优 先 级 较 低 多 数 运 算 符 具 有 左 结 合 性, 单 目 运 算 符 三 目 运 算 符 赋 值 运 算 符 具 有 右 结 合 性 第 54 页

55 表 达 式 表 达 式 是 由 运 算 符 连 接 常 量 变 量 函 数 所 组 成 的 式 子 每 个 表 达 式 都 有 一 个 值 和 类 型 表 达 式 求 值 按 运 算 符 的 优 先 级 和 结 合 性 所 规 定 的 顺 序 进 行 4 最 简 单 的 C 程 序 设 计 顺 序 程 序 设 计 从 程 序 流 程 的 角 度 来 看, 程 序 可 以 分 为 三 种 基 本 结 构, 即 顺 序 结 构 分 支 结 构 循 环 结 构 这 三 种 基 本 结 构 可 以 组 成 所 有 的 各 种 复 杂 程 序 C 语 言 提 供 了 多 种 语 句 来 实 现 这 些 程 序 结 构 本 章 介 绍 这 些 基 本 语 句 及 其 在 顺 序 结 构 中 的 应 用, 使 读 者 对 C 程 序 有 一 个 初 步 的 认 识, 为 后 面 各 章 的 学 习 打 下 基 础 4.1 C 语 句 概 述 C 程 序 的 结 构 : C 程 序 源 程 序 文 件 1 源 程 序 文 件 2 源 程 序 文 件 n 预 处 理 命 令 全 局 变 量 声 明 函 数 1 函 数 n 函 数 首 部 函 数 体 局 部 变 量 声 明 执 行 语 句 C 程 序 的 执 行 部 分 是 由 语 句 组 成 的 程 序 的 功 能 也 是 由 执 行 语 句 实 现 的 C 语 句 可 分 为 以 下 五 类 : 1) 表 达 式 语 句 2) 函 数 调 用 语 句 3) 控 制 语 句 4) 复 合 语 句 5) 空 语 句 1. 表 达 式 语 句 : 表 达 式 语 句 由 表 达 式 加 上 分 号 ; 组 成 第 55 页

56 其 一 般 形 式 为 : 表 达 式 ; 执 行 表 达 式 语 句 就 是 计 算 表 达 式 的 值 例 如 : x=y+z; 赋 值 语 句 ; y+z; 加 法 运 算 语 句, 但 计 算 结 果 不 能 保 留, 无 实 际 意 义 ; i++; 自 增 1 语 句,i 值 增 1 2. 函 数 调 用 语 句 : 由 函 数 名 实 际 参 数 加 上 分 号 ; 组 成 其 一 般 形 式 为 : 函 数 名 ( 实 际 参 数 表 ); 执 行 函 数 语 句 就 是 调 用 函 数 体 并 把 实 际 参 数 赋 予 函 数 定 义 中 的 形 式 参 数, 然 后 执 行 被 调 函 数 体 中 的 语 句, 求 取 函 数 值 ( 在 后 面 函 数 中 再 详 细 介 绍 ) 例 如 : printf("c Program"); 调 用 库 函 数, 输 出 字 符 串 3. 控 制 语 句 : 控 制 语 句 用 于 控 制 程 序 的 流 程, 以 实 现 程 序 的 各 种 结 构 方 式 它 们 由 特 定 的 语 句 定 义 符 组 成 C 语 言 有 九 种 控 制 语 句 可 分 成 以 下 三 类 : 1) 条 件 判 断 语 句 :if 语 句 switch 语 句 ; 2) 循 环 执 行 语 句 :do while 语 句 while 语 句 for 语 句 ; 3) 转 向 语 句 :break 语 句 goto 语 句 continue 语 句 return 语 句 4. 复 合 语 句 : 把 多 个 语 句 用 括 号 括 起 来 组 成 的 一 个 语 句 称 复 合 语 句 在 程 序 中 应 把 复 合 语 句 看 成 是 单 条 语 句, 而 不 是 多 条 语 句 例 如 : x=y+z; a=b+c; printf( %d%d,x,a); 是 一 条 复 合 语 句 复 合 语 句 内 的 各 条 语 句 都 必 须 以 分 号 ; 结 尾, 在 括 号 外 不 能 加 分 号 5. 空 语 句 : 只 有 分 号 ; 组 成 的 语 句 称 为 空 语 句 空 语 句 是 什 么 也 不 执 行 的 语 句 在 程 序 中 空 语 句 可 用 来 作 空 循 环 体 例 如 while(getchar()!='\n') ; 本 语 句 的 功 能 是, 只 要 从 键 盘 输 入 的 字 符 不 是 回 车 则 重 新 输 入 这 里 的 循 环 体 为 空 语 句 4.2 赋 值 语 句 赋 值 语 句 是 由 赋 值 表 达 式 再 加 上 分 号 构 成 的 表 达 式 语 句 其 一 般 形 式 为 : 变 量 = 表 达 式 ; 赋 值 语 句 的 功 能 和 特 点 都 与 赋 值 表 达 式 相 同 它 是 程 序 中 使 用 最 多 的 语 句 之 一 在 赋 值 语 句 的 使 用 中 需 要 注 意 以 下 几 点 : 1. 由 于 在 赋 值 符 = 右 边 的 表 达 式 也 可 以 又 是 一 个 赋 值 表 达 式, 第 56 页

57 因 此, 下 述 形 式 变 量 =( 变 量 = 表 达 式 ); 是 成 立 的, 从 而 形 成 嵌 套 的 情 形 其 展 开 之 后 的 一 般 形 式 为 : 变 量 = 变 量 = = 表 达 式 ; 例 如 : a=b=c=d=e=5; 按 照 赋 值 运 算 符 的 右 接 合 性, 因 此 实 际 上 等 效 于 : e=5; d=e; c=d; b=c; a=b; 2. 注 意 在 变 量 说 明 中 给 变 量 赋 初 值 和 赋 值 语 句 的 区 别 给 变 量 赋 初 值 是 变 量 说 明 的 一 部 分, 赋 初 值 后 的 变 量 与 其 后 的 其 它 同 类 变 量 之 间 仍 必 须 用 逗 号 间 隔, 而 赋 值 语 句 则 必 须 用 分 号 结 尾 例 如 : int a=5,b,c; 3. 在 变 量 说 明 中, 不 允 许 连 续 给 多 个 变 量 赋 初 值 如 下 述 说 明 是 错 误 的 : int a=b=c=5 必 须 写 为 int a=5,b=5,c=5; 而 赋 值 语 句 允 许 连 续 赋 值 4. 注 意 赋 值 表 达 式 和 赋 值 语 句 的 区 别 赋 值 表 达 式 是 一 种 表 达 式, 它 可 以 出 现 在 任 何 允 许 表 达 式 出 现 的 地 方, 而 赋 值 语 句 则 不 能 下 述 语 句 是 合 法 的 : if((x=y+5)>0) z=x; 语 句 的 功 能 是, 若 表 达 式 x=y+5 大 于 0 则 z=x 下 述 语 句 是 非 法 的 : if((x=y+5;)>0) z=x; 因 为 x=y+5; 是 语 句, 不 能 出 现 在 表 达 式 中 4.3 数 据 输 入 输 出 的 概 念 及 在 C 语 言 中 的 实 现 1) 所 谓 输 入 输 出 是 以 计 算 机 为 主 体 而 言 的 2) 本 章 介 绍 的 是 向 标 准 输 出 设 备 显 示 器 输 出 数 据 的 语 句 3) 在 C 语 言 中, 所 有 的 数 据 输 入 / 输 出 都 是 由 库 函 数 完 成 的 因 此 都 是 函 数 语 句 4) 在 使 用 C 语 言 库 函 数 时, 要 用 预 编 译 命 令 #include 将 有 关 头 文 件 包 括 到 源 文 件 中 使 用 标 准 输 入 输 出 库 函 数 时 要 用 到 stdio.h 文 件, 因 此 源 文 件 开 头 应 有 以 下 预 编 译 命 令 : #include< stdio.h > 或 第 57 页

58 #include stdio.h stdio 是 standard input &outupt 的 意 思 5) 考 虑 到 printf 和 scanf 函 数 使 用 频 繁, 系 统 允 许 在 使 用 这 两 个 函 数 时 可 不 加 #include< stdio.h > 或 #include stdio.h 4.4 字 符 数 据 的 输 入 输 出 putchar 函 数 ( 字 符 输 出 函 数 ) putchar 函 数 是 字 符 输 出 函 数, 其 功 能 是 在 显 示 器 上 输 出 单 个 字 符 其 一 般 形 式 为 : putchar( 字 符 变 量 ) 例 如 : putchar('a'); ( 输 出 大 写 字 母 A) putchar(x); ( 输 出 字 符 变 量 x 的 值 ) putchar( \101 ); ( 也 是 输 出 字 符 A) putchar('\n'); ( 换 行 ) 对 控 制 字 符 则 执 行 控 制 功 能, 不 在 屏 幕 上 显 示 使 用 本 函 数 前 必 须 要 用 文 件 包 含 命 令 : #include<stdio.h> 或 #include stdio.h 例 4.1 输 出 单 个 字 符 #include<stdio.h> main() char a='b',b='o',c='k'; putchar(a);putchar(b);putchar(b);putchar(c);putchar('\t'); putchar(a);putchar(b); putchar('\n'); putchar(b);putchar(c); getchar 函 数 ( 键 盘 输 入 函 数 ) getchar 函 数 的 功 能 是 从 键 盘 上 输 入 一 个 字 符 其 一 般 形 式 为 : getchar(); 通 常 把 输 入 的 字 符 赋 予 一 个 字 符 变 量, 构 成 赋 值 语 句, 如 : 第 58 页

59 char c; c=getchar(); 例 4.2 输 入 单 个 字 符 #include<stdio.h> void main() char c; printf("input a character\n"); c=getchar(); putchar(c); 使 用 getchar 函 数 还 应 注 意 几 个 问 题 : 1) getchar 函 数 只 能 接 受 单 个 字 符, 输 入 数 字 也 按 字 符 处 理 输 入 多 于 一 个 字 符 时, 只 接 收 第 一 个 字 符 2) 使 用 本 函 数 前 必 须 包 含 文 件 stdio.h 3) 在 TC 屏 幕 下 运 行 含 本 函 数 程 序 时, 将 退 出 TC 屏 幕 进 入 用 户 屏 幕 等 待 用 户 输 入 输 入 完 毕 再 返 回 TC 屏 幕 4) 程 序 最 后 两 行 可 用 下 面 两 行 的 任 意 一 行 代 替 : putchar(getchar()); printf( %c,getchar()); 4.5 格 式 输 入 与 输 出 printf 函 数 ( 格 式 输 出 函 数 ) printf 函 数 称 为 格 式 输 出 函 数, 其 关 键 字 最 末 一 个 字 母 f 即 为 格 式 (format) 之 意 其 功 能 是 按 用 户 指 定 的 格 式, 把 指 定 的 数 据 显 示 到 显 示 器 屏 幕 上 在 前 面 的 例 题 中 我 们 已 多 次 使 用 过 这 个 函 数 1. printf 函 数 调 用 的 一 般 形 式 printf 函 数 是 一 个 标 准 库 函 数, 它 的 函 数 原 型 在 头 文 件 stdio.h 中 但 作 为 一 个 特 例, 不 要 求 在 使 用 printf 函 数 之 前 必 须 包 含 stdio.h 文 件 printf 函 数 调 用 的 一 般 形 式 为 : printf( 格 式 控 制 字 符 串, 输 出 表 列 ) 其 中 格 式 控 制 字 符 串 用 于 指 定 输 出 格 式 格 式 控 制 串 可 由 格 式 字 符 串 和 非 格 式 字 符 串 两 种 组 成 格 式 字 符 串 是 以 % 开 头 的 字 符 串, 在 % 后 面 跟 有 各 种 格 式 字 符, 以 说 明 输 出 数 据 的 类 型 形 式 长 度 小 数 位 数 等 如 : %d 表 示 按 十 进 制 整 型 输 出 ; %ld 表 示 按 十 进 制 长 整 型 输 出 ; %c 表 示 按 字 符 型 输 出 等 非 格 式 字 符 串 在 输 出 时 原 样 照 印, 在 显 示 中 起 提 示 作 用 输 出 表 列 中 给 出 了 各 个 输 出 项, 要 求 格 式 字 符 串 和 各 输 出 项 在 数 量 和 类 型 上 应 该 一 一 对 应 例 4.3 main() 第 59 页

60 int a=88,b=89; printf("%d %d\n",a,b); printf("%d,%d\n",a,b); printf("%c,%c\n",a,b); printf("a=%d,b=%d",a,b); 本 例 中 四 次 输 出 了 a,b 的 值, 但 由 于 格 式 控 制 串 不 同, 输 出 的 结 果 也 不 相 同 第 四 行 的 输 出 语 句 格 式 控 制 串 中, 两 格 式 串 %d 之 间 加 了 一 个 空 格 ( 非 格 式 字 符 ), 所 以 输 出 的 a,b 值 之 间 有 一 个 空 格 第 五 行 的 printf 语 句 格 式 控 制 串 中 加 入 的 是 非 格 式 字 符 逗 号, 因 此 输 出 的 a,b 值 之 间 加 了 一 个 逗 号 第 六 行 的 格 式 串 要 求 按 字 符 型 输 出 a,b 值 第 七 行 中 为 了 提 示 输 出 结 果 又 增 加 了 非 格 式 字 符 串 2. 格 式 字 符 串 在 Turbo C 中 格 式 字 符 串 的 一 般 形 式 为 : [ 标 志 ][ 输 出 最 小 宽 度 ][. 精 度 ][ 长 度 ] 类 型 其 中 方 括 号 [] 中 的 项 为 可 选 项 各 项 的 意 义 介 绍 如 下 : 1) 类 型 : 类 型 字 符 用 以 表 示 输 出 数 据 的 类 型, 其 格 式 符 和 意 义 如 下 表 所 示 : 格 式 字 符 意 义 d 以 十 进 制 形 式 输 出 带 符 号 整 数 ( 正 数 不 输 出 符 号 ) o 以 八 进 制 形 式 输 出 无 符 号 整 数 ( 不 输 出 前 缀 0) x,x 以 十 六 进 制 形 式 输 出 无 符 号 整 数 ( 不 输 出 前 缀 Ox) u 以 十 进 制 形 式 输 出 无 符 号 整 数 f 以 小 数 形 式 输 出 单 双 精 度 实 数 e,e 以 指 数 形 式 输 出 单 双 精 度 实 数 g,g 以 %f 或 %e 中 较 短 的 输 出 宽 度 输 出 单 双 精 度 实 数 c 输 出 单 个 字 符 s 输 出 字 符 串 2) 标 志 : 标 志 字 符 为 - + # 空 格 四 种, 其 意 义 下 表 所 示 : 标 志 意 义 - 结 果 左 对 齐, 右 边 填 空 格 + 输 出 符 号 ( 正 号 或 负 号 ) 空 格 输 出 值 为 正 时 冠 以 空 格, 为 负 时 冠 以 负 号 # 对 c,s,d,u 类 无 影 响 ; 对 o 类, 在 输 出 时 加 前 缀 o; 对 x 类, 在 输 出 时 加 前 缀 0x; 对 e,g,f 类 当 结 果 有 小 数 时 才 给 出 小 数 点 3) 输 出 最 小 宽 度 : 用 十 进 制 整 数 来 表 示 输 出 的 最 少 位 数 若 实 际 位 数 多 于 定 义 的 宽 度, 则 按 实 际 位 数 输 出, 若 实 际 位 数 少 于 定 义 的 宽 度 则 补 以 空 格 或 0 4) 精 度 : 精 度 格 式 符 以. 开 头, 后 跟 十 进 制 整 数 本 项 的 意 义 是 : 如 果 输 出 数 字, 则 表 示 小 数 的 位 数 ; 如 果 输 出 的 是 字 符, 则 表 示 输 出 字 符 的 个 数 ; 若 实 际 位 数 大 于 所 定 义 的 精 度 数, 则 截 去 超 过 的 部 分 5. 长 度 : 长 度 格 式 符 为 h,l 两 种,h 表 示 按 短 整 型 量 输 出,l 表 示 按 长 整 型 量 输 出 例 4.4 main() 第 60 页

61 int a=15; float b= ; double c= ; char d='p'; printf("a=%d,%5d,%o,%x\n",a,a,a,a); printf("b=%f,%lf,%5.4lf,%e\n",b,b,b,b); printf("c=%lf,%f,%8.4lf\n",c,c,c); printf("d=%c,%8c\n",d,d); 本 例 第 七 行 中 以 四 种 格 式 输 出 整 型 变 量 a 的 值, 其 中 %5d 要 求 输 出 宽 度 为 5, 而 a 值 为 15 只 有 两 位 故 补 三 个 空 格 第 八 行 中 以 四 种 格 式 输 出 实 型 量 b 的 值 其 中 %f 和 %lf 格 式 的 输 出 相 同, 说 明 l 符 对 f 类 型 无 影 响 %5.4lf 指 定 输 出 宽 度 为 5, 精 度 为 4, 由 于 实 际 长 度 超 过 5 故 应 该 按 实 际 位 数 输 出, 小 数 位 数 超 过 4 位 部 分 被 截 去 第 九 行 输 出 双 精 度 实 数, %8.4lf 由 于 指 定 精 度 为 4 位 故 截 去 了 超 过 4 位 的 部 分 第 十 行 输 出 字 符 量 d, 其 中 %8c 指 定 输 出 宽 度 为 8 故 在 输 出 字 符 p 之 前 补 加 7 个 空 格 使 用 printf 函 数 时 还 要 注 意 一 个 问 题, 那 就 是 输 出 表 列 中 的 求 值 顺 序 不 同 的 编 译 系 统 不 一 定 相 同, 可 以 从 左 到 右, 也 可 从 右 到 左 Turbo C 是 按 从 右 到 左 进 行 的 请 看 下 面 两 个 例 子 : 例 4.5 main() int i=8; printf("%d\n%d\n%d\n%d\n%d\n%d\n",++i,--i,i++,i--,-i++,-i--); 例 4.6 main() int i=8; printf("%d\n",++i); printf("%d\n",--i); printf("%d\n",i++); printf("%d\n",i--); printf("%d\n",-i++); printf("%d\n",-i--); 这 两 个 程 序 的 区 别 是 用 一 个 printf 语 句 和 多 个 printf 语 句 输 出 但 从 结 果 可 以 看 出 是 不 同 的 为 什 么 结 果 会 不 同 呢? 就 是 因 为 printf 函 数 对 输 出 表 中 各 量 求 值 的 顺 序 是 自 右 至 左 进 行 的 在 第 一 例 中, 先 对 最 后 一 项 -i-- 求 值, 结 果 为 -8, 然 后 i 自 减 1 后 为 7 再 对 -i++ 项 求 值 得 -7, 然 后 i 自 增 1 后 为 8 再 对 i-- 项 求 值 得 8, 然 后 i 再 自 减 1 后 为 7 再 求 i++ 项 得 7, 然 后 i 再 自 增 1 后 为 8 再 求 --i 项,i 先 自 减 1 后 输 出, 输 出 值 为 7 最 后 才 求 输 出 表 列 中 的 第 一 项 ++i, 此 时 i 自 增 1 后 输 出 8 但 是 必 须 注 意, 求 值 顺 序 虽 是 自 右 至 左, 但 是 输 出 顺 序 还 是 从 左 至 右, 因 此 得 到 的 结 果 是 上 述 输 出 结 果 第 61 页

62 4.5.2 scanf 函 数 ( 格 式 输 入 函 数 ) scanf 函 数 称 为 格 式 输 入 函 数, 即 按 用 户 指 定 的 格 式 从 键 盘 上 把 数 据 输 入 到 指 定 的 变 量 之 中 1. scanf 函 数 的 一 般 形 式 scanf 函 数 是 一 个 标 准 库 函 数, 它 的 函 数 原 型 在 头 文 件 stdio.h 中, 与 printf 函 数 相 同,C 语 言 也 允 许 在 使 用 scanf 函 数 之 前 不 必 包 含 stdio.h 文 件 scanf 函 数 的 一 般 形 式 为 : scanf( 格 式 控 制 字 符 串, 地 址 表 列 ); 其 中, 格 式 控 制 字 符 串 的 作 用 与 printf 函 数 相 同, 但 不 能 显 示 非 格 式 字 符 串, 也 就 是 不 能 显 示 提 示 字 符 串 地 址 表 列 中 给 出 各 变 量 的 地 址 地 址 是 由 地 址 运 算 符 & 后 跟 变 量 名 组 成 的 例 如 : &a, &b 分 别 表 示 变 量 a 和 变 量 b 的 地 址 这 个 地 址 就 是 编 译 系 统 在 内 存 中 给 a,b 变 量 分 配 的 地 址 在 C 语 言 中, 使 用 了 地 址 这 个 概 念, 这 是 与 其 它 语 言 不 同 的 应 该 把 变 量 的 值 和 变 量 的 地 址 这 两 个 不 同 的 概 念 区 别 开 来 变 量 的 地 址 是 C 编 译 系 统 分 配 的, 用 户 不 必 关 心 具 体 的 地 址 是 多 少 变 量 的 地 址 和 变 量 值 的 关 系 如 下 : 在 赋 值 表 达 式 中 给 变 量 赋 值, 如 : a=567 则,a 为 变 量 名,567 是 变 量 的 值,&a 是 变 量 a 的 地 址 但 在 赋 值 号 左 边 是 变 量 名, 不 能 写 地 址, 而 scanf 函 数 在 本 质 上 也 是 给 变 量 赋 值, 但 要 求 写 变 量 的 地 址, 如 &a 这 两 者 在 形 式 上 是 不 同 的 & 是 一 个 取 地 址 运 算 符,&a 是 一 个 表 达 式, 其 功 能 是 求 变 量 的 地 址 例 4.7 main() int a,b,c; printf("input a,b,c\n"); scanf("%d%d%d",&a,&b,&c); printf("a=%d,b=%d,c=%d",a,b,c); 在 本 例 中, 由 于 scanf 函 数 本 身 不 能 显 示 提 示 串, 故 先 用 printf 语 句 在 屏 幕 上 输 出 提 示, 请 用 户 输 入 a b c 的 值 执 行 scanf 语 句, 则 退 出 TC 屏 幕 进 入 用 户 屏 幕 等 待 用 户 输 入 用 户 输 入 后 按 下 回 车 键, 此 时, 系 统 又 将 返 回 TC 屏 幕 在 scanf 语 句 的 格 式 串 中 由 于 没 有 非 格 式 字 符 在 %d%d%d 之 间 作 输 入 时 的 间 隔, 因 此 在 输 入 时 要 用 一 个 以 上 的 空 格 或 回 车 键 作 为 每 两 个 输 入 数 之 间 的 间 隔 如 : 或 格 式 字 符 串 格 式 字 符 串 的 一 般 形 式 为 : %[*][ 输 入 数 据 宽 度 ][ 长 度 ] 类 型 第 62 页

63 其 中 有 方 括 号 [] 的 项 为 任 选 项 各 项 的 意 义 如 下 : 1) 类 型 : 表 示 输 入 数 据 的 类 型, 其 格 式 符 和 意 义 如 下 表 所 示 格 式 字 符 意 义 d 输 入 十 进 制 整 数 o 输 入 八 进 制 整 数 x 输 入 十 六 进 制 整 数 u 输 入 无 符 号 十 进 制 整 数 f 或 e 输 入 实 型 数 ( 用 小 数 形 式 或 指 数 形 式 ) c 输 入 单 个 字 符 s 输 入 字 符 串 2) * 符 : 用 以 表 示 该 输 入 项, 读 入 后 不 赋 予 相 应 的 变 量, 即 跳 过 该 输 入 值 如 : scanf("%d %*d %d",&a,&b); 当 输 入 为 :1 2 3 时, 把 1 赋 予 a,2 被 跳 过,3 赋 予 b 3) 宽 度 : 用 十 进 制 整 数 指 定 输 入 的 宽 度 ( 即 字 符 数 ) 例 如 : scanf("%5d",&a); 输 入 : 只 把 赋 予 变 量 a, 其 余 部 分 被 截 去 又 如 : scanf("%4d%4d",&a,&b); 输 入 : 将 把 1234 赋 予 a, 而 把 5678 赋 予 b 4) 长 度 : 长 度 格 式 符 为 l 和 h,l 表 示 输 入 长 整 型 数 据 ( 如 %ld) 和 双 精 度 浮 点 数 ( 如 %lf) h 表 示 输 入 短 整 型 数 据 使 用 scanf 函 数 还 必 须 注 意 以 下 几 点 : 1) scanf 函 数 中 没 有 精 度 控 制, 如 :scanf("%5.2f",&a); 是 非 法 的 不 能 企 图 用 此 语 句 输 入 小 数 为 2 位 的 实 数 2) scanf 中 要 求 给 出 变 量 地 址, 如 给 出 变 量 名 则 会 出 错 如 scanf("%d",a); 是 非 法 的, 应 改 为 scnaf("%d",&a); 才 是 合 法 的 3) 在 输 入 多 个 数 值 数 据 时, 若 格 式 控 制 串 中 没 有 非 格 式 字 符 作 输 入 数 据 之 间 的 间 隔 则 可 用 空 格,TAB 或 回 车 作 间 隔 C 编 译 在 碰 到 空 格,TAB, 回 车 或 非 法 数 据 ( 如 对 %d 输 入 12A 时,A 即 为 非 法 数 据 ) 时 即 认 为 该 数 据 结 束 4) 在 输 入 字 符 数 据 时, 若 格 式 控 制 串 中 无 非 格 式 字 符, 则 认 为 所 有 输 入 的 字 符 均 为 有 效 字 符 例 如 : scanf("%c%c%c",&a,&b,&c); 输 入 为 : d e f 则 把 'd' 赋 予 a, ' ' 赋 予 b,'e' 赋 予 c 只 有 当 输 入 为 : def 时, 才 能 把 'd' 赋 于 a,'e' 赋 予 b,'f' 赋 予 c 如 果 在 格 式 控 制 中 加 入 空 格 作 为 间 隔, 如 : 第 63 页

64 scanf ("%c %c %c",&a,&b,&c); 则 输 入 时 各 数 据 之 间 可 加 空 格 例 4.8 main() char a,b; printf("input character a,b\n"); scanf("%c%c",&a,&b); printf("%c%c\n",a,b); 由 于 scanf 函 数 "%c%c" 中 没 有 空 格, 输 入 M N, 结 果 输 出 只 有 M 而 输 入 改 为 MN 时 则 可 输 出 MN 两 字 符 例 4.9 main() char a,b; printf("input character a,b\n"); scanf("%c %c",&a,&b); printf("\n%c%c\n",a,b); 本 例 表 示 scanf 格 式 控 制 串 "%c %c" 之 间 有 空 格 时, 输 入 的 数 据 之 间 可 以 有 空 格 间 隔 5) 如 果 格 式 控 制 串 中 有 非 格 式 字 符 则 输 入 时 也 要 输 入 该 非 格 式 字 符 例 如 : scanf("%d,%d,%d",&a,&b,&c); 其 中 用 非 格 式 符, 作 间 隔 符, 故 输 入 时 应 为 : 5,6,7 又 如 : scanf("a=%d,b=%d,c=%d",&a,&b,&c); 则 输 入 应 为 : a=5,b=6,c=7 6) 如 输 入 的 数 据 与 输 出 的 类 型 不 一 致 时, 虽 然 编 译 能 够 通 过, 但 结 果 将 不 正 确 例 4.10 main() int a; printf("input a number\n"); scanf("%d",&a); printf("%ld",a); 由 于 输 入 数 据 类 型 为 整 型, 而 输 出 语 句 的 格 式 串 中 说 明 为 长 整 型, 因 此 输 出 结 果 和 输 入 数 据 不 符 如 改 动 程 序 如 下 : 例 4.11 第 64 页

65 main() long a; printf("input a long integer\n"); scanf("%ld",&a); printf("%ld",a); 运 行 结 果 为 : input a long integer 当 输 入 数 据 改 为 长 整 型 后, 输 入 输 出 数 据 相 等 例 4.12 main() char a,b,c; printf("input character a,b,c\n"); scanf("%c %c %c",&a,&b,&c); printf("%d,%d,%d\n%c,%c,%c\n",a,b,c,a-32,b-32,c-32); 输 入 三 个 小 写 字 母, 输 出 其 ASCII 码 和 对 应 的 大 写 字 母 例 4.13 main() int a; long b; float f; double d; char c; printf("\nint:%d\nlong:%d\nfloat:%d\ndouble:%d\nchar:%d\n",sizeof(a),sizeof(b),sizeof(f),siz eof(d),sizeof(c)); 输 出 各 种 数 据 类 型 的 字 节 长 度 4.6 顺 序 结 构 程 序 设 计 举 例 例 4.14 输 入 三 角 形 的 三 边 长, 求 三 角 形 面 积 已 知 三 角 形 的 三 边 长 a,b,c, 则 该 三 角 形 的 面 积 公 式 为 : area = s( s a)( s b)( s c), 其 中 s = (a+b+c)/2 第 65 页

66 x 1 2 x 1 2 源 程 序 如 下 : #include<math.h> main() float a,b,c,s,area; scanf( %f,%f,%f,&a,&b,&c); s=1.0/2*(a+b+c); area=sqrt(s*(s-a)*(s-b)*(s-c)); printf( a=%7.2f,b=%7.2f,c=%7.2f,s=%7.2f\n,a,b,c,s); printf( area=%7.2f\n,area); 例 4.15 求 ax 2 +bx+c=0 方 程 的 根,a,b,c 由 键 盘 输 入, 设 b 2-4ac>0 求 根 公 式 为 : x b + = b b + b 4ac 1 = 2a 2a 2 4ac p b 2 4ac b 2 4ac q = q = 令 2a, 2a 则 x 1 =p+q x 2 =p-q 源 程 序 如 下 : #include<math.h> main() float a,b,c,disc,x1,x2,p,q; scanf( a=%f,b=%f,c=%f,&a,&b,&c); disc=b*b-4*a*c; p=-b/(2*a); q=sqrt(disc)/(2*a); x1=p+q;x2=p-q; printf( \nx1=%5.2f\nx2=%5.2f\n,x1,x2); = b 2 b b 4ac = + 2a a 第 66 页

67 5 分 支 结 构 程 序 5.1 关 系 运 算 符 和 表 达 式 算 符 在 程 序 中 经 常 需 要 比 较 两 个 量 的 大 小 关 系, 以 决 定 程 序 下 一 步 的 工 作 比 较 两 个 量 的 运 算 符 称 为 关 系 运 关 系 运 算 符 及 其 优 先 次 序 在 C 语 言 中 有 以 下 关 系 运 算 符 : 1) < 小 于 2) <= 小 于 或 等 于 3) > 大 于 4) >= 大 于 或 等 于 5) == 等 于 6)!= 不 等 于 关 系 运 算 符 都 是 双 目 运 算 符, 其 结 合 性 均 为 左 结 合 关 系 运 算 符 的 优 先 级 低 于 算 术 运 算 符, 高 于 赋 值 运 算 符 在 六 个 关 系 运 算 符 中,<,<=,>,>= 的 优 先 级 相 同, 高 于 == 和!=,== 和!= 的 优 先 级 相 同 关 系 表 达 式 关 系 表 达 式 的 一 般 形 式 为 : 表 达 式 关 系 运 算 符 表 达 式 例 如 : a+b>c-d x>3/2 a +1<c -i-5*j==k+1 都 是 合 法 的 关 系 表 达 式 由 于 表 达 式 也 可 以 又 是 关 系 表 达 式 因 此 也 允 许 出 现 嵌 套 的 情 况 例 如 : a>(b>c) a!=(c==d) 等 关 系 表 达 式 的 值 是 真 和 假, 用 1 和 0 表 示 如 : 5>0 的 值 为 真, 即 为 1 (a=3)>(b=5) 由 于 3>5 不 成 立, 故 其 值 为 假, 即 为 0 例 5.1 main() char c='k'; int i=1,j=2,k=3; float x=3e+5,y=0.85; 第 67 页

68 printf("%d,%d\n", a +5<c,-i-2*j>=k+1); printf("%d,%d\n",1<j<5,x-5.25<=x+y); printf("%d,%d\n",i+j+k==-2*j,k==j==i+5); 在 本 例 中 求 出 了 各 种 关 系 运 算 符 的 值 字 符 变 量 是 以 它 对 应 的 ASCII 码 参 与 运 算 的 对 于 含 多 个 关 系 运 算 符 的 表 达 式, 如 k==j==i+5, 根 据 运 算 符 的 左 结 合 性, 先 计 算 k==j, 该 式 不 成 立, 其 值 为 0, 再 计 算 0==i+5, 也 不 成 立, 故 表 达 式 值 为 逻 辑 运 算 符 和 表 达 式 逻 辑 运 算 符 极 其 优 先 次 序 C 语 言 中 提 供 了 三 种 逻 辑 运 算 符 : 1) && 与 运 算 2) 或 运 算 3)! 非 运 算 与 运 算 符 && 和 或 运 算 符 均 为 双 目 运 算 符 具 有 左 结 合 性 非 运 算 符! 为 单 目 运 算 符, 具 有 右 结 合 性 逻 辑 运 算 符 和 其 它 运 算 符 优 先 级 的 关 系 可 表 示 如 下 :!( 非 ) 算 术 运 算 符 关 系 运 算 符 && 和 赋 值 运 算 符!( 非 ) &&( 与 ) ( 或 ) && 和 低 于 关 系 运 算 符,! 高 于 算 术 运 算 符 按 照 运 算 符 的 优 先 顺 序 可 以 得 出 : a>b && c>d 等 价 于 (a>b)&&(c>d)!b==c d<a 等 价 于 ((!b)==c) (d<a) a+b>c&&x+y<b 等 价 于 ((a+b)>c)&&((x+y)<b) 逻 辑 运 算 的 值 逻 辑 运 算 的 值 也 为 真 和 假 两 种, 用 1 和 0 来 表 示 其 求 值 规 则 如 下 : 1. 与 运 算 &&: 参 与 运 算 的 两 个 量 都 为 真 时, 结 果 才 为 真, 否 则 为 假 例 如 : 5>0 && 4>2 由 于 5>0 为 真,4>2 也 为 真, 相 与 的 结 果 也 为 真 第 68 页

69 2. 或 运 算 : 参 与 运 算 的 两 个 量 只 要 有 一 个 为 真, 结 果 就 为 真 两 个 量 都 为 假 时, 结 果 为 假 例 如 : 5>0 5>8 由 于 5>0 为 真, 相 或 的 结 果 也 就 为 真 3. 非 运 算!: 参 与 运 算 量 为 真 时, 结 果 为 假 ; 参 与 运 算 量 为 假 时, 结 果 为 真 例 如 :!(5>0) 的 结 果 为 假 虽 然 C 编 译 在 给 出 逻 辑 运 算 值 时, 以 1 代 表 真, 0 代 表 假 但 反 过 来 在 判 断 一 个 量 是 为 真 还 是 为 假 时, 以 0 代 表 假, 以 非 0 的 数 值 作 为 真 例 如 : 由 于 5 和 3 均 为 非 0 因 此 5&&3 的 值 为 真, 即 为 1 又 如 : 5 0 的 值 为 真, 即 为 逻 辑 表 达 式 逻 辑 表 达 式 的 一 般 形 式 为 : 表 达 式 逻 辑 运 算 符 表 达 式 其 中 的 表 达 式 可 以 又 是 逻 辑 表 达 式, 从 而 组 成 了 嵌 套 的 情 形 例 如 : (a&&b)&&c 根 据 逻 辑 运 算 符 的 左 结 合 性, 上 式 也 可 写 为 : a&&b&&c 逻 辑 表 达 式 的 值 是 式 中 各 种 逻 辑 运 算 的 最 后 值, 以 1 和 0 分 别 代 表 真 和 假 例 5.2 main() char c='k'; int i=1,j=2,k=3; float x=3e+5,y=0.85; printf("%d,%d\n",!x*!y,!!!x); printf("%d,%d\n",x i&&j-3,i<j&&x<y); printf("%d,%d\n",i==5&&c&&(j=8),x+y i+j+k); 本 例 中!x 和!y 分 别 为 0,!x*!y 也 为 0, 故 其 输 出 值 为 0 由 于 x 为 非 0, 故!!!x 的 逻 辑 值 为 0 对 x i && j-3 式, 先 计 算 j-3 的 值 为 非 0, 再 求 i && j-3 的 逻 辑 值 为 1, 故 x i&&j-3 的 逻 辑 值 为 1 对 i<j&&x<y 式, 由 于 i<j 的 值 为 1, 而 x<y 为 0 故 表 达 式 的 值 为 1,0 相 与, 最 后 为 0, 对 i==5&&c&&(j=8) 式, 由 于 i==5 为 假, 即 值 为 0, 该 表 达 式 由 两 个 与 运 算 组 成, 所 以 整 个 表 达 式 的 值 为 0 对 于 式 x+ y i+j+k 由 于 x+y 的 值 为 非 0, 故 整 个 或 表 达 式 的 值 为 1 第 69 页

70 5.3 if 语 句 用 if 语 句 可 以 构 成 分 支 结 构 它 根 据 给 定 的 条 件 进 行 判 断, 以 决 定 执 行 某 个 分 支 程 序 段 C 语 言 的 if 语 句 有 三 种 基 本 形 式 if 语 句 的 三 种 形 式 1. 第 一 种 形 式 为 基 本 形 式 :if if( 表 达 式 ) 语 句 其 语 义 是 : 如 果 表 达 式 的 值 为 真, 则 执 行 其 后 的 语 句, 否 则 不 执 行 该 语 句 其 过 程 可 表 示 为 下 图 例 5.3 main() int a,b,max; printf("\n input two numbers: "); scanf("%d%d",&a,&b); max=a; if (max<b) max=b; printf("max=%d",max); 本 例 程 序 中, 输 入 两 个 数 a,b 把 a 先 赋 予 变 量 max, 再 用 if 语 句 判 别 max 和 b 的 大 小, 如 max 小 于 b, 则 把 b 赋 予 max 因 此 max 中 总 是 大 数, 最 后 输 出 max 的 值 2. 第 二 种 形 式 为 : if-else if( 表 达 式 ) 语 句 1; else 语 句 2; 其 语 义 是 : 如 果 表 达 式 的 值 为 真, 则 执 行 语 句 1, 否 则 执 行 语 句 2 其 执 行 过 程 可 表 示 为 下 图 第 70 页

71 例 5.4 main() int a, b; printf("input two numbers: "); scanf("%d%d",&a,&b); if(a>b) printf("max=%d\n",a); else printf("max=%d\n",b); 输 入 两 个 整 数, 输 出 其 中 的 大 数 改 用 if-else 语 句 判 别 a,b 的 大 小, 若 a 大, 则 输 出 a, 否 则 输 出 b 3. 第 三 种 形 式 为 if-else-if 形 式 前 二 种 形 式 的 if 语 句 一 般 都 用 于 两 个 分 支 的 情 况 当 有 多 个 分 支 选 择 时, 可 采 用 if-else-if 语 句, 其 一 般 形 式 为 : if( 表 达 式 1) 语 句 1; else if( 表 达 式 2) 语 句 2; else if( 表 达 式 3) 语 句 3; else if( 表 达 式 m) 语 句 m; else 语 句 n; 其 语 义 是 : 依 次 判 断 表 达 式 的 值, 当 出 现 某 个 值 为 真 时, 则 执 行 其 对 应 的 语 句 然 后 跳 到 整 个 if 语 句 之 外 继 续 执 行 程 序 如 果 所 有 的 表 达 式 均 为 假, 则 执 行 语 句 n 然 后 继 续 执 行 后 续 程 序 if-else-if 语 句 的 执 行 过 程 如 图 3 3 所 示 第 71 页

72 例 5.5 #include"stdio.h" main() char c; printf("input a character: "); c=getchar(); if(c<32) printf("this is a control character\n"); else if(c>='0'&&c<='9') printf("this is a digit\n"); else if(c>='a'&&c<='z') printf("this is a capital letter\n"); else if(c>='a'&&c<='z') printf("this is a small letter\n"); else printf("this is an other character\n"); 本 例 要 求 判 别 键 盘 输 入 字 符 的 类 别 可 以 根 据 输 入 字 符 的 ASCII 码 来 判 别 类 型 由 ASCII 码 表 可 知 ASCII 值 小 于 32 的 为 控 制 字 符 在 0 和 9 之 间 的 为 数 字, 在 A 和 Z 之 间 为 大 写 字 母, 在 a 和 z 之 间 为 小 写 字 母, 其 余 则 为 其 它 字 符 这 是 一 个 多 分 支 选 择 的 问 题, 用 if-else-if 语 句 编 程, 判 断 输 入 字 符 ASCII 码 所 在 的 范 围, 分 别 给 出 不 同 的 输 出 例 如 输 入 为 g, 输 出 显 示 它 为 小 写 字 符 4. 在 使 用 if 语 句 中 还 应 注 意 以 下 问 题 : 第 72 页

73 1) 在 三 种 形 式 的 if 语 句 中, 在 if 关 键 字 之 后 均 为 表 达 式 该 表 达 式 通 常 是 逻 辑 表 达 式 或 关 系 表 达 式, 但 也 可 以 是 其 它 表 达 式, 如 赋 值 表 达 式 等, 甚 至 也 可 以 是 一 个 变 量 例 如 : if(a=5) 语 句 ; if(b) 语 句 ; 都 是 允 许 的 只 要 表 达 式 的 值 为 非 0, 即 为 真 如 在 : if(a=5) ; 中 表 达 式 的 值 永 远 为 非 0, 所 以 其 后 的 语 句 总 是 要 执 行 的, 当 然 这 种 情 况 在 程 序 中 不 一 定 会 出 现, 但 在 语 法 上 是 合 法 的 又 如, 有 程 序 段 : if(a=b) printf("%d",a); else printf("a=0"); 本 语 句 的 语 义 是, 把 b 值 赋 予 a, 如 为 非 0 则 输 出 该 值, 否 则 输 出 a=0 字 符 串 这 种 用 法 在 程 序 中 是 经 常 出 现 的 2) 在 if 语 句 中, 条 件 判 断 表 达 式 必 须 用 括 号 括 起 来, 在 语 句 之 后 必 须 加 分 号 3) 在 if 语 句 的 三 种 形 式 中, 所 有 的 语 句 应 为 单 个 语 句, 如 果 要 想 在 满 足 条 件 时 执 行 一 组 ( 多 个 ) 语 句, 则 必 须 把 这 一 组 语 句 用 括 起 来 组 成 一 个 复 合 语 句 但 要 注 意 的 是 在 之 后 不 能 再 加 分 号 例 如 : if(a>b) a++; b++; else a=0; b=10; if 语 句 的 嵌 套 当 if 语 句 中 的 执 行 语 句 又 是 if 语 句 时, 则 构 成 了 if 语 句 嵌 套 的 情 形 其 一 般 形 式 可 表 示 如 下 : if( 表 达 式 ) if 语 句 ; 或 者 为 if( 表 达 式 ) if 语 句 ; else if 语 句 ; 在 嵌 套 内 的 if 语 句 可 能 又 是 if-else 型 的, 这 将 会 出 现 多 个 if 和 多 个 else 重 叠 的 情 况, 这 时 要 特 别 注 意 if 和 else 的 配 对 问 题 例 如 : if( 表 达 式 1) if( 表 达 式 2) 第 73 页

74 语 句 1; else 语 句 2; 其 中 的 else 究 竟 是 与 哪 一 个 if 配 对 呢? 应 该 理 解 为 : if( 表 达 式 1) if( 表 达 式 2) 语 句 1; else 语 句 2; 还 是 应 理 解 为 : if( 表 达 式 1) if( 表 达 式 2) 语 句 1; else 语 句 2; 为 了 避 免 这 种 二 义 性,C 语 言 规 定,else 总 是 与 它 前 面 最 近 的 if 配 对, 因 此 对 上 述 例 子 应 按 前 一 种 情 况 理 解 例 5.6 main() int a,b; printf("please input A,B: "); scanf("%d%d",&a,&b); if(a!=b) if(a>b) printf("a>b\n"); else printf("a<b\n"); else printf("a=b\n"); 比 较 两 个 数 的 大 小 关 系 本 例 中 用 了 if 语 句 的 嵌 套 结 构 采 用 嵌 套 结 构 实 质 上 是 为 了 进 行 多 分 支 选 择, 实 际 上 有 三 种 选 择 即 A>B A<B 或 A=B 这 种 问 题 用 if-else-if 语 句 也 可 以 完 成 而 且 程 序 更 加 清 晰 因 此, 在 一 般 情 况 下 较 少 使 用 if 语 句 的 嵌 套 结 构 以 使 程 序 更 便 于 阅 读 理 解 例 5.7 main() int a,b; printf("please input A,B: "); scanf("%d%d",&a,&b); if(a==b) printf("a=b\n"); else if(a>b) printf("a>b\n"); else printf("a<b\n"); 第 74 页

75 5.3.3 条 件 运 算 符 和 条 件 表 达 式 如 果 在 条 件 语 句 中, 只 执 行 单 个 的 赋 值 语 句 时, 常 可 使 用 条 件 表 达 式 来 实 现 不 但 使 程 序 简 洁, 也 提 高 了 运 行 效 率 条 件 运 算 符 为? 和 :, 它 是 一 个 三 目 运 算 符, 即 有 三 个 参 与 运 算 的 量 由 条 件 运 算 符 组 成 条 件 表 达 式 的 一 般 形 式 为 : 表 达 式 1? 表 达 式 2: 表 达 式 3 其 求 值 规 则 为 : 如 果 表 达 式 1 的 值 为 真, 则 以 表 达 式 2 的 值 作 为 条 件 表 达 式 的 值, 否 则 以 表 达 式 2 的 值 作 为 整 个 条 件 表 达 式 的 值 条 件 表 达 式 通 常 用 于 赋 值 语 句 之 中 例 如 条 件 语 句 : if(a>b) max=a; else max=b; 可 用 条 件 表 达 式 写 为 max=(a>b)?a:b; 执 行 该 语 句 的 语 义 是 : 如 a>b 为 真, 则 把 a 赋 予 max, 否 则 把 b 赋 予 max 使 用 条 件 表 达 式 时, 还 应 注 意 以 下 几 点 : 1) 条 件 运 算 符 的 运 算 优 先 级 低 于 关 系 运 算 符 和 算 术 运 算 符, 但 高 于 赋 值 符 因 此 max=(a>b)?a:b 可 以 去 掉 括 号 而 写 为 max=a>b?a:b 2) 条 件 运 算 符? 和 : 是 一 对 运 算 符, 不 能 分 开 单 独 使 用 3) 条 件 运 算 符 的 结 合 方 向 是 自 右 至 左 例 如 : a>b?a:c>d?c:d 应 理 解 为 a>b?a:(c>d?c:d) 这 也 就 是 条 件 表 达 式 嵌 套 的 情 形, 即 其 中 的 表 达 式 3 又 是 一 个 条 件 表 达 式 例 5.8 main() int a,b,max; printf("\n input two numbers: "); scanf("%d%d",&a,&b); printf("max=%d",a>b?a:b); 用 条 件 表 达 式 对 上 例 重 新 编 程, 输 出 两 个 数 中 的 大 数 第 75 页

76 5.4 switch 语 句 C 语 言 还 提 供 了 另 一 种 用 于 多 分 支 选 择 的 switch 语 句, 其 一 般 形 式 为 : switch( 表 达 式 ) case 常 量 表 达 式 1: 语 句 1; case 常 量 表 达 式 2: 语 句 2; case 常 量 表 达 式 n: 语 句 n; default : 语 句 n+1; 其 语 义 是 : 计 算 表 达 式 的 值 并 逐 个 与 其 后 的 常 量 表 达 式 值 相 比 较, 当 表 达 式 的 值 与 某 个 常 量 表 达 式 的 值 相 等 时, 即 执 行 其 后 的 语 句, 然 后 不 再 进 行 判 断, 继 续 执 行 后 面 所 有 case 后 的 语 句 如 表 达 式 的 值 与 所 有 case 后 的 常 量 表 达 式 均 不 相 同 时, 则 执 行 default 后 的 语 句 例 4.9 main() int a; printf("input integer number: "); scanf("%d",&a); switch (a) case 1:printf("Monday\n"); case 2:printf("Tuesday\n"); case 3:printf("Wednesday\n"); case 4:printf("Thursday\n"); case 5:printf("Friday\n"); case 6:printf("Sa urday\n"); case 7:printf("Sunday\n"); default:printf("error\n"); 本 程 序 是 要 求 输 入 一 个 数 字, 输 出 一 个 英 文 单 词 但 是 当 输 入 3 之 后, 却 执 行 了 case3 以 及 以 后 的 所 有 语 句, 输 出 了 Wednesday 及 以 后 的 所 有 单 词 这 当 然 是 不 希 望 的 为 什 么 会 出 现 这 种 情 况 呢? 这 恰 恰 反 应 了 switch 语 句 的 一 个 特 点 在 switch 语 句 中, case 常 量 表 达 式 只 相 当 于 一 个 语 句 标 号, 表 达 式 的 值 和 某 标 号 相 等 则 转 向 该 标 号 执 行, 但 不 能 在 执 行 完 该 标 号 的 语 句 后 自 动 跳 出 整 个 switch 语 句, 所 以 出 现 了 继 续 执 行 所 有 后 面 case 语 句 的 情 况 这 是 与 前 面 介 绍 的 if 语 句 完 全 不 同 的, 应 特 别 注 意 为 了 避 免 上 述 情 况, C 语 言 还 提 供 了 一 种 break 语 句, 专 用 于 跳 出 switch 语 句,break 语 句 只 有 关 键 字 break, 没 有 参 数 在 后 面 还 将 详 细 介 绍 修 改 例 题 的 程 序, 在 每 一 case 语 句 之 后 增 加 break 语 句, 使 每 一 次 执 行 之 后 均 可 跳 出 switch 语 句, 从 而 避 免 输 出 不 应 有 的 结 果 例 4.10 第 76 页

77 main() int a; printf("input integer number: "); scanf("%d",&a); switch (a) case 1:printf("Monday\n");break; case 2:printf("Tuesday\n"); break; case 3:printf("Wednesday\n");break; case 4:printf("Thursday\n");break; case 5:printf("Friday\n");break; case 6:printf("Saturday\n");break; case 7:printf("Sunday\n");break; default:printf("error\n"); 在 使 用 switch 语 句 时 还 应 注 意 以 下 几 点 : 1) 在 case 后 的 各 常 量 表 达 式 的 值 不 能 相 同, 否 则 会 出 现 错 误 2) 在 case 后, 允 许 有 多 个 语 句, 可 以 不 用 括 起 来 3) 各 case 和 default 子 句 的 先 后 顺 序 可 以 变 动, 而 不 会 影 响 程 序 执 行 结 果 4) default 子 句 可 以 省 略 不 用 5.5 程 序 举 例 例 4.11 输 入 三 个 整 数, 输 出 最 大 数 和 最 小 数 main() int a,b,c,max,min; printf("input three numbers: "); scanf("%d%d%d",&a,&b,&c); if(a>b) max=a;min=b; else max=b;min=a; if(max<c) max=c; else if(min>c) min=c; printf("max=%d\nmin=%d",max,min); 第 77 页

78 本 程 序 中, 首 先 比 较 输 入 的 a,b 的 大 小, 并 把 大 数 装 入 max, 小 数 装 入 min 中, 然 后 再 与 c 比 较, 若 max 小 于 c, 则 把 c 赋 予 max; 如 果 c 小 于 min, 则 把 c 赋 予 min 因 此 max 内 总 是 最 大 数, 而 min 内 总 是 最 小 数 最 后 输 出 max 和 min 的 值 即 可 例 4.12 计 算 器 程 序 用 户 输 入 运 算 数 和 四 则 运 算 符, 输 出 计 算 结 果 main() float a,b; char c; printf("input expression: a+(-,*,/)b \n"); scanf("%f%c%f",&a,&c,&b); switch(c) case '+': printf("%f\n",a+b);break; case '-': printf("%f\n",a-b);break; case '*': printf("%f\n",a*b);break; case '/': printf("%f\n",a/b);break; default: printf("input error\n" 循 环 控 制 6 本 例 可 用 于 四 则 运 算 求 值 switch 语 句 用 于 判 断 运 算 符, 然 后 输 出 运 算 值 当 输 入 运 算 符 不 是 +,-,*,/ 时 给 出 错 误 提 示 循 环 控 制 6.1 概 述 循 环 结 构 是 程 序 中 一 种 很 重 要 的 结 构 其 特 点 是, 在 给 定 条 件 成 立 时, 反 复 执 行 某 程 序 段, 直 到 条 件 不 成 立 为 止 给 定 的 条 件 称 为 循 环 条 件, 反 复 执 行 的 程 序 段 称 为 循 环 体 C 语 言 提 供 了 多 种 循 环 语 句, 可 以 组 成 各 种 不 同 形 式 的 循 环 结 构 1) 用 goto 语 句 和 if 语 句 构 成 循 环 ; 2) 用 while 语 句 ; 3) 用 do-while 语 句 ; 4) 用 for 语 句 ; 6.2 goto 语 句 以 及 用 goto 语 句 构 成 循 环 goto 语 句 是 一 种 无 条 件 转 移 语 句, 与 BASIC 中 的 goto 语 句 相 似 goto 语 句 的 使 用 格 式 为 : goto 语 句 标 号 ; 第 78 页

79 其 中 标 号 是 一 个 有 效 的 标 识 符, 这 个 标 识 符 加 上 一 个 : 一 起 出 现 在 函 数 内 某 处, 执 行 goto 语 句 后, 程 序 将 跳 转 到 该 标 号 处 并 执 行 其 后 的 语 句 另 外 标 号 必 须 与 goto 语 句 同 处 于 一 个 函 数 中, 但 可 以 不 在 一 个 循 环 层 中 通 常 goto 语 句 与 if 条 件 语 句 连 用, 当 满 足 某 一 条 件 时, 程 序 跳 到 标 号 处 运 行 合 理 goto 语 句 通 常 不 用, 主 要 因 为 它 将 使 程 序 层 次 不 清, 且 不 易 读, 但 在 多 层 嵌 套 退 出 时, 用 goto 语 句 则 比 较 例 6.1 用 goto 语 句 和 if 语 句 构 成 循 环, main() loop: int i,sum=0; i=1; if(i<=100) 100 n= 1 n sum=s m+i; i++; goto loop; printf("%d\n",sum); 6.3 while 语 句 while 语 句 的 一 般 形 式 为 : while( 表 达 式 ) 语 句 其 中 表 达 式 是 循 环 条 件, 语 句 为 循 环 体 while 语 句 的 语 义 是 : 计 算 表 达 式 的 值, 当 值 为 真 ( 非 0) 时, 执 行 循 环 体 语 句 其 执 行 过 程 可 用 下 图 表 示 第 79 页

80 例 6.2 用 while 语 句 求 100 n= 1 n 用 传 统 流 程 图 和 N-S 结 构 流 程 图 表 示 算 法, 见 图 : main() int i,sum=0; i=1; while(i<=100) sum=sum+i; i++; printf("%d\n",sum); 例 6.3 统 计 从 键 盘 输 入 一 行 字 符 的 个 数 #include <stdio.h> main() int n=0; 第 80 页

81 printf("input a string:\n"); while(getchar()!='\n') n++; printf("%d",n); 本 例 程 序 中 的 循 环 条 件 为 getchar()!='\n', 其 意 义 是, 只 要 从 键 盘 输 入 的 字 符 不 是 回 车 就 继 续 循 环 循 环 体 n++ 完 成 对 输 入 字 符 个 数 计 数 从 而 程 序 实 现 了 对 输 入 一 行 字 符 的 字 符 个 数 计 数 使 用 while 语 句 应 注 意 以 下 几 点 : 1) while 语 句 中 的 表 达 式 一 般 是 关 系 表 达 或 逻 辑 表 达 式, 只 要 表 达 式 的 值 为 真 ( 非 0) 即 可 继 续 循 环 例 6.4 main() int a=0,n; printf("\n input n: "); scanf("%d",&n); while (n--) printf("%d ",a++*2); 本 例 程 序 将 执 行 n 次 循 环, 每 执 行 一 次,n 值 减 1 循 环 体 输 出 表 达 式 a++*2 的 值 该 表 达 式 等 效 于 (a*2; a++) 2) 循 环 体 如 包 括 有 一 个 以 上 的 语 句, 则 必 须 用 括 起 来, 组 成 复 合 语 句 6.4 do-while 语 句 do-while 语 句 的 一 般 形 式 为 : do 语 句 while( 表 达 式 ); 这 个 循 环 与 while 循 环 的 不 同 在 于 : 它 先 执 行 循 环 中 的 语 句, 然 后 再 判 断 表 达 式 是 否 为 真, 如 果 为 真 则 继 续 循 环 ; 如 果 为 假, 则 终 止 循 环 因 此, do-while 循 环 至 少 要 执 行 一 次 循 环 语 句 其 执 行 过 程 可 用 下 图 表 示 第 81 页

82 例 6.5 用 do-while 语 句 求 100 n= 1 n 用 传 统 流 程 图 和 N-S 结 构 流 程 图 表 示 算 法, 见 图 : main() int i,sum=0; i=1; do sum=sum+i; i++; while(i<=100) printf("%d\n",sum); 第 82 页

83 同 样 当 有 许 多 语 句 参 加 循 环 时, 要 用 "" 和 "" 把 它 们 括 起 来 例 6.6 while 和 do-while 循 环 比 较 (1)main() int sum=0,i; scanf( %d,&i); while(i<=10) sum=sum+i; i++; printf( sum=%d,sum); (2)main() int sum=0,i; scanf( %d,&i); do sum=sum+i; i++; while(i<=10); printf( sum=%d,sum); 6.5 for 语 句 在 C 语 言 中,for 语 句 使 用 最 为 灵 活, 它 完 全 可 以 取 代 while 语 句 它 的 一 般 形 式 为 : for( 表 达 式 1; 表 达 式 2; 表 达 式 3) 语 句 它 的 执 行 过 程 如 下 : 1) 先 求 解 表 达 式 1 2) 求 解 表 达 式 2, 若 其 值 为 真 ( 非 0), 则 执 行 for 语 句 中 指 定 的 内 嵌 语 句, 然 后 执 行 下 面 第 3) 步 ; 若 其 值 为 假 (0), 则 结 束 循 环, 转 到 第 5) 步 3) 求 解 表 达 式 3 4) 转 回 上 面 第 2) 步 继 续 执 行 5) 循 环 结 束, 执 行 for 语 句 下 面 的 一 个 语 句 其 执 行 过 程 可 用 下 图 表 示 第 83 页

84 for 语 句 最 简 单 的 应 用 形 式 也 是 最 容 易 理 解 的 形 式 如 下 : for( 循 环 变 量 赋 初 值 ; 循 环 条 件 ; 循 环 变 量 增 量 ) 语 句 循 环 变 量 赋 初 值 总 是 一 个 赋 值 语 句, 它 用 来 给 循 环 控 制 变 量 赋 初 值 ; 循 环 条 件 是 一 个 关 系 表 达 式, 它 决 定 什 么 时 候 退 出 循 环 ; 循 环 变 量 增 量, 定 义 循 环 控 制 变 量 每 循 环 一 次 后 按 什 么 方 式 变 化 这 三 个 部 分 之 间 用 ; 分 开 例 如 : for(i=1; i<=100; i++)sum=sum+i; 先 给 i 赋 初 值 1, 判 断 i 是 否 小 于 等 于 100, 若 是 则 执 行 语 句, 之 后 值 增 加 1 再 重 新 判 断, 直 到 条 件 为 假, 即 i>100 时, 结 束 循 环 相 当 于 : i=1; while(i<=100) sum=sum+i; i++; 对 于 for 循 环 中 语 句 的 一 般 形 式, 就 是 如 下 的 while 循 环 形 式 : 表 达 式 1; while( 表 达 式 2) 语 句 表 达 式 3; 注 意 : 1) for 循 环 中 的 表 达 式 1( 循 环 变 量 赋 初 值 ) 表 达 式 2( 循 环 条 件 ) 和 表 达 式 3( 循 环 变 量 增 量 ) 都 是 第 84 页

85 选 择 项, 即 可 以 缺 省, 但 ; 不 能 缺 省 2) 省 略 了 表 达 式 1( 循 环 变 量 赋 初 值 ), 表 示 不 对 循 环 控 制 变 量 赋 初 值 3) 省 略 了 表 达 式 2( 循 环 条 件 ), 则 不 做 其 它 处 理 时 便 成 为 死 循 环 例 如 : for(i=1;;i++)sum=sum+i; 相 当 于 : i=1; while(1) sum=sum+i; i++; 4) 省 略 了 表 达 式 3( 循 环 变 量 增 量 ), 则 不 对 循 环 控 制 变 量 进 行 操 作, 这 时 可 在 语 句 体 中 加 入 修 改 循 环 控 制 变 量 的 语 句 例 如 : for(i=1;i<=100;) sum=sum+i; i++; 5) 省 略 了 表 达 式 1( 循 环 变 量 赋 初 值 ) 和 表 达 式 3( 循 环 变 量 增 量 ) 例 如 : for(;i<=100;) sum=sum+i; i++; 相 当 于 : while(i<=100) sum=sum+i; i++; 6) 3 个 表 达 式 都 可 以 省 略 例 如 : for(;; ) 语 句 相 当 于 : while(1) 语 句 7) 表 达 式 1 可 以 是 设 置 循 环 变 量 的 初 值 的 赋 值 表 达 式, 也 可 以 是 其 他 表 达 式 例 如 : for(sum=0;i<=100;i++)sum=sum+i; 8) 表 达 式 1 和 表 达 式 3 可 以 是 一 个 简 单 表 达 式 也 可 以 是 逗 号 表 达 式 for(sum=0,i=1;i<=100;i++)sum=sum+i; 或 : for(i=0,j=100;i<=100;i++,j--)k=i+j; 9) 表 达 式 2 一 般 是 关 系 表 达 式 或 逻 辑 表 达 式, 但 也 可 是 数 值 表 达 式 或 字 符 表 达 式, 只 要 其 值 非 零, 就 执 行 循 环 体 例 如 : for(i=0;(c=getchar())!= \n ;i+=c); 又 如 : for(;(c=getchar())!= \n ;) printf( %c,c); 第 85 页

86 6.6 循 环 的 嵌 套 例 6.7 main() int i, j, k; printf("i j k\n"); for (i=0; i<2; i++) for(j=0; j<2; j++) for(k=0; k<2; k++) printf( %d %d %d\n", i, j, k); 6.7 几 种 循 环 的 比 较 1) 四 种 循 环 都 可 以 用 来 处 理 同 一 个 问 题, 一 般 可 以 互 相 代 替 但 一 般 不 提 倡 用 goto 型 循 环 2) while 和 do-while 循 环, 循 环 体 中 应 包 括 使 循 环 趋 于 结 束 的 语 句 for 语 句 功 能 最 强 3) 用 while 和 do-while 循 环 时, 循 环 变 量 初 始 化 的 操 作 应 在 while 和 do-while 语 句 之 前 完 成, 而 for 语 句 可 以 在 表 达 式 1 中 实 现 循 环 变 量 的 初 始 化 6.8 break 和 continue 语 句 break 语 句 break 语 句 通 常 用 在 循 环 语 句 和 开 关 语 句 中 当 break 用 于 开 关 语 句 switch 中 时, 可 使 程 序 跳 出 switch 而 执 行 switch 以 后 的 语 句 ; 如 果 没 有 break 语 句, 则 将 成 为 一 个 死 循 环 而 无 法 退 出 break 在 switch 中 的 用 法 已 在 前 面 介 绍 开 关 语 句 时 的 例 子 中 碰 到, 这 里 不 再 举 例 当 break 语 句 用 于 do-while for while 循 环 语 句 中 时, 可 使 程 序 终 止 循 环 而 执 行 循 环 后 面 的 语 句, 通 常 break 语 句 总 是 与 if 语 句 联 在 一 起 即 满 足 条 件 时 便 跳 出 循 环 例 6.8 main() int i=0; char c; while(1) /* 设 置 循 环 */ c='\0'; /* 变 量 赋 初 值 */ while(c!=13&&c!=27) /* 键 盘 接 收 字 符 直 到 按 回 车 或 Esc 键 */ 第 86 页

87 c=getch(); printf("%c\n", c); if(c==27) break; /* 判 断 若 按 Esc 键 则 退 出 循 环 */ i++; printf("the No. is %d\n", i); printf("the end"); 注 意 : 1) break 语 句 对 if-else 的 条 件 语 句 不 起 作 用 2) 在 多 层 循 环 中, 一 个 break 语 句 只 向 外 跳 一 层 continue 语 句 continue 语 句 的 作 用 是 跳 过 循 环 本 中 剩 余 的 语 句 而 强 行 执 行 下 一 次 循 环 continue 语 句 只 用 在 for while do-while 等 循 环 体 中, 常 与 if 条 件 语 句 一 起 使 用, 用 来 加 速 循 环 其 执 行 过 程 可 用 下 图 表 示 1) while( 表 达 式 1) if( 表 达 式 2)break; 2) while( 表 达 式 1) if( 表 达 式 2)continue; 第 87 页

88 例 6.9 main() char c; while(c!=13) /* 不 是 回 车 符 则 循 环 */ c=getch(); if(c==0x1b) continue; /* 若 按 Esc 键 不 输 出 便 进 行 下 次 循 环 */ printf("%c\n", c); 6.9 程 序 举 例 π = 例 6.10 用 公 式 求 π 第 88 页

89 N-S 流 程 图 : #include<math.h> main() int s; float n,t,pi; t=1,pi=0;n=1.0;s=1; while(fabs(t)>1e-6) pi=pi+t; n=n+2; s=-s; t=s/n; pi=pi*4; printf("pi=%10.6f\n",pi); 例 6.11 判 断 m 是 否 素 数 N-S 流 程 图 : #include<math.h> main() int m,i,k; scanf( %d,&m); k=sqrt(m); for(i=2;i<=k;i++) if(m%i==0)break; if(i>=k+1) printf( %d is a prime number\n,m); else printf( %d is not a prime number\n,m); 例 6.12 求 100 至 200 间 的 全 部 素 数 #include<math.h> main() int m,i,k,n=0; for(m=101;m<=200;m=m+2) k=sqrt(m); for(i=2;i<=k;i++) 第 89 页

90 if(m%i==0)break; if(i>=k+1) printf( %d,m); n=n+1; if(n%n==0)printf( \n ); printf( \n ); 7 数 组 在 程 序 设 计 中, 为 了 处 理 方 便, 把 具 有 相 同 类 型 的 若 干 变 量 按 有 序 的 形 式 组 织 起 来 这 些 按 序 排 列 的 同 类 数 据 元 素 的 集 合 称 为 数 组 在 C 语 言 中, 数 组 属 于 构 造 数 据 类 型 一 个 数 组 可 以 分 解 为 多 个 数 组 元 素, 这 些 数 组 元 素 可 以 是 基 本 数 据 类 型 或 是 构 造 类 型 因 此 按 数 组 元 素 的 类 型 不 同, 数 组 又 可 分 为 数 值 数 组 字 符 数 组 指 针 数 组 结 构 数 组 等 各 种 类 别 本 章 介 绍 数 值 数 组 和 字 符 数 组, 其 余 的 在 以 后 各 章 陆 续 介 绍 7.1 一 维 数 组 的 定 义 和 引 用 一 维 数 组 的 定 义 方 式 在 C 语 言 中 使 用 数 组 必 须 先 进 行 定 义 一 维 数 组 的 定 义 方 式 为 : 类 型 说 明 符 数 组 名 [ 常 量 表 达 式 ]; 其 中 : 类 型 说 明 符 是 任 一 种 基 本 数 据 类 型 或 构 造 数 据 类 型 数 组 名 是 用 户 定 义 的 数 组 标 识 符 方 括 号 中 的 常 量 表 达 式 表 示 数 据 元 素 的 个 数, 也 称 为 数 组 的 长 度 例 如 : int a[10]; 说 明 整 型 数 组 a, 有 10 个 元 素 float b[10],c[20]; 说 明 实 型 数 组 b, 有 10 个 元 素, 实 型 数 组 c, 有 20 个 元 素 char ch[20]; 说 明 字 符 数 组 ch, 有 20 个 元 素 对 于 数 组 类 型 说 明 应 注 意 以 下 几 点 : 1) 数 组 的 类 型 实 际 上 是 指 数 组 元 素 的 取 值 类 型 对 于 同 一 个 数 组, 其 所 有 元 素 的 数 据 类 型 都 是 相 同 的 2) 数 组 名 的 书 写 规 则 应 符 合 标 识 符 的 书 写 规 定 3) 数 组 名 不 能 与 其 它 变 量 名 相 同 例 如 : main() 第 90 页

91 int a; float a[10]; 是 错 误 的 4) 方 括 号 中 常 量 表 达 式 表 示 数 组 元 素 的 个 数, 如 a[5] 表 示 数 组 a 有 5 个 元 素 但 是 其 下 标 从 0 开 始 计 算 因 此 5 个 元 素 分 别 为 a[0],a[1],a[2],a[3],a[4] 5) 不 能 在 方 括 号 中 用 变 量 来 表 示 元 素 的 个 数, 但 是 可 以 是 符 号 常 数 或 常 量 表 达 式 例 如 : #define FD 5 main() int a[3+2],b[7+fd]; 是 合 法 的 但 是 下 述 说 明 方 式 是 错 误 的 main() int n=5; int a[n]; 6) 允 许 在 同 一 个 类 型 说 明 中, 说 明 多 个 数 组 和 多 个 变 量 例 如 : int a,b,c,d,k1[10],k2[20]; 一 维 数 组 元 素 的 引 用 数 组 元 素 是 组 成 数 组 的 基 本 单 元 数 组 元 素 也 是 一 种 变 量, 其 标 识 方 法 为 数 组 名 后 跟 一 个 下 标 下 标 表 示 了 元 素 在 数 组 中 的 顺 序 号 数 组 元 素 的 一 般 形 式 为 : 数 组 名 [ 下 标 ] 其 中 下 标 只 能 为 整 型 常 量 或 整 型 表 达 式 如 为 小 数 时,C 编 译 将 自 动 取 整 例 如 : a[5] a[i+j] a[i++] 都 是 合 法 的 数 组 元 素 数 组 元 素 通 常 也 称 为 下 标 变 量 必 须 先 定 义 数 组, 才 能 使 用 下 标 变 量 在 C 语 言 中 只 能 逐 个 地 使 用 下 标 变 量, 而 不 能 一 次 引 用 整 个 数 组 例 如, 输 出 有 10 个 元 素 的 数 组 必 须 使 用 循 环 语 句 逐 个 输 出 各 下 标 变 量 : for(i=0; i<10; i++) printf("%d",a[i]); 第 91 页

92 而 不 能 用 一 个 语 句 输 出 整 个 数 组 下 面 的 写 法 是 错 误 的 : printf("%d",a); 例 7.1 main() int i,a[10]; for(i=0;i<=9;i++) a[i]=i; for(i=9;i>=0;i--) printf("%d ",a[i]); 例 7.2 main() int i,a[10]; for(i=0;i<10;) a[i++]=i; for(i=9;i>=0;i--) printf("%d",a[i]); 例 7.3 main() int i,a[10]; for(i=0;i<10;) a[i++]=2*i+1; for(i=0;i<=9;i++) printf("%d ",a[i]); printf("\n%d %d\n",a[5.2],a[5.8]); 本 例 中 用 一 个 循 环 语 句 给 a 数 组 各 元 素 送 入 奇 数 值, 然 后 用 第 二 个 循 环 语 句 输 出 各 个 奇 数 在 第 一 个 for 语 句 中, 表 达 式 3 省 略 了 在 下 标 变 量 中 使 用 了 表 达 式 i++, 用 以 修 改 循 环 变 量 当 然 第 二 个 for 语 句 也 可 以 这 样 作,C 语 言 允 许 用 表 达 式 表 示 下 标 程 序 中 最 后 一 个 printf 语 句 输 出 了 两 次 a[5] 的 值, 可 以 看 出 当 下 标 不 为 整 数 时 将 自 动 取 整 第 92 页

93 7.1.3 一 维 数 组 的 初 始 化 给 数 组 赋 值 的 方 法 除 了 用 赋 值 语 句 对 数 组 元 素 逐 个 赋 值 外, 还 可 采 用 初 始 化 赋 值 和 动 态 赋 值 的 方 法 数 组 初 始 化 赋 值 是 指 在 数 组 定 义 时 给 数 组 元 素 赋 予 初 值 数 组 初 始 化 是 在 编 译 阶 段 进 行 的 这 样 将 减 少 运 行 时 间, 提 高 效 率 初 始 化 赋 值 的 一 般 形 式 为 : 类 型 说 明 符 数 组 名 [ 常 量 表 达 式 ]= 值, 值 值 ; 其 中 在 中 的 各 数 据 值 即 为 各 元 素 的 初 值, 各 值 之 间 用 逗 号 间 隔 例 如 : int a[10]= 0,1,2,3,4,5,6,7,8,9 ; 相 当 于 a[0]=0;a[1]=1...a[9]=9; C 语 言 对 数 组 的 初 始 化 赋 值 还 有 以 下 几 点 规 定 : 1) 可 以 只 给 部 分 元 素 赋 初 值 当 中 值 的 个 数 少 于 元 素 个 数 时, 只 给 前 面 部 分 元 素 赋 值 例 如 : int a[10]=0,1,2,3,4; 表 示 只 给 a[0]~a[4]5 个 元 素 赋 值, 而 后 5 个 元 素 自 动 赋 0 值 2) 只 能 给 元 素 逐 个 赋 值, 不 能 给 数 组 整 体 赋 值 例 如 给 十 个 元 素 全 部 赋 1 值, 只 能 写 为 : int a[10]=1,1,1,1,1,1,1,1,1,1; 而 不 能 写 为 : int a[10]=1; 3) 如 给 全 部 元 素 赋 值, 则 在 数 组 说 明 中, 可 以 不 给 出 数 组 元 素 的 个 数 例 如 : int a[5]=1,2,3,4,5; 可 写 为 : int a[]=1,2,3,4,5; 一 维 数 组 程 序 举 例 可 以 在 程 序 执 行 过 程 中, 对 数 组 作 动 态 赋 值 这 时 可 用 循 环 语 句 配 合 scanf 函 数 逐 个 对 数 组 元 素 赋 值 例 7.4 main() int i,max,a[10]; printf("input 10 numbers:\n"); for(i=0;i<10;i++) scanf("%d",&a[i]); max=a[0]; for(i=1;i<10;i++) if(a[i]>max) max=a[i]; printf("maxmum=%d\n",max); 第 93 页

94 本 例 程 序 中 第 一 个 for 语 句 逐 个 输 入 10 个 数 到 数 组 a 中 然 后 把 a[0] 送 入 max 中 在 第 二 个 for 语 句 中, 从 a[1] 到 a[9] 逐 个 与 max 中 的 内 容 比 较, 若 比 max 的 值 大, 则 把 该 下 标 变 量 送 入 max 中, 因 此 max 总 是 在 已 比 较 过 的 下 标 变 量 中 为 最 大 者 比 较 结 束, 输 出 max 的 值 例 7.5 main() int i,j,p,q,s,a[10]; printf("\n input 10 numbers:\n"); for(i=0;i<10;i++) scanf("%d",&a[i]); for(i=0;i<10;i++) p=i;q=a[i]; for(j=i+1;j<10;j++) if(q<a[j]) p=j;q=a[j]; if(i!=p) s=a[i]; a[i]=a[p]; a[p]=s; printf("%d",a[i]); 本 例 程 序 中 用 了 两 个 并 列 的 for 循 环 语 句, 在 第 二 个 for 语 句 中 又 嵌 套 了 一 个 循 环 语 句 第 一 个 for 语 句 用 于 输 入 10 个 元 素 的 初 值 第 二 个 for 语 句 用 于 排 序 本 程 序 的 排 序 采 用 逐 个 比 较 的 方 法 进 行 在 i 次 循 环 时, 把 第 一 个 元 素 的 下 标 i 赋 于 p, 而 把 该 下 标 变 量 值 a[i] 赋 于 q 然 后 进 入 小 循 环, 从 a[i+1] 起 到 最 后 一 个 元 素 止 逐 个 与 a[i] 作 比 较, 有 比 a[i] 大 者 则 将 其 下 标 送 p, 元 素 值 送 q 一 次 循 环 结 束 后,p 即 为 最 大 元 素 的 下 标,q 则 为 该 元 素 值 若 此 时 i p, 说 明 p,q 值 均 已 不 是 进 入 小 循 环 之 前 所 赋 之 值, 则 交 换 a[i] 和 a[p] 之 值 此 时 a[i] 为 已 排 序 完 毕 的 元 素 输 出 该 值 之 后 转 入 下 一 次 循 环 对 i+1 以 后 各 个 元 素 排 序 7.2 二 维 数 组 的 定 义 和 引 用 二 维 数 组 的 定 义 前 面 介 绍 的 数 组 只 有 一 个 下 标, 称 为 一 维 数 组, 其 数 组 元 素 也 称 为 单 下 标 变 量 在 实 际 问 题 中 有 很 多 量 是 二 维 的 或 多 维 的, 因 此 C 语 言 允 许 构 造 多 维 数 组 多 维 数 组 元 素 有 多 个 下 标, 以 标 识 它 在 数 组 中 的 位 置, 所 以 也 称 为 多 下 标 变 量 本 小 节 只 介 绍 二 维 数 组, 多 维 数 组 可 由 二 维 数 组 类 推 而 得 到 二 维 数 组 定 义 的 一 般 形 式 是 : 类 型 说 明 符 数 组 名 [ 常 量 表 达 式 1][ 常 量 表 达 式 2] 其 中 常 量 表 达 式 1 表 示 第 一 维 下 标 的 长 度, 常 量 表 达 式 2 表 示 第 二 维 下 标 的 长 度 例 如 : 第 94 页

95 int a[3][4]; 说 明 了 一 个 三 行 四 列 的 数 组, 数 组 名 为 a, 其 下 标 变 量 的 类 型 为 整 型 该 数 组 的 下 标 变 量 共 有 3 4 个, 即 : a[0][0],a[0][1],a[0][2],a[0][3] a[1][0],a[1][1],a[1][2],a[1][3] a[2][0],a[2][1],a[2][2],a[2][3] 二 维 数 组 在 概 念 上 是 二 维 的, 即 是 说 其 下 标 在 两 个 方 向 上 变 化, 下 标 变 量 在 数 组 中 的 位 置 也 处 于 一 个 平 面 之 中, 而 不 是 象 一 维 数 组 只 是 一 个 向 量 但 是, 实 际 的 硬 件 存 储 器 却 是 连 续 编 址 的, 也 就 是 说 存 储 器 单 元 是 按 一 维 线 性 排 列 的 如 何 在 一 维 存 储 器 中 存 放 二 维 数 组, 可 有 两 种 方 式 : 一 种 是 按 行 排 列, 即 放 完 一 行 之 后 顺 次 放 入 第 二 行 另 一 种 是 按 列 排 列, 即 放 完 一 列 之 后 再 顺 次 放 入 第 二 列 在 C 语 言 中, 二 维 数 组 是 按 行 排 列 的 即 : 先 存 放 a[0] 行, 再 存 放 a[1] 行, 最 后 存 放 a[2] 行 每 行 中 有 四 个 元 素 也 是 依 次 存 放 由 于 数 组 a 说 明 为 int 类 型, 该 类 型 占 两 个 字 节 的 内 存 空 间, 所 以 每 个 元 素 均 占 有 两 个 字 节 ) 二 维 数 组 元 素 的 引 用 二 维 数 组 的 元 素 也 称 为 双 下 标 变 量, 其 表 示 的 形 式 为 : 数 组 名 [ 下 标 ][ 下 标 ] 其 中 下 标 应 为 整 型 常 量 或 整 型 表 达 式 例 如 : a[3][4] 表 示 a 数 组 三 行 四 列 的 元 素 下 标 变 量 和 数 组 说 明 在 形 式 中 有 些 相 似, 但 这 两 者 具 有 完 全 不 同 的 含 义 数 组 说 明 的 方 括 号 中 给 出 的 是 某 一 维 的 长 度, 即 可 取 下 标 的 最 大 值 ; 而 数 组 元 素 中 的 下 标 是 该 元 素 在 数 组 中 的 位 置 标 识 前 者 只 能 是 常 量, 后 者 可 以 是 常 量, 变 量 或 表 达 式 例 7.6 一 个 学 习 小 组 有 5 个 人, 每 个 人 有 三 门 课 的 考 试 成 绩 求 全 组 分 科 的 平 均 成 绩 和 各 科 总 平 均 成 绩 张 王 李 赵 周 Math C Foxpro 可 设 一 个 二 维 数 组 a[5][3] 存 放 五 个 人 三 门 课 的 成 绩 再 设 一 个 一 维 数 组 v[3] 存 放 所 求 得 各 分 科 平 均 成 绩, 设 变 量 average 为 全 组 各 科 总 平 均 成 绩 编 程 如 下 : main() int i,j,s=0,average,v[3],a[5][3]; printf("input score\n"); for(i=0;i<3;i++) for(j=0;j<5;j++) scanf("%d",&a[j][i]); s=s+a[j][i]; v[i]=s/5; 第 95 页

96 s=0; average =(v[0]+v[1]+v[2])/3; printf("math:%d\nc languag:%d\ndbase:%d\n",v[0],v[1],v[2]); printf("total:%d\n", average ); 程 序 中 首 先 用 了 一 个 双 重 循 环 在 内 循 环 中 依 次 读 入 某 一 门 课 程 的 各 个 学 生 的 成 绩, 并 把 这 些 成 绩 累 加 起 来, 退 出 内 循 环 后 再 把 该 累 加 成 绩 除 以 5 送 入 v[i] 之 中, 这 就 是 该 门 课 程 的 平 均 成 绩 外 循 环 共 循 环 三 次, 分 别 求 出 三 门 课 各 自 的 平 均 成 绩 并 存 放 在 v 数 组 之 中 退 出 外 循 环 之 后, 把 v[0],v[1],v[2] 相 加 除 以 3 即 得 到 各 科 总 平 均 成 绩 最 后 按 题 意 输 出 各 个 成 绩 二 维 数 组 的 初 始 化 二 维 数 组 初 始 化 也 是 在 类 型 说 明 时 给 各 下 标 变 量 赋 以 初 值 二 维 数 组 可 按 行 分 段 赋 值, 也 可 按 行 连 续 赋 值 例 如 对 数 组 a[5][3]: 1) 按 行 分 段 赋 值 可 写 为 : int a[5][3]= 80,75,92,61,65,71,59,63,70,85,87,90,76,77,85 ; 2) 按 行 连 续 赋 值 可 写 为 : int a[5][3]= 80,75,92,61,65,71,59,63,70,85,87,90,76,77,85; 这 两 种 赋 初 值 的 结 果 是 完 全 相 同 的 例 7.7 main() int i,j,s=0, average,v[3]; int a[5][3]=80,75,92,61,65,71,59,63,70,85,87,90,76,77,85; for(i=0;i<3;i++) for(j=0;j<5;j++) s=s+a[j][i]; v[i]=s/5; s=0; average=(v[0]+v[1]+v[2])/3; printf("math:%d\nc languag:%d\ndfoxpro:%d\n",v[0],v[1],v[2]); printf("total:%d\n", average); 对 于 二 维 数 组 初 始 化 赋 值 还 有 以 下 说 明 : 1) 可 以 只 对 部 分 元 素 赋 初 值, 未 赋 初 值 的 元 素 自 动 取 0 值 例 如 : int a[3][3]=1,2,3; 第 96 页

97 是 对 每 一 行 的 第 一 列 元 素 赋 值, 未 赋 值 的 元 素 取 0 值 赋 值 后 各 元 素 的 值 为 : int a [3][3]=0,1,0,0,2,3; 赋 值 后 的 元 素 值 为 : ) 如 对 全 部 元 素 赋 初 值, 则 第 一 维 的 长 度 可 以 不 给 出 例 如 : int a[3][3]=1,2,3,4,5,6,7,8,9; 可 以 写 为 : int a[][3]=1,2,3,4,5,6,7,8,9; 3) 数 组 是 一 种 构 造 类 型 的 数 据 二 维 数 组 可 以 看 作 是 由 一 维 数 组 的 嵌 套 而 构 成 的 设 一 维 数 组 的 每 个 元 素 都 又 是 一 个 数 组, 就 组 成 了 二 维 数 组 当 然, 前 提 是 各 元 素 类 型 必 须 相 同 根 据 这 样 的 分 析, 一 个 二 维 数 组 也 可 以 分 解 为 多 个 一 维 数 组 C 语 言 允 许 这 种 分 解 如 二 维 数 组 a[3][4], 可 分 解 为 三 个 一 维 数 组, 其 数 组 名 分 别 为 : a[0] a[1] a[2] 对 这 三 个 一 维 数 组 不 需 另 作 说 明 即 可 使 用 这 三 个 一 维 数 组 都 有 4 个 元 素, 例 如 : 一 维 数 组 a[0] 的 元 素 为 a[0][0],a[0][1],a[0][2],a[0][3] 必 须 强 调 的 是,a[0],a[1],a[2] 不 能 当 作 下 标 变 量 使 用, 它 们 是 数 组 名, 不 是 一 个 单 纯 的 下 标 变 量 二 维 数 组 程 序 举 例 7.3 字 符 数 组 用 来 存 放 字 符 量 的 数 组 称 为 字 符 数 组 字 符 数 组 的 定 义 形 式 与 前 面 介 绍 的 数 值 数 组 相 同 例 如 : char c[10]; 由 于 字 符 型 和 整 型 通 用, 也 可 以 定 义 为 int c[10] 但 这 时 每 个 数 组 元 素 占 2 个 字 节 的 内 存 单 元 字 符 数 组 也 可 以 是 二 维 或 多 维 数 组 例 如 : char c[5][10]; 即 为 二 维 字 符 数 组 第 97 页

98 7.3.2 字 符 数 组 的 初 始 化 字 符 数 组 也 允 许 在 定 义 时 作 初 始 化 赋 值 例 如 : char c[10]= c,, p, r, o, g, r, a, m ; 赋 值 后 各 元 素 的 值 为 : 数 组 C c[0] 的 值 为 c c[1] 的 值 为 c[2] 的 值 为 p c[3] 的 值 为 r c[4] 的 值 为 0 c[5] 的 值 为 g c[6] 的 值 为 r c[7] 的 值 为 a c[8] 的 值 为 m 其 中 c[9] 未 赋 值, 由 的 值 为 p 系 统 自 动 赋 予 0 值 当 对 全 体 元 素 赋 初 值 时 也 可 以 省 去 长 度 说 明 例 如 : char c[]=`c`,` `,`p`,`r`,`o`,`g`,`r`,`a`,`m`; 这 时 C 数 组 的 长 度 自 动 定 为 字 符 数 组 的 引 用 例 7.8 main() int i,j; char a[][5]='b','a','s','i','c',,'d','b','a','s','e'; for(i=0;i<=1;i++) for(j=0;j<=4;j++) printf("%c",a[i][j]); printf("\n"); 本 例 的 二 维 字 符 数 组 由 于 在 初 始 化 时 全 部 元 素 都 赋 以 初 值, 因 此 一 维 下 标 的 长 度 可 以 不 加 以 说 明 字 符 串 和 字 符 串 结 束 标 志 在 C 语 言 中 没 有 专 门 的 字 符 串 变 量, 通 常 用 一 个 字 符 数 组 来 存 放 一 个 字 符 串 前 面 介 绍 字 符 串 常 量 时, 第 98 页

99 已 说 明 字 符 串 总 是 以 '\0' 作 为 串 的 结 束 符 因 此 当 把 一 个 字 符 串 存 入 一 个 数 组 时, 也 把 结 束 符 '\0' 存 入 数 组, 并 以 此 作 为 该 字 符 串 是 否 结 束 的 标 志 有 了 '\0' 标 志 后, 就 不 必 再 用 字 符 数 组 的 长 度 来 判 断 字 符 串 的 长 度 了 C 语 言 允 许 用 字 符 串 的 方 式 对 数 组 作 初 始 化 赋 值 例 如 : char c[]='c', ' ','p','r','o','g','r','a','m'; 可 写 为 : char c[]="c program"; 或 去 掉 写 为 : char c[]="c program"; 用 字 符 串 方 式 赋 值 比 用 字 符 逐 个 赋 值 要 多 占 一 个 字 节, 用 于 存 放 字 符 串 结 束 标 志 '\0' 上 面 的 数 组 c 在 内 存 中 的 实 际 存 放 情 况 为 : C p r o g r a m \0 \0' 是 由 C 编 译 系 统 自 动 加 上 的 由 于 采 用 了 \0' 标 志, 所 以 在 用 字 符 串 赋 初 值 时 一 般 无 须 指 定 数 组 的 长 度, 而 由 系 统 自 行 处 理 字 符 数 组 的 输 入 输 出 在 采 用 字 符 串 方 式 后, 字 符 数 组 的 输 入 输 出 将 变 得 简 单 方 便 除 了 上 述 用 字 符 串 赋 初 值 的 办 法 外, 还 可 用 printf 函 数 和 scanf 函 数 一 次 性 输 出 输 入 一 个 字 符 数 组 中 的 字 符 串, 而 不 必 使 用 循 环 语 句 逐 个 地 输 入 输 出 每 个 字 符 例 7.9 main() char c[]="basic\ndbase"; printf("%s\n",c); 注 意 在 本 例 的 printf 函 数 中, 使 用 的 格 式 字 符 串 为 %s, 表 示 输 出 的 是 一 个 字 符 串 而 在 输 出 表 列 中 给 出 数 组 名 则 可 不 能 写 为 : printf("%s",c[]); 例 7.10 main() char st[15]; printf("input string:\n"); scanf("%s",st); printf("%s\n",st); 本 例 中 由 于 定 义 数 组 长 度 为 15, 因 此 输 入 的 字 符 串 长 度 必 须 小 于 15, 以 留 出 一 个 字 节 用 于 存 放 字 符 串 结 束 标 志 `\0` 应 该 说 明 的 是, 对 一 个 字 符 数 组, 如 果 不 作 初 始 化 赋 值, 则 必 须 说 明 数 组 长 度 还 应 该 特 别 注 意 的 是, 当 用 scanf 函 数 输 入 字 符 串 时, 字 符 串 中 不 能 含 有 空 格, 否 则 将 以 空 格 作 为 串 的 结 束 符 第 99 页

100 例 如 当 输 入 的 字 符 串 中 含 有 空 格 时, 运 行 情 况 为 : input string: this is a book 输 出 为 : this 从 输 出 结 果 可 以 看 出 空 格 以 后 的 字 符 都 未 能 输 出 为 了 避 免 这 种 情 况, 可 多 设 几 个 字 符 数 组 分 段 存 放 含 空 格 的 串 程 序 可 改 写 如 下 : 例 7.11 main() char st1[6],st2[6],st3[6],st4[6]; printf("input string:\n"); scanf("%s%s%s%s",st1,st2,st3,st4); printf("%s %s %s %s\n",st1,st2,st3,st4); 本 程 序 分 别 设 了 四 个 数 组, 输 入 的 一 行 字 符 的 空 格 分 段 分 别 装 入 四 个 数 组 然 后 分 别 输 出 这 四 个 数 组 中 的 字 符 串 在 前 面 介 绍 过,scanf 的 各 输 入 项 必 须 以 地 址 方 式 出 现, 如 &a,&b 等 但 在 前 例 中 却 是 以 数 组 名 方 式 出 现 的, 这 是 为 什 么 呢? 这 是 由 于 在 C 语 言 中 规 定, 数 组 名 就 代 表 了 该 数 组 的 首 地 址 整 个 数 组 是 以 首 地 址 开 头 的 一 块 连 续 的 内 存 单 元 如 有 字 符 数 组 char c[10], 在 内 存 可 表 示 如 图 C[0] C[1] C[2] C[3] C[4] C[5] C[6] C[7] C[8] C[9] 设 数 组 c 的 首 地 址 为 2000, 也 就 是 说 c[0] 单 元 地 址 为 2000 则 数 组 名 c 就 代 表 这 个 首 地 址 因 此 在 c 前 面 不 能 再 加 地 址 运 算 符 & 如 写 作 scanf("%s",&c); 则 是 错 误 的 在 执 行 函 数 printf("%s",c) 时, 按 数 组 名 c 找 到 首 地 址, 然 后 逐 个 输 出 数 组 中 各 个 字 符 直 到 遇 到 字 符 串 终 止 标 志 '\0' 为 止 字 符 串 处 理 函 数 C 语 言 提 供 了 丰 富 的 字 符 串 处 理 函 数, 大 致 可 分 为 字 符 串 的 输 入 输 出 合 并 修 改 比 较 转 换 复 制 搜 索 几 类 使 用 这 些 函 数 可 大 大 减 轻 编 程 的 负 担 用 于 输 入 输 出 的 字 符 串 函 数, 在 使 用 前 应 包 含 头 文 件 "stdio.h", 使 用 其 它 字 符 串 函 数 则 应 包 含 头 文 件 "string.h" 下 面 介 绍 几 个 最 常 用 的 字 符 串 函 数 1. 字 符 串 输 出 函 数 puts 格 式 : puts ( 字 符 数 组 名 ) 功 能 : 把 字 符 数 组 中 的 字 符 串 输 出 到 显 示 器 即 在 屏 幕 上 显 示 该 字 符 串 例 7.12 #include"stdio.h" main() 第 100 页

101 char c[]="basic\ndbase"; puts(c); 从 程 序 中 可 以 看 出 puts 函 数 中 可 以 使 用 转 义 字 符, 因 此 输 出 结 果 成 为 两 行 puts 函 数 完 全 可 以 由 printf 函 数 取 代 当 需 要 按 一 定 格 式 输 出 时, 通 常 使 用 printf 函 数 2. 字 符 串 输 入 函 数 gets 格 式 : gets ( 字 符 数 组 名 ) 功 能 : 从 标 准 输 入 设 备 键 盘 上 输 入 一 个 字 符 串 本 函 数 得 到 一 个 函 数 值, 即 为 该 字 符 数 组 的 首 地 址 例 7.13 #include"stdio.h" main() char st[15]; printf("input string:\n"); gets(st); puts(st); 可 以 看 出 当 输 入 的 字 符 串 中 含 有 空 格 时, 输 出 仍 为 全 部 字 符 串 说 明 gets 函 数 并 不 以 空 格 作 为 字 符 串 输 入 结 束 的 标 志, 而 只 以 回 车 作 为 输 入 结 束 这 是 与 scanf 函 数 不 同 的 3. 字 符 串 连 接 函 数 strcat 格 式 : strcat ( 字 符 数 组 名 1, 字 符 数 组 名 2) 功 能 : 把 字 符 数 组 2 中 的 字 符 串 连 接 到 字 符 数 组 1 中 字 符 串 的 后 面, 并 删 去 字 符 串 1 后 的 串 标 志 \0 本 函 数 返 回 值 是 字 符 数 组 1 的 首 地 址 例 7.14 #include"string.h" main() static char st1[30]="my name is "; int st2[10]; printf("input your name:\n"); gets(st2); strcat(st1,st2); puts(st1); 本 程 序 把 初 始 化 赋 值 的 字 符 数 组 与 动 态 赋 值 的 字 符 串 连 接 起 来 要 注 意 的 是, 字 符 数 组 1 应 定 义 足 够 的 长 度, 否 则 不 能 全 部 装 入 被 连 接 的 字 符 串 4. 字 符 串 拷 贝 函 数 strcpy 第 101 页

102 格 式 : strcpy ( 字 符 数 组 名 1, 字 符 数 组 名 2) 功 能 : 把 字 符 数 组 2 中 的 字 符 串 拷 贝 到 字 符 数 组 1 中 串 结 束 标 志 \0 也 一 同 拷 贝 字 符 数 名 2, 也 可 以 是 一 个 字 符 串 常 量 这 时 相 当 于 把 一 个 字 符 串 赋 予 一 个 字 符 数 组 例 7.15 #include"string.h" main() char st1[15],st2[]="c Language"; strcpy(st1,st2); puts(st1);printf("\n"); 本 函 数 要 求 字 符 数 组 1 应 有 足 够 的 长 度, 否 则 不 能 全 部 装 入 所 拷 贝 的 字 符 串 5. 字 符 串 比 较 函 数 strcmp 格 式 : strcmp( 字 符 数 组 名 1, 字 符 数 组 名 2) 功 能 : 按 照 ASCII 码 顺 序 比 较 两 个 数 组 中 的 字 符 串, 并 由 函 数 返 回 值 返 回 比 较 结 果 字 符 串 1= 字 符 串 2, 返 回 值 =0; 字 符 串 2 字 符 串 2, 返 回 值 0; 字 符 串 1 字 符 串 2, 返 回 值 0 本 函 数 也 可 用 于 比 较 两 个 字 符 串 常 量, 或 比 较 数 组 和 字 符 串 常 量 例 7.16 #include"string.h" main() int k; static char st1[15],st2[]="c Language"; printf("input a string:\n"); gets(st1); k=strcmp(st1,st2); if(k==0) printf("st1=st2\n"); if(k>0) printf("st1>st2\n"); if(k<0) printf("st1<st2\n"); 本 程 序 中 把 输 入 的 字 符 串 和 数 组 st2 中 的 串 比 较, 比 较 结 果 返 回 到 k 中, 根 据 k 值 再 输 出 结 果 提 示 串 当 输 入 为 dbase 时, 由 ASCII 码 可 知 dbase 大 于 C Language 故 k 0, 输 出 结 果 st1>st2 6. 测 字 符 串 长 度 函 数 strlen 格 式 : strlen( 字 符 数 组 名 ) 功 能 : 测 字 符 串 的 实 际 长 度 ( 不 含 字 符 串 结 束 标 志 \0 ) 并 作 为 函 数 返 回 值 例 7.17 #include"string.h" main() 第 102 页

103 int k; static char st[]="c language"; k=strlen(st); printf("the lenth of the string is %d\n",k); 7.4 程 序 举 例 例 7.18 把 一 个 整 数 按 大 小 顺 序 插 入 已 排 好 序 的 数 组 中 为 了 把 一 个 数 按 大 小 插 入 已 排 好 序 的 数 组 中, 应 首 先 确 定 排 序 是 从 大 到 小 还 是 从 小 到 大 进 行 的 设 排 序 是 从 大 到 小 进 序 的, 则 可 把 欲 插 入 的 数 与 数 组 中 各 数 逐 个 比 较, 当 找 到 第 一 个 比 插 入 数 小 的 元 素 i 时, 该 元 素 之 前 即 为 插 入 位 置 然 后 从 数 组 最 后 一 个 元 素 开 始 到 该 元 素 为 止, 逐 个 后 移 一 个 单 元 最 后 把 插 入 数 赋 予 元 素 i 即 可 如 果 被 插 入 数 比 所 有 的 元 素 值 都 小 则 插 入 最 后 位 置 main() int i,j,p,q,s,n,a[11]=127,3,6,28,54,68,87,105,162,18; for(i=0;i<10;i++) p=i;q=a[i]; for(j=i+1;j<10;j++) if(q<a[j]) p=j;q=a[j]; if(p!=i) s=a[i]; a[i]=a[p]; a[p]=s; printf("%d ",a[i]); printf("\ninput number:\n"); scanf("%d",&n); for(i=0;i<10;i++) if(n>a[i]) for(s=9;s>=i;s--) a[s+1]=a[s]; break; a[i]=n; for(i=0;i<=10;i++) printf("%d ",a[i]); printf("\n"); 本 程 序 首 先 对 数 组 a 中 的 10 个 数 从 大 到 小 排 序 并 输 出 排 序 结 果 然 后 输 入 要 插 入 的 整 数 n 再 用 一 个 for 第 103 页

104 语 句 把 n 和 数 组 元 素 逐 个 比 较, 如 果 发 现 有 n>a[i] 时, 则 由 一 个 内 循 环 把 i 以 下 各 元 素 值 顺 次 后 移 一 个 单 元 后 移 应 从 后 向 前 进 行 ( 从 a[9] 开 始 到 a[i] 为 止 ) 后 移 结 束 跳 出 外 循 环 插 入 点 为 i, 把 n 赋 予 a[i] 即 可 如 所 有 的 元 素 均 大 于 被 插 入 数, 则 并 未 进 行 过 后 移 工 作 此 时 i=10, 结 果 是 把 n 赋 于 a[10] 最 后 一 个 循 环 输 出 插 入 数 后 的 数 组 各 元 素 值 程 序 运 行 时, 输 入 数 47 从 结 果 中 可 以 看 出 47 已 插 入 到 54 和 28 之 间 例 7.19 在 二 维 数 组 a 中 选 出 各 行 最 大 的 元 素 组 成 一 个 一 维 数 组 b a=( ) b=( ) 本 题 的 编 程 思 路 是, 在 数 组 A 的 每 一 行 中 寻 找 最 大 的 元 素, 找 到 之 后 把 该 值 赋 予 数 组 B 相 应 的 元 素 即 可 程 序 如 下 : main() int a[][4]=3,16,87,65,4,32,11,108,10,25,12,27; int b[3],i,j,l; for(i=0;i<=2;i++) l=a[i][0]; for(j=1;j<=3;j++) if(a[i][j]>l) l=a[i][j]; b[i]=l; printf("\narray a:\n"); for(i=0;i<=2;i++) for(j=0;j<=3;j++) printf("%5d",a[i][j]); printf("\n"); printf("\narray b:\n"); for(i=0;i<=2;i++) printf("%5d",b[i]); printf("\n"); 程 序 中 第 一 个 for 语 句 中 又 嵌 套 了 一 个 for 语 句 组 成 了 双 重 循 环 外 循 环 控 制 逐 行 处 理, 并 把 每 行 的 第 0 列 元 素 赋 予 l 进 入 内 循 环 后, 把 l 与 后 面 各 列 元 素 比 较, 并 把 比 l 大 者 赋 予 l 内 循 环 结 束 时 l 即 为 该 行 最 大 的 元 素, 然 后 把 l 值 赋 予 b[i] 等 外 循 环 全 部 完 成 时, 数 组 b 中 已 装 入 了 a 各 行 中 的 最 大 值 后 面 的 两 个 for 语 句 分 别 输 出 数 组 a 和 数 组 b 例 7.20 输 入 五 个 国 家 的 名 称 按 字 母 顺 序 排 列 输 出 本 题 编 程 思 路 如 下 : 五 个 国 家 名 应 由 一 个 二 维 字 符 数 组 来 处 理 然 而 C 语 言 规 定 可 以 把 一 个 二 维 数 组 当 成 多 个 一 维 数 组 处 理 因 此 本 题 又 可 以 按 五 个 一 维 数 组 处 理, 而 每 一 个 一 维 数 组 就 是 一 个 国 家 名 字 符 串 用 字 符 串 比 较 函 数 比 较 各 一 维 数 组 的 大 小, 并 排 序, 输 出 结 果 即 可 编 程 如 下 : main() 第 104 页

105 char st[20],cs[5][20]; int i,j,p; printf("input country's name:\n"); for(i=0;i<5;i++) gets(cs[i]); printf("\n"); for(i=0;i<5;i++) p=i;strcpy(st,cs[i]); for(j=i+1;j<5;j++) if(strcmp(cs[j],st)<0) p=j;strcpy(st,cs[j]); if(p!=i) strcpy(st,cs[i]); strcpy(cs[i],cs[p]); strcpy(cs[p],st); puts(cs[i]);printf("\n"); 本 程 序 的 第 一 个 for 语 句 中, 用 gets 函 数 输 入 五 个 国 家 名 字 符 串 上 面 说 过 C 语 言 允 许 把 一 个 二 维 数 组 按 多 个 一 维 数 组 处 理, 本 程 序 说 明 cs[5][20] 为 二 维 字 符 数 组, 可 分 为 五 个 一 维 数 组 cs[0],cs[1],cs[2], cs[3],cs[4] 因 此 在 gets 函 数 中 使 用 cs[i] 是 合 法 的 在 第 二 个 for 语 句 中 又 嵌 套 了 一 个 for 语 句 组 成 双 重 循 环 这 个 双 重 循 环 完 成 按 字 母 顺 序 排 序 的 工 作 在 外 层 循 环 中 把 字 符 数 组 cs[i] 中 的 国 名 字 符 串 拷 贝 到 数 组 st 中, 并 把 下 标 i 赋 予 P 进 入 内 层 循 环 后, 把 st 与 cs[i] 以 后 的 各 字 符 串 作 比 较, 若 有 比 st 小 者 则 把 该 字 符 串 拷 贝 到 st 中, 并 把 其 下 标 赋 予 p 内 循 环 完 成 后 如 p 不 等 于 i 说 明 有 比 cs[i] 更 小 的 字 符 串 出 现, 因 此 交 换 cs[i] 和 st 的 内 容 至 此 已 确 定 了 数 组 cs 的 第 i 号 元 素 的 排 序 值 然 后 输 出 该 字 符 串 在 外 循 环 全 部 完 成 之 后 即 完 成 全 部 排 序 和 输 出 7.5 本 章 小 结 1. 数 组 是 程 序 设 计 中 最 常 用 的 数 据 结 构 数 组 可 分 为 数 值 数 组 ( 整 数 组, 实 数 组 ), 字 符 数 组 以 及 后 面 将 要 介 绍 的 指 针 数 组, 结 构 数 组 等 2. 数 组 可 以 是 一 维 的, 二 维 的 或 多 维 的 3. 数 组 类 型 说 明 由 类 型 说 明 符 数 组 名 数 组 长 度 ( 数 组 元 素 个 数 ) 三 部 分 组 成 数 组 元 素 又 称 为 下 标 变 量 数 组 的 类 型 是 指 下 标 变 量 取 值 的 类 型 4. 对 数 组 的 赋 值 可 以 用 数 组 初 始 化 赋 值, 输 入 函 数 动 态 赋 值 和 赋 值 语 句 赋 值 三 种 方 法 实 现 对 数 值 数 组 不 能 用 赋 值 语 句 整 体 赋 值 输 入 或 输 出, 而 必 须 用 循 环 语 句 逐 个 对 数 组 元 素 进 行 操 作 第 105 页

106 8 函 数 8.1 概 述 在 前 面 已 经 介 绍 过,C 源 程 序 是 由 函 数 组 成 的 虽 然 在 前 面 各 章 的 程 序 中 大 都 只 有 一 个 主 函 数 main(), 但 实 用 程 序 往 往 由 多 个 函 数 组 成 函 数 是 C 源 程 序 的 基 本 模 块, 通 过 对 函 数 模 块 的 调 用 实 现 特 定 的 功 能 C 语 言 中 的 函 数 相 当 于 其 它 高 级 语 言 的 子 程 序 C 语 言 不 仅 提 供 了 极 为 丰 富 的 库 函 数 ( 如 Turbo C,MS C 都 提 供 了 三 百 多 个 库 函 数 ), 还 允 许 用 户 建 立 自 己 定 义 的 函 数 用 户 可 把 自 己 的 算 法 编 成 一 个 个 相 对 独 立 的 函 数 模 块, 然 后 用 调 用 的 方 法 来 使 用 函 数 可 以 说 C 程 序 的 全 部 工 作 都 是 由 各 式 各 样 的 函 数 完 成 的, 所 以 也 把 C 语 言 称 为 函 数 式 语 言 由 于 采 用 了 函 数 模 块 式 的 结 构,C 语 言 易 于 实 现 结 构 化 程 序 设 计 使 程 序 的 层 次 结 构 清 晰, 便 于 程 序 的 编 写 阅 读 调 试 在 C 语 言 中 可 从 不 同 的 角 度 对 函 数 分 类 1. 从 函 数 定 义 的 角 度 看, 函 数 可 分 为 库 函 数 和 用 户 定 义 函 数 两 种 1) 库 函 数 : 由 C 系 统 提 供, 用 户 无 须 定 义, 也 不 必 在 程 序 中 作 类 型 说 明, 只 需 在 程 序 前 包 含 有 该 函 数 原 型 的 头 文 件 即 可 在 程 序 中 直 接 调 用 在 前 面 各 章 的 例 题 中 反 复 用 到 printf scanf getchar putchar gets puts strcat 等 函 数 均 属 此 类 2) 用 户 定 义 函 数 : 由 用 户 按 需 要 写 的 函 数 对 于 用 户 自 定 义 函 数, 不 仅 要 在 程 序 中 定 义 函 数 本 身, 而 且 在 主 调 函 数 模 块 中 还 必 须 对 该 被 调 函 数 进 行 类 型 说 明, 然 后 才 能 使 用 2. C 语 言 的 函 数 兼 有 其 它 语 言 中 的 函 数 和 过 程 两 种 功 能, 从 这 个 角 度 看, 又 可 把 函 数 分 为 有 返 回 值 函 数 和 无 返 回 值 函 数 两 种 1) 有 返 回 值 函 数 : 此 类 函 数 被 调 用 执 行 完 后 将 向 调 用 者 返 回 一 个 执 行 结 果, 称 为 函 数 返 回 值 如 数 学 函 数 即 属 于 此 类 函 数 由 用 户 定 义 的 这 种 要 返 回 函 数 值 的 函 数, 必 须 在 函 数 定 义 和 函 数 说 明 中 明 确 返 回 值 的 类 型 2) 无 返 回 值 函 数 : 此 类 函 数 用 于 完 成 某 项 特 定 的 处 理 任 务, 执 行 完 成 后 不 向 调 用 者 返 回 函 数 值 这 类 函 数 类 似 于 其 它 语 言 的 过 程 由 于 函 数 无 须 返 回 值, 用 户 在 定 义 此 类 函 数 时 可 指 定 它 的 返 回 为 空 类 型, 空 类 型 的 说 明 符 为 void 3. 从 主 调 函 数 和 被 调 函 数 之 间 数 据 传 送 的 角 度 看 又 可 分 为 无 参 函 数 和 有 参 函 数 两 种 1) 无 参 函 数 : 函 数 定 义 函 数 说 明 及 函 数 调 用 中 均 不 带 参 数 主 调 函 数 和 被 调 函 数 之 间 不 进 行 参 数 传 送 此 类 函 数 通 常 用 来 完 成 一 组 指 定 的 功 能, 可 以 返 回 或 不 返 回 函 数 值 2) 有 参 函 数 : 也 称 为 带 参 函 数 在 函 数 定 义 及 函 数 说 明 时 都 有 参 数, 称 为 形 式 参 数 ( 简 称 为 形 参 ) 在 函 数 调 用 时 也 必 须 给 出 参 数, 称 为 实 际 参 数 ( 简 称 为 实 参 ) 进 行 函 数 调 用 时, 主 调 函 数 将 把 实 参 的 值 传 送 给 形 参, 供 被 调 函 数 使 用 4. C 语 言 提 供 了 极 为 丰 富 的 库 函 数, 这 些 库 函 数 又 可 从 功 能 角 度 作 以 下 分 类 1) 字 符 类 型 分 类 函 数 : 用 于 对 字 符 按 ASCII 码 分 类 : 字 母, 数 字, 控 制 字 符, 分 隔 符, 大 小 写 字 母 等 2) 转 换 函 数 : 用 于 字 符 或 字 符 串 的 转 换 ; 在 字 符 量 和 各 类 数 字 量 ( 整 型, 实 型 等 ) 之 间 进 行 转 换 ; 在 大 小 写 之 间 进 行 转 换 3) 目 录 路 径 函 数 : 用 于 文 件 目 录 和 路 径 操 作 4) 诊 断 函 数 : 用 于 内 部 错 误 检 测 5) 图 形 函 数 : 用 于 屏 幕 管 理 和 各 种 图 形 功 能 6) 输 入 输 出 函 数 : 用 于 完 成 输 入 输 出 功 能 7) 接 口 函 数 : 用 于 与 DOS,BIOS 和 硬 件 的 接 口 第 106 页

107 8) 字 符 串 函 数 : 用 于 字 符 串 操 作 和 处 理 9) 内 存 管 理 函 数 : 用 于 内 存 管 理 10) 数 学 函 数 : 用 于 数 学 函 数 计 算 11) 日 期 和 时 间 函 数 : 用 于 日 期, 时 间 转 换 操 作 12) 进 程 控 制 函 数 : 用 于 进 程 管 理 和 控 制 13) 其 它 函 数 : 用 于 其 它 各 种 功 能 以 上 各 类 函 数 不 仅 数 量 多, 而 且 有 的 还 需 要 硬 件 知 识 才 会 使 用, 因 此 要 想 全 部 掌 握 则 需 要 一 个 较 长 的 学 习 过 程 应 首 先 掌 握 一 些 最 基 本 最 常 用 的 函 数, 再 逐 步 深 入 由 于 课 时 关 系, 我 们 只 介 绍 了 很 少 一 部 分 库 函 数, 其 余 部 分 读 者 可 根 据 需 要 查 阅 有 关 手 册 还 应 该 指 出 的 是, 在 C 语 言 中, 所 有 的 函 数 定 义, 包 括 主 函 数 main 在 内, 都 是 平 行 的 也 就 是 说, 在 一 个 函 数 的 函 数 体 内, 不 能 再 定 义 另 一 个 函 数, 即 不 能 嵌 套 定 义 但 是 函 数 之 间 允 许 相 互 调 用, 也 允 许 嵌 套 调 用 习 惯 上 把 调 用 者 称 为 主 调 函 数 函 数 还 可 以 自 己 调 用 自 己, 称 为 递 归 调 用 main 函 数 是 主 函 数, 它 可 以 调 用 其 它 函 数, 而 不 允 许 被 其 它 函 数 调 用 因 此,C 程 序 的 执 行 总 是 从 main 函 数 开 始, 完 成 对 其 它 函 数 的 调 用 后 再 返 回 到 main 函 数, 最 后 由 main 函 数 结 束 整 个 程 序 一 个 C 源 程 序 必 须 有, 也 只 能 有 一 个 主 函 数 main 8.2 函 数 定 义 的 一 般 形 式 1. 无 参 函 数 的 定 义 形 式 类 型 标 识 符 函 数 名 () 声 明 部 分 语 句 其 中 类 型 标 识 符 和 函 数 名 称 为 函 数 头 类 型 标 识 符 指 明 了 本 函 数 的 类 型, 函 数 的 类 型 实 际 上 是 函 数 返 回 值 的 类 型 该 类 型 标 识 符 与 前 面 介 绍 的 各 种 说 明 符 相 同 函 数 名 是 由 用 户 定 义 的 标 识 符, 函 数 名 后 有 一 个 空 括 号, 其 中 无 参 数, 但 括 号 不 可 少 中 的 内 容 称 为 函 数 体 在 函 数 体 中 声 明 部 分, 是 对 函 数 体 内 部 所 用 到 的 变 量 的 类 型 说 明 在 很 多 情 况 下 都 不 要 求 无 参 函 数 有 返 回 值, 此 时 函 数 类 型 符 可 以 写 为 void 我 们 可 以 改 写 一 个 函 数 定 义 : void Hello() printf ("Hello,world \n"); 这 里, 只 把 main 改 为 Hello 作 为 函 数 名, 其 余 不 变 Hello 函 数 是 一 个 无 参 函 数, 当 被 其 它 函 数 调 用 时, 输 出 Hello world 字 符 串 2. 有 参 函 数 定 义 的 一 般 形 式 类 型 标 识 符 函 数 名 ( 形 式 参 数 表 列 ) 声 明 部 分 语 句 有 参 函 数 比 无 参 函 数 多 了 一 个 内 容, 即 形 式 参 数 表 列 在 形 参 表 中 给 出 的 参 数 称 为 形 式 参 数, 它 们 可 以 是 各 种 类 型 的 变 量, 各 参 数 之 间 用 逗 号 间 隔 在 进 行 函 数 调 用 时, 主 调 函 数 将 赋 予 这 些 形 式 参 数 实 际 的 值 形 参 既 然 是 变 量, 必 须 在 形 参 表 中 给 出 形 参 的 类 型 说 明 例 如, 定 义 一 个 函 数, 用 于 求 两 个 数 中 的 大 数, 可 写 为 : 第 107 页

108 int max(int a, int b) if (a>b) return a; else return b; 第 一 行 说 明 max 函 数 是 一 个 整 型 函 数, 其 返 回 的 函 数 值 是 一 个 整 数 形 参 为 a,b, 均 为 整 型 量 a,b 的 具 体 值 是 由 主 调 函 数 在 调 用 时 传 送 过 来 的 在 中 的 函 数 体 内, 除 形 参 外 没 有 使 用 其 它 变 量, 因 此 只 有 语 句 而 没 有 声 明 部 分 在 max 函 数 体 中 的 return 语 句 是 把 a( 或 b) 的 值 作 为 函 数 的 值 返 回 给 主 调 函 数 有 返 回 值 函 数 中 至 少 应 有 一 个 return 语 句 在 C 程 序 中, 一 个 函 数 的 定 义 可 以 放 在 任 意 位 置, 既 可 放 在 主 函 数 main 之 前, 也 可 放 在 main 之 后 例 如 : 可 把 max 函 数 置 在 main 之 后, 也 可 以 把 它 放 在 main 之 前 修 改 后 的 程 序 如 下 所 示 例 8.1 int max(int a,int b) if(a>b)return a; else return b; main() int max(int a,int b); int x,y,z; printf("input two numbers:\n"); scanf("%d%d",&x,&y); z=max(x,y); printf("maxmum=%d",z); 现 在 我 们 可 以 从 函 数 定 义 函 数 说 明 及 函 数 调 用 的 角 度 来 分 析 整 个 程 序, 从 中 进 一 步 了 解 函 数 的 各 种 特 点 程 序 的 第 1 行 至 第 5 行 为 max 函 数 定 义 进 入 主 函 数 后, 因 为 准 备 调 用 max 函 数, 故 先 对 max 函 数 进 行 说 明 ( 程 序 第 8 行 ) 函 数 定 义 和 函 数 说 明 并 不 是 一 回 事, 在 后 面 还 要 专 门 讨 论 可 以 看 出 函 数 说 明 与 函 数 定 义 中 的 函 数 头 部 分 相 同, 但 是 末 尾 要 加 分 号 程 序 第 12 行 为 调 用 max 函 数, 并 把 x, y 中 的 值 传 送 给 max 的 形 参 a, b max 函 数 执 行 的 结 果 (a 或 b) 将 返 回 给 变 量 z 最 后 由 主 函 数 输 出 z 的 值 8.3 函 数 的 参 数 和 函 数 的 值 形 式 参 数 和 实 际 参 数 前 面 已 经 介 绍 过, 函 数 的 参 数 分 为 形 参 和 实 参 两 种 在 本 小 节 中, 进 一 步 介 绍 形 参 实 参 的 特 点 和 两 者 的 关 系 形 参 出 现 在 函 数 定 义 中, 在 整 个 函 数 体 内 都 可 以 使 用, 离 开 该 函 数 则 不 能 使 用 实 参 出 现 在 主 调 函 数 中, 进 入 被 调 函 数 后, 实 参 变 量 也 不 能 使 用 形 参 和 实 参 的 功 能 是 作 数 据 传 送 发 生 函 数 调 用 时, 主 调 函 第 108 页

109 数 把 实 参 的 值 传 送 给 被 调 函 数 的 形 参 从 而 实 现 主 调 函 数 向 被 调 函 数 的 数 据 传 送 函 数 的 形 参 和 实 参 具 有 以 下 特 点 : 1. 形 参 变 量 只 有 在 被 调 用 时 才 分 配 内 存 单 元, 在 调 用 结 束 时, 即 刻 释 放 所 分 配 的 内 存 单 元 因 此, 形 参 只 有 在 函 数 内 部 有 效 函 数 调 用 结 束 返 回 主 调 函 数 后 则 不 能 再 使 用 该 形 参 变 量 2. 实 参 可 以 是 常 量 变 量 表 达 式 函 数 等, 无 论 实 参 是 何 种 类 型 的 量, 在 进 行 函 数 调 用 时, 它 们 都 必 须 具 有 确 定 的 值, 以 便 把 这 些 值 传 送 给 形 参 因 此 应 预 先 用 赋 值, 输 入 等 办 法 使 实 参 获 得 确 定 值 3. 实 参 和 形 参 在 数 量 上, 类 型 上, 顺 序 上 应 严 格 一 致, 否 则 会 发 生 类 型 不 匹 配 的 错 误 4. 函 数 调 用 中 发 生 的 数 据 传 送 是 单 向 的 即 只 能 把 实 参 的 值 传 送 给 形 参, 而 不 能 把 形 参 的 值 反 向 地 传 送 给 实 参 因 此 在 函 数 调 用 过 程 中, 形 参 的 值 发 生 改 变, 而 实 参 中 的 值 不 会 变 化 例 8.2 可 以 说 明 这 个 问 题 main() int n; printf("input number\n"); scanf("%d",&n); s(n); printf("n=%d\n",n); int s(int n) int i; for(i=n-1;i>=1;i--) n=n+i; printf("n=%d\n",n); 本 程 序 中 定 义 了 一 个 函 数 s, 该 函 数 的 功 能 是 求 n i 的 值 在 主 函 数 中 输 入 n 值, 并 作 为 实 参, 在 调 用 时 传 送 给 s 函 数 的 形 参 量 n( 注 意, 本 例 的 形 参 变 量 和 实 参 变 量 的 标 识 符 都 为 n, 但 这 是 两 个 不 同 的 量, 各 自 的 作 用 域 不 同 ) 在 主 函 数 中 用 printf 语 句 输 出 一 次 n 值, 这 个 n 值 是 实 参 n 的 值 在 函 数 s 中 也 用 printf 语 句 输 出 了 一 次 n 值, 这 个 n 值 是 形 参 最 后 取 得 的 n 值 0 从 运 行 情 况 看, 输 入 n 值 为 100 即 实 参 n 的 值 为 100 把 此 值 传 给 函 数 s 时, 形 参 n 的 初 值 也 为 100, 在 执 行 函 数 过 程 中, 形 参 n 的 值 变 为 5050 返 回 主 函 数 之 后, 输 出 实 参 n 的 值 仍 为 100 可 见 实 参 的 值 不 随 形 参 的 变 化 而 变 化 第 109 页

110 8.3.2 函 数 的 返 回 值 函 数 的 值 是 指 函 数 被 调 用 之 后, 执 行 函 数 体 中 的 程 序 段 所 取 得 的 并 返 回 给 主 调 函 数 的 值 如 调 用 正 弦 函 数 取 得 正 弦 值, 调 用 例 8.1 的 max 函 数 取 得 的 最 大 数 等 对 函 数 的 值 ( 或 称 函 数 返 回 值 ) 有 以 下 一 些 说 明 : 1) 函 数 的 值 只 能 通 过 return 语 句 返 回 主 调 函 数 return 语 句 的 一 般 形 式 为 : return 表 达 式 ; 或 者 为 : return ( 表 达 式 ); 该 语 句 的 功 能 是 计 算 表 达 式 的 值, 并 返 回 给 主 调 函 数 在 函 数 中 允 许 有 多 个 return 语 句, 但 每 次 调 用 只 能 有 一 个 return 语 句 被 执 行, 因 此 只 能 返 回 一 个 函 数 值 2) 函 数 值 的 类 型 和 函 数 定 义 中 函 数 的 类 型 应 保 持 一 致 如 果 两 者 不 一 致, 则 以 函 数 类 型 为 准, 自 动 进 行 类 型 转 换 3) 如 函 数 值 为 整 型, 在 函 数 定 义 时 可 以 省 去 类 型 说 明 4) 不 返 回 函 数 值 的 函 数, 可 以 明 确 定 义 为 空 类 型, 类 型 说 明 符 为 void 如 例 8.2 中 函 数 s 并 不 向 主 函 数 返 函 数 值, 因 此 可 定 义 为 : void s(int n) 一 旦 函 数 被 定 义 为 空 类 型 后, 就 不 能 在 主 调 函 数 中 使 用 被 调 函 数 的 函 数 值 了 例 如, 在 定 义 s 为 空 类 型 后, 在 主 函 数 中 写 下 述 语 句 sum=s(n); 就 是 错 误 的 为 了 使 程 序 有 良 好 的 可 读 性 并 减 少 出 错, 凡 不 要 求 返 回 值 的 函 数 都 应 定 义 为 空 类 型 8.4 函 数 的 调 用 函 数 调 用 的 一 般 形 式 前 面 已 经 说 过, 在 程 序 中 是 通 过 对 函 数 的 调 用 来 执 行 函 数 体 的, 其 过 程 与 其 它 语 言 的 子 程 序 调 用 相 似 C 语 言 中, 函 数 调 用 的 一 般 形 式 为 : 函 数 名 ( 实 际 参 数 表 ) 对 无 参 函 数 调 用 时 则 无 实 际 参 数 表 实 际 参 数 表 中 的 参 数 可 以 是 常 数, 变 量 或 其 它 构 造 类 型 数 据 及 表 达 式 各 实 参 之 间 用 逗 号 分 隔 函 数 调 用 的 方 式 在 C 语 言 中, 可 以 用 以 下 几 种 方 式 调 用 函 数 : 1. 函 数 表 达 式 : 函 数 作 为 表 达 式 中 的 一 项 出 现 在 表 达 式 中, 以 函 数 返 回 值 参 与 表 达 式 的 运 算 这 种 方 式 要 求 函 数 是 有 返 回 值 的 例 如 :z=max(x,y) 是 一 个 赋 值 表 达 式, 把 max 的 返 回 值 赋 予 变 量 z 2. 函 数 语 句 : 函 数 调 用 的 一 般 形 式 加 上 分 号 即 构 成 函 数 语 句 例 如 : printf ("%d",a);scanf ("%d",&b); 第 110 页

111 都 是 以 函 数 语 句 的 方 式 调 用 函 数 3. 函 数 实 参 : 函 数 作 为 另 一 个 函 数 调 用 的 实 际 参 数 出 现 这 种 情 况 是 把 该 函 数 的 返 回 值 作 为 实 参 进 行 传 送, 因 此 要 求 该 函 数 必 须 是 有 返 回 值 的 例 如 : printf("%d",max(x,y)); 即 是 把 max 调 用 的 返 回 值 又 作 为 printf 函 数 的 实 参 来 使 用 的 在 函 数 调 用 中 还 应 该 注 意 的 一 个 问 题 是 求 值 顺 序 的 问 题 所 谓 求 值 顺 序 是 指 对 实 参 表 中 各 量 是 自 左 至 右 使 用 呢, 还 是 自 右 至 左 使 用 对 此, 各 系 统 的 规 定 不 一 定 相 同 介 绍 printf 函 数 时 已 提 到 过, 这 里 从 函 数 调 用 的 角 度 再 强 调 一 下 例 8.3 main() int i=8; printf("%d\n%d\n%d\n%d\n",++i,--i,i++,i--); 如 按 照 从 右 至 左 的 顺 序 求 值 运 行 结 果 应 为 : 如 对 printf 语 句 中 的 ++i,--i,i++,i-- 从 左 至 右 求 值, 结 果 应 为 : 应 特 别 注 意 的 是, 无 论 是 从 左 至 右 求 值, 还 是 自 右 至 左 求 值, 其 输 出 顺 序 都 是 不 变 的, 即 输 出 顺 序 总 是 和 实 参 表 中 实 参 的 顺 序 相 同 由 于 Turbo C 现 定 是 自 右 至 左 求 值, 所 以 结 果 为 8,7,7,8 上 述 问 题 如 还 不 理 解, 上 机 一 试 就 明 白 了 被 调 用 函 数 的 声 明 和 函 数 原 型 在 主 调 函 数 中 调 用 某 函 数 之 前 应 对 该 被 调 函 数 进 行 说 明 ( 声 明 ), 这 与 使 用 变 量 之 前 要 先 进 行 变 量 说 明 是 一 样 的 在 主 调 函 数 中 对 被 调 函 数 作 说 明 的 目 的 是 使 编 译 系 统 知 道 被 调 函 数 返 回 值 的 类 型, 以 便 在 主 调 函 数 中 按 此 种 类 型 对 返 回 值 作 相 应 的 处 理 其 一 般 形 式 为 : 类 型 说 明 符 被 调 函 数 名 ( 类 型 形 参, 类 型 形 参 ); 或 为 : 类 型 说 明 符 被 调 函 数 名 ( 类 型, 类 型 ); 括 号 内 给 出 了 形 参 的 类 型 和 形 参 名, 或 只 给 出 形 参 类 型 这 便 于 编 译 系 统 进 行 检 错, 以 防 止 可 能 出 现 的 错 误 例 8.1 main 函 数 中 对 max 函 数 的 说 明 为 : int max(int a,int b); 或 写 为 : int max(int,int); C 语 言 中 又 规 定 在 以 下 几 种 情 况 时 可 以 省 去 主 调 函 数 中 对 被 调 函 数 的 函 数 说 明 第 111 页

112 1) 如 果 被 调 函 数 的 返 回 值 是 整 型 或 字 符 型 时, 可 以 不 对 被 调 函 数 作 说 明, 而 直 接 调 用 这 时 系 统 将 自 动 对 被 调 函 数 返 回 值 按 整 型 处 理 例 8.2 的 主 函 数 中 未 对 函 数 s 作 说 明 而 直 接 调 用 即 属 此 种 情 形 2) 当 被 调 函 数 的 函 数 定 义 出 现 在 主 调 函 数 之 前 时, 在 主 调 函 数 中 也 可 以 不 对 被 调 函 数 再 作 说 明 而 直 接 调 用 例 如 例 8.1 中, 函 数 max 的 定 义 放 在 main 函 数 之 前, 因 此 可 在 main 函 数 中 省 去 对 max 函 数 的 函 数 说 明 int max(int a,int b) 3) 如 在 所 有 函 数 定 义 之 前, 在 函 数 外 预 先 说 明 了 各 个 函 数 的 类 型, 则 在 以 后 的 各 主 调 函 数 中, 可 不 再 对 被 调 函 数 作 说 明 例 如 : char str(int a); float f(float b); main() char str(int a) float f(float b) 其 中 第 一, 二 行 对 str 函 数 和 f 函 数 预 先 作 了 说 明 因 此 在 以 后 各 函 数 中 无 须 对 str 和 f 函 数 再 作 说 明 就 可 直 接 调 用 4) 对 库 函 数 的 调 用 不 需 要 再 作 说 明, 但 必 须 把 该 函 数 的 头 文 件 用 include 命 令 包 含 在 源 文 件 前 部 8.5 函 数 的 嵌 套 调 用 C 语 言 中 不 允 许 作 嵌 套 的 函 数 定 义 因 此 各 函 数 之 间 是 平 行 的, 不 存 在 上 一 级 函 数 和 下 一 级 函 数 的 问 题 但 是 C 语 言 允 许 在 一 个 函 数 的 定 义 中 出 现 对 另 一 个 函 数 的 调 用 这 样 就 出 现 了 函 数 的 嵌 套 调 用 即 在 被 调 函 数 中 又 调 用 其 它 函 数 这 与 其 它 语 言 的 子 程 序 嵌 套 的 情 形 是 类 似 的 其 关 系 可 表 示 如 图 图 表 示 了 两 层 嵌 套 的 情 形 其 执 行 过 程 是 : 执 行 main 函 数 中 调 用 a 函 数 的 语 句 时, 即 转 去 执 行 a 函 数, 在 a 函 数 中 调 用 b 函 数 时, 又 转 去 执 行 b 函 数,b 函 数 执 行 完 毕 返 回 a 函 数 的 断 点 继 续 执 行,a 函 数 执 行 完 第 112 页

113 毕 返 回 main 函 数 的 断 点 继 续 执 行 例 8.4 计 算 s=2 2!+3 2! 本 题 可 编 写 两 个 函 数, 一 个 是 用 来 计 算 平 方 值 的 函 数 f1, 另 一 个 是 用 来 计 算 阶 乘 值 的 函 数 f2 主 函 数 先 调 f1 计 算 出 平 方 值, 再 在 f1 中 以 平 方 值 为 实 参, 调 用 f2 计 算 其 阶 乘 值, 然 后 返 回 f1, 再 返 回 主 函 数, 在 循 环 程 序 中 计 算 累 加 和 long f1(int p) int k; long r; long f2(int); k=p*p; r=f2(k); return r; long f2(int q) long c=1; int i; for(i=1;i<=q;i++) c=c*i; return c; main() int i; long s=0; for (i=2;i<=3;i++) s=s+f1(i); printf("\ns=%ld\n",s); 在 程 序 中, 函 数 f1 和 f2 均 为 长 整 型, 都 在 主 函 数 之 前 定 义, 故 不 必 再 在 主 函 数 中 对 f1 和 f2 加 以 说 明 在 主 程 序 中, 执 行 循 环 程 序 依 次 把 i 值 作 为 实 参 调 用 函 数 f1 求 i 2 值 在 f1 中 又 发 生 对 函 数 f2 的 调 用, 这 时 是 把 i 2 的 值 作 为 实 参 去 调 f2, 在 f2 中 完 成 求 i 2! 的 计 算 f2 执 行 完 毕 把 C 值 ( 即 i 2!) 返 回 给 f1, 再 由 f1 返 回 主 函 数 实 现 累 加 至 此, 由 函 数 的 嵌 套 调 用 实 现 了 题 目 的 要 求 由 于 数 值 很 大, 所 以 函 数 和 一 些 变 量 的 类 型 都 说 明 为 长 整 型, 否 则 会 造 成 计 算 错 误 8.6 函 数 的 递 归 调 用 一 个 函 数 在 它 的 函 数 体 内 调 用 它 自 身 称 为 递 归 调 用 这 种 函 数 称 为 递 归 函 数 C 语 言 允 许 函 数 的 递 归 调 第 113 页

114 用 在 递 归 调 用 中, 主 调 函 数 又 是 被 调 函 数 执 行 递 归 函 数 将 反 复 调 用 其 自 身, 每 调 用 一 次 就 进 入 新 的 一 层 例 如 有 函 数 f 如 下 : int f(int x) int y; z=f(y); return z; 这 个 函 数 是 一 个 递 归 函 数 但 是 运 行 该 函 数 将 无 休 止 地 调 用 其 自 身, 这 当 然 是 不 正 确 的 为 了 防 止 递 归 调 用 无 终 止 地 进 行, 必 须 在 函 数 内 有 终 止 递 归 调 用 的 手 段 常 用 的 办 法 是 加 条 件 判 断, 满 足 某 种 条 件 后 就 不 再 作 递 归 调 用, 然 后 逐 层 返 回 下 面 举 例 说 明 递 归 调 用 的 执 行 过 程 例 8.5 用 递 归 法 计 算 n! 用 递 归 法 计 算 n! 可 用 下 述 公 式 表 示 : n!=1 (n=0,1) n (n-1)! (n>1) 按 公 式 可 编 程 如 下 : long ff(int n) long f; if(n<0) printf("n<0,input error"); else if(n==0 n==1) f=1; else f=ff(n-1)*n; return(f); main() int n; long y; printf("\ninput a inteager number:\n"); scanf("%d",&n); y=ff(n); printf("%d!=%ld",n,y); 程 序 中 给 出 的 函 数 ff 是 一 个 递 归 函 数 主 函 数 调 用 ff 后 即 进 入 函 数 ff 执 行, 如 果 n<0,n==0 或 n=1 时 都 将 结 束 函 数 的 执 行, 否 则 就 递 归 调 用 ff 函 数 自 身 由 于 每 次 递 归 调 用 的 实 参 为 n-1, 即 把 n-1 的 值 赋 予 形 参 n, 最 后 当 n-1 的 值 为 1 时 再 作 递 归 调 用, 形 参 n 的 值 也 为 1, 将 使 递 归 终 止 然 后 可 逐 层 退 回 下 面 我 们 再 举 例 说 明 该 过 程 设 执 行 本 程 序 时 输 入 为 5, 即 求 5! 在 主 函 数 中 的 调 用 语 句 即 为 y=ff(5), 进 入 ff 函 数 后, 由 于 n=5, 不 等 于 0 或 1, 故 应 执 行 f=ff(n-1)*n, 即 f=ff(5-1)*5 该 语 句 对 ff 作 递 归 调 用 即 ff(4) 进 行 四 次 递 归 调 用 后,ff 函 数 形 参 取 得 的 值 变 为 1, 故 不 再 继 续 递 归 调 用 而 开 始 逐 层 返 回 主 调 函 数 ff(1) 的 函 数 返 回 值 为 1,ff(2) 的 返 回 值 为 1*2=2,ff(3) 的 返 回 值 为 2*3=6,ff(4) 的 返 回 值 为 6*4=24, 最 后 返 回 值 ff(5) 为 24*5=120 第 114 页

115 例 8.5 也 可 以 不 用 递 归 的 方 法 来 完 成 如 可 以 用 递 推 法, 即 从 1 开 始 乘 以 2, 再 乘 以 3 直 到 n 递 推 法 比 递 归 法 更 容 易 理 解 和 实 现 但 是 有 些 问 题 则 只 能 用 递 归 算 法 才 能 实 现 典 型 的 问 题 是 Hanoi 塔 问 题 例 8.6 Hanoi 塔 问 题 一 块 板 上 有 三 根 针,A,B,C A 针 上 套 有 64 个 大 小 不 等 的 圆 盘, 大 的 在 下, 小 的 在 上 如 图 5.4 所 示 要 把 这 64 个 圆 盘 从 A 针 移 动 C 针 上, 每 次 只 能 移 动 一 个 圆 盘, 移 动 可 以 借 助 B 针 进 行 但 在 任 何 时 候, 任 何 针 上 的 圆 盘 都 必 须 保 持 大 盘 在 下, 小 盘 在 上 求 移 动 的 步 骤 本 题 算 法 分 析 如 下, 设 A 上 有 n 个 盘 子 如 果 n=1, 则 将 圆 盘 从 A 直 接 移 动 到 C 如 果 n=2, 则 : 1. 将 A 上 的 n-1( 等 于 1) 个 圆 盘 移 到 B 上 ; 2. 再 将 A 上 的 一 个 圆 盘 移 到 C 上 ; 3. 最 后 将 B 上 的 n-1( 等 于 1) 个 圆 盘 移 到 C 上 如 果 n=3, 则 : A. 将 A 上 的 n-1( 等 于 2, 令 其 为 n`) 个 圆 盘 移 到 B( 借 助 于 C), 步 骤 如 下 : (1) 将 A 上 的 n`-1( 等 于 1) 个 圆 盘 移 到 C 上 (2) 将 A 上 的 一 个 圆 盘 移 到 B (3) 将 C 上 的 n`-1( 等 于 1) 个 圆 盘 移 到 B B. 将 A 上 的 一 个 圆 盘 移 到 C C. 将 B 上 的 n-1( 等 于 2, 令 其 为 n`) 个 圆 盘 移 到 C( 借 助 A), 步 骤 如 下 : (1) 将 B 上 的 n`-1( 等 于 1) 个 圆 盘 移 到 A (2) 将 B 上 的 一 个 盘 子 移 到 C (3) 将 A 上 的 n`-1( 等 于 1) 个 圆 盘 移 到 C 到 此, 完 成 了 三 个 圆 盘 的 移 动 过 程 从 上 面 分 析 可 以 看 出, 当 n 大 于 等 于 2 时, 移 动 的 过 程 可 分 解 为 三 个 步 骤 : 第 一 步 把 A 上 的 n-1 个 圆 盘 移 到 B 上 ; 第 二 步 把 A 上 的 一 个 圆 盘 移 到 C 上 ; 第 三 步 把 B 上 的 n-1 个 圆 盘 移 到 C 上 ; 其 中 第 一 步 和 第 三 步 是 类 同 的 当 n=3 时, 第 一 步 和 第 三 步 又 分 解 为 类 同 的 三 步, 即 把 n`-1 个 圆 盘 从 一 个 针 移 到 另 一 个 针 上, 这 里 的 n`=n-1 显 然 这 是 一 个 递 归 过 程, 据 此 算 法 可 编 程 如 下 : move(int n,int x,int y,int z) if(n==1) printf("%c-->%c\n",x,z); else move(n-1,x,z,y); printf("%c-->%c\n",x,z); move(n-1,y,x,z); main() int h; printf("\ninput number:\n"); 第 115 页

116 scanf("%d",&h); printf("the step to moving %2d diskes:\n",h); move(h,'a','b','c'); 从 程 序 中 可 以 看 出,move 函 数 是 一 个 递 归 函 数, 它 有 四 个 形 参 n,x,y,z n 表 示 圆 盘 数,x,y,z 分 别 表 示 三 根 针 move 函 数 的 功 能 是 把 x 上 的 n 个 圆 盘 移 动 到 z 上 当 n==1 时, 直 接 把 x 上 的 圆 盘 移 至 z 上, 输 出 x z 如 n!=1 则 分 为 三 步 : 递 归 调 用 move 函 数, 把 n-1 个 圆 盘 从 x 移 到 y; 输 出 x z; 递 归 调 用 move 函 数, 把 n-1 个 圆 盘 从 y 移 到 z 在 递 归 调 用 过 程 中 n=n-1, 故 n 的 值 逐 次 递 减, 最 后 n=1 时, 终 止 递 归, 逐 层 返 回 当 n=4 时 程 序 运 行 的 结 果 为 : input number: 4 the step to moving 4 diskes: a b a c b c a b c a c b a b a c b c b a c a b c a b a c b c 8.7 数 组 作 为 函 数 参 数 数 组 可 以 作 为 函 数 的 参 数 使 用, 进 行 数 据 传 送 数 组 用 作 函 数 参 数 有 两 种 形 式, 一 种 是 把 数 组 元 素 ( 下 标 变 量 ) 作 为 实 参 使 用 ; 另 一 种 是 把 数 组 名 作 为 函 数 的 形 参 和 实 参 使 用 1. 数 组 元 素 作 函 数 实 参 数 组 元 素 就 是 下 标 变 量, 它 与 普 通 变 量 并 无 区 别 因 此 它 作 为 函 数 实 参 使 用 与 普 通 变 量 是 完 全 相 同 的, 在 发 生 函 数 调 用 时, 把 作 为 实 参 的 数 组 元 素 的 值 传 送 给 形 参, 实 现 单 向 的 值 传 送 例 5.4 说 明 了 这 种 情 况 例 8.7 判 别 一 个 整 数 数 组 中 各 元 素 的 值, 若 大 于 0 则 输 出 该 值, 若 小 于 等 于 0 则 输 出 0 值 编 程 如 下 : void nzp(int v) if(v>0) printf("%d ",v); else printf("%d ",0); 第 116 页

117 main() int a[5],i; printf("input 5 numbers\n"); for(i=0;i<5;i++) scanf("%d",&a[i]); nzp(a[i]); 本 程 序 中 首 先 定 义 一 个 无 返 回 值 函 数 nzp, 并 说 明 其 形 参 v 为 整 型 变 量 在 函 数 体 中 根 据 v 值 输 出 相 应 的 结 果 在 main 函 数 中 用 一 个 for 语 句 输 入 数 组 各 元 素, 每 输 入 一 个 就 以 该 元 素 作 实 参 调 用 一 次 nzp 函 数, 即 把 a[i] 的 值 传 送 给 形 参 v, 供 nzp 函 数 使 用 2. 数 组 名 作 为 函 数 参 数 用 数 组 名 作 函 数 参 数 与 用 数 组 元 素 作 实 参 有 几 点 不 同 : 1) 用 数 组 元 素 作 实 参 时, 只 要 数 组 类 型 和 函 数 的 形 参 变 量 的 类 型 一 致, 那 么 作 为 下 标 变 量 的 数 组 元 素 的 类 型 也 和 函 数 形 参 变 量 的 类 型 是 一 致 的 因 此, 并 不 要 求 函 数 的 形 参 也 是 下 标 变 量 换 句 话 说, 对 数 组 元 素 的 处 理 是 按 普 通 变 量 对 待 的 用 数 组 名 作 函 数 参 数 时, 则 要 求 形 参 和 相 对 应 的 实 参 都 必 须 是 类 型 相 同 的 数 组, 都 必 须 有 明 确 的 数 组 说 明 当 形 参 和 实 参 二 者 不 一 致 时, 即 会 发 生 错 误 2) 在 普 通 变 量 或 下 标 变 量 作 函 数 参 数 时, 形 参 变 量 和 实 参 变 量 是 由 编 译 系 统 分 配 的 两 个 不 同 的 内 存 单 元 在 函 数 调 用 时 发 生 的 值 传 送 是 把 实 参 变 量 的 值 赋 予 形 参 变 量 在 用 数 组 名 作 函 数 参 数 时, 不 是 进 行 值 的 传 送, 即 不 是 把 实 参 数 组 的 每 一 个 元 素 的 值 都 赋 予 形 参 数 组 的 各 个 元 素 因 为 实 际 上 形 参 数 组 并 不 存 在, 编 译 系 统 不 为 形 参 数 组 分 配 内 存 那 么, 数 据 的 传 送 是 如 何 实 现 的 呢? 在 我 们 曾 介 绍 过, 数 组 名 就 是 数 组 的 首 地 址 因 此 在 数 组 名 作 函 数 参 数 时 所 进 行 的 传 送 只 是 地 址 的 传 送, 也 就 是 说 把 实 参 数 组 的 首 地 址 赋 予 形 参 数 组 名 形 参 数 组 名 取 得 该 首 地 址 之 后, 也 就 等 于 有 了 实 在 的 数 组 实 际 上 是 形 参 数 组 和 实 参 数 组 为 同 一 数 组, 共 同 拥 有 一 段 内 存 空 间 上 图 说 明 了 这 种 情 形 图 中 设 a 为 实 参 数 组, 类 型 为 整 型 a 占 有 以 2000 为 首 地 址 的 一 块 内 存 区 b 为 形 参 数 组 名 当 发 生 函 数 调 用 时, 进 行 地 址 传 送, 把 实 参 数 组 a 的 首 地 址 传 送 给 形 参 数 组 名 b, 于 是 b 也 取 得 该 地 址 2000 于 是 a,b 两 数 组 共 同 占 有 以 2000 为 首 地 址 的 一 段 连 续 内 存 单 元 从 图 中 还 可 以 看 出 a 和 b 下 标 相 同 的 元 素 实 际 上 也 占 相 同 的 两 个 内 存 单 元 ( 整 型 数 组 每 个 元 素 占 二 字 节 ) 例 如 a[0] 和 b[0] 都 占 用 2000 和 2001 单 元, 当 然 a[0] 等 于 b[0] 类 推 则 有 a[i] 等 于 b[i] 例 8.8 数 组 a 中 存 放 了 一 个 学 生 5 门 课 程 的 成 绩, 求 平 均 成 绩 float aver(float a[5]) int i; float av,s=a[0]; for(i=1;i<5;i++) 第 117 页

118 s=s+a[i]; av=s/5; return av; void main() float sco[5],av; int i; printf("\ninput 5 scores:\n"); for(i=0;i<5;i++) scanf("%f",&sco[i]); av=aver(sco); printf("average score is %5.2f",av); 本 程 序 首 先 定 义 了 一 个 实 型 函 数 aver, 有 一 个 形 参 为 实 型 数 组 a, 长 度 为 5 在 函 数 aver 中, 把 各 元 素 值 相 加 求 出 平 均 值, 返 回 给 主 函 数 主 函 数 main 中 首 先 完 成 数 组 sco 的 输 入, 然 后 以 sco 作 为 实 参 调 用 aver 函 数, 函 数 返 回 值 送 av, 最 后 输 出 av 值 从 运 行 情 况 可 以 看 出, 程 序 实 现 了 所 要 求 的 功 能 3) 前 面 已 经 讨 论 过, 在 变 量 作 函 数 参 数 时, 所 进 行 的 值 传 送 是 单 向 的 即 只 能 从 实 参 传 向 形 参, 不 能 从 形 参 传 回 实 参 形 参 的 初 值 和 实 参 相 同, 而 形 参 的 值 发 生 改 变 后, 实 参 并 不 变 化, 两 者 的 终 值 是 不 同 的 而 当 用 数 组 名 作 函 数 参 数 时, 情 况 则 不 同 由 于 实 际 上 形 参 和 实 参 为 同 一 数 组, 因 此 当 形 参 数 组 发 生 变 化 时, 实 参 数 组 也 随 之 变 化 当 然 这 种 情 况 不 能 理 解 为 发 生 了 双 向 的 值 传 递 但 从 实 际 情 况 来 看, 调 用 函 数 之 后 实 参 数 组 的 值 将 由 于 形 参 数 组 值 的 变 化 而 变 化 为 了 说 明 这 种 情 况, 把 例 5.4 改 为 例 5.6 的 形 式 例 8.9 题 目 同 8.7 例 改 用 数 组 名 作 函 数 参 数 void nzp(int a[5]) int i; printf("\nvalues of array a are:\n"); for(i=0;i<5;i++) if(a[i]<0) a[i]=0; printf("%d ",a[i]); main() int b[5],i; printf("\ninput 5 numbers:\n"); for(i=0;i<5;i++) scanf("%d",&b[i]); printf("initial values of array b are:\n"); 第 118 页

119 for(i=0;i<5;i++) printf("%d ",b[i]); nzp(b); printf("\nlast values of array b are:\n"); for(i=0;i<5;i++) printf("%d ",b[i]); 本 程 序 中 函 数 nzp 的 形 参 为 整 数 组 a, 长 度 为 5 主 函 数 中 实 参 数 组 b 也 为 整 型, 长 度 也 为 5 在 主 函 数 中 首 先 输 入 数 组 b 的 值, 然 后 输 出 数 组 b 的 初 始 值 然 后 以 数 组 名 b 为 实 参 调 用 nzp 函 数 在 nzp 中, 按 要 求 把 负 值 单 元 清 0, 并 输 出 形 参 数 组 a 的 值 返 回 主 函 数 之 后, 再 次 输 出 数 组 b 的 值 从 运 行 结 果 可 以 看 出, 数 组 b 的 初 值 和 终 值 是 不 同 的, 数 组 b 的 终 值 和 数 组 a 是 相 同 的 这 说 明 实 参 形 参 为 同 一 数 组, 它 们 的 值 同 时 得 以 改 变 用 数 组 名 作 为 函 数 参 数 时 还 应 注 意 以 下 几 点 : a. 形 参 数 组 和 实 参 数 组 的 类 型 必 须 一 致, 否 则 将 引 起 错 误 b. 形 参 数 组 和 实 参 数 组 的 长 度 可 以 不 相 同, 因 为 在 调 用 时, 只 传 送 首 地 址 而 不 检 查 形 参 数 组 的 长 度 当 形 参 数 组 的 长 度 与 实 参 数 组 不 一 致 时, 虽 不 至 于 出 现 语 法 错 误 ( 编 译 能 通 过 ), 但 程 序 执 行 结 果 将 与 实 际 不 符, 这 是 应 予 以 注 意 的 例 8.10 如 把 例 8.9 修 改 如 下 : void nzp(int a[8]) int i; printf("\nvalues of array aare:\n"); for(i=0;i<8;i++) if(a[i]<0)a[i]=0; printf("%d ",a[i]); main() int b[5],i; printf("\ninput 5 numbers:\n"); for(i=0;i<5;i++) scanf("%d",&b[i]); printf("initial values of array b are:\n"); for(i=0;i<5;i++) printf("%d ",b[i]); nzp(b); printf("\nlast values of array b are:\n"); for(i=0;i<5;i++) printf("%d ",b[i]); 第 119 页

120 本 程 序 与 例 8.9 程 序 比,nzp 函 数 的 形 参 数 组 长 度 改 为 8, 函 数 体 中,for 语 句 的 循 环 条 件 也 改 为 i<8 因 此, 形 参 数 组 a 和 实 参 数 组 b 的 长 度 不 一 致 编 译 能 够 通 过, 但 从 结 果 看, 数 组 a 的 元 素 a[5],a[6],a[7] 显 然 是 无 意 义 的 c. 在 函 数 形 参 表 中, 允 许 不 给 出 形 参 数 组 的 长 度, 或 用 一 个 变 量 来 表 示 数 组 元 素 的 个 数 例 如, 可 以 写 为 : void nzp(int a[]) 或 写 为 void nzp(int a[],int n) 其 中 形 参 数 组 a 没 有 给 出 长 度, 而 由 n 值 动 态 地 表 示 数 组 的 长 度 n 的 值 由 主 调 函 数 的 实 参 进 行 传 送 由 此, 例 8.10 又 可 改 为 例 8.11 的 形 式 例 8.11 void nzp(int a[],int n) int i; printf("\nvalues of array a are:\n"); for(i=0;i<n;i++) if(a[i]<0) a[i]=0; printf("%d ",a[i]); main() int b[5],i; printf("\ninput 5 numbers:\n"); for(i=0;i<5;i++) scanf("%d",&b[i]); printf("initial values of array b are:\n"); for(i=0;i<5;i++) printf("%d ",b[i]); nzp(b,5); printf("\nlast values of array b are:\n"); for(i=0;i<5;i++) printf("%d ",b[i]); 本 程 序 nzp 函 数 形 参 数 组 a 没 有 给 出 长 度, 由 n 动 态 确 定 该 长 度 在 main 函 数 中, 函 数 调 用 语 句 为 nzp(b, 5), 其 中 实 参 5 将 赋 予 形 参 n 作 为 形 参 数 组 的 长 度 d. 多 维 数 组 也 可 以 作 为 函 数 的 参 数 在 函 数 定 义 时 对 形 参 数 组 可 以 指 定 每 一 维 的 长 度, 也 可 省 去 第 一 维 的 长 度 因 此, 以 下 写 法 都 是 合 法 的 第 120 页

121 或 int MA(int a[3][10]) int MA(int a[][10]) 8.8 局 部 变 量 和 全 局 变 量 在 讨 论 函 数 的 形 参 变 量 时 曾 经 提 到, 形 参 变 量 只 在 被 调 用 期 间 才 分 配 内 存 单 元, 调 用 结 束 立 即 释 放 这 一 点 表 明 形 参 变 量 只 有 在 函 数 内 才 是 有 效 的, 离 开 该 函 数 就 不 能 再 使 用 了 这 种 变 量 有 效 性 的 范 围 称 变 量 的 作 用 域 不 仅 对 于 形 参 变 量,C 语 言 中 所 有 的 量 都 有 自 己 的 作 用 域 变 量 说 明 的 方 式 不 同, 其 作 用 域 也 不 同 C 语 言 中 的 变 量, 按 作 用 域 范 围 可 分 为 两 种, 即 局 部 变 量 和 全 局 变 量 局 部 变 量 局 部 变 量 也 称 为 内 部 变 量 局 部 变 量 是 在 函 数 内 作 定 义 说 明 的 其 作 用 域 仅 限 于 函 数 内, 离 开 该 函 数 后 再 使 用 这 种 变 量 是 非 法 的 例 如 : int f1(int a) /* 函 数 f1*/ int b,c; a,b,c 有 效 int f2(int x) /* 函 数 f2*/ int y,z; x,y,z 有 效 main() int m,n; m,n 有 效 在 函 数 f1 内 定 义 了 三 个 变 量,a 为 形 参,b,c 为 一 般 变 量 在 f1 的 范 围 内 a,b,c 有 效, 或 者 说 a,b,c 变 量 的 作 用 域 限 于 f1 内 同 理,x,y,z 的 作 用 域 限 于 f2 内 m,n 的 作 用 域 限 于 main 函 数 内 关 于 局 部 变 量 的 作 用 域 还 要 说 明 以 下 几 点 : 1) 主 函 数 中 定 义 的 变 量 也 只 能 在 主 函 数 中 使 用, 不 能 在 其 它 函 数 中 使 用 同 时, 主 函 数 中 也 不 能 使 用 其 它 函 数 中 定 义 的 变 量 因 为 主 函 数 也 是 一 个 函 数, 它 与 其 它 函 数 是 平 行 关 系 这 一 点 是 与 其 它 语 言 不 同 的, 应 予 以 注 意 2) 形 参 变 量 是 属 于 被 调 函 数 的 局 部 变 量, 实 参 变 量 是 属 于 主 调 函 数 的 局 部 变 量 3) 允 许 在 不 同 的 函 数 中 使 用 相 同 的 变 量 名, 它 们 代 表 不 同 的 对 象, 分 配 不 同 的 单 元, 互 不 干 扰, 也 不 会 发 生 混 淆 如 在 前 例 中, 形 参 和 实 参 的 变 量 名 都 为 n, 是 完 全 允 许 的 第 121 页

122 4) 在 复 合 语 句 中 也 可 定 义 变 量, 其 作 用 域 只 在 复 合 语 句 范 围 内 例 如 : main() int s,a; int b; s=a+b; /*b 作 用 域 */ /*s,a 作 用 域 */ 例 8.12 main() int i=2,j=3,k; k=i+j; int k=8; printf("%d\n",k); printf("%d\n",k); 本 程 序 在 main 中 定 义 了 i,j,k 三 个 变 量, 其 中 k 未 赋 初 值 而 在 复 合 语 句 内 又 定 义 了 一 个 变 量 k, 并 赋 初 值 为 8 应 该 注 意 这 两 个 k 不 是 同 一 个 变 量 在 复 合 语 句 外 由 main 定 义 的 k 起 作 用, 而 在 复 合 语 句 内 则 由 在 复 合 语 句 内 定 义 的 k 起 作 用 因 此 程 序 第 4 行 的 k 为 main 所 定 义, 其 值 应 为 5 第 7 行 输 出 k 值, 该 行 在 复 合 语 句 内, 由 复 合 语 句 内 定 义 的 k 起 作 用, 其 初 值 为 8, 故 输 出 值 为 8, 第 9 行 输 出 i,k 值 i 是 在 整 个 程 序 中 有 效 的, 第 7 行 对 i 赋 值 为 3, 故 以 输 出 也 为 3 而 第 9 行 已 在 复 合 语 句 之 外, 输 出 的 k 应 为 main 所 定 义 的 k, 此 k 值 由 第 4 行 已 获 得 为 5, 故 输 出 也 为 全 局 变 量 全 局 变 量 也 称 为 外 部 变 量, 它 是 在 函 数 外 部 定 义 的 变 量 它 不 属 于 哪 一 个 函 数, 它 属 于 一 个 源 程 序 文 件 其 作 用 域 是 整 个 源 程 序 在 函 数 中 使 用 全 局 变 量, 一 般 应 作 全 局 变 量 说 明 只 有 在 函 数 内 经 过 说 明 的 全 局 变 量 才 能 使 用 全 局 变 量 的 说 明 符 为 extern 但 在 一 个 函 数 之 前 定 义 的 全 局 变 量, 在 该 函 数 内 使 用 可 不 再 加 以 说 明 例 如 : int a,b; /* 外 部 变 量 */ void f1() /* 函 数 f1*/ 第 122 页

123 float x,y; /* 外 部 变 量 */ int fz() /* 函 数 fz*/ main() /* 主 函 数 */ 从 上 例 可 以 看 出 a b x y 都 是 在 函 数 外 部 定 义 的 外 部 变 量, 都 是 全 局 变 量 但 x,y 定 义 在 函 数 f1 之 后, 而 在 f1 内 又 无 对 x,y 的 说 明, 所 以 它 们 在 f1 内 无 效 a,b 定 义 在 源 程 序 最 前 面, 因 此 在 f1,f2 及 main 内 不 加 说 明 也 可 使 用 例 8.13 输 入 正 方 体 的 长 宽 高 l,w,h 求 体 积 及 三 个 面 x*y,x*z,y*z 的 面 积 int s1,s2,s3; int vs( int a,int b,int c) int v; v=a*b*c; s1=a*b; s2=b*c; s3=a*c; return v; main() int v,l,w,h; printf("\ninput length,width and height\n"); scanf("%d%d%d",&l,&w,&h); v=vs(l,w,h); printf("\nv=%d,s1=%d,s2=%d,s3=%d\n",v,s1,s2,s3); 例 8.14 外 部 变 量 与 局 部 变 量 同 名 int a=3,b=5; /*a,b 为 外 部 变 量 */ max(int a,int b) /*a,b 为 外 部 变 量 */ int c; c=a>b?a:b; return(c); main() int a=8; printf("%d\n",max(a,b)); 第 123 页

124 如 果 同 一 个 源 文 件 中, 外 部 变 量 与 局 部 变 量 同 名, 则 在 局 部 变 量 的 作 用 范 围 内, 外 部 变 量 被 屏 蔽, 即 它 不 起 作 用 8.9 变 量 的 存 储 类 别 动 态 存 储 方 式 与 静 态 动 态 存 储 方 式 前 面 已 经 介 绍 了, 从 变 量 的 作 用 域 ( 即 从 空 间 ) 角 度 来 分, 可 以 分 为 全 局 变 量 和 局 部 变 量 从 另 一 个 角 度, 从 变 量 值 存 在 的 作 时 间 ( 即 生 存 期 ) 角 度 来 分, 可 以 分 为 静 态 存 储 方 式 和 动 态 存 储 方 式 静 态 存 储 方 式 : 是 指 在 程 序 运 行 期 间 分 配 固 定 的 存 储 空 间 的 方 式 动 态 存 储 方 式 : 是 在 程 序 运 行 期 间 根 据 需 要 进 行 动 态 的 分 配 存 储 空 间 的 方 式 用 户 存 储 空 间 可 以 分 为 三 个 部 分 : 1) 程 序 区 ; 2) 静 态 存 储 区 ; 3) 动 态 存 储 区 ; 全 局 变 量 全 部 存 放 在 静 态 存 储 区, 在 程 序 开 始 执 行 时 给 全 局 变 量 分 配 存 储 区, 程 序 行 完 毕 就 释 放 在 程 序 执 行 过 程 中 它 们 占 据 固 定 的 存 储 单 元, 而 不 动 态 地 进 行 分 配 和 释 放 ; 动 态 存 储 区 存 放 以 下 数 据 : 1) 函 数 形 式 参 数 ; 2) 自 动 变 量 ( 未 加 static 声 明 的 局 部 变 量 ); 3) 函 数 调 用 实 的 现 场 保 护 和 返 回 地 址 ; 对 以 上 这 些 数 据, 在 函 数 开 始 调 用 时 分 配 动 态 存 储 空 间, 函 数 结 束 时 释 放 这 些 空 间 在 c 语 言 中, 每 个 变 量 和 函 数 有 两 个 属 性 : 数 据 类 型 和 数 据 的 存 储 类 别 auto 变 量 函 数 中 的 局 部 变 量, 如 不 专 门 声 明 为 static 存 储 类 别, 都 是 动 态 地 分 配 存 储 空 间 的, 数 据 存 储 在 动 态 存 储 区 中 函 数 中 的 形 参 和 在 函 数 中 定 义 的 变 量 ( 包 括 在 复 合 语 句 中 定 义 的 变 量 ), 都 属 此 类, 在 调 用 该 函 数 时 系 统 会 给 它 们 分 配 存 储 空 间, 在 函 数 调 用 结 束 时 就 自 动 释 放 这 些 存 储 空 间 这 类 局 部 变 量 称 为 自 动 变 量 自 动 变 量 用 关 键 字 auto 作 存 储 类 别 的 声 明 例 如 : int f(int a) /* 定 义 f 函 数,a 为 参 数 */ auto int b,c=3; /* 定 义 b,c 自 动 变 量 */ 第 124 页

125 a 是 形 参,b,c 是 自 动 变 量, 对 c 赋 初 值 3 执 行 完 f 函 数 后, 自 动 释 放 a,b,c 所 占 的 存 储 单 元 关 键 字 auto 可 以 省 略,auto 不 写 则 隐 含 定 为 自 动 存 储 类 别, 属 于 动 态 存 储 方 式 用 static 声 明 局 部 变 量 有 时 希 望 函 数 中 的 局 部 变 量 的 值 在 函 数 调 用 结 束 后 不 消 失 而 保 留 原 值, 这 时 就 应 该 指 定 局 部 变 量 为 静 态 局 部 变 量, 用 关 键 字 static 进 行 声 明 例 8.15 考 察 静 态 局 部 变 量 的 值 f(int a) auto b=0; static c=3; b=b+1; c=c+1; return(a+b+c); main() int a=2,i; for(i=0;i<3;i++) printf("%d",f(a)); 对 静 态 局 部 变 量 的 说 明 : 1) 静 态 局 部 变 量 属 于 静 态 存 储 类 别, 在 静 态 存 储 区 内 分 配 存 储 单 元 在 程 序 整 个 运 行 期 间 都 不 释 放 而 自 动 变 量 ( 即 动 态 局 部 变 量 ) 属 于 动 态 存 储 类 别, 占 动 态 存 储 空 间, 函 数 调 用 结 束 后 即 释 放 2) 静 态 局 部 变 量 在 编 译 时 赋 初 值, 即 只 赋 初 值 一 次 ; 而 对 自 动 变 量 赋 初 值 是 在 函 数 调 用 时 进 行, 每 调 用 一 次 函 数 重 新 给 一 次 初 值, 相 当 于 执 行 一 次 赋 值 语 句 3) 如 果 在 定 义 局 部 变 量 时 不 赋 初 值 的 话, 则 对 静 态 局 部 变 量 来 说, 编 译 时 自 动 赋 初 值 0( 对 数 值 型 变 量 ) 或 空 字 符 ( 对 字 符 变 量 ) 而 对 自 动 变 量 来 说, 如 果 不 赋 初 值 则 它 的 值 是 一 个 不 确 定 的 值 例 8.16 打 印 1 到 5 的 阶 乘 值 int fac(int n) static int f=1; f=f*n; return(f); main() int i; for(i=1;i<=5;i++) printf("%d!=%d\n",i,fac(i)); 第 125 页

126 8.9.4 register 变 量 为 了 提 高 效 率,C 语 言 允 许 将 局 部 变 量 得 值 放 在 CPU 中 的 寄 存 器 中, 这 种 变 量 叫 寄 存 器 变 量, 用 关 键 字 register 作 声 明 例 8.17 使 用 寄 存 器 变 量 int fac(int n) register int i,f=1; for(i=1;i<=n;i++) f=f*i return(f); main() int i; for(i=0;i<=5;i++) printf("%d!=%d\n",i,fac(i)); 说 明 : 1) 只 有 局 部 自 动 变 量 和 形 式 参 数 可 以 作 为 寄 存 器 变 量 ; 2) 一 个 计 算 机 系 统 中 的 寄 存 器 数 目 有 限, 不 能 定 义 任 意 多 个 寄 存 器 变 量 ; 3) 局 部 静 态 变 量 不 能 定 义 为 寄 存 器 变 量 用 extern 声 明 外 部 变 量 外 部 变 量 ( 即 全 局 变 量 ) 是 在 函 数 的 外 部 定 义 的, 它 的 作 用 域 为 从 变 量 定 义 处 开 始, 到 本 程 序 文 件 的 末 尾 如 果 外 部 变 量 不 在 文 件 的 开 头 定 义, 其 有 效 的 作 用 范 围 只 限 于 定 义 处 到 文 件 终 了 如 果 在 定 义 点 之 前 的 函 数 想 引 用 该 外 部 变 量, 则 应 该 在 引 用 之 前 用 关 键 字 extern 对 该 变 量 作 外 部 变 量 声 明 表 示 该 变 量 是 一 个 已 经 定 义 的 外 部 变 量 有 了 此 声 明, 就 可 以 从 声 明 处 起, 合 法 地 使 用 该 外 部 变 量 例 8.18 用 extern 声 明 外 部 变 量, 扩 展 程 序 文 件 中 的 作 用 域 int max(int x,int y) int z; z=x>y?x:y; return(z); main() extern A,B; printf("%d\n",max(a,b)); int A=13,B=-8; 说 明 : 在 本 程 序 文 件 的 最 后 1 行 定 义 了 外 部 变 量 A,B, 但 由 于 外 部 变 量 定 义 的 位 置 在 函 数 main 之 后, 因 此 第 126 页

127 本 来 在 main 函 数 中 不 能 引 用 外 部 变 量 A,B 现 在 我 们 在 main 函 数 中 用 extern 对 A 和 B 进 行 外 部 变 量 声 明, 就 可 以 从 声 明 处 起, 合 法 地 使 用 该 外 部 变 量 A 和 B 9 预 处 理 命 令 9.1 概 述 在 前 面 各 章 中, 已 多 次 使 用 过 以 # 号 开 头 的 预 处 理 命 令 如 包 含 命 令 #include, 宏 定 义 命 令 #define 等 在 源 程 序 中 这 些 命 令 都 放 在 函 数 之 外, 而 且 一 般 都 放 在 源 文 件 的 前 面, 它 们 称 为 预 处 理 部 分 所 谓 预 处 理 是 指 在 进 行 编 译 的 第 一 遍 扫 描 ( 词 法 扫 描 和 语 法 分 析 ) 之 前 所 作 的 工 作 预 处 理 是 C 语 言 的 一 个 重 要 功 能, 它 由 预 处 理 程 序 负 责 完 成 当 对 一 个 源 文 件 进 行 编 译 时, 系 统 将 自 动 引 用 预 处 理 程 序 对 源 程 序 中 的 预 处 理 部 分 作 处 理, 处 理 完 毕 自 动 进 入 对 源 程 序 的 编 译 C 语 言 提 供 了 多 种 预 处 理 功 能, 如 宏 定 义 文 件 包 含 条 件 编 译 等 合 理 地 使 用 预 处 理 功 能 编 写 的 程 序 便 于 阅 读 修 改 移 植 和 调 试, 也 有 利 于 模 块 化 程 序 设 计 本 章 介 绍 常 用 的 几 种 预 处 理 功 能 9.2 宏 定 义 在 C 语 言 源 程 序 中 允 许 用 一 个 标 识 符 来 表 示 一 个 字 符 串, 称 为 宏 被 定 义 为 宏 的 标 识 符 称 为 宏 名 在 编 译 预 处 理 时, 对 程 序 中 所 有 出 现 的 宏 名, 都 用 宏 定 义 中 的 字 符 串 去 代 换, 这 称 为 宏 代 换 或 宏 展 开 宏 定 义 是 由 源 程 序 中 的 宏 定 义 命 令 完 成 的 宏 代 换 是 由 预 处 理 程 序 自 动 完 成 的 在 C 语 言 中, 宏 分 为 有 参 数 和 无 参 数 两 种 下 面 分 别 讨 论 这 两 种 宏 的 定 义 和 调 用 无 参 宏 定 义 无 参 宏 的 宏 名 后 不 带 参 数 其 定 义 的 一 般 形 式 为 : #define 标 识 符 字 符 串 其 中 的 # 表 示 这 是 一 条 预 处 理 命 令 凡 是 以 # 开 头 的 均 为 预 处 理 命 令 define 为 宏 定 义 命 令 标 识 符 为 所 定 义 的 宏 名 字 符 串 可 以 是 常 数 表 达 式 格 式 串 等 在 前 面 介 绍 过 的 符 号 常 量 的 定 义 就 是 一 种 无 参 宏 定 义 此 外, 常 对 程 序 中 反 复 使 用 的 表 达 式 进 行 宏 定 义 例 如 : #define M (y*y+3*y) 它 的 作 用 是 指 定 标 识 符 M 来 代 替 表 达 式 (y*y+3*y) 在 编 写 源 程 序 时, 所 有 的 (y*y+3*y) 都 可 由 M 代 替, 而 对 源 程 序 作 编 译 时, 将 先 由 预 处 理 程 序 进 行 宏 代 换, 即 用 (y*y+3*y) 表 达 式 去 置 换 所 有 的 宏 名 M, 然 后 再 进 行 编 译 例 9.1 #define M (y*y+3*y) main() int s,y; printf("input a number: "); scanf("%d",&y); 第 127 页

128 s=3*m+4*m+5*m; printf("s=%d\n",s); 上 例 程 序 中 首 先 进 行 宏 定 义, 定 义 M 来 替 代 表 达 式 (y*y+3*y), 在 s=3*m+4*m+5* M 中 作 了 宏 调 用 在 预 处 理 时 经 宏 展 开 后 该 语 句 变 为 : s=3*(y*y+3*y)+4*(y*y+3*y)+5*(y*y+3*y); 但 要 注 意 的 是, 在 宏 定 义 中 表 达 式 (y*y+3*y) 两 边 的 括 号 不 能 少 否 则 会 发 生 错 误 如 当 作 以 下 定 义 后 : #difine M y*y+3*y 在 宏 展 开 时 将 得 到 下 述 语 句 : 这 相 当 于 : s=3*y*y+3*y+4*y*y+3*y+5*y*y+3*y; 3y 2 +3y+4y 2 +3y+5y 2 +3y; 显 然 与 原 题 意 要 求 不 符 计 算 结 果 当 然 是 错 误 的 因 此 在 作 宏 定 义 时 必 须 十 分 注 意 应 保 证 在 宏 代 换 之 后 不 发 生 错 误 对 于 宏 定 义 还 要 说 明 以 下 几 点 : 1) 宏 定 义 是 用 宏 名 来 表 示 一 个 字 符 串, 在 宏 展 开 时 又 以 该 字 符 串 取 代 宏 名, 这 只 是 一 种 简 单 的 代 换, 字 符 串 中 可 以 含 任 何 字 符, 可 以 是 常 数, 也 可 以 是 表 达 式, 预 处 理 程 序 对 它 不 作 任 何 检 查 如 有 错 误, 只 能 在 编 译 已 被 宏 展 开 后 的 源 程 序 时 发 现 2) 宏 定 义 不 是 说 明 或 语 句, 在 行 末 不 必 加 分 号, 如 加 上 分 号 则 连 分 号 也 一 起 置 换 3) 宏 定 义 必 须 写 在 函 数 之 外, 其 作 用 域 为 宏 定 义 命 令 起 到 源 程 序 结 束 如 要 终 止 其 作 用 域 可 使 用 # undef 命 令 例 如 : #define PI main() #undef PI f1() 表 示 PI 只 在 main 函 数 中 有 效, 在 f1 中 无 效 4) 宏 名 在 源 程 序 中 若 用 引 号 括 起 来, 则 预 处 理 程 序 不 对 其 作 宏 代 换 例 9.2 #define OK 100 main() printf("ok"); 第 128 页

129 printf("\n"); 上 例 中 定 义 宏 名 OK 表 示 100, 但 在 printf 语 句 中 OK 被 引 号 括 起 来, 因 此 不 作 宏 代 换 程 序 的 运 行 结 果 为 :OK 这 表 示 把 OK 当 字 符 串 处 理 5) 宏 定 义 允 许 嵌 套, 在 宏 定 义 的 字 符 串 中 可 以 使 用 已 经 定 义 的 宏 名 在 宏 展 开 时 由 预 处 理 程 序 层 层 代 换 例 如 : #define PI #define S PI*y*y /* PI 是 已 定 义 的 宏 名 */ 对 语 句 : printf("%f",s); 在 宏 代 换 后 变 为 : printf("%f", *y*y); 6) 习 惯 上 宏 名 用 大 写 字 母 表 示, 以 便 于 与 变 量 区 别 但 也 允 许 用 小 写 字 母 7) 可 用 宏 定 义 表 示 数 据 类 型, 使 书 写 方 便 例 如 : #define STU struct stu 在 程 序 中 可 用 STU 作 变 量 说 明 : STU body[5],*p; #define INTEGER int 在 程 序 中 即 可 用 INTEGER 作 整 型 变 量 说 明 : INTEGER a,b; 应 注 意 用 宏 定 义 表 示 数 据 类 型 和 用 typedef 定 义 数 据 说 明 符 的 区 别 宏 定 义 只 是 简 单 的 字 符 串 代 换, 是 在 预 处 理 完 成 的, 而 typedef 是 在 编 译 时 处 理 的, 它 不 是 作 简 单 的 代 换, 而 是 对 类 型 说 明 符 重 新 命 名 被 命 名 的 标 识 符 具 有 类 型 定 义 说 明 的 功 能 请 看 下 面 的 例 子 : #define PIN1 int * typedef (int *) PIN2; 从 形 式 上 看 这 两 者 相 似, 但 在 实 际 使 用 中 却 不 相 同 下 面 用 PIN1,PIN2 说 明 变 量 时 就 可 以 看 出 它 们 的 区 别 : PIN1 a,b; 在 宏 代 换 后 变 成 : int *a,b; 表 示 a 是 指 向 整 型 的 指 针 变 量, 而 b 是 整 型 变 量 然 而 : PIN2 a,b; 表 示 a,b 都 是 指 向 整 型 的 指 针 变 量 因 为 PIN2 是 一 个 类 型 说 明 符 由 这 个 例 子 可 见, 宏 定 义 虽 然 也 可 表 示 数 据 类 型, 但 毕 竟 是 作 字 符 代 换 在 使 用 时 要 分 外 小 心, 以 避 出 错 8) 对 输 出 格 式 作 宏 定 义, 可 以 减 少 书 写 麻 烦 例 9.3 中 就 采 用 了 这 种 方 法 #define P printf #define D "%d\n" #define F "%f\n" 第 129 页

130 main() int a=5, c=8, e=11; float b=3.8, d=9.7, f=21.08; P(D F,a,b); P(D F,c,d); P(D F,e,f); 带 参 宏 定 义 C 语 言 允 许 宏 带 有 参 数 在 宏 定 义 中 的 参 数 称 为 形 式 参 数, 在 宏 调 用 中 的 参 数 称 为 实 际 参 数 对 带 参 数 的 宏, 在 调 用 中, 不 仅 要 宏 展 开, 而 且 要 用 实 参 去 代 换 形 参 带 参 宏 定 义 的 一 般 形 式 为 : #define 宏 名 ( 形 参 表 ) 字 符 串 在 字 符 串 中 含 有 各 个 形 参 带 参 宏 调 用 的 一 般 形 式 为 : 宏 名 ( 实 参 表 ); 例 如 : #define M(y) y*y+3*y /* 宏 定 义 */ k=m(5); /* 宏 调 用 */ 在 宏 调 用 时, 用 实 参 5 去 代 替 形 参 y, 经 预 处 理 宏 展 开 后 的 语 句 为 : k=5*5+3*5 例 9.4 #define MAX(a,b) (a>b)?a:b main() int x,y,max; printf("input two numbers: "); scanf("%d%d",&x,&y); max=max(x,y); printf("max=%d\n",max); 上 例 程 序 的 第 一 行 进 行 带 参 宏 定 义, 用 宏 名 MAX 表 示 条 件 表 达 式 (a>b)?a:b, 形 参 a,b 均 出 现 在 条 件 表 达 式 中 程 序 第 七 行 max=max(x,y) 为 宏 调 用, 实 参 x,y, 将 代 换 形 参 a,b 宏 展 开 后 该 语 句 为 : max=(x>y)?x:y; 用 于 计 算 x,y 中 的 大 数 对 于 带 参 的 宏 定 义 有 以 下 问 题 需 要 说 明 : 1. 带 参 宏 定 义 中, 宏 名 和 形 参 表 之 间 不 能 有 空 格 出 现 例 如 把 : 第 130 页

131 #define MAX(a,b) (a>b)?a:b 写 为 : #define MAX (a,b) (a>b)?a:b 将 被 认 为 是 无 参 宏 定 义, 宏 名 MAX 代 表 字 符 串 (a,b) (a>b)?a:b 宏 展 开 时, 宏 调 用 语 句 : max=max(x,y); 将 变 为 : max=(a,b)(a>b)?a:b(x,y); 这 显 然 是 错 误 的 2. 在 带 参 宏 定 义 中, 形 式 参 数 不 分 配 内 存 单 元, 因 此 不 必 作 类 型 定 义 而 宏 调 用 中 的 实 参 有 具 体 的 值 要 用 它 们 去 代 换 形 参, 因 此 必 须 作 类 型 说 明 这 是 与 函 数 中 的 情 况 不 同 的 在 函 数 中, 形 参 和 实 参 是 两 个 不 同 的 量, 各 有 自 己 的 作 用 域, 调 用 时 要 把 实 参 值 赋 予 形 参, 进 行 值 传 递 而 在 带 参 宏 中, 只 是 符 号 代 换, 不 存 在 值 传 递 的 问 题 3. 在 宏 定 义 中 的 形 参 是 标 识 符, 而 宏 调 用 中 的 实 参 可 以 是 表 达 式 例 9.5 #define SQ(y) (y)*(y) main() int a,sq; printf("input a number: "); scanf("%d",&a); sq=sq(a+1); printf("sq=%d\n",sq); 上 例 中 第 一 行 为 宏 定 义, 形 参 为 y 程 序 第 七 行 宏 调 用 中 实 参 为 a+1, 是 一 个 表 达 式, 在 宏 展 开 时, 用 a+1 代 换 y, 再 用 (y)*(y) 代 换 SQ, 得 到 如 下 语 句 : sq=(a+1)*(a+1); 这 与 函 数 的 调 用 是 不 同 的, 函 数 调 用 时 要 把 实 参 表 达 式 的 值 求 出 来 再 赋 予 形 参 而 宏 代 换 中 对 实 参 表 达 式 不 作 计 算 直 接 地 照 原 样 代 换 4. 在 宏 定 义 中, 字 符 串 内 的 形 参 通 常 要 用 括 号 括 起 来 以 避 免 出 错 在 上 例 中 的 宏 定 义 中 (y)*(y) 表 达 式 的 y 都 用 括 号 括 起 来, 因 此 结 果 是 正 确 的 如 果 去 掉 括 号, 把 程 序 改 为 以 下 形 式 : 例 9.6 #define SQ(y) y*y main() int a,sq; printf("input a number: "); scanf("%d",&a); sq=sq(a+1); printf("sq=%d\n",sq); 运 行 结 果 为 : input a number:3 第 131 页

132 sq=7 同 样 输 入 3, 但 结 果 却 是 不 一 样 的 问 题 在 哪 里 呢? 这 是 由 于 代 换 只 作 符 号 代 换 而 不 作 其 它 处 理 而 造 成 的 宏 代 换 后 将 得 到 以 下 语 句 : sq=a+1*a+1; 由 于 a 为 3 故 sq 的 值 为 7 这 显 然 与 题 意 相 违, 因 此 参 数 两 边 的 括 号 是 不 能 少 的 即 使 在 参 数 两 边 加 括 号 还 是 不 够 的, 请 看 下 面 程 序 : 例 9.7 #define SQ(y) (y)*(y) main() int a,sq; printf("input a number: "); scanf("%d",&a); sq=160/sq(a+1); printf("sq=%d\n",sq); 本 程 序 与 前 例 相 比, 只 把 宏 调 用 语 句 改 为 : sq=160/sq(a+1); 运 行 本 程 序 如 输 入 值 仍 为 3 时, 希 望 结 果 为 10 但 实 际 运 行 的 结 果 如 下 : input a number:3 sq=160 为 什 么 会 得 这 样 的 结 果 呢? 分 析 宏 调 用 语 句, 在 宏 代 换 之 后 变 为 : sq=160/(a+1)*(a+1); a 为 3 时, 由 于 / 和 * 运 算 符 优 先 级 和 结 合 性 相 同, 则 先 作 160/(3+1) 得 40, 再 作 40*(3+1) 最 后 得 160 为 了 得 到 正 确 答 案 应 在 宏 定 义 中 的 整 个 字 符 串 外 加 括 号, 程 序 修 改 如 下 : 例 9.8 #define SQ(y) ((y)*(y)) main() int a,sq; printf("input a number: "); scanf("%d",&a); sq=160/sq(a+1); printf("sq=%d\n",sq); 以 上 讨 论 说 明, 对 于 宏 定 义 不 仅 应 在 参 数 两 侧 加 括 号, 也 应 在 整 个 字 符 串 外 加 括 号 5. 带 参 的 宏 和 带 参 函 数 很 相 似, 但 有 本 质 上 的 不 同, 除 上 面 已 谈 到 的 各 点 外, 把 同 一 表 达 式 用 函 数 处 理 与 用 宏 处 理 两 者 的 结 果 有 可 能 是 不 同 的 例 9.9 main() int i=1; while(i<=5) 第 132 页

133 printf("%d\n",sq(i++)); SQ(int y) return((y)*(y)); 例 9.10 #define SQ(y) ((y)*(y)) main() int i=1; while(i<=5) printf("%d\n",sq(i++)); 在 例 9.9 中 函 数 名 为 SQ, 形 参 为 Y, 函 数 体 表 达 式 为 ((y)*(y)) 在 例 9.10 中 宏 名 为 SQ, 形 参 也 为 y, 字 符 串 表 达 式 为 (y)*(y)) 例 9.9 的 函 数 调 用 为 SQ(i++), 例 9.10 的 宏 调 用 为 SQ(i++), 实 参 也 是 相 同 的 从 输 出 结 果 来 看, 却 大 不 相 同 分 析 如 下 : 在 例 9.9 中, 函 数 调 用 是 把 实 参 i 值 传 给 形 参 y 后 自 增 1 然 后 输 出 函 数 值 因 而 要 循 环 5 次 输 出 1~5 的 平 方 值 而 在 例 9.10 中 宏 调 用 时, 只 作 代 换 SQ(i++) 被 代 换 为 ((i++)*(i++)) 在 第 一 次 循 环 时, 由 于 i 等 于 1, 其 计 算 过 程 为 : 表 达 式 中 前 一 个 i 初 值 为 1, 然 后 i 自 增 1 变 为 2, 因 此 表 达 式 中 第 2 个 i 初 值 为 2, 两 相 乘 的 结 果 也 为 2, 然 后 i 值 再 自 增 1, 得 3 在 第 二 次 循 环 时,i 值 已 有 初 值 为 3, 因 此 表 达 式 中 前 一 个 i 为 3, 后 一 个 i 为 4, 乘 积 为 12, 然 后 i 再 自 增 1 变 为 5 进 入 第 三 次 循 环, 由 于 i 值 已 为 5, 所 以 这 将 是 最 后 一 次 循 环 计 算 表 达 式 的 值 为 5*6 等 于 30 i 值 再 自 增 1 变 为 6, 不 再 满 足 循 环 条 件, 停 止 循 环 从 以 上 分 析 可 以 看 出 函 数 调 用 和 宏 调 用 二 者 在 形 式 上 相 似, 在 本 质 上 是 完 全 不 同 的 6. 宏 定 义 也 可 用 来 定 义 多 个 语 句, 在 宏 调 用 时, 把 这 些 语 句 又 代 换 到 源 程 序 内 看 下 面 的 例 子 例 9.11 #define SSSV(s1,s2,s3,v) s1=l*w;s2=l*h;s3=w*h;v=w*l*h; main() int l=3,w=4,h=5,sa,sb,sc,vv; SSSV(sa,sb,sc,vv); printf("sa=%d\nsb=%d\nsc=%d\nvv=%d\n",sa,sb,sc,vv); 程 序 第 一 行 为 宏 定 义, 用 宏 名 SSSV 表 示 4 个 赋 值 语 句,4 个 形 参 分 别 为 4 个 赋 值 符 左 部 的 变 量 在 宏 调 用 时, 把 4 个 语 句 展 开 并 用 实 参 代 替 形 参 使 计 算 结 果 送 入 实 参 之 中 9.3 文 件 包 含 文 件 包 含 是 C 预 处 理 程 序 的 另 一 个 重 要 功 能 第 133 页

134 文 件 包 含 命 令 行 的 一 般 形 式 为 : #include" 文 件 名 " 在 前 面 我 们 已 多 次 用 此 命 令 包 含 过 库 函 数 的 头 文 件 例 如 : #include"stdio.h" #include"math.h" 文 件 包 含 命 令 的 功 能 是 把 指 定 的 文 件 插 入 该 命 令 行 位 置 取 代 该 命 令 行, 从 而 把 指 定 的 文 件 和 当 前 的 源 程 序 文 件 连 成 一 个 源 文 件 在 程 序 设 计 中, 文 件 包 含 是 很 有 用 的 一 个 大 的 程 序 可 以 分 为 多 个 模 块, 由 多 个 程 序 员 分 别 编 程 有 些 公 用 的 符 号 常 量 或 宏 定 义 等 可 单 独 组 成 一 个 文 件, 在 其 它 文 件 的 开 头 用 包 含 命 令 包 含 该 文 件 即 可 使 用 这 样, 可 避 免 在 每 个 文 件 开 头 都 去 书 写 那 些 公 用 量, 从 而 节 省 时 间, 并 减 少 出 错 对 文 件 包 含 命 令 还 要 说 明 以 下 几 点 : 1. 包 含 命 令 中 的 文 件 名 可 以 用 双 引 号 括 起 来, 也 可 以 用 尖 括 号 括 起 来 例 如 以 下 写 法 都 是 允 许 的 : #include"stdio.h" #include<math.h> 但 是 这 两 种 形 式 是 有 区 别 的 : 使 用 尖 括 号 表 示 在 包 含 文 件 目 录 中 去 查 找 ( 包 含 目 录 是 由 用 户 在 设 置 环 境 时 设 置 的 ), 而 不 在 源 文 件 目 录 去 查 找 ; 使 用 双 引 号 则 表 示 首 先 在 当 前 的 源 文 件 目 录 中 查 找, 若 未 找 到 才 到 包 含 目 录 中 去 查 找 用 户 编 程 时 可 根 据 自 己 文 件 所 在 的 目 录 来 选 择 某 一 种 命 令 形 式 2. 一 个 include 命 令 只 能 指 定 一 个 被 包 含 文 件, 若 有 多 个 文 件 要 包 含, 则 需 用 多 个 include 命 令 3. 文 件 包 含 允 许 嵌 套, 即 在 一 个 被 包 含 的 文 件 中 又 可 以 包 含 另 一 个 文 件 9.4 条 件 编 译 预 处 理 程 序 提 供 了 条 件 编 译 的 功 能 可 以 按 不 同 的 条 件 去 编 译 不 同 的 程 序 部 分, 因 而 产 生 不 同 的 目 标 代 码 文 件 这 对 于 程 序 的 移 植 和 调 试 是 很 有 用 的 条 件 编 译 有 三 种 形 式, 下 面 分 别 介 绍 : 1. 第 一 种 形 式 : #ifdef 标 识 符 程 序 段 1 #else 程 序 段 2 #endif 它 的 功 能 是, 如 果 标 识 符 已 被 #define 命 令 定 义 过 则 对 程 序 段 1 进 行 编 译 ; 否 则 对 程 序 段 2 进 行 编 译 如 果 没 有 程 序 段 2( 它 为 空 ), 本 格 式 中 的 #else 可 以 没 有, 即 可 以 写 为 : #ifdef 标 识 符 程 序 段 #endif 例 9.12 #define NUM ok main() struct stu int num; char *name; 第 134 页

135 char sex; float score; *ps; ps=(struct stu*)malloc(sizeof(struct stu)); ps->num=102; ps->name="zhang ping"; ps->sex='m'; ps->score=62.5; #ifdef NUM printf("number=%d\nscore=%f\n",ps->num,ps->score); #else printf("name=%s\nsex=%c\n",ps->name,ps->sex); #endif free(ps); 由 于 在 程 序 的 第 16 行 插 入 了 条 件 编 译 预 处 理 命 令, 因 此 要 根 据 NUM 是 否 被 定 义 过 来 决 定 编 译 那 一 个 printf 语 句 而 在 程 序 的 第 一 行 已 对 NUM 作 过 宏 定 义, 因 此 应 对 第 一 个 printf 语 句 作 编 译 故 运 行 结 果 是 输 出 了 学 号 和 成 绩 在 程 序 的 第 一 行 宏 定 义 中, 定 义 NUM 表 示 字 符 串 OK, 其 实 也 可 以 为 任 何 字 符 串, 甚 至 不 给 出 任 何 字 符 串, 写 为 : #define NUM 也 具 有 同 样 的 意 义 只 有 取 消 程 序 的 第 一 行 才 会 去 编 译 第 二 个 printf 语 句 读 者 可 上 机 试 作 2. 第 二 种 形 式 : #ifndef 标 识 符 程 序 段 1 #else 程 序 段 2 #endif 与 第 一 种 形 式 的 区 别 是 将 ifdef 改 为 ifndef 它 的 功 能 是, 如 果 标 识 符 未 被 #define 命 令 定 义 过 则 对 程 序 段 1 进 行 编 译, 否 则 对 程 序 段 2 进 行 编 译 这 与 第 一 种 形 式 的 功 能 正 相 反 3. 第 三 种 形 式 : #if 常 量 表 达 式 程 序 段 1 #else 程 序 段 2 #endif 它 的 功 能 是, 如 常 量 表 达 式 的 值 为 真 ( 非 0), 则 对 程 序 段 1 进 行 编 译, 否 则 对 程 序 段 2 进 行 编 译 因 此 可 以 使 程 序 在 不 同 条 件 下, 完 成 不 同 的 功 能 例 9.13 #define R 1 main() float c,r,s; 第 135 页

136 printf ("input a number: "); scanf("%f",&c); #if R r= *c*c; printf("area of round is: %f\n",r); #else s=c*c; printf("area of square is: %f\n",s); #endif 本 例 中 采 用 了 第 三 种 形 式 的 条 件 编 译 在 程 序 第 一 行 宏 定 义 中, 定 义 R 为 1, 因 此 在 条 件 编 译 时, 常 量 表 达 式 的 值 为 真, 故 计 算 并 输 出 圆 面 积 上 面 介 绍 的 条 件 编 译 当 然 也 可 以 用 条 件 语 句 来 实 现 但 是 用 条 件 语 句 将 会 对 整 个 源 程 序 进 行 编 译, 生 成 的 目 标 代 码 程 序 很 长, 而 采 用 条 件 编 译, 则 根 据 条 件 只 编 译 其 中 的 程 序 段 1 或 程 序 段 2, 生 成 的 目 标 程 序 较 短 如 果 条 件 选 择 的 程 序 段 很 长, 采 用 条 件 编 译 的 方 法 是 十 分 必 要 的 9.5 本 章 小 结 1. 预 处 理 功 能 是 C 语 言 特 有 的 功 能, 它 是 在 对 源 程 序 正 式 编 译 前 由 预 处 理 程 序 完 成 的 程 序 员 在 程 序 中 用 预 处 理 命 令 来 调 用 这 些 功 能 2. 宏 定 义 是 用 一 个 标 识 符 来 表 示 一 个 字 符 串, 这 个 字 符 串 可 以 是 常 量 变 量 或 表 达 式 在 宏 调 用 中 将 用 该 字 符 串 代 换 宏 名 3. 宏 定 义 可 以 带 有 参 数, 宏 调 用 时 是 以 实 参 代 换 形 参 而 不 是 值 传 送 4. 为 了 避 免 宏 代 换 时 发 生 错 误, 宏 定 义 中 的 字 符 串 应 加 括 号, 字 符 串 中 出 现 的 形 式 参 数 两 边 也 应 加 括 号 5. 文 件 包 含 是 预 处 理 的 一 个 重 要 功 能, 它 可 用 来 把 多 个 源 文 件 连 接 成 一 个 源 文 件 进 行 编 译, 结 果 将 生 成 一 个 目 标 文 件 6. 条 件 编 译 允 许 只 编 译 源 程 序 中 满 足 条 件 的 程 序 段, 使 生 成 的 目 标 程 序 较 短, 从 而 减 少 了 内 存 的 开 销 并 提 高 了 程 序 的 效 率 7. 使 用 预 处 理 功 能 便 于 程 序 的 修 改 阅 读 移 植 和 调 试, 也 便 于 实 现 模 块 化 程 序 设 计 10 指 针 指 针 是 C 语 言 中 广 泛 使 用 的 一 种 数 据 类 型 运 用 指 针 编 程 是 C 语 言 最 主 要 的 风 格 之 一 利 用 指 针 变 量 可 以 表 示 各 种 数 据 结 构 ; 能 很 方 便 地 使 用 数 组 和 字 符 串 ; 并 能 象 汇 编 语 言 一 样 处 理 内 存 地 址, 从 而 编 出 精 练 而 高 效 的 程 序 指 针 极 大 地 丰 富 了 C 语 言 的 功 能 学 习 指 针 是 学 习 C 语 言 中 最 重 要 的 一 环, 能 否 正 确 理 解 和 使 用 指 针 是 我 们 是 否 掌 握 C 语 言 的 一 个 标 志 同 时, 指 针 也 是 C 语 言 中 最 为 困 难 的 一 部 分, 在 学 习 中 除 了 要 正 确 理 解 基 本 概 念, 还 必 须 要 多 编 程, 上 机 调 试 只 要 作 到 这 些, 指 针 也 是 不 难 掌 握 的 第 136 页

137 10.1 地 址 指 针 的 基 本 概 念 在 计 算 机 中, 所 有 的 数 据 都 是 存 放 在 存 储 器 中 的 一 般 把 存 储 器 中 的 一 个 字 节 称 为 一 个 内 存 单 元, 不 同 的 数 据 类 型 所 占 用 的 内 存 单 元 数 不 等, 如 整 型 量 占 2 个 单 元, 字 符 量 占 1 个 单 元 等, 在 前 面 已 有 详 细 的 介 绍 为 了 正 确 地 访 问 这 些 内 存 单 元, 必 须 为 每 个 内 存 单 元 编 上 号 根 据 一 个 内 存 单 元 的 编 号 即 可 准 确 地 找 到 该 内 存 单 元 内 存 单 元 的 编 号 也 叫 做 地 址 既 然 根 据 内 存 单 元 的 编 号 或 地 址 就 可 以 找 到 所 需 的 内 存 单 元, 所 以 通 常 也 把 这 个 地 址 称 为 指 针 内 存 单 元 的 指 针 和 内 存 单 元 的 内 容 是 两 个 不 同 的 概 念 可 以 用 一 个 通 俗 的 例 子 来 说 明 它 们 之 间 的 关 系 我 们 到 银 行 去 存 取 款 时, 银 行 工 作 人 员 将 根 据 我 们 的 帐 号 去 找 我 们 的 存 款 单, 找 到 之 后 在 存 单 上 写 入 存 款 取 款 的 金 额 在 这 里, 帐 号 就 是 存 单 的 指 针, 存 款 数 是 存 单 的 内 容 对 于 一 个 内 存 单 元 来 说, 单 元 的 地 址 即 为 指 针, 其 中 存 放 的 数 据 才 是 该 单 元 的 内 容 在 C 语 言 中, 允 许 用 一 个 变 量 来 存 放 指 针, 这 种 变 量 称 为 指 针 变 量 因 此, 一 个 指 针 变 量 的 值 就 是 某 个 内 存 单 元 的 地 址 或 称 为 某 内 存 单 元 的 指 针 图 中, 设 有 字 符 变 量 C, 其 内 容 为 K (ASCII 码 为 十 进 制 数 75),C 占 用 了 011A 号 单 元 ( 地 址 用 十 六 进 数 表 示 ) 设 有 指 针 变 量 P, 内 容 为 011A, 这 种 情 况 我 们 称 为 P 指 向 变 量 C, 或 说 P 是 指 向 变 量 C 的 指 针 严 格 地 说, 一 个 指 针 是 一 个 地 址, 是 一 个 常 量 而 一 个 指 针 变 量 却 可 以 被 赋 予 不 同 的 指 针 值, 是 变 量 但 常 把 指 针 变 量 简 称 为 指 针 为 了 避 免 混 淆, 我 们 中 约 定 : 指 针 是 指 地 址, 是 常 量, 指 针 变 量 是 指 取 值 为 地 址 的 变 量 定 义 指 针 的 目 的 是 为 了 通 过 指 针 去 访 问 内 存 单 元 既 然 指 针 变 量 的 值 是 一 个 地 址, 那 么 这 个 地 址 不 仅 可 以 是 变 量 的 地 址, 也 可 以 是 其 它 数 据 结 构 的 地 址 在 一 个 指 针 变 量 中 存 放 一 个 数 组 或 一 个 函 数 的 首 地 址 有 何 意 义 呢? 因 为 数 组 或 函 数 都 是 连 续 存 放 的 通 过 访 问 指 针 变 量 取 得 了 数 组 或 函 数 的 首 地 址, 也 就 找 到 了 该 数 组 或 函 数 这 样 一 来, 凡 是 出 现 数 组, 函 数 的 地 方 都 可 以 用 一 个 指 针 变 量 来 表 示, 只 要 该 指 针 变 量 中 赋 予 数 组 或 函 数 的 首 地 址 即 可 这 样 做, 将 会 使 程 序 的 概 念 十 分 清 楚, 程 序 本 身 也 精 练, 高 效 在 C 语 言 中, 一 种 数 据 类 型 或 数 据 结 构 往 往 都 占 有 一 组 连 续 的 内 存 单 元 用 地 址 这 个 概 念 并 不 能 很 好 地 描 述 一 种 数 据 类 型 或 数 据 结 构, 而 指 针 虽 然 实 际 上 也 是 一 个 地 址, 但 它 却 是 一 个 数 据 结 构 的 首 地 址, 它 是 指 向 一 个 数 据 结 构 的, 因 而 概 念 更 为 清 楚, 表 示 更 为 明 确 这 也 是 引 入 指 针 概 念 的 一 个 重 要 原 因 10.2 变 量 的 指 针 和 指 向 变 量 的 指 针 变 量 变 量 的 指 针 就 是 变 量 的 地 址 存 放 变 量 地 址 的 变 量 是 指 针 变 量 即 在 C 语 言 中, 允 许 用 一 个 变 量 来 存 放 指 针, 这 种 变 量 称 为 指 针 变 量 因 此, 一 个 指 针 变 量 的 值 就 是 某 个 变 量 的 地 址 或 称 为 某 变 量 的 指 针 为 了 表 示 指 针 变 量 和 它 所 指 向 的 变 量 之 间 的 关 系, 在 程 序 中 用 * 符 号 表 示 指 向, 例 如,i_pointer 代 表 指 针 变 量, 而 *i_pointer 是 i_pointer 所 指 向 的 变 量 第 137 页

138 因 此, 下 面 两 个 语 句 作 用 相 同 : i=3; *i_pointer=3; 第 二 个 语 句 的 含 义 是 将 3 赋 给 指 针 变 量 i_pointer 所 指 向 的 变 量 定 义 一 个 指 针 变 量 对 指 针 变 量 的 定 义 包 括 三 个 内 容 : (1) 指 针 类 型 说 明, 即 定 义 变 量 为 一 个 指 针 变 量 ; (2) 指 针 变 量 名 ; (3) 变 量 值 ( 指 针 ) 所 指 向 的 变 量 的 数 据 类 型 其 一 般 形 式 为 : 类 型 说 明 符 * 变 量 名 ; 其 中,* 表 示 这 是 一 个 指 针 变 量, 变 量 名 即 为 定 义 的 指 针 变 量 名, 类 型 说 明 符 表 示 本 指 针 变 量 所 指 向 的 变 量 的 数 据 类 型 例 如 : int *p1; 表 示 p1 是 一 个 指 针 变 量, 它 的 值 是 某 个 整 型 变 量 的 地 址 或 者 说 p1 指 向 一 个 整 型 变 量 至 于 p1 究 竟 指 向 哪 一 个 整 型 变 量, 应 由 向 p1 赋 予 的 地 址 来 决 定 再 如 : int *p2; /*p2 是 指 向 整 型 变 量 的 指 针 变 量 */ float *p3; /*p3 是 指 向 浮 点 变 量 的 指 针 变 量 */ char *p4; /*p4 是 指 向 字 符 变 量 的 指 针 变 量 */ 应 该 注 意 的 是, 一 个 指 针 变 量 只 能 指 向 同 类 型 的 变 量, 如 P3 只 能 指 向 浮 点 变 量, 不 能 时 而 指 向 一 个 浮 点 变 量, 时 而 又 指 向 一 个 字 符 变 量 指 针 变 量 的 引 用 指 针 变 量 同 普 通 变 量 一 样, 使 用 之 前 不 仅 要 定 义 说 明, 而 且 必 须 赋 予 具 体 的 值 未 经 赋 值 的 指 针 变 量 不 能 使 用, 否 则 将 造 成 系 统 混 乱, 甚 至 死 机 指 针 变 量 的 赋 值 只 能 赋 予 地 址, 决 不 能 赋 予 任 何 其 它 数 据, 否 则 将 引 起 错 误 在 C 语 言 中, 变 量 的 地 址 是 由 编 译 系 统 分 配 的, 对 用 户 完 全 透 明, 用 户 不 知 道 变 量 的 具 体 地 址 两 个 有 关 的 运 算 符 : 1) &: 取 地 址 运 算 符 2) *: 指 针 运 算 符 ( 或 称 间 接 访 问 运 算 符 ) C 语 言 中 提 供 了 地 址 运 算 符 & 来 表 示 变 量 的 地 址 其 一 般 形 式 为 : 第 138 页

139 & 变 量 名 ; 如 &a 表 示 变 量 a 的 地 址,&b 表 示 变 量 b 的 地 址 变 量 本 身 必 须 预 先 说 明 设 有 指 向 整 型 变 量 的 指 针 变 量 p, 如 要 把 整 型 变 量 a 的 地 址 赋 予 p 可 以 有 以 下 两 种 方 式 : (1) 指 针 变 量 初 始 化 的 方 法 int a; int *p=&a; (2) 赋 值 语 句 的 方 法 int a; int *p; p=&a; 不 允 许 把 一 个 数 赋 予 指 针 变 量, 故 下 面 的 赋 值 是 错 误 的 : int *p; p=1000; 被 赋 值 的 指 针 变 量 前 不 能 再 加 * 说 明 符, 如 写 为 *p=&a 也 是 错 误 的 假 设 : int i=200, x; int *ip; 我 们 定 义 了 两 个 整 型 变 量 i,x, 还 定 义 了 一 个 指 向 整 型 数 的 指 针 变 量 ip i,x 中 可 存 放 整 数, 而 ip 中 只 能 存 放 整 型 变 量 的 地 址 我 们 可 以 把 i 的 地 址 赋 给 ip: ip=&i; 此 时 指 针 变 量 ip 指 向 整 型 变 量 i, 假 设 变 量 i 的 地 址 为 1800, 这 个 赋 值 可 形 象 理 解 为 下 图 所 示 的 联 系 以 后 我 们 便 可 以 通 过 指 针 变 量 ip 间 接 访 问 变 量 i, 例 如 : x=*ip; 运 算 符 * 访 问 以 ip 为 地 址 的 存 贮 区 域, 而 ip 中 存 放 的 是 变 量 i 的 地 址, 因 此,*ip 访 问 的 是 地 址 为 1800 的 存 贮 区 域 ( 因 为 是 整 数, 实 际 上 是 从 1800 开 始 的 两 个 字 节 ), 它 就 是 i 所 占 用 的 存 贮 区 域, 所 以 上 面 的 赋 值 表 达 式 等 价 于 x=i; 另 外, 指 针 变 量 和 一 般 变 量 一 样, 存 放 在 它 们 之 中 的 值 是 可 以 改 变 的, 也 就 是 说 可 以 改 变 它 们 的 指 向, 假 设 int i,j,*p1,*p2; i='a'; j='b'; p1=&i; p2=&j; 则 建 立 如 下 图 所 示 的 联 系 : 第 139 页

140 这 时 赋 值 表 达 式 : p2=p1 就 使 p2 与 p1 指 向 同 一 对 象 i, 此 时 *p2 就 等 价 于 i, 而 不 是 j, 图 所 示 : 如 果 执 行 如 下 表 达 式 : *p2=*p1; 则 表 示 把 p1 指 向 的 内 容 赋 给 p2 所 指 的 区 域, 此 时 就 变 成 图 所 示 通 过 指 针 访 问 它 所 指 向 的 一 个 变 量 是 以 间 接 访 问 的 形 式 进 行 的, 所 以 比 直 接 访 问 一 个 变 量 要 费 时 间, 而 且 不 直 观, 因 为 通 过 指 针 要 访 问 哪 一 个 变 量, 取 决 于 指 针 的 值 ( 即 指 向 ), 例 如 "*p2=*p1;" 实 际 上 就 是 "j=i;", 前 者 第 140 页

141 不 仅 速 度 慢 而 且 目 的 不 明 但 由 于 指 针 是 变 量, 我 们 可 以 通 过 改 变 它 们 的 指 向, 以 间 接 访 问 不 同 的 变 量, 这 给 程 序 员 带 来 灵 活 性, 也 使 程 序 代 码 编 写 得 更 为 简 洁 和 有 效 指 针 变 量 可 出 现 在 表 达 式 中, 设 int x,y,*px=&x; 指 针 变 量 px 指 向 整 数 x, 则 *px 可 出 现 在 x 能 出 现 的 任 何 地 方 例 如 : y=*px+5; /* 表 示 把 x 的 内 容 加 5 并 赋 给 y*/ y=++*px; /*px 的 内 容 加 上 1 之 后 赋 给 y,++*px 相 当 于 ++(*px)*/ y=*px++; /* 相 当 于 y=*px; px++*/ 例 10.1 main() int a,b; int *pointer_1, *pointer_2; a=100;b=10; pointer_1=&a; pointer_2=&b; printf("%d,%d\n",a,b); printf("%d,%d\n",*pointer_1, *pointer_2); 对 程 序 的 说 明 : 1) 在 开 头 处 虽 然 定 义 了 两 个 指 针 变 量 pointer_1 和 pointer_2, 担 它 们 并 未 指 向 任 何 一 个 整 型 变 量 只 是 提 供 两 个 指 针 变 量, 规 定 它 们 可 以 指 向 整 型 变 量 程 序 第 5 6 行 的 作 用 就 是 使 pointer_1 指 向 a,pointer_2 指 向 b 2) 最 后 一 行 的 *pointer_1 和 *pointer_2 就 是 变 量 a 和 b 最 后 两 个 printf 函 数 作 用 是 相 同 的 3) 程 序 中 有 两 处 出 现 *pointer_1 和 *pointer_2, 请 区 分 它 们 的 不 同 含 义 4) 程 序 第 5 6 行 的 pointer_1=&a 和 pointer_2=&b 不 能 写 成 *pointer_1=&a 和 *pointer_2=&b 请 对 下 面 再 的 关 于 & 和 * 的 问 题 进 行 考 虑 : 1) 如 果 已 经 执 行 了 pointer_1=&a; 语 句, 则 &*pointer_1 是 什 么 含 义? 2) *&a 含 义 是 什 么? 3) (pointer_1)++ 和 pointer_1++ 的 区 别? 例 10.2 输 入 a 和 b 两 个 整 数, 按 先 大 后 小 的 顺 序 输 出 a 和 b 第 141 页

142 main() int *p1,*p2,*p,a,b; scanf("%d,%d",&a,&b); p1=&a;p2=&b; if(a<b) p=p1;p1=p2;p2=p; printf("\na=%d,b=%d\n",a,b); printf("max=%d,min=%d\n",*p1, *p2); 指 针 变 量 作 为 函 数 参 数 函 数 的 参 数 不 仅 可 以 是 整 型 实 型 字 符 型 等 数 据, 还 可 以 是 指 针 类 型 它 的 作 用 是 将 一 个 变 量 的 地 址 传 送 到 另 一 个 函 数 中 例 10.3 题 目 同 例 10.2, 即 输 入 的 两 个 整 数 按 大 小 顺 序 输 出 今 用 函 数 处 理, 而 且 用 指 针 类 型 的 数 据 作 函 数 参 数 swap(int *p1,int *p2) int temp; temp=*p1; *p1=*p2; *p2=temp; main() int a,b; int *pointer_1,*pointer_2; scanf("%d,%d",&a,&b); pointer_1=&a;pointer_2=&b; if(a<b) swap(pointer_1,pointer_2); printf("\n%d,%d\n",a,b); 对 程 序 的 说 明 : swap 是 用 户 定 义 的 函 数, 它 的 作 用 是 交 换 两 个 变 量 (a 和 b) 的 值 swap 函 数 的 形 参 p1 p2 是 指 针 变 量 程 序 运 行 时, 先 执 行 main 函 数, 输 入 a 和 b 的 值 然 后 将 a 和 b 的 地 址 分 别 赋 给 指 针 变 量 pointer_1 和 pointer_2, 使 pointer_1 指 向 a,pointer_2 指 向 b 第 142 页

143 接 着 执 行 if 语 句, 由 于 a b, 因 此 执 行 swap 函 数 注 意 实 参 pointer_1 和 pointer_2 是 指 针 变 量, 在 函 数 调 用 时, 将 实 参 变 量 的 值 传 递 给 形 参 变 量 采 取 的 依 然 是 值 传 递 方 式 因 此 虚 实 结 合 后 形 参 p1 的 值 为 &a, p2 的 值 为 &b 这 时 p1 和 pointer_1 指 向 变 量 a,p2 和 pointer_2 指 向 变 量 b 接 着 执 行 执 行 swap 函 数 的 函 数 体 使 *p1 和 *p2 的 值 互 换, 也 就 是 使 a 和 b 的 值 互 换 函 数 调 用 结 束 后,p1 和 p2 不 复 存 在 ( 已 释 放 ) 如 图 最 后 在 main 函 数 中 输 出 的 a 和 b 的 值 是 已 经 过 交 换 的 值 请 注 意 交 换 *p1 和 *p2 的 值 是 如 何 实 现 的 请 找 出 下 列 程 序 段 的 错 误 : swap(int *p1,int *p2) int *temp; *temp=*p1; /* 此 语 句 有 问 题 */ *p1=*p2; *p2=temp; 第 143 页

144 请 考 虑 下 面 的 函 数 能 否 实 现 实 现 a 和 b 互 换 swap(int x,int y) int temp; temp=x; x=y; y=temp; 如 果 在 main 函 数 中 用 swap(a,b); 调 用 swap 函 数, 会 有 什 么 结 果 呢? 请 看 下 图 所 示 例 10.4 请 注 意, 不 能 企 图 通 过 改 变 指 针 形 参 的 值 而 使 指 针 实 参 的 值 改 变 swap(int *p1,int *p2) int *p; p=p1; p1=p2; p2=p; main() int a,b; int *pointer_1,*pointer_2; scanf("%d,%d",&a,&b); pointer_1=&a;pointer_2=&b; if(a<b) swap(pointer_1,pointer_2); printf("\n%d,%d\n",*pointer_1,*pointer_2); 其 中 的 问 题 在 于 不 能 实 现 如 图 所 示 的 第 四 步 (d) 例 10.5 输 入 a b c3 个 整 数, 按 大 小 顺 序 输 出 swap(int *pt1,int *pt2) 第 144 页

145 int temp; temp=*pt1; *pt1=*pt2; *pt2=temp; exchange(int *q1,int *q2,int *q3) if(*q1<*q2)swap(q1,q2); if(*q1<*q3)swap(q1,q3); if(*q2<*q3)swap(q2,q3); main() int a,b,c,*p1,*p2,*p3; scanf("%d,%d,%d",&a,&b,&c); p1=&a;p2=&b; p3=&c; exchange(p1,p2,p3); printf("\n%d,%d,%d \n",a,b,c); 指 针 变 量 几 个 问 题 的 进 一 步 说 明 指 针 变 量 可 以 进 行 某 些 运 算, 但 其 运 算 的 种 类 是 有 限 的 它 只 能 进 行 赋 值 运 算 和 部 分 算 术 运 算 及 关 系 运 算 1. 指 针 运 算 符 1) 取 地 址 运 算 符 &: 取 地 址 运 算 符 & 是 单 目 运 算 符, 其 结 合 性 为 自 右 至 左, 其 功 能 是 取 变 量 的 地 址 在 scanf 函 数 及 前 面 介 绍 指 针 变 量 赋 值 中, 我 们 已 经 了 解 并 使 用 了 & 运 算 符 2) 取 内 容 运 算 符 *: 取 内 容 运 算 符 * 是 单 目 运 算 符, 其 结 合 性 为 自 右 至 左, 用 来 表 示 指 针 变 量 所 指 的 变 量 在 * 运 算 符 之 后 跟 的 变 量 必 须 是 指 针 变 量 需 要 注 意 的 是 指 针 运 算 符 * 和 指 针 变 量 说 明 中 的 指 针 说 明 符 * 不 是 一 回 事 在 指 针 变 量 说 明 中, * 是 类 型 说 明 符, 表 示 其 后 的 变 量 是 指 针 类 型 而 表 达 式 中 出 现 的 * 则 是 一 个 运 算 符 用 以 表 示 指 针 变 量 所 指 的 变 量 例 10.6 main() int a=5,*p=&a; printf ("%d",*p); 表 示 指 针 变 量 p 取 得 了 整 型 变 量 a 的 地 址 printf("%d",*p) 语 句 表 示 输 出 变 量 a 的 值 2. 指 针 变 量 的 运 算 1) 赋 值 运 算 : 指 针 变 量 的 赋 值 运 算 有 以 下 几 种 形 式 1 指 针 变 量 初 始 化 赋 值, 前 面 已 作 介 绍 第 145 页

146 2 把 一 个 变 量 的 地 址 赋 予 指 向 相 同 数 据 类 型 的 指 针 变 量 例 如 : int a,*pa; pa=&a; /* 把 整 型 变 量 a 的 地 址 赋 予 整 型 指 针 变 量 pa*/ 3 把 一 个 指 针 变 量 的 值 赋 予 指 向 相 同 类 型 变 量 的 另 一 个 指 针 变 量 如 : int a,*pa=&a,*pb; pb=pa; /* 把 a 的 地 址 赋 予 指 针 变 量 pb*/ 由 于 pa,pb 均 为 指 向 整 型 变 量 的 指 针 变 量, 因 此 可 以 相 互 赋 值 4 把 数 组 的 首 地 址 赋 予 指 向 数 组 的 指 针 变 量 例 如 : int a[5],*pa; pa=a; ( 数 组 名 表 示 数 组 的 首 地 址, 故 可 赋 予 指 向 数 组 的 指 针 变 量 pa) 也 可 写 为 : pa=&a[0]; /* 数 组 第 一 个 元 素 的 地 址 也 是 整 个 数 组 的 首 地 址, 也 可 赋 予 pa*/ 当 然 也 可 采 取 初 始 化 赋 值 的 方 法 : int a[5],*pa=a; 5 把 字 符 串 的 首 地 址 赋 予 指 向 字 符 类 型 的 指 针 变 量 例 如 : char *pc; pc="c Language"; 或 用 初 始 化 赋 值 的 方 法 写 为 : char *pc="c Language"; 这 里 应 说 明 的 是 并 不 是 把 整 个 字 符 串 装 入 指 针 变 量, 而 是 把 存 放 该 字 符 串 的 字 符 数 组 的 首 地 址 装 入 指 针 变 量 在 后 面 还 将 详 细 介 绍 6 把 函 数 的 入 口 地 址 赋 予 指 向 函 数 的 指 针 变 量 例 如 : int (*pf)(); pf=f; /*f 为 函 数 名 */ 2) 加 减 算 术 运 算 对 于 指 向 数 组 的 指 针 变 量, 可 以 加 上 或 减 去 一 个 整 数 n 设 pa 是 指 向 数 组 a 的 指 针 变 量, 则 pa+n,pa-n,pa++,++pa,pa--,--pa 运 算 都 是 合 法 的 指 针 变 量 加 或 减 一 个 整 数 n 的 意 义 是 把 指 针 指 向 的 当 前 位 置 ( 指 向 某 数 组 元 素 ) 向 前 或 向 后 移 动 n 个 位 置 应 该 注 意, 数 组 指 针 变 量 向 前 或 向 后 移 动 一 个 位 置 和 地 址 加 1 或 减 1 在 概 念 上 是 不 同 的 因 为 数 组 可 以 有 不 同 的 类 型, 各 种 类 型 的 数 组 元 素 所 占 的 字 节 长 度 是 不 同 的 如 指 针 变 量 加 1, 即 向 后 移 动 1 个 位 置 表 示 指 针 变 量 指 向 下 一 个 数 据 元 素 的 首 地 址 而 不 是 在 原 地 址 基 础 上 加 1 例 如 : int a[5],*pa; pa=a; /*pa 指 向 数 组 a, 也 是 指 向 a[0]*/ pa=pa+2; /*pa 指 向 a[2], 即 pa 的 值 为 &pa[2]*/ 指 针 变 量 的 加 减 运 算 只 能 对 数 组 指 针 变 量 进 行, 对 指 向 其 它 类 型 变 量 的 指 针 变 量 作 加 减 运 算 是 毫 无 意 义 的 3) 两 个 指 针 变 量 之 间 的 运 算 : 只 有 指 向 同 一 数 组 的 两 个 指 针 变 量 之 间 才 能 进 行 运 算, 否 则 运 算 毫 无 意 义 1 两 指 针 变 量 相 减 : 两 指 针 变 量 相 减 所 得 之 差 是 两 个 指 针 所 指 数 组 元 素 之 间 相 差 的 元 素 个 数 实 际 上 第 146 页

147 是 两 个 指 针 值 ( 地 址 ) 相 减 之 差 再 除 以 该 数 组 元 素 的 长 度 ( 字 节 数 ) 例 如 pf1 和 pf2 是 指 向 同 一 浮 点 数 组 的 两 个 指 针 变 量, 设 pf1 的 值 为 2010H,pf2 的 值 为 2000H, 而 浮 点 数 组 每 个 元 素 占 4 个 字 节, 所 以 pf1-pf2 的 结 果 为 (2000H-2010H)/4=4, 表 示 pf1 和 pf2 之 间 相 差 4 个 元 素 两 个 指 针 变 量 不 能 进 行 加 法 运 算 例 如,pf1+pf2 是 什 么 意 思 呢? 毫 无 实 际 意 义 2 两 指 针 变 量 进 行 关 系 运 算 : 指 向 同 一 数 组 的 两 指 针 变 量 进 行 关 系 运 算 可 表 示 它 们 所 指 数 组 元 素 之 间 的 关 系 例 如 : pf1==pf2 表 示 pf1 和 pf2 指 向 同 一 数 组 元 素 ; pf1>pf2 表 示 pf1 处 于 高 地 址 位 置 ; pf1<pf2 表 示 pf2 处 于 低 地 址 位 置 指 针 变 量 还 可 以 与 0 比 较 设 p 为 指 针 变 量, 则 p==0 表 明 p 是 空 指 针, 它 不 指 向 任 何 变 量 ; p!=0 表 示 p 不 是 空 指 针 空 指 针 是 由 对 指 针 变 量 赋 予 0 值 而 得 到 的 例 如 : #define NULL 0 int *p=null; 对 指 针 变 量 赋 0 值 和 不 赋 值 是 不 同 的 指 针 变 量 未 赋 值 时, 可 以 是 任 意 值, 是 不 能 使 用 的 否 则 将 造 成 意 外 错 误 而 指 针 变 量 赋 0 值 后, 则 可 以 使 用, 只 是 它 不 指 向 具 体 的 变 量 而 已 例 10.7 main() int a=10,b=20,s,t,*pa,*pb; /* 说 明 pa,pb 为 整 型 指 针 变 量 */ pa=&a; /* 给 指 针 变 量 pa 赋 值,pa 指 向 变 量 a*/ pb=&b; /* 给 指 针 变 量 pb 赋 值,pb 指 向 变 量 b*/ s=*pa+*pb; /* 求 a+b 之 和,(*pa 就 是 a,*pb 就 是 b)*/ t=*pa**pb; /* 本 行 是 求 a*b 之 积 */ printf("a=%d\nb=%d\na+b=%d\na*b=%d\n",a,b,a+b,a*b); printf("s=%d\nt=%d\n",s,t); 例 10.8 main() int a,b,c,*pmax,*pmin; /*pmax,pmin 为 整 型 指 针 变 量 */ printf("input three numbers:\n"); /* 输 入 提 示 */ scanf("%d%d%d",&a,&b,&c); /* 输 入 三 个 数 字 */ if(a>b) /* 如 果 第 一 个 数 字 大 于 第 二 个 数 字...*/ pmax=&a; /* 指 针 变 量 赋 值 */ pmin=&b; /* 指 针 变 量 赋 值 */ else pmax=&b; /* 指 针 变 量 赋 值 */ pmin=&a; /* 指 针 变 量 赋 值 */ if(c>*pmax) pmax=&c; /* 判 断 并 赋 值 */ if(c<*pmin) pmin=&c; /* 判 断 并 赋 值 */ 第 147 页

148 printf("max=%d\nmin=%d\n",*pmax,*pmin); /* 输 出 结 果 */ 10.3 数 组 指 针 和 指 向 数 组 的 指 针 变 量 一 个 变 量 有 一 个 地 址, 一 个 数 组 包 含 若 干 元 素, 每 个 数 组 元 素 都 在 内 存 中 占 用 存 储 单 元, 它 们 都 有 相 应 的 地 址 所 谓 数 组 的 指 针 是 指 数 组 的 起 始 地 址, 数 组 元 素 的 指 针 是 数 组 元 素 的 地 址 指 向 数 组 元 素 的 指 针 一 个 数 组 是 由 连 续 的 一 块 内 存 单 元 组 成 的 数 组 名 就 是 这 块 连 续 内 存 单 元 的 首 地 址 一 个 数 组 也 是 由 各 个 数 组 元 素 ( 下 标 变 量 ) 组 成 的 每 个 数 组 元 素 按 其 类 型 不 同 占 有 几 个 连 续 的 内 存 单 元 一 个 数 组 元 素 的 首 地 址 也 是 指 它 所 占 有 的 几 个 内 存 单 元 的 首 地 址 定 义 一 个 指 向 数 组 元 素 的 指 针 变 量 的 方 法, 与 以 前 介 绍 的 指 针 变 量 相 同 例 如 : int a[10]; /* 定 义 a 为 包 含 10 个 整 型 数 据 的 数 组 */ int *p; /* 定 义 p 为 指 向 整 型 变 量 的 指 针 */ 应 当 注 意, 因 为 数 组 为 int 型, 所 以 指 针 变 量 也 应 为 指 向 int 型 的 指 针 变 量 下 面 是 对 指 针 变 量 赋 值 : p=&a[0]; 把 a[0] 元 素 的 地 址 赋 给 指 针 变 量 p 也 就 是 说,p 指 向 a 数 组 的 第 0 号 元 素 C 语 言 规 定, 数 组 名 代 表 数 组 的 首 地 址, 也 就 是 第 0 号 元 素 的 地 址 因 此, 下 面 两 个 语 句 等 价 : p=&a[0]; p=a; 在 定 义 指 针 变 量 时 可 以 赋 给 初 值 : int *p=&a[0]; 它 等 效 于 : int *p; 第 148 页

149 p=&a[0]; 当 然 定 义 时 也 可 以 写 成 : int *p=a; 从 图 中 我 们 可 以 看 出 有 以 下 关 系 : p,a,&a[0] 均 指 向 同 一 单 元, 它 们 是 数 组 a 的 首 地 址, 也 是 0 号 元 素 a[0] 的 首 地 址 应 该 说 明 的 是 p 是 变 量, 而 a,&a[0] 都 是 常 量 在 编 程 时 应 予 以 注 意 数 组 指 针 变 量 说 明 的 一 般 形 式 为 : 类 型 说 明 符 * 指 针 变 量 名 ; 其 中 类 型 说 明 符 表 示 所 指 数 组 的 类 型 从 一 般 形 式 可 以 看 出 指 向 数 组 的 指 针 变 量 和 指 向 普 通 变 量 的 指 针 变 量 的 说 明 是 相 同 的 通 过 指 针 引 用 数 组 元 素 C 语 言 规 定 : 如 果 指 针 变 量 p 已 指 向 数 组 中 的 一 个 元 素, 则 p+1 指 向 同 一 数 组 中 的 下 一 个 元 素 引 入 指 针 变 量 后, 就 可 以 用 两 种 方 法 来 访 问 数 组 元 素 了 如 果 p 的 初 值 为 &a[0], 则 : 1) p+i 和 a+i 就 是 a[i] 的 地 址, 或 者 说 它 们 指 向 a 数 组 的 第 i 个 元 素 2) *(p+i) 或 *(a+i) 就 是 p+i 或 a+i 所 指 向 的 数 组 元 素, 即 a[i] 例 如,*(p+5) 或 *(a+5) 就 是 a[5] 3) 指 向 数 组 的 指 针 变 量 也 可 以 带 下 标, 如 p[i] 与 *(p+i) 等 价 根 据 以 上 叙 述, 引 用 一 个 数 组 元 素 可 以 用 : 1) 下 标 法, 即 用 a[i] 形 式 访 问 数 组 元 素 在 前 面 介 绍 数 组 时 都 是 采 用 这 种 方 法 2) 指 针 法, 即 采 用 *(a+i) 或 *(p+i) 形 式, 用 间 接 访 问 的 方 法 来 访 问 数 组 元 素, 其 中 a 是 数 组 名,p 是 指 向 数 组 的 指 针 变 量, 其 处 值 p=a 例 10.9 输 出 数 组 中 的 全 部 元 素 ( 下 标 法 ) main() int a[10],i; for(i=0;i<10;i++) a[i]=i; for(i=0;i<5;i++) printf("a[%d]=%d\n",i,a[i]); 第 149 页

150 例 输 出 数 组 中 的 全 部 元 素 ( 通 过 数 组 名 计 算 元 素 的 地 址, 找 出 元 素 的 值 ) main() int a[10],i; for(i=0;i<10;i++) *(a+i)=i; for(i=0;i<10;i++) printf("a[%d]=%d\n",i,*(a+i)); 例 输 出 数 组 中 的 全 部 元 素 ( 用 指 针 变 量 指 向 元 素 ) main() int a[10],i,*p; p=a; for(i=0;i<10;i++) *(p+i)=i; for(i=0;i<10;i++) printf("a[%d]=%d\n",i,*(p+i)); 例 main() int a[10],i,*p=a; for(i=0;i<10;) *p=i; printf("a[%d]=%d\n",i++,*p++); 几 个 注 意 的 问 题 : 1) 指 针 变 量 可 以 实 现 本 身 的 值 的 改 变 如 p++ 是 合 法 的 ; 而 a++ 是 错 误 的 因 为 a 是 数 组 名, 它 是 数 组 的 首 地 址, 是 常 量 2) 要 注 意 指 针 变 量 的 当 前 值 请 看 下 面 的 程 序 例 找 出 错 误 main() int *p,i,a[10]; p=a; for(i=0;i<10;i++) *p++=i; 第 150 页

151 for(i=0;i<10;i++) printf("a[%d]=%d\n",i,*p++); 例 改 正 main() int *p,i,a[10]; p=a; for(i=0;i<10;i++) *p++=i; p=a; for(i=0;i<10;i++) printf("a[%d]=%d\n",i,*p++); 3) 从 上 例 可 以 看 出, 虽 然 定 义 数 组 时 指 定 它 包 含 10 个 元 素, 但 指 针 变 量 可 以 指 到 数 组 以 后 的 内 存 单 元, 系 统 并 不 认 为 非 法 4) *p++, 由 于 ++ 和 * 同 优 先 级, 结 合 方 向 自 右 而 左, 等 价 于 *(p++) 5) *(p++) 与 *(++p) 作 用 不 同 若 p 的 初 值 为 a, 则 *(p++) 等 价 a[0],*(++p) 等 价 a[1] 6) (*p)++ 表 示 p 所 指 向 的 元 素 值 加 1 7) 如 果 p 当 前 指 向 a 数 组 中 的 第 i 个 元 素, 则 *(p--) 相 当 于 a[i--]; *(++p) 相 当 于 a[++i]; *(--p) 相 当 于 a[--i] 数 组 名 作 函 数 参 数 数 组 名 可 以 作 函 数 的 实 参 和 形 参 如 : main() int array[10]; f(array,10); f(int arr[],int n); 第 151 页

152 array 为 实 参 数 组 名,arr 为 形 参 数 组 名 在 学 习 指 针 变 量 之 后 就 更 容 易 理 解 这 个 问 题 了 数 组 名 就 是 数 组 的 首 地 址, 实 参 向 形 参 传 送 数 组 名 实 际 上 就 是 传 送 数 组 的 地 址, 形 参 得 到 该 地 址 后 也 指 向 同 一 数 组 这 就 好 象 同 一 件 物 品 有 两 个 彼 此 不 同 的 名 称 一 样 同 样, 指 针 变 量 的 值 也 是 地 址, 数 组 指 针 变 量 的 值 即 为 数 组 的 首 地 址, 当 然 也 可 作 为 函 数 的 参 数 使 用 例 float aver(float *pa); main() float sco[5],av,*sp; int i; sp=sco; printf("\ninput 5 scores:\n"); for(i=0;i<5;i++) scanf("%f",&sco[i]); av=aver(sp); printf("average score is %5.2f",av); float aver(float *pa) int i; float av,s=0; for(i=0;i<5;i++) s=s+*pa++; av=s/5; return av; 例 将 数 组 a 中 的 n 个 整 数 按 相 反 顺 序 存 放 算 法 为 : 将 a[0] 与 a[n-1] 对 换, 再 a[1] 与 a[n-2] 对 换, 直 到 将 a[(n-1/2)] 与 a[n-int((n-1)/2)] 对 换 今 用 循 环 处 理 此 问 题, 设 两 个 位 置 指 示 变 量 i 和 j,i 的 初 值 为 0,j 的 初 值 为 n-1 将 a[i] 与 a[j] 交 换, 然 后 使 i 的 值 加 1,j 的 值 减 1, 再 将 a[i] 与 a[j] 交 换, 直 到 i=(n-1)/2 为 止, 如 图 所 示 第 152 页

153 程 序 如 下 : void inv(int x[],int n) /* 形 参 x 是 数 组 名 */ int temp,i,j,m=(n-1)/2; for(i=0;i<=m;i++) j=n-1-i; temp=x[i];x[i]=x[j];x[j]=temp; return; main() int i,a[10]=3,7,9,11,0,6,7,5,4,2; printf("the original array:\n"); for(i=0;i<10;i++) printf("%d,",a[i]); printf("\n"); inv(a,10); printf("the array has benn inverted:\n"); for(i=0;i<10;i++) printf("%d,",a[i]); printf("\n"); 对 此 程 序 可 以 作 一 些 改 动 将 函 数 inv 中 的 形 参 x 改 成 指 针 变 量 例 对 例 可 以 作 一 些 改 动 将 函 数 inv 中 的 形 参 x 改 成 指 针 变 量 程 序 如 下 : void inv(int *x,int n) /* 形 参 x 为 指 针 变 量 */ int *p,temp,*i,*j,m=(n-1)/2; i=x;j=x+n-1;p=x+m; for(;i<=p;i++,j--) temp=*i;*i=*j;*j=temp; return; main() int i,a[10]=3,7,9,11,0,6,7,5,4,2; printf("the original array:\n"); 第 153 页

154 for(i=0;i<10;i++) printf("%d,",a[i]); printf("\n"); inv(a,10); printf("the array has benn inverted:\n"); for(i=0;i<10;i++) printf("%d,",a[i]); printf("\n"); 运 行 情 况 与 前 一 程 序 相 同 例 从 0 个 数 中 找 出 其 中 最 大 值 和 最 小 值 调 用 一 个 函 数 只 能 得 到 一 个 返 回 值, 今 用 全 局 变 量 在 函 数 之 间 传 递 数 据 程 序 如 下 : int max,min; /* 全 局 变 量 */ void max_min_value(int array[],int n) int *p,*array_end; array_end=array+n; max=min=*array; for(p=array+1;p<array_end;p++) if(*p>max)max=*p; else if (*p<min)min=*p; return; main() int i,number[10]; printf("enter 10 integer umbers:\n"); for(i=0;i<10;i++) scanf("%d",&number[i]); max_min_value(number,10); printf("\nmax=%d,min=%d\n",max,min); 说 明 : 1) 在 函 数 max_min_value 中 求 出 的 最 大 值 和 最 小 值 放 在 max 和 min 中 由 于 它 们 是 全 局, 因 此 在 主 函 数 中 可 以 直 接 使 用 2) 函 数 max_min_value 中 的 语 句 : max=min=*array; array 是 数 组 名, 它 接 收 从 实 参 传 来 的 数 组 numuber 的 首 地 址 *array 相 当 于 *(&array[0]) 上 述 语 句 与 max=min=array[0]; 等 价 3) 在 执 行 for 循 环 时,p 的 初 值 为 array+1, 也 就 是 使 p 指 向 array[1] 以 后 每 次 执 行 p++, 使 p 指 向 下 一 个 元 素 每 次 将 *p 和 max 与 min 比 较 将 大 者 放 入 max, 小 者 放 min 第 154 页

155 4) 函 数 max_min_value 的 形 参 array 可 以 改 为 指 针 变 量 类 型 实 参 也 可 以 不 用 数 组 名, 而 用 指 针 变 量 传 递 地 址 例 程 序 可 改 为 : int max,min; /* 全 局 变 量 */ void max_min_value(int *array,int n) int *p,*array_end; array_end=array+n; max=min=*array; for(p=array+1;p<array_end;p++) if(*p>max)max=*p; else if (*p<min)min=*p; return; main() int i,number[10],*p; p=number; /* 使 p 指 向 number 数 组 */ printf("enter 10 integer umbers:\n"); for(i=0;i<10;i++,p++) scanf("%d",p); p=number; max_min_value(p,10); printf("\nmax=%d,min=%d\n",max,min); 归 纳 起 来, 如 果 有 一 个 实 参 数 组, 想 在 函 数 中 改 变 此 数 组 的 元 素 的 值, 实 参 与 形 参 的 对 应 关 系 有 以 下 4 种 : 1) 形 参 和 实 参 都 是 数 组 名 第 155 页

156 main() f(int x[],int n) int a[10]; f(a,10) a 和 x 指 的 是 同 一 组 数 组 2) 实 用 数 组, 形 参 用 指 针 变 量 main() f(int *x,int n) int a[10]; f(a,10) 3) 实 参 型 参 都 用 指 针 变 量 4) 实 参 为 指 针 变 量, 型 参 为 数 组 名 例 用 实 参 指 针 变 量 改 写 将 n 个 整 数 按 相 反 顺 序 存 放 void inv(int *x,int n) int *p,m,temp,*i,*j; m=(n-1)/2; i=x;j=x+n-1;p=x+m; for(;i<=p;i++,j--) temp=*i;*i=*j;*j=temp; return; main() int i,arr[10]=3,7,9,11,0,6,7,5,4,2,*p; p=arr; printf("the original array:\n"); for(i=0;i<10;i++,p++) printf("%d,",*p); printf("\n"); p=arr; inv(p,10); printf("the array has benn inverted:\n"); for(p=arr;p<arr+10;p++) printf("%d,",*p); printf("\n"); 注 意 :main 函 数 中 的 指 针 变 量 p 是 有 确 定 值 的 即 如 果 用 指 针 变 作 实 参, 必 须 现 使 指 针 变 量 有 确 定 值, 指 向 一 个 已 定 义 的 数 组 例 用 选 择 法 对 10 个 整 数 排 序 第 156 页

157 main() int *p,i,a[10]=3,7,9,11,0,6,7,5,4,2; printf("the original array:\n"); for(i=0;i<10;i++) printf("%d,",a[i]); printf("\n"); p=a; sort(p,10); for(p=a,i=0;i<10;i++) printf("%d ",*p);p++; printf("\n"); sort(int x[],int n) int i,j,k,t; for(i=0;i<n-1;i++) k=i; for(j=i+1;j<n;j++) if(x[j]>x[k])k=j; if(k!=i) t=x[i];x[i]=x[k];x[k]=t; 说 明 : 函 数 sort 用 数 组 名 作 为 形 参, 也 可 改 为 用 指 针 变 量, 这 时 函 数 的 首 部 可 以 改 为 : sort(int *x,int n) 其 他 可 一 律 不 改 第 157 页

158 指 向 多 维 数 组 的 指 针 和 指 针 变 量 本 小 节 以 二 维 数 组 为 例 介 绍 多 维 数 组 的 指 针 变 量 1. 多 维 数 组 的 地 址 设 有 整 型 二 维 数 组 a[3][4] 如 下 : 它 的 定 义 为 : int a[3][4]=0,1,2,3,4,5,6,7,8,9,10,11 设 数 组 a 的 首 地 址 为 1000, 各 下 标 变 量 的 首 地 址 及 其 值 如 图 所 示 前 面 介 绍 过,C 语 言 允 许 把 一 个 二 维 数 组 分 解 为 多 个 一 维 数 组 来 处 理 因 此 数 组 a 可 分 解 为 三 个 一 维 数 组, 即 a[0],a[1],a[2] 每 一 个 一 维 数 组 又 含 有 四 个 元 素 例 如 a[0] 数 组, 含 有 a[0][0],a[0][1],a[0][2],a[0][3] 四 个 元 素 数 组 及 数 组 元 素 的 地 址 表 示 如 下 : 从 二 维 数 组 的 角 度 来 看,a 是 二 维 数 组 名,a 代 表 整 个 二 维 数 组 的 首 地 址, 也 是 二 维 数 组 0 行 的 首 地 址, 等 于 1000 a+1 代 表 第 一 行 的 首 地 址, 等 于 1008 如 图 : a[0] 是 第 一 个 一 维 数 组 的 数 组 名 和 首 地 址, 因 此 也 为 1000 *(a+0) 或 *a 是 与 a[0] 等 效 的, 它 表 示 一 维 数 组 a[0]0 号 元 素 的 首 地 址, 也 为 1000 &a[0][0] 是 二 维 数 组 a 的 0 行 0 列 元 素 首 地 址, 同 样 是 1000 因 此,a,a[0],*(a+0),*a,&a[0][0] 是 相 等 的 同 理,a+1 是 二 维 数 组 1 行 的 首 地 址, 等 于 1008 a[1] 是 第 二 个 一 维 数 组 的 数 组 名 和 首 第 158 页

159 地 址, 因 此 也 为 1008 &a[1][0] 是 二 维 数 组 a 的 1 行 0 列 元 素 地 址, 也 是 1008 因 此 a+1,a[1],*(a+1),&a[1][0] 是 等 同 的 由 此 可 得 出 :a+i,a[i],*(a+i),&a[i][0] 是 等 同 的 此 外,&a[i] 和 a[i] 也 是 等 同 的 因 为 在 二 维 数 组 中 不 能 把 &a[i] 理 解 为 元 素 a[i] 的 地 址, 不 存 在 元 素 a[i] C 语 言 规 定, 它 是 一 种 地 址 计 算 方 法, 表 示 数 组 a 第 i 行 首 地 址 由 此, 我 们 得 出 :a[i],&a[i],*(a+i) 和 a+i 也 都 是 等 同 的 另 外,a[0] 也 可 以 看 成 是 a[0]+0, 是 一 维 数 组 a[0] 的 0 号 元 素 的 首 地 址, 而 a[0]+1 则 是 a[0] 的 1 号 元 素 首 地 址, 由 此 可 得 出 a[i]+j 则 是 一 维 数 组 a[i] 的 j 号 元 素 首 地 址, 它 等 于 &a[i][j] 由 a[i]=*(a+i) 得 a[i]+j=*(a+i)+j 由 于 *(a+i)+j 是 二 维 数 组 a 的 i 行 j 列 元 素 的 首 地 址, 所 以, 该 元 素 的 值 等 于 *(*(a+i)+j) 例 main() int a[3][4]=0,1,2,3,4,5,6,7,8,9,10,11; printf("%d,",a); printf("%d,",*a); printf("%d,",a[0]); printf("%d,",&a[0]); printf("%d\n",&a[0][0]); printf("%d,",a+1); printf("%d,",*(a+1)); printf("%d,",a[1]); printf("%d,",&a[1]); printf("%d\n",&a[1][0]); printf("%d,",a+2); printf("%d,",*(a+2)); printf("%d,",a[2]); printf("%d,",&a[2]); printf("%d\n",&a[2][0]); printf("%d,",a[1]+1); printf("%d\n",*(a+1)+1); printf("%d,%d\n",*(a[1]+1),*(*(a+1)+1)); 第 159 页

160 2. 指 向 多 维 数 组 的 指 针 变 量 把 二 维 数 组 a 分 解 为 一 维 数 组 a[0],a[1],a[2] 之 后, 设 p 为 指 向 二 维 数 组 的 指 针 变 量 可 定 义 为 : int (*p)[4] 它 表 示 p 是 一 个 指 针 变 量, 它 指 向 包 含 4 个 元 素 的 一 维 数 组 若 指 向 第 一 个 一 维 数 组 a[0], 其 值 等 于 a,a[0], 或 &a[0][0] 等 而 p+i 则 指 向 一 维 数 组 a[i] 从 前 面 的 分 析 可 得 出 *(p+i)+j 是 二 维 数 组 i 行 j 列 的 元 素 的 地 址, 而 *(*(p+i)+j) 则 是 i 行 j 列 元 素 的 值 二 维 数 组 指 针 变 量 说 明 的 一 般 形 式 为 : 类 型 说 明 符 (* 指 针 变 量 名 )[ 长 度 ] 其 中 类 型 说 明 符 为 所 指 数 组 的 数 据 类 型 * 表 示 其 后 的 变 量 是 指 针 类 型 长 度 表 示 二 维 数 组 分 解 为 多 个 一 维 数 组 时, 一 维 数 组 的 长 度, 也 就 是 二 维 数 组 的 列 数 应 注 意 (* 指 针 变 量 名 ) 两 边 的 括 号 不 可 少, 如 缺 少 括 号 则 表 示 是 指 针 数 组 ( 本 章 后 面 介 绍 ), 意 义 就 完 全 不 同 了 例 main() int a[3][4]=0,1,2,3,4,5,6,7,8,9,10,11; int(*p)[4]; int i,j; p=a; for(i=0;i<3;i++) for(j=0;j<4;j++) printf("%2d ",*(*(p+i)+j)); printf("\n"); 10.4 字 符 串 的 指 针 指 向 字 符 串 的 针 指 变 量 字 符 串 的 表 示 形 式 在 C 语 言 中, 可 以 用 两 种 方 法 访 问 一 个 字 符 串 1) 用 字 符 数 组 存 放 一 个 字 符 串, 然 后 输 出 该 字 符 串 例 main() char string[]= I love China! ; printf("%s\n",string); 说 明 : 和 前 面 介 绍 的 数 组 属 性 一 样,string 是 数 组 名, 它 代 表 字 符 数 组 的 首 地 址 第 160 页

161 2) 用 字 符 串 指 针 指 向 一 个 字 符 串 例 main() char *string= I love China! ; printf("%s\n",string); 字 符 串 指 针 变 量 的 定 义 说 明 与 指 向 字 符 变 量 的 指 针 变 量 说 明 是 相 同 的 只 能 按 对 指 针 变 量 的 赋 值 不 同 来 区 别 对 指 向 字 符 变 量 的 指 针 变 量 应 赋 予 该 字 符 变 量 的 地 址 如 : char c,*p=&c; 表 示 p 是 一 个 指 向 字 符 变 量 c 的 指 针 变 量 而 : char *s="c Language"; 则 表 示 s 是 一 个 指 向 字 符 串 的 指 针 变 量 把 字 符 串 的 首 地 址 赋 予 s 上 例 中, 首 先 定 义 string 是 一 个 字 符 指 针 变 量, 然 后 把 字 符 串 的 首 地 址 赋 予 string( 应 写 出 整 个 字 符 串, 以 便 编 译 系 统 把 该 串 装 入 连 续 的 一 块 内 存 单 元 ), 并 把 首 地 址 送 入 string 程 序 中 的 : char *ps="c Language"; 等 效 于 : char *ps; ps="c Language"; 例 输 出 字 符 串 中 n 个 字 符 后 的 所 有 字 符 main() char *ps="this is a book"; int n=10; ps=ps+n; 第 161 页

162 printf("%s\n",ps); 运 行 结 果 为 : book 在 程 序 中 对 ps 初 始 化 时, 即 把 字 符 串 首 地 址 赋 予 ps, 当 ps= ps+10 之 后,ps 指 向 字 符 b, 因 此 输 出 为 "book" 例 在 输 入 的 字 符 串 中 查 找 有 无 k 字 符 main() char st[20],*ps; int i; printf("input a string:\n"); ps=st; scanf("%s",ps); for(i=0;ps[i]!='\0';i++) if(ps[i]=='k') printf("there is a 'k' in the string\n"); break; if(ps[i]=='\0') printf("there is no 'k' in the string\n"); 例 本 例 是 将 指 针 变 量 指 向 一 个 格 式 字 符 串, 用 在 printf 函 数 中, 用 于 输 出 二 维 数 组 的 各 种 地 址 表 示 的 值 但 在 printf 语 句 中 用 指 针 变 量 PF 代 替 了 格 式 串 这 也 是 程 序 中 常 用 的 方 法 main() static int a[3][4]=0,1,2,3,4,5,6,7,8,9,10,11; char *PF; PF="%d,%d,%d,%d,%d\n"; printf(pf,a,*a,a[0],&a[0],&a[0][0]); printf(pf,a+1,*(a+1),a[1],&a[1],&a[1][0]); printf(pf,a+2,*(a+2),a[2],&a[2],&a[2][0]); printf("%d,%d\n",a[1]+1,*(a+1)+1); printf("%d,%d\n",*(a[1]+1),*(*(a+1)+1)); 例 本 例 是 把 字 符 串 指 针 作 为 函 数 参 数 的 使 用 要 求 把 一 个 字 符 串 的 内 容 复 制 到 另 一 个 字 符 串 中, 并 且 不 能 使 用 strcpy 函 数 函 数 cprstr 的 形 参 为 两 个 字 符 指 针 变 量 pss 指 向 源 字 符 串,pds 指 向 目 标 字 符 串 注 意 表 达 式 :(*pds=*pss)!=`\0' 的 用 法 cpystr(char *pss,char *pds) while((*pds=*pss)!='\0') 第 162 页

163 pds++; pss++; main() char *pa="china",b[10],*pb; pb=b; cpystr(pa,pb); printf("string a=%s\nstring b=%s\n",pa,pb); 在 本 例 中, 程 序 完 成 了 两 项 工 作 : 一 是 把 pss 指 向 的 源 字 符 串 复 制 到 pds 所 指 向 的 目 标 字 符 串 中, 二 是 判 断 所 复 制 的 字 符 是 否 为 `\0', 若 是 则 表 明 源 字 符 串 结 束, 不 再 循 环 否 则, pds 和 pss 都 加 1, 指 向 下 一 字 符 在 主 函 数 中, 以 指 针 变 量 pa,pb 为 实 参, 分 别 取 得 确 定 值 后 调 用 cprstr 函 数 由 于 采 用 的 指 针 变 量 pa 和 pss,pb 和 pds 均 指 向 同 一 字 符 串, 因 此 在 主 函 数 和 cprstr 函 数 中 均 可 使 用 这 些 字 符 串 也 可 以 把 cprstr 函 数 简 化 为 以 下 形 式 : cprstr(char *pss,char*pds) while ((*pds++=*pss++)!=`\0'); 即 把 指 针 的 移 动 和 赋 值 合 并 在 一 个 语 句 中 进 一 步 分 析 还 可 发 现 `\0' 的 ASCⅡ 码 为 0, 对 于 while 语 句 只 看 表 达 式 的 值 为 非 0 就 循 环, 为 0 则 结 束 循 环, 因 此 也 可 省 去!=`\0' 这 一 判 断 部 分, 而 写 为 以 下 形 式 : cprstr (char *pss,char *pds) while (*pdss++=*pss++); 表 达 式 的 意 义 可 解 释 为, 源 字 符 向 目 标 字 符 赋 值, 移 动 指 针, 若 所 赋 值 为 非 0 则 循 环, 否 则 结 束 循 环 这 样 使 程 序 更 加 简 洁 例 简 化 后 的 程 序 如 下 所 示 cpystr(char *pss,char *pds) while(*pds++=*pss++); main() char *pa="china",b[10],*pb; pb=b; cpystr(pa,pb); printf("string a=%s\nstring b=%s\n",pa,pb); 使 用 字 符 串 指 针 变 量 与 字 符 数 组 的 区 别 用 字 符 数 组 和 字 符 指 针 变 量 都 可 实 现 字 符 串 的 存 储 和 运 算 但 是 两 者 是 有 区 别 的 在 使 用 时 应 注 意 以 下 几 个 问 题 : 1. 字 符 串 指 针 变 量 本 身 是 一 个 变 量, 用 于 存 放 字 符 串 的 首 地 址 而 字 符 串 本 身 是 存 放 在 以 该 首 地 址 为 首 的 一 块 连 续 的 内 存 空 间 中 并 以 \0 作 为 串 的 结 束 字 符 数 组 是 第 163 页

164 由 于 若 干 个 数 组 元 素 组 成 的, 它 可 用 来 存 放 整 个 字 符 串 2. 对 字 符 串 指 针 方 式 char *ps="c Language"; 可 以 写 为 : char *ps; ps="c Language"; 而 对 数 组 方 式 : static char st[]="c Language"; 不 能 写 为 : char st[20]; st="c Language"; 而 只 能 对 字 符 数 组 的 各 元 素 逐 个 赋 值 从 以 上 几 点 可 以 看 出 字 符 串 指 针 变 量 与 字 符 数 组 在 使 用 时 的 区 别, 同 时 也 可 看 出 使 用 指 针 变 量 更 加 方 便 前 面 说 过, 当 一 个 指 针 变 量 在 未 取 得 确 定 地 址 前 使 用 是 危 险 的, 容 易 引 起 错 误 但 是 对 指 针 变 量 直 接 赋 值 是 可 以 的 因 为 C 系 统 对 指 针 变 量 赋 值 时 要 给 以 确 定 的 地 址 因 此, char *ps="c Langage"; 或 者 char *ps; ps="c Language"; 都 是 合 法 的 10.5 函 数 指 针 变 量 在 C 语 言 中, 一 个 函 数 总 是 占 用 一 段 连 续 的 内 存 区, 而 函 数 名 就 是 该 函 数 所 占 内 存 区 的 首 地 址 我 们 可 以 把 函 数 的 这 个 首 地 址 ( 或 称 入 口 地 址 ) 赋 予 一 个 指 针 变 量, 使 该 指 针 变 量 指 向 该 函 数 然 后 通 过 指 针 变 量 就 可 以 找 到 并 调 用 这 个 函 数 我 们 把 这 种 指 向 函 数 的 指 针 变 量 称 为 函 数 指 针 变 量 函 数 指 针 变 量 定 义 的 一 般 形 式 为 : 类 型 说 明 符 (* 指 针 变 量 名 )(); 其 中 类 型 说 明 符 表 示 被 指 函 数 的 返 回 值 的 类 型 (* 指 针 变 量 名 ) 表 示 * 后 面 的 变 量 是 定 义 的 指 针 变 量 最 后 的 空 括 号 表 示 指 针 变 量 所 指 的 是 一 个 函 数 例 如 : int (*pf)(); 表 示 pf 是 一 个 指 向 函 数 入 口 的 指 针 变 量, 该 函 数 的 返 回 值 ( 函 数 值 ) 是 整 型 例 本 例 用 来 说 明 用 指 针 形 式 实 现 对 函 数 调 用 的 方 法 int max(int a,int b) if(a>b)return a; else return b; main() int max(int a,int b); int(*pmax)(); 第 164 页

165 int x,y,z; pmax=max; printf("input two numbers:\n"); scanf("%d%d",&x,&y); z=(*pmax)(x,y); printf("maxmum=%d",z); 从 上 述 程 序 可 以 看 出 用, 函 数 指 针 变 量 形 式 调 用 函 数 的 步 骤 如 下 : 1) 先 定 义 函 数 指 针 变 量, 如 后 一 程 序 中 第 9 行 int (*pmax)(); 定 义 pmax 为 函 数 指 针 变 量 2) 把 被 调 函 数 的 入 口 地 址 ( 函 数 名 ) 赋 予 该 函 数 指 针 变 量, 如 程 序 中 第 11 行 pmax=max; 3) 用 函 数 指 针 变 量 形 式 调 用 函 数, 如 程 序 第 14 行 z=(*pmax)(x,y); 4) 调 用 函 数 的 一 般 形 式 为 : (* 指 针 变 量 名 ) ( 实 参 表 ) 使 用 函 数 指 针 变 量 还 应 注 意 以 下 两 点 : a) 函 数 指 针 变 量 不 能 进 行 算 术 运 算, 这 是 与 数 组 指 针 变 量 不 同 的 数 组 指 针 变 量 加 减 一 个 整 数 可 使 指 针 移 动 指 向 后 面 或 前 面 的 数 组 元 素, 而 函 数 指 针 的 移 动 是 毫 无 意 义 的 b) 函 数 调 用 中 "(* 指 针 变 量 名 )" 的 两 边 的 括 号 不 可 少, 其 中 的 * 不 应 该 理 解 为 求 值 运 算, 在 此 处 它 只 是 一 种 表 示 符 号 10.6 指 针 型 函 数 前 面 我 们 介 绍 过, 所 谓 函 数 类 型 是 指 函 数 返 回 值 的 类 型 在 C 语 言 中 允 许 一 个 函 数 的 返 回 值 是 一 个 指 针 ( 即 地 址 ), 这 种 返 回 指 针 值 的 函 数 称 为 指 针 型 函 数 定 义 指 针 型 函 数 的 一 般 形 式 为 : 类 型 说 明 符 * 函 数 名 ( 形 参 表 ) /* 函 数 体 */ 其 中 函 数 名 之 前 加 了 * 号 表 明 这 是 一 个 指 针 型 函 数, 即 返 回 值 是 一 个 指 针 类 型 说 明 符 表 示 了 返 回 的 指 针 值 所 指 向 的 数 据 类 型 如 : int *ap(int x,int y)... /* 函 数 体 */ 表 示 ap 是 一 个 返 回 指 针 值 的 指 针 型 函 数, 它 返 回 的 指 针 指 向 一 个 整 型 变 量 例 本 程 序 是 通 过 指 针 函 数, 输 入 一 个 1~7 之 间 的 整 数, 输 出 对 应 的 星 期 名 main() int i; char *day_name(int n); printf("input Day No:\n"); 第 165 页

166 scanf("%d",&i); if(i<0) exit(1); printf("day No:%2d-->%s\n",i,day_name(i)); char *day_name(int n) static char *name[]= "Illegal day", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"; return((n<1 n>7)? name[0] : name[n]); 本 例 中 定 义 了 一 个 指 针 型 函 数 day_name, 它 的 返 回 值 指 向 一 个 字 符 串 该 函 数 中 定 义 了 一 个 静 态 指 针 数 组 name name 数 组 初 始 化 赋 值 为 八 个 字 符 串, 分 别 表 示 各 个 星 期 名 及 出 错 提 示 形 参 n 表 示 与 星 期 名 所 对 应 的 整 数 在 主 函 数 中, 把 输 入 的 整 数 i 作 为 实 参, 在 printf 语 句 中 调 用 day_name 函 数 并 把 i 值 传 送 给 形 参 n day_name 函 数 中 的 return 语 句 包 含 一 个 条 件 表 达 式,n 值 若 大 于 7 或 小 于 1 则 把 name[0] 指 针 返 回 主 函 数 输 出 出 错 提 示 字 符 串 Illegal day 否 则 返 回 主 函 数 输 出 对 应 的 星 期 名 主 函 数 中 的 第 7 行 是 个 条 件 语 句, 其 语 义 是, 如 输 入 为 负 数 (i<0) 则 中 止 程 序 运 行 退 出 程 序 exit 是 一 个 库 函 数,exit(1) 表 示 发 生 错 误 后 退 出 程 序,exit(0) 表 示 正 常 退 出 应 该 特 别 注 意 的 是 函 数 指 针 变 量 和 指 针 型 函 数 这 两 者 在 写 法 和 意 义 上 的 区 别 如 int(*p)() 和 int *p() 是 两 个 完 全 不 同 的 量 int (*p)() 是 一 个 变 量 说 明, 说 明 p 是 一 个 指 向 函 数 入 口 的 指 针 变 量, 该 函 数 的 返 回 值 是 整 型 量,(*p) 的 两 边 的 括 号 不 能 少 int *p() 则 不 是 变 量 说 明 而 是 函 数 说 明, 说 明 p 是 一 个 指 针 型 函 数, 其 返 回 值 是 一 个 指 向 整 型 量 的 指 针,*p 两 边 没 有 括 号 作 为 函 数 说 明, 在 括 号 内 最 好 写 入 形 式 参 数, 这 样 便 于 与 变 量 说 明 区 别 对 于 指 针 型 函 数 定 义,int *p() 只 是 函 数 头 部 分, 一 般 还 应 该 有 函 数 体 部 分 10.7 指 针 数 组 和 指 向 指 针 的 指 针 指 针 数 组 的 概 念 一 个 数 组 的 元 素 值 为 指 针 则 是 指 针 数 组 指 针 数 组 是 一 组 有 序 的 指 针 的 集 合 指 针 数 组 的 所 有 元 素 都 必 须 是 具 有 相 同 存 储 类 型 和 指 向 相 同 数 据 类 型 的 指 针 变 量 指 针 数 组 说 明 的 一 般 形 式 为 : 类 型 说 明 符 * 数 组 名 [ 数 组 长 度 ] 其 中 类 型 说 明 符 为 指 针 值 所 指 向 的 变 量 的 类 型 第 166 页

167 例 如 : int *pa[3] 表 示 pa 是 一 个 指 针 数 组, 它 有 三 个 数 组 元 素, 每 个 元 素 值 都 是 一 个 指 针, 指 向 整 型 变 量 例 通 常 可 用 一 个 指 针 数 组 来 指 向 一 个 二 维 数 组 指 针 数 组 中 的 每 个 元 素 被 赋 予 二 维 数 组 每 一 行 的 首 地 址, 因 此 也 可 理 解 为 指 向 一 个 一 维 数 组 main() int a[3][3]=1,2,3,4,5,6,7,8,9; int *pa[3]=a[0],a[1],a[2]; int *p=a[0]; int i; for(i=0;i<3;i++) printf("%d,%d,%d\n",a[i][2-i],*a[i],*(*(a+i)+i)); for(i=0;i<3;i++) printf("%d,%d,%d\n",*pa[i],p[i],*(p+i)); 本 例 程 序 中,pa 是 一 个 指 针 数 组, 三 个 元 素 分 别 指 向 二 维 数 组 a 的 各 行 然 后 用 循 环 语 句 输 出 指 定 的 数 组 元 素 其 中 *a[i] 表 示 i 行 0 列 元 素 值 ;*(*(a+i)+i) 表 示 i 行 i 列 的 元 素 值 ;*pa[i] 表 示 i 行 0 列 元 素 值 ; 由 于 p 与 a[0] 相 同, 故 p[i] 表 示 0 行 i 列 的 值 ;*(p+i) 表 示 0 行 i 列 的 值 读 者 可 仔 细 领 会 元 素 值 的 各 种 不 同 的 表 示 方 法 应 该 注 意 指 针 数 组 和 二 维 数 组 指 针 变 量 的 区 别 这 两 者 虽 然 都 可 用 来 表 示 二 维 数 组, 但 是 其 表 示 方 法 和 意 义 是 不 同 的 二 维 数 组 指 针 变 量 是 单 个 的 变 量, 其 一 般 形 式 中 "(* 指 针 变 量 名 )" 两 边 的 括 号 不 可 少 而 指 针 数 组 类 型 表 示 的 是 多 个 指 针 ( 一 组 有 序 指 针 ) 在 一 般 形 式 中 "* 指 针 数 组 名 " 两 边 不 能 有 括 号 例 如 : int (*p)[3]; 表 示 一 个 指 向 二 维 数 组 的 指 针 变 量 该 二 维 数 组 的 列 数 为 3 或 分 解 为 一 维 数 组 的 长 度 为 3 int *p[3] 表 示 p 是 一 个 指 针 数 组, 有 三 个 下 标 变 量 p[0],p[1],p[2] 均 为 指 针 变 量 指 针 数 组 也 常 用 来 表 示 一 组 字 符 串, 这 时 指 针 数 组 的 每 个 元 素 被 赋 予 一 个 字 符 串 的 首 地 址 指 向 字 符 串 的 指 针 数 组 的 初 始 化 更 为 简 单 例 如 在 例 中 即 采 用 指 针 数 组 来 表 示 一 组 字 符 串 其 初 始 化 赋 值 为 : char *name[]="illagal day", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"; 完 成 这 个 初 始 化 赋 值 之 后,name[0] 即 指 向 字 符 串 "Illegal day",name[1] 指 向 第 167 页

168 "Monday"... 指 针 数 组 也 可 以 用 作 函 数 参 数 例 指 针 数 组 作 指 针 型 函 数 的 参 数 在 本 例 主 函 数 中, 定 义 了 一 个 指 针 数 组 name, 并 对 name 作 了 初 始 化 赋 值 其 每 个 元 素 都 指 向 一 个 字 符 串 然 后 又 以 name 作 为 实 参 调 用 指 针 型 函 数 day_name, 在 调 用 时 把 数 组 名 name 赋 予 形 参 变 量 name, 输 入 的 整 数 i 作 为 第 二 个 实 参 赋 予 形 参 n 在 day_ name 函 数 中 定 义 了 两 个 指 针 变 量 pp1 和 pp2,pp1 被 赋 予 name[0] 的 值 ( 即 *name),pp2 被 赋 予 name[n] 的 值 即 *(name+ n) 由 条 件 表 达 式 决 定 返 回 pp1 或 pp2 指 针 给 主 函 数 中 的 指 针 变 量 ps 最 后 输 出 i 和 ps 的 值 main() static char *name[]= "Illegal day", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"; char *ps; int i; char *day_name(char *name[],int n); printf("input Day No:\n"); scanf("%d",&i); if(i<0) exit(1); ps=day_name(name,i); printf("day No:%2d-->%s\n",i,ps); char *day_name(char *name[],int n) char *pp1,*pp2; pp1=*name; pp2=*(name+n); return((n<1 n>7)? pp1:pp2); 例 输 入 5 个 国 名 并 按 字 母 顺 序 排 列 后 输 出 现 编 程 如 下 : #include"string.h" main() void sort(char *name[],int n); void print(char *name[],int n); static char *name[]= "CHINA","AMERICA","AUSTRALIA", "FRANCE","GERMAN"; int n=5; sort(name,n); 第 168 页

169 print(name,n); void sort(char *name[],int n) char *pt; int i,j,k; for(i=0;i<n-1;i++) k=i; for(j=i+1;j<n;j++) if(strcmp(name[k],name[j])>0) k=j; if(k!=i) pt=name[i]; name[i]=name[k]; name[k]=pt; void print(char *name[],int n) int i; for (i=0;i<n;i++) printf("%s\n",name[i]); 说 明 : 在 以 前 的 例 子 中 采 用 了 普 通 的 排 序 方 法, 逐 个 比 较 之 后 交 换 字 符 串 的 位 置 交 换 字 符 串 的 物 理 位 置 是 通 过 字 符 串 复 制 函 数 完 成 的 反 复 的 交 换 将 使 程 序 执 行 的 速 度 很 慢, 同 时 由 于 各 字 符 串 ( 国 名 ) 的 长 度 不 同, 又 增 加 了 存 储 管 理 的 负 担 用 指 针 数 组 能 很 好 地 解 决 这 些 问 题 把 所 有 的 字 符 串 存 放 在 一 个 数 组 中, 把 这 些 字 符 数 组 的 首 地 址 放 在 一 个 指 针 数 组 中, 当 需 要 交 换 两 个 字 符 串 时, 只 须 交 换 指 针 数 组 相 应 两 元 素 的 内 容 ( 地 址 ) 即 可, 而 不 必 交 换 字 符 串 本 身 本 程 序 定 义 了 两 个 函 数, 一 个 名 为 sort 完 成 排 序, 其 形 参 为 指 针 数 组 name, 即 为 待 排 序 的 各 字 符 串 数 组 的 指 针 形 参 n 为 字 符 串 的 个 数 另 一 个 函 数 名 为 print, 用 于 排 序 后 字 符 串 的 输 出, 其 形 参 与 sort 的 形 参 相 同 主 函 数 main 中, 定 义 了 指 针 数 组 name 并 作 了 初 始 化 赋 值 然 后 分 别 调 用 sort 函 数 和 print 函 数 完 成 排 序 和 输 出 值 得 说 明 的 是 在 sort 函 数 中, 对 两 个 字 符 串 比 较, 采 用 了 strcmp 函 数,strcmp 函 数 允 许 参 与 比 较 的 字 符 串 以 指 针 方 式 出 现 name[k] 和 name[j] 均 为 指 针, 因 此 是 合 法 的 字 符 串 比 较 后 需 要 交 换 时, 只 交 换 指 针 数 组 元 素 的 值, 而 不 交 换 具 体 的 字 符 串, 这 样 将 大 大 减 少 时 间 的 开 销, 提 高 了 运 行 效 率 指 向 指 针 的 指 针 如 果 一 个 指 针 变 量 存 放 的 又 是 另 一 个 指 针 变 量 的 地 址, 则 称 这 个 指 针 变 量 为 指 向 指 针 的 指 针 变 量 在 前 面 已 经 介 绍 过, 通 过 指 针 访 问 变 量 称 为 间 接 访 问 由 于 指 针 变 量 直 接 指 向 变 量, 所 以 称 为 单 级 间 址 而 如 果 通 过 指 向 指 针 的 指 针 变 量 来 访 问 变 量 则 构 成 二 级 间 址 第 169 页

170 从 下 图 可 以 看 到,name 是 一 个 指 针 数 组, 它 的 每 一 个 元 素 是 一 个 指 针 型 数 据, 其 值 为 地 址 Name 是 一 个 数 据, 它 的 每 一 个 元 素 都 有 相 应 的 地 址 数 组 名 name 代 表 该 指 针 数 组 的 首 地 址 name+1 是 mane[i] 的 地 址 name+1 就 是 指 向 指 针 型 数 据 的 指 针 ( 地 址 ) 还 可 以 设 置 一 个 指 针 变 量 p, 使 它 指 向 指 针 数 组 元 素 P 就 是 指 向 指 针 型 数 据 的 指 针 变 量 怎 样 定 义 一 个 指 向 指 针 型 数 据 的 指 针 变 量 呢? 如 下 : char **p; p 前 面 有 两 个 * 号, 相 当 于 *(*p) 显 然 *p 是 指 针 变 量 的 定 义 形 式, 如 果 没 有 最 前 面 的 *, 那 就 是 定 义 了 一 个 指 向 字 符 数 据 的 指 针 变 量 现 在 它 前 面 又 有 一 个 * 号, 表 示 指 针 变 量 p 是 指 向 一 个 字 符 指 针 型 变 量 的 *p 就 是 p 所 指 向 的 另 一 个 指 针 变 量 从 下 图 可 以 看 到,name 是 一 个 指 针 数 组, 它 的 每 一 个 元 素 是 一 个 指 针 型 数 据, 其 值 为 地 址 name 是 一 个 数 组, 它 的 每 一 个 元 素 都 有 相 应 的 地 址 数 组 名 name 代 表 该 指 针 数 组 的 首 地 址 name+1 是 mane[i] 的 地 址 name+1 就 是 指 向 指 针 型 数 据 的 指 针 ( 地 址 ) 还 可 以 设 置 一 个 指 针 变 量 p, 使 它 指 向 指 针 数 组 元 素 P 就 是 指 向 指 针 型 数 据 的 指 针 变 量 如 果 有 : p=name+2; printf( %o\n,*p); printf( %s\n,*p); 则, 第 一 个 printf 函 数 语 句 输 出 name[2] 的 值 ( 它 是 一 个 地 址 ), 第 二 个 printf 函 数 语 句 以 字 符 串 形 式 (%s) 输 出 字 符 串 Great Wall 例 使 用 指 向 指 针 的 指 针 main() char *name[]="follow me","basic","great Wall","FORTRAN","Computer desighn"; char **p; int i; for(i=0;i<5;i++) p=name+i; 第 170 页

171 printf("%s\n",*p); 说 明 : p 是 指 向 指 针 的 指 针 变 量 例 一 个 指 针 数 组 的 元 素 指 向 数 据 的 简 单 例 子 main() static int a[5]=1,3,5,7,9; int *num[5]=&a[0],&a[1],&a[2],&a[3],&a[4]; int **p,i; p=num; for(i=0;i<5;i++) printf("%d\t",**p);p++; 说 明 : 指 针 数 组 的 元 素 只 能 存 放 地 址 main 函 数 的 参 数 前 面 介 绍 的 main 函 数 都 是 不 带 参 数 的 因 此 main 后 的 括 号 都 是 空 括 号 实 际 上,main 函 数 可 以 带 参 数, 这 个 参 数 可 以 认 为 是 main 函 数 的 形 式 参 数 C 语 言 规 定 main 函 数 的 参 数 只 能 有 两 个, 习 惯 上 这 两 个 参 数 写 为 argc 和 argv 因 此,main 函 数 的 函 数 头 可 写 为 : main (argc,argv) C 语 言 还 规 定 argc( 第 一 个 形 参 ) 必 须 是 整 型 变 量,argv( 第 二 个 形 参 ) 必 须 是 指 向 字 符 串 的 指 针 数 组 加 上 形 参 说 明 后,main 函 数 的 函 数 头 应 写 为 : main (int argc,char *argv[]) 由 于 main 函 数 不 能 被 其 它 函 数 调 用, 因 此 不 可 能 在 程 序 内 部 取 得 实 际 值 那 么, 在 何 处 把 实 参 值 赋 予 main 函 数 的 形 参 呢? 实 际 上,main 函 数 的 参 数 值 是 从 操 作 系 统 命 令 行 上 获 得 的 当 我 们 要 运 行 一 个 可 执 行 文 件 时, 在 DOS 提 示 符 下 键 入 文 件 名, 再 输 入 实 际 参 数 即 可 把 这 些 实 参 传 送 到 main 的 形 参 中 去 DOS 提 示 符 下 命 令 行 的 一 般 形 式 为 : C:\> 可 执 行 文 件 名 参 数 参 数 ; 但 是 应 该 特 别 注 意 的 是,main 的 两 个 形 参 和 命 令 行 中 的 参 数 在 位 置 上 不 是 一 一 对 应 的 因 为,main 的 形 参 只 有 二 个, 而 命 令 行 中 的 参 数 个 数 原 则 上 未 加 限 制 argc 参 数 表 示 了 命 令 行 中 参 数 的 个 数 ( 注 意 : 文 件 名 本 身 也 算 一 个 参 数 ),argc 的 值 是 在 输 入 命 令 行 时 由 系 统 按 实 际 参 数 的 个 数 自 动 赋 予 的 例 如 有 命 令 行 为 : C:\>E24 BASIC foxpro FORTRAN 由 于 文 件 名 E24 本 身 也 算 一 个 参 数, 所 以 共 有 4 个 参 数, 因 此 argc 取 得 的 值 为 4 argv 参 数 是 字 符 串 指 针 数 组, 其 各 元 素 值 为 命 令 行 中 各 字 符 串 ( 参 数 均 按 字 符 串 处 理 ) 的 首 地 址 指 第 171 页

172 针 数 组 的 长 度 即 为 参 数 个 数 数 组 元 素 初 值 由 系 统 自 动 赋 予 其 表 示 如 图 所 示 : 例 main(int argc,char *argv) while(argc-->1) printf("%s\n",*++argv); 本 例 是 显 示 命 令 行 中 输 入 的 参 数 如 果 上 例 的 可 执 行 文 件 名 为 e24.exe, 存 放 在 A 驱 动 器 的 盘 内 因 此 输 入 的 命 令 行 为 : C:\>a:e24 BASIC foxpro FORTRAN 则 运 行 结 果 为 : BASIC foxpro FORTRAN 该 行 共 有 4 个 参 数, 执 行 main 时,argc 的 初 值 即 为 4 argv 的 4 个 元 素 分 为 4 个 字 符 串 的 首 地 址 执 行 while 语 句, 每 循 环 一 次 argv 值 减 1, 当 argv 等 于 1 时 停 止 循 环, 共 循 环 三 次, 因 此 共 可 输 出 三 个 参 数 在 printf 函 数 中, 由 于 打 印 项 *++argv 是 先 加 1 再 打 印, 故 第 一 次 打 印 的 是 argv[1] 所 指 的 字 符 串 BASIC 第 二 三 次 循 环 分 别 打 印 后 二 个 字 符 串 而 参 数 e24 是 文 件 名, 不 必 输 出 10.8 有 关 指 针 的 数 据 类 型 和 指 针 运 算 的 小 结 有 关 指 针 的 数 据 类 型 的 小 结 定 义 含 义 int i; 定 义 整 型 变 量 i int *p p 为 指 向 整 型 数 据 的 指 针 变 量 int a[n]; 定 义 整 型 数 组 a, 它 有 n 个 元 素 int *p[n]; 定 义 指 针 数 组 p, 它 由 n 个 指 向 整 型 数 据 的 指 针 元 素 组 成 int (*p)[n]; p 为 指 向 含 n 个 元 素 的 一 维 数 组 的 指 针 变 量 int f(); f 为 带 回 整 型 函 数 值 的 函 数 int *p(); p 为 带 回 一 个 指 针 的 函 数, 该 指 针 指 向 整 型 数 据 int (*p)(); p 为 指 向 函 数 的 指 针, 该 函 数 返 回 一 个 整 型 值 第 172 页

173 int **p; P 是 一 个 指 针 变 量, 它 指 向 一 个 指 向 整 型 数 据 的 指 针 变 量 指 针 运 算 的 小 结 现 把 全 部 指 针 运 算 列 出 如 下 : 1) 指 针 变 量 加 ( 减 ) 一 个 整 数 : 例 如 :p++ p-- p+i p-i p+=i p-=i 一 个 指 针 变 量 加 ( 减 ) 一 个 整 数 并 不 是 简 单 地 将 原 值 加 ( 减 ) 一 个 整 数, 而 是 将 该 指 针 变 量 的 原 值 ( 是 一 个 地 址 ) 和 它 指 向 的 变 量 所 占 用 的 内 存 单 元 字 节 数 加 ( 减 ) 2) 指 针 变 量 赋 值 : 将 一 个 变 量 的 地 址 赋 给 一 个 指 针 变 量 p=&a; ( 将 变 量 a 的 地 址 赋 给 p) p=array; ( 将 数 组 array 的 首 地 址 赋 给 p) p=&array[i]; ( 将 数 组 array 第 i 个 元 素 的 地 址 赋 给 p) p=max; (max 为 已 定 义 的 函 数, 将 max 的 入 口 地 址 赋 给 p) p1=p2; (p1 和 p2 都 是 指 针 变 量, 将 p2 的 值 赋 给 p1) 注 意 : 不 能 如 下 : p=1000; 3) 指 针 变 量 可 以 有 空 值, 即 该 指 针 变 量 不 指 向 任 何 变 量 : p=null; 4) 两 个 指 针 变 量 可 以 相 减 : 如 果 两 个 指 针 变 量 指 向 同 一 个 数 组 的 元 素, 则 两 个 指 针 变 量 值 之 差 是 两 个 指 针 之 间 的 元 素 个 数 5) 两 个 指 针 变 量 比 较 : 如 果 两 个 指 针 变 量 指 向 同 一 个 数 组 的 元 素, 则 两 个 指 针 变 量 可 以 进 行 比 较 指 向 前 面 的 元 素 的 指 针 变 量 小 于 指 向 后 面 的 元 素 的 指 针 变 量 void 指 针 类 型 ANSI 新 标 准 增 加 了 一 种 void 指 针 类 型, 即 可 以 定 义 一 个 指 针 变 量, 但 不 指 定 它 是 指 向 哪 一 种 类 型 数 据 11 结 构 体 与 共 用 体 11.1 定 义 一 个 结 构 的 一 般 形 式 在 实 际 问 题 中, 一 组 数 据 往 往 具 有 不 同 的 数 据 类 型 例 如, 在 学 生 登 记 表 中, 姓 名 应 为 字 符 型 ; 学 号 可 为 整 型 或 字 符 型 ; 年 龄 应 为 整 型 ; 性 别 应 为 字 符 型 ; 成 绩 可 为 整 型 或 实 型 显 然 不 能 用 一 个 数 组 来 存 放 这 一 组 数 据 因 为 数 组 中 各 元 素 的 类 型 和 长 度 都 必 须 一 致, 以 便 于 编 译 系 统 处 理 为 了 解 决 这 个 问 题,C 语 言 中 给 出 了 另 一 种 构 造 数 据 类 型 结 构 (structure) 或 叫 结 构 体 它 相 当 于 其 它 高 级 语 言 中 的 记 录 结 构 是 一 种 构 造 类 型, 它 是 由 若 干 成 员 组 成 的 每 一 个 成 员 可 以 是 一 个 基 本 数 据 类 型 或 者 又 是 一 个 构 造 类 型 结 构 既 是 一 种 构 造 而 成 的 数 据 类 型, 那 么 在 说 明 和 使 用 之 前 必 须 先 定 义 它, 也 就 是 构 造 它 如 同 在 说 明 和 调 用 函 数 之 前 要 先 定 义 函 数 一 样 第 173 页

174 定 义 一 个 结 构 的 一 般 形 式 为 : struct 结 构 名 成 员 表 列 ; 成 员 表 列 由 若 干 个 成 员 组 成, 每 个 成 员 都 是 该 结 构 的 一 个 组 成 部 分 对 每 个 成 员 也 必 须 作 类 型 说 明, 其 形 式 为 : 类 型 说 明 符 成 员 名 ; 成 员 名 的 命 名 应 符 合 标 识 符 的 书 写 规 定 例 如 : struct stu int num; char name[20]; char sex; float score; ; 在 这 个 结 构 定 义 中, 结 构 名 为 stu, 该 结 构 由 4 个 成 员 组 成 第 一 个 成 员 为 num, 整 型 变 量 ; 第 二 个 成 员 为 name, 字 符 数 组 ; 第 三 个 成 员 为 sex, 字 符 变 量 ; 第 四 个 成 员 为 score, 实 型 变 量 应 注 意 在 括 号 后 的 分 号 是 不 可 少 的 结 构 定 义 之 后, 即 可 进 行 变 量 说 明 凡 说 明 为 结 构 stu 的 变 量 都 由 上 述 4 个 成 员 组 成 由 此 可 见, 结 构 是 一 种 复 杂 的 数 据 类 型, 是 数 目 固 定, 类 型 不 同 的 若 干 有 序 变 量 的 集 合 11.2 结 构 类 型 变 量 的 说 明 说 明 结 构 变 量 有 以 下 三 种 方 法 以 上 面 定 义 的 stu 为 例 来 加 以 说 明 1. 先 定 义 结 构, 再 说 明 结 构 变 量 如 : struct stu int num; char name[20]; char sex; float score; ; struct stu boy1,boy2; 说 明 了 两 个 变 量 boy1 和 boy2 为 stu 结 构 类 型 也 可 以 用 宏 定 义 使 一 个 符 号 常 量 来 表 示 一 个 结 构 类 型 例 如 : #define STU struct stu STU int num; char name[20]; char sex; float score; ; 第 174 页

175 STU boy1,boy2; 2. 在 定 义 结 构 类 型 的 同 时 说 明 结 构 变 量 例 如 : struct stu int num; char name[20]; char sex; float score; boy1,boy2; 这 种 形 式 的 说 明 的 一 般 形 式 为 : struct 结 构 名 成 员 表 列 变 量 名 表 列 ; 3. 直 接 说 明 结 构 变 量 例 如 : struct int num; char name[20]; char sex; float score; boy1,boy2; 这 种 形 式 的 说 明 的 一 般 形 式 为 : struct 成 员 表 列 变 量 名 表 列 ; 第 三 种 方 法 与 第 二 种 方 法 的 区 别 在 于 第 三 种 方 法 中 省 去 了 结 构 名, 而 直 接 给 出 结 构 变 量 三 种 方 法 中 说 明 的 boy1,boy2 变 量 都 具 有 下 图 所 示 的 结 构 说 明 了 boy1,boy2 变 量 为 stu 类 型 后, 即 可 向 这 两 个 变 量 中 的 各 个 成 员 赋 值 在 上 述 stu 结 构 定 义 中, 所 有 的 成 员 都 是 基 本 数 据 类 型 或 数 组 类 型 成 员 也 可 以 又 是 一 个 结 构, 即 构 成 了 嵌 套 的 结 构 例 如, 下 图 给 出 了 另 一 个 数 据 结 构 按 图 可 给 出 以 下 结 构 定 义 : struct date 第 175 页

176 int month; int day; int year; ; struct int num; char name[20]; char sex; struct date birthday; float score; boy1,boy2; 首 先 定 义 一 个 结 构 date, 由 month( 月 ) day( 日 ) year( 年 ) 三 个 成 员 组 成 在 定 义 并 说 明 变 量 boy1 和 boy2 时, 其 中 的 成 员 birthday 被 说 明 为 data 结 构 类 型 成 员 名 可 与 程 序 中 其 它 变 量 同 名, 互 不 干 扰 11.3 结 构 变 量 成 员 的 表 示 方 法 在 程 序 中 使 用 结 构 变 量 时, 往 往 不 把 它 作 为 一 个 整 体 来 使 用 在 ANSI C 中 除 了 允 许 具 有 相 同 类 型 的 结 构 变 量 相 互 赋 值 以 外, 一 般 对 结 构 变 量 的 使 用, 包 括 赋 值 输 入 输 出 运 算 等 都 是 通 过 结 构 变 量 的 成 员 来 实 现 的 表 示 结 构 变 量 成 员 的 一 般 形 式 是 : 结 构 变 量 名. 成 员 名 例 如 : boy1.num 即 第 一 个 人 的 学 号 boy2.sex 即 第 二 个 人 的 性 别 如 果 成 员 本 身 又 是 一 个 结 构 则 必 须 逐 级 找 到 最 低 级 的 成 员 才 能 使 用 例 如 : boy1.birthday.month 即 第 一 个 人 出 生 的 月 份 成 员 可 以 在 程 序 中 单 独 使 用, 与 普 通 变 量 完 全 相 同 11.4 结 构 变 量 的 赋 值 结 构 变 量 的 赋 值 就 是 给 各 成 员 赋 值 可 用 输 入 语 句 或 赋 值 语 句 来 完 成 例 11.1 给 结 构 变 量 赋 值 并 输 出 其 值 main() struct stu int num; char *name; char sex; float score; boy1,boy2; 第 176 页

177 boy1.num=102; boy1.name="zhang ping"; printf("input sex and score\n"); scanf("%c %f",&boy1.sex,&boy1.score); boy2=boy1; printf("number=%d\nname=%s\n",boy2.num,boy2.name); printf("sex=%c\nscore=%f\n",boy2.sex,boy2.score); 本 程 序 中 用 赋 值 语 句 给 num 和 name 两 个 成 员 赋 值,name 是 一 个 字 符 串 指 针 变 量 用 scanf 函 数 动 态 地 输 入 sex 和 score 成 员 值, 然 后 把 boy1 的 所 有 成 员 的 值 整 体 赋 予 boy2 最 后 分 别 输 出 boy2 的 各 个 成 员 值 本 例 表 示 了 结 构 变 量 的 赋 值 输 入 和 输 出 的 方 法 11.5 结 构 变 量 的 初 始 化 和 其 他 类 型 变 量 一 样, 对 结 构 变 量 可 以 在 定 义 时 进 行 初 始 化 赋 值 例 11.2 对 结 构 变 量 初 始 化 main() struct stu /* 定 义 结 构 */ int num; char *name; char sex; float score; boy2,boy1=102,"zhang ping",'m',78.5; boy2=boy1; printf("number=%d\nname=%s\n",boy2.num,boy2.name); printf("sex=%c\nscore=%f\n",boy2.sex,boy2.score); 本 例 中,boy2,boy1 均 被 定 义 为 外 部 结 构 变 量, 并 对 boy1 作 了 初 始 化 赋 值 在 main 函 数 中, 把 boy1 的 值 整 体 赋 予 boy2, 然 后 用 两 个 printf 语 句 输 出 boy2 各 成 员 的 值 11.6 结 构 数 组 的 定 义 数 组 的 元 素 也 可 以 是 结 构 类 型 的 因 此 可 以 构 成 结 构 型 数 组 结 构 数 组 的 每 一 个 元 素 都 是 具 有 相 同 结 构 类 型 的 下 标 结 构 变 量 在 实 际 应 用 中, 经 常 用 结 构 数 组 来 表 示 具 有 相 同 数 据 结 构 的 一 个 群 体 如 一 个 班 的 学 生 档 案, 一 个 车 间 职 工 的 工 资 表 等 方 法 和 结 构 变 量 相 似, 只 需 说 明 它 为 数 组 类 型 即 可 例 如 : 第 177 页

178 struct stu int num; char *name; char sex; float score; boy[5]; 定 义 了 一 个 结 构 数 组 boy, 共 有 5 个 元 素,boy[0]~boy[4] 每 个 数 组 元 素 都 具 有 struct stu 的 结 构 形 式 对 结 构 数 组 可 以 作 初 始 化 赋 值 例 如 : struct stu int num; char *name; char sex; float score; boy[5]= 101,"Li ping","m",45, 102,"Zhang ping","m",62.5, 103,"He fang","f",92.5, 104,"Cheng ling","f",87, 105,"Wang ming","m",58; 当 对 全 部 元 素 作 初 始 化 赋 值 时, 也 可 不 给 出 数 组 长 度 例 11.3 计 算 学 生 的 平 均 成 绩 和 不 及 格 的 人 数 struct stu int num; char *name; char sex; float score; boy[5]= 101,"Li ping",'m',45, 102,"Zhang ping",'m',62.5, 103,"He fang",'f',92.5, 104,"Cheng ling",'f',87, 105,"Wang ming",'m',58, ; main() int i,c=0; float ave,s=0; for(i=0;i<5;i++) 第 178 页

179 s+=boy[i].score; if(boy[i].score<60) c+=1; printf("s=%f\n",s); ave=s/5; printf("average=%f\ncount=%d\n",ave,c); 本 例 程 序 中 定 义 了 一 个 外 部 结 构 数 组 boy, 共 5 个 元 素, 并 作 了 初 始 化 赋 值 在 main 函 数 中 用 for 语 句 逐 个 累 加 各 元 素 的 score 成 员 值 存 于 s 之 中, 如 score 的 值 小 于 60( 不 及 格 ) 即 计 数 器 C 加 1, 循 环 完 毕 后 计 算 平 均 成 绩, 并 输 出 全 班 总 分, 平 均 分 及 不 及 格 人 数 例 11.4 建 立 同 学 通 讯 录 #include"stdio.h" #define NUM 3 struct mem char name[20]; char phone[10]; ; main() struct mem man[num]; int i; for(i=0;i<num;i++) printf("input name:\n"); gets(man[i].name); printf("input phone:\n"); gets(man[i].phone); printf("name\t\t\tphone\n\n"); for(i=0;i<num;i++) printf("%s\t\t\t%s\n",man[i].name,man[i].phone); 本 程 序 中 定 义 了 一 个 结 构 mem, 它 有 两 个 成 员 name 和 phone 用 来 表 示 姓 名 和 电 话 号 码 在 主 函 数 中 定 义 man 为 具 有 mem 类 型 的 结 构 数 组 在 for 语 句 中, 用 gets 函 数 分 别 输 入 各 个 元 素 中 两 个 成 员 的 值 然 后 又 在 for 语 句 中 用 printf 语 句 输 出 各 元 素 中 两 个 成 员 值 第 179 页

180 11.7 结 构 指 针 变 量 的 说 明 和 使 用 指 向 结 构 变 量 的 指 针 一 个 指 针 变 量 当 用 来 指 向 一 个 结 构 变 量 时, 称 之 为 结 构 指 针 变 量 结 构 指 针 变 量 中 的 值 是 所 指 向 的 结 构 变 量 的 首 地 址 通 过 结 构 指 针 即 可 访 问 该 结 构 变 量, 这 与 数 组 指 针 和 函 数 指 针 的 情 况 是 相 同 的 结 构 指 针 变 量 说 明 的 一 般 形 式 为 : struct 结 构 名 * 结 构 指 针 变 量 名 例 如, 在 前 面 的 例 题 中 定 义 了 stu 这 个 结 构, 如 要 说 明 一 个 指 向 stu 的 指 针 变 量 pstu, 可 写 为 : struct stu *pstu; 当 然 也 可 在 定 义 stu 结 构 时 同 时 说 明 pstu 与 前 面 讨 论 的 各 类 指 针 变 量 相 同, 结 构 指 针 变 量 也 必 须 要 先 赋 值 后 才 能 使 用 赋 值 是 把 结 构 变 量 的 首 地 址 赋 予 该 指 针 变 量, 不 能 把 结 构 名 赋 予 该 指 针 变 量 如 果 boy 是 被 说 明 为 stu 类 型 的 结 构 变 量, 则 : pstu=&boy 是 正 确 的, 而 : pstu=&stu 是 错 误 的 结 构 名 和 结 构 变 量 是 两 个 不 同 的 概 念, 不 能 混 淆 结 构 名 只 能 表 示 一 个 结 构 形 式, 编 译 系 统 并 不 对 它 分 配 内 存 空 间 只 有 当 某 变 量 被 说 明 为 这 种 类 型 的 结 构 时, 才 对 该 变 量 分 配 存 储 空 间 因 此 上 面 &stu 这 种 写 法 是 错 误 的, 不 可 能 去 取 一 个 结 构 名 的 首 地 址 有 了 结 构 指 针 变 量, 就 能 更 方 便 地 访 问 结 构 变 量 的 各 个 成 员 其 访 问 的 一 般 形 式 为 : (* 结 构 指 针 变 量 ). 成 员 名 或 为 : 结 构 指 针 变 量 -> 成 员 名 例 如 : (*pstu).num 或 者 : pstu->num 应 该 注 意 (*pstu) 两 侧 的 括 号 不 可 少, 因 为 成 员 符. 的 优 先 级 高 于 * 如 去 掉 括 号 写 作 *pstu.num 则 等 效 于 *(pstu.num), 这 样, 意 义 就 完 全 不 对 了 下 面 通 过 例 子 来 说 明 结 构 指 针 变 量 的 具 体 说 明 和 使 用 方 法 例 11.5 struct stu int num; char *name; char sex; float score; boy1=102,"zhang ping",'m',78.5,*pstu; 第 180 页

181 main() pstu=&boy1; printf("number=%d\nname=%s\n",boy1.num,boy1.name); printf("sex=%c\nscore=%f\n\n",boy1.sex,boy1.score); printf("number=%d\nname=%s\n",(*pstu).num,(*pstu).name); printf("sex=%c\nscore=%f\n\n",(*pstu).sex,(*pstu).score); printf("number=%d\nname=%s\n",pstu->num,pstu->name); printf("sex=%c\nscore=%f\n\n",pstu->sex,pstu->score); 本 例 程 序 定 义 了 一 个 结 构 stu, 定 义 了 stu 类 型 结 构 变 量 boy1 并 作 了 初 始 化 赋 值, 还 定 义 了 一 个 指 向 stu 类 型 结 构 的 指 针 变 量 pstu 在 main 函 数 中,pstu 被 赋 予 boy1 的 地 址, 因 此 pstu 指 向 boy1 然 后 在 printf 语 句 内 用 三 种 形 式 输 出 boy1 的 各 个 成 员 值 从 运 行 结 果 可 以 看 出 : 结 构 变 量. 成 员 名 (* 结 构 指 针 变 量 ). 成 员 名 结 构 指 针 变 量 -> 成 员 名 这 三 种 用 于 表 示 结 构 成 员 的 形 式 是 完 全 等 效 的 指 向 结 构 数 组 的 指 针 指 针 变 量 可 以 指 向 一 个 结 构 数 组, 这 时 结 构 指 针 变 量 的 值 是 整 个 结 构 数 组 的 首 地 址 结 构 指 针 变 量 也 可 指 向 结 构 数 组 的 一 个 元 素, 这 时 结 构 指 针 变 量 的 值 是 该 结 构 数 组 元 素 的 首 地 址 设 ps 为 指 向 结 构 数 组 的 指 针 变 量, 则 ps 也 指 向 该 结 构 数 组 的 0 号 元 素,ps+1 指 向 1 号 元 素,ps+i 则 指 向 i 号 元 素 这 与 普 通 数 组 的 情 况 是 一 致 的 例 11.6 用 指 针 变 量 输 出 结 构 数 组 struct stu int num; char *name; char sex; float score; boy[5]= 101,"Zhou ping",'m',45, 102,"Zhang ping",'m',62.5, 103,"Liou fang",'f',92.5, 104,"Cheng ling",'f',87, 105,"Wang ming",'m',58, ; main() 第 181 页

182 struct stu *ps; printf("no\tname\t\t\tsex\tscore\t\n"); for(ps=boy;ps<boy+5;ps++) printf("%d\t%s\t\t%c\t%f\t\n",ps->num,ps->name,ps->sex,ps->score); 在 程 序 中, 定 义 了 stu 结 构 类 型 的 外 部 数 组 boy 并 作 了 初 始 化 赋 值 在 main 函 数 内 定 义 ps 为 指 向 stu 类 型 的 指 针 在 循 环 语 句 for 的 表 达 式 1 中,ps 被 赋 予 boy 的 首 地 址, 然 后 循 环 5 次, 输 出 boy 数 组 中 各 成 员 值 应 该 注 意 的 是, 一 个 结 构 指 针 变 量 虽 然 可 以 用 来 访 问 结 构 变 量 或 结 构 数 组 元 素 的 成 员, 但 是, 不 能 使 它 指 向 一 个 成 员 也 就 是 说 不 允 许 取 一 个 成 员 的 地 址 来 赋 予 它 因 此, 下 面 的 赋 值 是 错 误 的 ps=&boy[1].sex; 而 只 能 是 : ps=boy;( 赋 予 数 组 首 地 址 ) 或 者 是 : ps=&boy[0];( 赋 予 0 号 元 素 首 地 址 ) 结 构 指 针 变 量 作 函 数 参 数 在 ANSI C 标 准 中 允 许 用 结 构 变 量 作 函 数 参 数 进 行 整 体 传 送 但 是 这 种 传 送 要 将 全 部 成 员 逐 个 传 送, 特 别 是 成 员 为 数 组 时 将 会 使 传 送 的 时 间 和 空 间 开 销 很 大, 严 重 地 降 低 了 程 序 的 效 率 因 此 最 好 的 办 法 就 是 使 用 指 针, 即 用 指 针 变 量 作 函 数 参 数 进 行 传 送 这 时 由 实 参 传 向 形 参 的 只 是 地 址, 从 而 减 少 了 时 间 和 空 间 的 开 销 例 11.7 计 算 一 组 学 生 的 平 均 成 绩 和 不 及 格 人 数 用 结 构 指 针 变 量 作 函 数 参 数 编 程 struct stu int num; char *name; char sex; float score;boy[5]= 101,"Li ping",'m',45, 102,"Zhang ping",'m',62.5, 103,"He fang",'f',92.5, 104,"Cheng ling",'f',87, 105,"Wang ming",'m',58, ; main() struct stu *ps; void ave(struct stu *ps); ps=boy; ave(ps); 第 182 页

183 void ave(struct stu *ps) int c=0,i; float ave,s=0; for(i=0;i<5;i++,ps++) s+=ps->score; if(ps->score<60) c+=1; printf("s=%f\n",s); ave=s/5; printf("average=%f\ncount=%d\n",ave,c); 本 程 序 中 定 义 了 函 数 ave, 其 形 参 为 结 构 指 针 变 量 ps boy 被 定 义 为 外 部 结 构 数 组, 因 此 在 整 个 源 程 序 中 有 效 在 main 函 数 中 定 义 说 明 了 结 构 指 针 变 量 ps, 并 把 boy 的 首 地 址 赋 予 它, 使 ps 指 向 boy 数 组 然 后 以 ps 作 实 参 调 用 函 数 ave 在 函 数 ave 中 完 成 计 算 平 均 成 绩 和 统 计 不 及 格 人 数 的 工 作 并 输 出 结 果 由 于 本 程 序 全 部 采 用 指 针 变 量 作 运 算 和 处 理, 故 速 度 更 快, 程 序 效 率 更 高 11.8 动 态 存 储 分 配 在 数 组 一 章 中, 曾 介 绍 过 数 组 的 长 度 是 预 先 定 义 好 的, 在 整 个 程 序 中 固 定 不 变 C 语 言 中 不 允 许 动 态 数 组 类 型 例 如 : int n; scanf("%d",&n); int a[n]; 用 变 量 表 示 长 度, 想 对 数 组 的 大 小 作 动 态 说 明, 这 是 错 误 的 但 是 在 实 际 的 编 程 中, 往 往 会 发 生 这 种 情 况, 即 所 需 的 内 存 空 间 取 决 于 实 际 输 入 的 数 据, 而 无 法 预 先 确 定 对 于 这 种 问 题, 用 数 组 的 办 法 很 难 解 决 为 了 解 决 上 述 问 题,C 语 言 提 供 了 一 些 内 存 管 理 函 数, 这 些 内 存 管 理 函 数 可 以 按 需 要 动 态 地 分 配 内 存 空 间, 也 可 把 不 再 使 用 的 空 间 回 收 待 用, 为 有 效 地 利 用 内 存 资 源 提 供 了 手 段 常 用 的 内 存 管 理 函 数 有 以 下 三 个 : 1. 分 配 内 存 空 间 函 数 malloc 调 用 形 式 : ( 类 型 说 明 符 *)malloc(size) 功 能 : 在 内 存 的 动 态 存 储 区 中 分 配 一 块 长 度 为 "size" 字 节 的 连 续 区 域 函 数 的 返 回 值 为 该 区 域 的 首 地 址 类 型 说 明 符 表 示 把 该 区 域 用 于 何 种 数 据 类 型 ( 类 型 说 明 符 *) 表 示 把 返 回 值 强 制 转 换 为 该 类 型 指 针 size 是 一 个 无 符 号 数 第 183 页

184 例 如 : pc=(char *)malloc(100); 表 示 分 配 100 个 字 节 的 内 存 空 间, 并 强 制 转 换 为 字 符 数 组 类 型, 函 数 的 返 回 值 为 指 向 该 字 符 数 组 的 指 针, 把 该 指 针 赋 予 指 针 变 量 pc 2. 分 配 内 存 空 间 函 数 calloc calloc 也 用 于 分 配 内 存 空 间 调 用 形 式 : ( 类 型 说 明 符 *)calloc(n,size) 功 能 : 在 内 存 动 态 存 储 区 中 分 配 n 块 长 度 为 size 字 节 的 连 续 区 域 函 数 的 返 回 值 为 该 区 域 的 首 地 址 ( 类 型 说 明 符 *) 用 于 强 制 类 型 转 换 calloc 函 数 与 malloc 函 数 的 区 别 仅 在 于 一 次 可 以 分 配 n 块 区 域 例 如 : ps=(struet stu*)calloc(2,sizeof(struct stu)); 其 中 的 sizeof(struct stu) 是 求 stu 的 结 构 长 度 因 此 该 语 句 的 意 思 是 : 按 stu 的 长 度 分 配 2 块 连 续 区 域, 强 制 转 换 为 stu 类 型, 并 把 其 首 地 址 赋 予 指 针 变 量 ps 2. 释 放 内 存 空 间 函 数 free 调 用 形 式 : free(void*ptr); 功 能 : 释 放 ptr 所 指 向 的 一 块 内 存 空 间,ptr 是 一 个 任 意 类 型 的 指 针 变 量, 它 指 向 被 释 放 区 域 的 首 地 址 被 释 放 区 应 是 由 malloc 或 calloc 函 数 所 分 配 的 区 域 例 11.8 分 配 一 块 区 域, 输 入 一 个 学 生 数 据 main() struct stu int num; char *name; char sex; float score; *ps; ps=(struct stu*)malloc(sizeof(struct stu)); ps->num=102; ps->name="zhang ping"; ps->sex='m'; ps->score=62.5; printf("number=%d\nname=%s\n",ps->num,ps->name); printf("sex=%c\nscore=%f\n",ps->sex,ps->score); free(ps); 本 例 中, 定 义 了 结 构 stu, 定 义 了 stu 类 型 指 针 变 量 ps 然 后 分 配 一 块 stu 大 内 存 区, 并 把 首 地 址 赋 予 ps, 使 ps 指 向 该 区 域 再 以 ps 为 指 向 结 构 的 指 针 变 量 对 各 成 员 赋 值, 并 第 184 页

185 用 printf 输 出 各 成 员 值 最 后 用 free 函 数 释 放 ps 指 向 的 内 存 空 间 整 个 程 序 包 含 了 申 请 内 存 空 间 使 用 内 存 空 间 释 放 内 存 空 间 三 个 步 骤, 实 现 存 储 空 间 的 动 态 分 配 11.9 链 表 的 概 念 在 例 7.8 中 采 用 了 动 态 分 配 的 办 法 为 一 个 结 构 分 配 内 存 空 间 每 一 次 分 配 一 块 空 间 可 用 来 存 放 一 个 学 生 的 数 据, 我 们 可 称 之 为 一 个 结 点 有 多 少 个 学 生 就 应 该 申 请 分 配 多 少 块 内 存 空 间, 也 就 是 说 要 建 立 多 少 个 结 点 当 然 用 结 构 数 组 也 可 以 完 成 上 述 工 作, 但 如 果 预 先 不 能 准 确 把 握 学 生 人 数, 也 就 无 法 确 定 数 组 大 小 而 且 当 学 生 留 级 退 学 之 后 也 不 能 把 该 元 素 占 用 的 空 间 从 数 组 中 释 放 出 来 用 动 态 存 储 的 方 法 可 以 很 好 地 解 决 这 些 问 题 有 一 个 学 生 就 分 配 一 个 结 点, 无 须 预 先 确 定 学 生 的 准 确 人 数, 某 学 生 退 学, 可 删 去 该 结 点, 并 释 放 该 结 点 占 用 的 存 储 空 间 从 而 节 约 了 宝 贵 的 内 存 资 源 另 一 方 面, 用 数 组 的 方 法 必 须 占 用 一 块 连 续 的 内 存 区 域 而 使 用 动 态 分 配 时, 每 个 结 点 之 间 可 以 是 不 连 续 的 ( 结 点 内 是 连 续 的 ) 结 点 之 间 的 联 系 可 以 用 指 针 实 现 即 在 结 点 结 构 中 定 义 一 个 成 员 项 用 来 存 放 下 一 结 点 的 首 地 址, 这 个 用 于 存 放 地 址 的 成 员, 常 把 它 称 为 指 针 域 可 在 第 一 个 结 点 的 指 针 域 内 存 入 第 二 个 结 点 的 首 地 址, 在 第 二 个 结 点 的 指 针 域 内 又 存 放 第 三 个 结 点 的 首 地 址, 如 此 串 连 下 去 直 到 最 后 一 个 结 点 最 后 一 个 结 点 因 无 后 续 结 点 连 接, 其 指 针 域 可 赋 为 0 这 样 一 种 连 接 方 式, 在 数 据 结 构 中 称 为 链 表 下 图 为 最 一 简 单 链 表 的 示 意 图 图 中, 第 0 个 结 点 称 为 头 结 点, 它 存 放 有 第 一 个 结 点 的 首 地 址, 它 没 有 数 据, 只 是 一 个 指 针 变 量 以 下 的 每 个 结 点 都 分 为 两 个 域, 一 个 是 数 据 域, 存 放 各 种 实 际 的 数 据, 如 学 号 num, 姓 名 name, 性 别 sex 和 成 绩 score 等 另 一 个 域 为 指 针 域, 存 放 下 一 结 点 的 首 地 址 链 表 中 的 每 一 个 结 点 都 是 同 一 种 结 构 类 型 例 如, 一 个 存 放 学 生 学 号 和 成 绩 的 结 点 应 为 以 下 结 构 : struct stu int num; int score; struct stu *next; 前 两 个 成 员 项 组 成 数 据 域, 后 一 个 成 员 项 next 构 成 指 针 域, 它 是 一 个 指 向 stu 类 型 结 构 的 指 针 变 量 链 表 的 基 本 操 作 对 链 表 的 主 要 操 作 有 以 下 几 种 : 1. 建 立 链 表 ; 2. 结 构 的 查 找 与 输 出 ; 3. 插 入 一 个 结 点 ; 4. 删 除 一 个 结 点 ; 下 面 通 过 例 题 来 说 明 这 些 操 作 例 11.9 建 立 一 个 三 个 结 点 的 链 表, 存 放 学 生 数 据 为 简 单 起 见, 我 们 假 定 学 生 数 据 结 构 中 只 有 学 号 和 年 龄 两 项 可 编 写 一 个 建 立 链 表 的 函 数 creat 程 序 如 下 : 第 185 页

186 #define NULL 0 #define TYPE struct stu #define LEN sizeof (struct stu) struct stu int num; int age; struct stu *next; ; TYPE *creat(int n) struct stu *head,*pf,*pb; int i; for(i=0;i<n;i++) pb=(type*) malloc(len); printf("input Number and Age\n"); scanf("%d%d",&pb->num,&pb->age); if(i==0) pf=head=pb; else pf->next=pb; pb->next=null; pf=pb; return(head); 在 函 数 外 首 先 用 宏 定 义 对 三 个 符 号 常 量 作 了 定 义 这 里 用 TYPE 表 示 struct stu, 用 LEN 表 示 sizeof(struct stu) 主 要 的 目 的 是 为 了 在 以 下 程 序 内 减 少 书 写 并 使 阅 读 更 加 方 便 结 构 stu 定 义 为 外 部 类 型, 程 序 中 的 各 个 函 数 均 可 使 用 该 定 义 creat 函 数 用 于 建 立 一 个 有 n 个 结 点 的 链 表, 它 是 一 个 指 针 函 数, 它 返 回 的 指 针 指 向 stu 结 构 在 creat 函 数 内 定 义 了 三 个 stu 结 构 的 指 针 变 量 head 为 头 指 针,pf 为 指 向 两 相 邻 结 点 的 前 一 结 点 的 指 针 变 量 pb 为 后 一 结 点 的 指 针 变 量 枚 举 类 型 在 实 际 问 题 中, 有 些 变 量 的 取 值 被 限 定 在 一 个 有 限 的 范 围 内 例 如, 一 个 星 期 内 只 有 七 天, 一 年 只 有 十 二 个 月, 一 个 班 每 周 有 六 门 课 程 等 等 如 果 把 这 些 量 说 明 为 整 型, 字 符 型 或 其 它 类 型 显 然 是 不 妥 当 的 为 此,C 语 言 提 供 了 一 种 称 为 枚 举 的 类 型 在 枚 举 类 型 的 定 义 中 列 举 出 所 有 可 能 的 取 值, 被 说 明 为 该 枚 举 类 型 的 变 量 取 值 不 能 超 过 定 义 的 范 围 应 该 说 明 的 是, 枚 举 类 型 是 一 种 基 本 数 据 类 型, 而 不 是 一 种 构 造 类 型, 因 为 它 不 能 再 分 解 为 任 何 基 本 类 型 第 186 页

187 枚 举 类 型 的 定 义 和 枚 举 变 量 的 说 明 1. 枚 举 的 定 义 枚 举 类 型 定 义 的 一 般 形 式 为 : enum 枚 举 名 枚 举 值 表 ; 在 枚 举 值 表 中 应 罗 列 出 所 有 可 用 值 这 些 值 也 称 为 枚 举 元 素 例 如 : 该 枚 举 名 为 weekday, 枚 举 值 共 有 7 个, 即 一 周 中 的 七 天 凡 被 说 明 为 weekday 类 型 变 量 的 取 值 只 能 是 七 天 中 的 某 一 天 2. 枚 举 变 量 的 说 明 如 同 结 构 和 联 合 一 样, 枚 举 变 量 也 可 用 不 同 的 方 式 说 明, 即 先 定 义 后 说 明, 同 时 定 义 说 明 或 直 接 说 明 设 有 变 量 a,b,c 被 说 明 为 上 述 的 weekday, 可 采 用 下 述 任 一 种 方 式 : enum weekday sun,mou,tue,wed,thu,fri,sat ; enum weekday a,b,c; 或 者 为 : enum weekday sun,mou,tue,wed,thu,fri,sat a,b,c; 或 者 为 : enum sun,mou,tue,wed,thu,fri,sat a,b,c; 枚 举 类 型 变 量 的 赋 值 和 使 用 枚 举 类 型 在 使 用 中 有 以 下 规 定 : 1. 枚 举 值 是 常 量, 不 是 变 量 不 能 在 程 序 中 用 赋 值 语 句 再 对 它 赋 值 例 如 对 枚 举 weekday 的 元 素 再 作 以 下 赋 值 : sun=5; mon=2; sun=mon; 都 是 错 误 的 2. 枚 举 元 素 本 身 由 系 统 定 义 了 一 个 表 示 序 号 的 数 值, 从 0 开 始 顺 序 定 义 为 0,1,2 如 在 weekday 中,sun 值 为 0,mon 值 为 1,,sat 值 为 6 例 main() enum weekday sun,mon,tue,wed,thu,fri,sat a,b,c; a=sun; b=mon; c=tue; printf("%d,%d,%d",a,b,c); 说 明 : 第 187 页

188 只 能 把 枚 举 值 赋 予 枚 举 变 量, 不 能 把 元 素 的 数 值 直 接 赋 予 枚 举 变 量 如 : a=sum; b=mon; 是 正 确 的 而 : a=0; b=1; 是 错 误 的 如 一 定 要 把 数 值 赋 予 枚 举 变 量, 则 必 须 用 强 制 类 型 转 换 如 : a=(enum weekday)2; 其 意 义 是 将 顺 序 号 为 2 的 枚 举 元 素 赋 予 枚 举 变 量 a, 相 当 于 : a=tue; 还 应 该 说 明 的 是 枚 举 元 素 不 是 字 符 常 量 也 不 是 字 符 串 常 量, 使 用 时 不 要 加 单 双 引 号 例 main() enum body a,b,c,d month[31],j; int i; j=a; for(i=1;i<=30;i++) month[i]=j; j++; if (j>d) j=a; for(i=1;i<=30;i++) switch(month[i]) case a:printf(" %2d %c\t",i,'a'); break; case b:printf(" %2d %c\t",i,'b'); break; case c:printf(" %2d %c\t",i,'c'); break; case d:printf(" %2d %c\t",i,'d'); break; default:break; printf("\n"); 类 型 定 义 符 typedef C 语 言 不 仅 提 供 了 丰 富 的 数 据 类 型, 而 且 还 允 许 由 用 户 自 己 定 义 类 型 说 明 符, 也 就 是 说 允 许 由 用 户 为 数 据 类 型 取 别 名 类 型 定 义 符 typedef 即 可 用 来 完 成 此 功 能 例 如, 有 整 型 量 a,b, 其 说 明 如 下 : int a,b; 第 188 页

189 其 中 int 是 整 型 变 量 的 类 型 说 明 符 int 的 完 整 写 法 为 integer, 为 了 增 加 程 序 的 可 读 性, 可 把 整 型 说 明 符 用 typedef 定 义 为 : typedef int INTEGER 这 以 后 就 可 用 INTEGER 来 代 替 int 作 整 型 变 量 的 类 型 说 明 了 例 如 : INTEGER a,b; 它 等 效 于 : int a,b; 用 typedef 定 义 数 组 指 针 结 构 等 类 型 将 带 来 很 大 的 方 便, 不 仅 使 程 序 书 写 简 单 而 且 使 意 义 更 为 明 确, 因 而 增 强 了 可 读 性 例 如 : typedef char NAME[20]; 表 示 NAME 是 字 符 数 组 类 型, 数 组 长 度 为 20 然 后 可 用 NAME 说 明 变 量, 如 : NAME a1,a2,s1,s2; 完 全 等 效 于 : char a1[20],a2[20],s1[20],s2[20] 又 如 : typedef struct stu char name[20]; int age; char sex; STU; 定 义 STU 表 示 stu 的 结 构 类 型, 然 后 可 用 STU 来 说 明 结 构 变 量 : STU body1,body2; typedef 定 义 的 一 般 形 式 为 : typedef 原 类 型 名 新 类 型 名 其 中 原 类 型 名 中 含 有 定 义 部 分, 新 类 型 名 一 般 用 大 写 表 示, 以 便 于 区 别 有 时 也 可 用 宏 定 义 来 代 替 typedef 的 功 能, 但 是 宏 定 义 是 由 预 处 理 完 成 的, 而 typedef 则 是 在 编 译 时 完 成 的, 后 者 更 为 灵 活 方 便 12 位 运 算 前 面 介 绍 的 各 种 运 算 都 是 以 字 节 作 为 最 基 本 位 进 行 的 但 在 很 多 系 统 程 序 中 常 要 求 在 位 (bit) 一 级 进 行 运 算 或 处 理 C 语 言 提 供 了 位 运 算 的 功 能, 这 使 得 C 语 言 也 能 像 汇 编 语 言 一 样 用 来 编 写 系 统 程 序 12.1 位 运 算 符 C 语 言 提 供 了 六 种 位 运 算 符 : & 按 位 与 按 位 或 ^ 按 位 异 或 ~ 取 反 第 189 页

190 << 左 移 >> 右 移 按 位 与 运 算 按 位 与 运 算 符 "&" 是 双 目 运 算 符 其 功 能 是 参 与 运 算 的 两 数 各 对 应 的 二 进 位 相 与 只 有 对 应 的 两 个 二 进 位 均 为 1 时, 结 果 位 才 为 1, 否 则 为 0 参 与 运 算 的 数 以 补 码 方 式 出 现 例 如 :9&5 可 写 算 式 如 下 : (9 的 二 进 制 补 码 ) & (5 的 二 进 制 补 码 ) (1 的 二 进 制 补 码 ) 可 见 9&5=1 按 位 与 运 算 通 常 用 来 对 某 些 位 清 0 或 保 留 某 些 位 例 如 把 a 的 高 八 位 清 0, 保 留 低 八 位, 可 作 a&255 运 算 ( 255 的 二 进 制 数 为 ) 例 12.1 main() int a=9,b=5,c; c=a&b; printf("a=%d\nb=%d\nc=%d\n",a,b,c); 按 位 或 运 算 按 位 或 运 算 符 是 双 目 运 算 符 其 功 能 是 参 与 运 算 的 两 数 各 对 应 的 二 进 位 相 或 只 要 对 应 的 二 个 二 进 位 有 一 个 为 1 时, 结 果 位 就 为 1 参 与 运 算 的 两 个 数 均 以 补 码 出 现 例 如 :9 5 可 写 算 式 如 下 : ( 十 进 制 为 13) 可 见 9 5=13 例 12.2 main() int a=9,b=5,c; c=a b; printf("a=%d\nb=%d\nc=%d\n",a,b,c); 第 190 页

191 按 位 异 或 运 算 按 位 异 或 运 算 符 ^ 是 双 目 运 算 符 其 功 能 是 参 与 运 算 的 两 数 各 对 应 的 二 进 位 相 异 或, 当 两 对 应 的 二 进 位 相 异 时, 结 果 为 1 参 与 运 算 数 仍 以 补 码 出 现, 例 如 9^5 可 写 成 算 式 如 下 : ^ ( 十 进 制 为 12) 例 12.3 main() int a=9; a=a^5; printf("a=%d\n",a); 求 反 运 算 求 反 运 算 符 ~ 为 单 目 运 算 符, 具 有 右 结 合 性 其 功 能 是 对 参 与 运 算 的 数 的 各 二 进 位 按 位 求 反 例 如 ~9 的 运 算 为 : ~( ) 结 果 为 : 左 移 运 算 左 移 运 算 符 << 是 双 目 运 算 符 其 功 能 把 << 左 边 的 运 算 数 的 各 二 进 位 全 部 左 移 若 干 位, 由 << 右 边 的 数 指 定 移 动 的 位 数, 高 位 丢 弃, 低 位 补 0 例 如 : a<<4 指 把 a 的 各 二 进 位 向 左 移 动 4 位 如 a= ( 十 进 制 3), 左 移 4 位 后 为 ( 十 进 制 48) 右 移 运 算 右 移 运 算 符 >> 是 双 目 运 算 符 其 功 能 是 把 >> 左 边 的 运 算 数 的 各 二 进 位 全 部 右 移 若 干 位, >> 右 边 的 数 指 定 移 动 的 位 数 例 如 : 设 a=15, a>>2 表 示 把 右 移 为 ( 十 进 制 3) 第 191 页

192 应 该 说 明 的 是, 对 于 有 符 号 数, 在 右 移 时, 符 号 位 将 随 同 移 动 当 为 正 数 时, 最 高 位 补 0, 而 为 负 数 时, 符 号 位 为 1, 最 高 位 是 补 0 或 是 补 1 取 决 于 编 译 系 统 的 规 定 Turbo C 和 很 多 系 统 规 定 为 补 1 例 12.4 main() unsigned a,b; printf("input a number: "); scanf("%d",&a); b=a>>5; b=b&15; printf("a=%d\tb=%d\n",a,b); 请 再 看 一 例! 例 12.5 main() char a='a',b='b'; int p,c,d; p=a; p=(p<<8) b; d=p&0xff; c=(p&0xff00)>>8; printf("a=%d\nb=%d\nc=%d\nd=%d\n",a,b,c,d); 12.2 位 域 ( 位 段 ) 有 些 信 息 在 存 储 时, 并 不 需 要 占 用 一 个 完 整 的 字 节, 而 只 需 占 几 个 或 一 个 二 进 制 位 例 如 在 存 放 一 个 开 关 量 时, 只 有 0 和 1 两 种 状 态, 用 一 位 二 进 位 即 可 为 了 节 省 存 储 空 间, 并 使 处 理 简 便,C 语 言 又 提 供 了 一 种 数 据 结 构, 称 为 位 域 或 位 段 所 谓 位 域 是 把 一 个 字 节 中 的 二 进 位 划 分 为 几 个 不 同 的 区 域, 并 说 明 每 个 区 域 的 位 数 每 个 域 有 一 个 域 名, 允 许 在 程 序 中 按 域 名 进 行 操 作 这 样 就 可 以 把 几 个 不 同 的 对 象 用 一 个 字 节 的 二 进 制 位 域 来 表 示 1. 位 域 的 定 义 和 位 域 变 量 的 说 明 位 域 定 义 与 结 构 定 义 相 仿, 其 形 式 为 : struct 位 域 结 构 名 位 域 列 表 ; 其 中 位 域 列 表 的 形 式 为 : 类 型 说 明 符 位 域 名 : 位 域 长 度 例 如 : struct bs 第 192 页

193 int a:8; int b:2; int c:6; ; 位 域 变 量 的 说 明 与 结 构 变 量 说 明 的 方 式 相 同 可 采 用 先 定 义 后 说 明, 同 时 定 义 说 明 或 者 直 接 说 明 这 三 种 方 式 例 如 : struct bs int a:8; int b:2; int c:6; data; 说 明 data 为 bs 变 量, 共 占 两 个 字 节 其 中 位 域 a 占 8 位, 位 域 b 占 2 位, 位 域 c 占 6 位 对 于 位 域 的 定 义 尚 有 以 下 几 点 说 明 : 1) 一 个 位 域 必 须 存 储 在 同 一 个 字 节 中, 不 能 跨 两 个 字 节 如 一 个 字 节 所 剩 空 间 不 够 存 放 另 一 位 域 时, 应 从 下 一 单 元 起 存 放 该 位 域 也 可 以 有 意 使 某 位 域 从 下 一 单 元 开 始 例 如 : struct bs unsigned a:4 unsigned :0 /* 空 域 */ unsigned b:4 /* 从 下 一 单 元 开 始 存 放 */ unsigned c:4 在 这 个 位 域 定 义 中,a 占 第 一 字 节 的 4 位, 后 4 位 填 0 表 示 不 使 用,b 从 第 二 字 节 开 始, 占 用 4 位,c 占 用 4 位 2) 由 于 位 域 不 允 许 跨 两 个 字 节, 因 此 位 域 的 长 度 不 能 大 于 一 个 字 节 的 长 度, 也 就 是 说 不 能 超 过 8 位 二 进 位 3) 位 域 可 以 无 位 域 名, 这 时 它 只 用 来 作 填 充 或 调 整 位 置 无 名 的 位 域 是 不 能 使 用 的 例 如 : struct k int a:1 int :2 /* 该 2 位 不 能 使 用 */ int b:3 int c:2 ; 从 以 上 分 析 可 以 看 出, 位 域 在 本 质 上 就 是 一 种 结 构 类 型, 不 过 其 成 员 是 按 二 进 位 分 配 的 2. 位 域 的 使 用 位 域 的 使 用 和 结 构 成 员 的 使 用 相 同, 其 一 般 形 式 为 : 位 域 变 量 名 位 域 名 第 193 页

194 位 域 允 许 用 各 种 格 式 输 出 例 12.6 main() struct bs unsigned a:1; unsigned b:3; unsigned c:4; bit,*pbit; bit.a=1; bit.b=7; bit.c=15; printf("%d,%d,%d\n",bit.a,bit.b,bit.c); pbit=&bit; pbit->a=0; pbit->b&=3; pbit->c =1; printf("%d,%d,%d\n",pbit->a,pbit->b,pbit->c); 上 例 程 序 中 定 义 了 位 域 结 构 bs, 三 个 位 域 为 a,b,c 说 明 了 bs 类 型 的 变 量 bit 和 指 向 bs 类 型 的 指 针 变 量 pbit 这 表 示 位 域 也 是 可 以 使 用 指 针 的 程 序 的 三 行 分 别 给 三 个 位 域 赋 值 ( 应 注 意 赋 值 不 能 超 过 该 位 域 的 允 许 范 围 ) 程 序 第 12 行 以 整 型 量 格 式 输 出 三 个 域 的 内 容 第 13 行 把 位 域 变 量 bit 的 地 址 送 给 指 针 变 量 pbit 第 14 行 用 指 针 方 式 给 位 域 a 重 新 赋 值, 赋 为 0 第 15 行 使 用 了 复 合 的 位 运 算 符 "&=", 该 行 相 当 于 : pbit->b=pbit->b&3 位 域 b 中 原 有 值 为 7, 与 3 作 按 位 与 运 算 的 结 果 为 3(111&011=011, 十 进 制 值 为 3) 同 样, 程 序 第 16 行 中 使 用 了 复 合 位 运 算 符 " =", 相 当 于 : pbit->c=pbit->c 1 其 结 果 为 15 程 序 第 17 行 用 指 针 方 式 输 出 了 这 三 个 域 的 值 12.3 本 章 小 结 1. 位 运 算 是 C 语 言 的 一 种 特 殊 运 算 功 能, 它 是 以 二 进 制 位 为 单 位 进 行 运 算 的 位 运 算 符 只 有 逻 辑 运 算 和 移 位 运 算 两 类 位 运 算 符 可 以 与 赋 值 符 一 起 组 成 复 合 赋 值 符 如 &=, =,^=,>>=,<<= 等 2. 利 用 位 运 算 可 以 完 成 汇 编 语 言 的 某 些 功 能, 如 置 位, 位 清 零, 移 位 等 还 可 进 行 数 据 的 压 缩 存 储 和 并 行 运 算 3. 位 域 在 本 质 上 也 是 结 构 类 型, 不 过 它 的 成 员 按 二 进 制 位 分 配 内 存 其 定 义 说 明 及 使 用 的 方 式 都 与 结 构 相 同 4. 位 域 提 供 了 一 种 手 段, 使 得 可 在 高 级 语 言 中 实 现 数 据 的 压 缩, 节 省 了 存 储 空 间, 同 时 也 提 高 了 程 序 的 效 率 第 194 页

195 13 文 件 13.1 C 文 件 概 述 所 谓 文 件 是 指 一 组 相 关 数 据 的 有 序 集 合 这 个 数 据 集 有 一 个 名 称, 叫 做 文 件 名 实 际 上 在 前 面 的 各 章 中 我 们 已 经 多 次 使 用 了 文 件, 例 如 源 程 序 文 件 目 标 文 件 可 执 行 文 件 库 文 件 ( 头 文 件 ) 等 文 件 通 常 是 驻 留 在 外 部 介 质 ( 如 磁 盘 等 ) 上 的, 在 使 用 时 才 调 入 内 存 中 来 从 不 同 的 角 度 可 对 文 件 作 不 同 的 分 类 从 用 户 的 角 度 看, 文 件 可 分 为 普 通 文 件 和 设 备 文 件 两 种 普 通 文 件 是 指 驻 留 在 磁 盘 或 其 它 外 部 介 质 上 的 一 个 有 序 数 据 集, 可 以 是 源 文 件 目 标 文 件 可 执 行 程 序 ; 也 可 以 是 一 组 待 输 入 处 理 的 原 始 数 据, 或 者 是 一 组 输 出 的 结 果 对 于 源 文 件 目 标 文 件 可 执 行 程 序 可 以 称 作 程 序 文 件, 对 输 入 输 出 数 据 可 称 作 数 据 文 件 设 备 文 件 是 指 与 主 机 相 联 的 各 种 外 部 设 备, 如 显 示 器 打 印 机 键 盘 等 在 操 作 系 统 中, 把 外 部 设 备 也 看 作 是 一 个 文 件 来 进 行 管 理, 把 它 们 的 输 入 输 出 等 同 于 对 磁 盘 文 件 的 读 和 写 通 常 把 显 示 器 定 义 为 标 准 输 出 文 件, 一 般 情 况 下 在 屏 幕 上 显 示 有 关 信 息 就 是 向 标 准 输 出 文 件 输 出 如 前 面 经 常 使 用 的 printf,putchar 函 数 就 是 这 类 输 出 键 盘 通 常 被 指 定 标 准 的 输 入 文 件, 从 键 盘 上 输 入 就 意 味 着 从 标 准 输 入 文 件 上 输 入 数 据 scanf,getchar 函 数 就 属 于 这 类 输 入 从 文 件 编 码 的 方 式 来 看, 文 件 可 分 为 ASCII 码 文 件 和 二 进 制 码 文 件 两 种 ASCII 文 件 也 称 为 文 本 文 件, 这 种 文 件 在 磁 盘 中 存 放 时 每 个 字 符 对 应 一 个 字 节, 用 于 存 放 对 应 的 ASCII 码 例 如, 数 5678 的 存 储 形 式 为 : ASCII 码 : 十 进 制 码 : 共 占 用 4 个 字 节 ASCII 码 文 件 可 在 屏 幕 上 按 字 符 显 示, 例 如 源 程 序 文 件 就 是 ASCII 文 件, 用 DOS 命 令 TYPE 可 显 示 文 件 的 内 容 由 于 是 按 字 符 显 示, 因 此 能 读 懂 文 件 内 容 二 进 制 文 件 是 按 二 进 制 的 编 码 方 式 来 存 放 文 件 的 例 如, 数 5678 的 存 储 形 式 为 : 只 占 二 个 字 节 二 进 制 文 件 虽 然 也 可 在 屏 幕 上 显 示, 但 其 内 容 无 法 读 懂 C 系 统 在 处 理 这 些 文 件 时, 并 不 区 分 类 型, 都 看 成 是 字 符 流, 按 字 节 进 行 处 理 输 入 输 出 字 符 流 的 开 始 和 结 束 只 由 程 序 控 制 而 不 受 物 理 符 号 ( 如 回 车 符 ) 的 控 制 因 此 也 把 这 种 文 件 称 作 流 式 文 件 本 章 讨 论 流 式 文 件 的 打 开 关 闭 读 写 定 位 等 各 种 操 作 13.2 文 件 指 针 在 C 语 言 中 用 一 个 指 针 变 量 指 向 一 个 文 件, 这 个 指 针 称 为 文 件 指 针 通 过 文 件 指 针 就 可 对 它 所 指 的 文 件 进 行 各 种 操 作 第 195 页

196 定 义 说 明 文 件 指 针 的 一 般 形 式 为 : FILE * 指 针 变 量 标 识 符 ; 其 中 FILE 应 为 大 写, 它 实 际 上 是 由 系 统 定 义 的 一 个 结 构, 该 结 构 中 含 有 文 件 名 文 件 状 态 和 文 件 当 前 位 置 等 信 息 在 编 写 源 程 序 时 不 必 关 心 FILE 结 构 的 细 节 例 如 : FILE *fp; 表 示 fp 是 指 向 FILE 结 构 的 指 针 变 量, 通 过 fp 即 可 找 存 放 某 个 文 件 信 息 的 结 构 变 量, 然 后 按 结 构 变 量 提 供 的 信 息 找 到 该 文 件, 实 施 对 文 件 的 操 作 习 惯 上 也 笼 统 地 把 fp 称 为 指 向 一 个 文 件 的 指 针 13.3 文 件 的 打 开 与 关 闭 文 件 在 进 行 读 写 操 作 之 前 要 先 打 开, 使 用 完 毕 要 关 闭 所 谓 打 开 文 件, 实 际 上 是 建 立 文 件 的 各 种 有 关 信 息, 并 使 文 件 指 针 指 向 该 文 件, 以 便 进 行 其 它 操 作 关 闭 文 件 则 断 开 指 针 与 文 件 之 间 的 联 系, 也 就 禁 止 再 对 该 文 件 进 行 操 作 在 C 语 言 中, 文 件 操 作 都 是 由 库 函 数 来 完 成 的 在 本 章 内 将 介 绍 主 要 的 文 件 操 作 函 数 文 件 的 打 开 (fopen 函 数 ) fopen 函 数 用 来 打 开 一 个 文 件, 其 调 用 的 一 般 形 式 为 : 文 件 指 针 名 =fopen( 文 件 名, 使 用 文 件 方 式 ); 其 中, 文 件 指 针 名 必 须 是 被 说 明 为 FILE 类 型 的 指 针 变 量 ; 文 件 名 是 被 打 开 文 件 的 文 件 名 ; 使 用 文 件 方 式 是 指 文 件 的 类 型 和 操 作 要 求 文 件 名 是 字 符 串 常 量 或 字 符 串 数 组 例 如 : FILE *fp; fp=("file a","r"); 其 意 义 是 在 当 前 目 录 下 打 开 文 件 file a, 只 允 许 进 行 读 操 作, 并 使 fp 指 向 该 文 件 又 如 : FILE *fphzk fphzk=("c:\\hzk16","rb") 其 意 义 是 打 开 C 驱 动 器 磁 盘 的 根 目 录 下 的 文 件 hzk16, 这 是 一 个 二 进 制 文 件, 只 允 许 按 二 进 制 方 式 进 行 读 操 作 两 个 反 斜 线 \\ 中 的 第 一 个 表 示 转 义 字 符, 第 二 个 表 示 根 目 录 使 用 文 件 的 方 式 共 有 12 种, 下 面 给 出 了 它 们 的 符 号 和 意 义 文 件 使 用 方 式 意 义 rt 只 读 打 开 一 个 文 本 文 件, 只 允 许 读 数 据 wt 只 写 打 开 或 建 立 一 个 文 本 文 件, 只 允 许 写 数 据 at 追 加 打 开 一 个 文 本 文 件, 并 在 文 件 末 尾 写 数 据 rb 只 读 打 开 一 个 二 进 制 文 件, 只 允 许 读 数 据 wb 只 写 打 开 或 建 立 一 个 二 进 制 文 件, 只 允 许 写 数 据 ab 追 加 打 开 一 个 二 进 制 文 件, 并 在 文 件 末 尾 写 数 据 第 196 页

197 rt+ 读 写 打 开 一 个 文 本 文 件, 允 许 读 和 写 wt+ 读 写 打 开 或 建 立 一 个 文 本 文 件, 允 许 读 写 at+ 读 写 打 开 一 个 文 本 文 件, 允 许 读, 或 在 文 件 末 追 加 数 据 rb+ 读 写 打 开 一 个 二 进 制 文 件, 允 许 读 和 写 wb+ 读 写 打 开 或 建 立 一 个 二 进 制 文 件, 允 许 读 和 写 ab+ 读 写 打 开 一 个 二 进 制 文 件, 允 许 读, 或 在 文 件 末 追 加 数 据 对 于 文 件 使 用 方 式 有 以 下 几 点 说 明 : 1) 文 件 使 用 方 式 由 r,w,a,t,b,+ 六 个 字 符 拼 成, 各 字 符 的 含 义 是 : r(read): 读 w(write): 写 a(append): 追 加 t(text): 文 本 文 件, 可 省 略 不 写 b(banary): 二 进 制 文 件 +: 读 和 写 2) 凡 用 r 打 开 一 个 文 件 时, 该 文 件 必 须 已 经 存 在, 且 只 能 从 该 文 件 读 出 3) 用 w 打 开 的 文 件 只 能 向 该 文 件 写 入 若 打 开 的 文 件 不 存 在, 则 以 指 定 的 文 件 名 建 立 该 文 件, 若 打 开 的 文 件 已 经 存 在, 则 将 该 文 件 删 去, 重 建 一 个 新 文 件 4) 若 要 向 一 个 已 存 在 的 文 件 追 加 新 的 信 息, 只 能 用 a 方 式 打 开 文 件 但 此 时 该 文 件 必 须 是 存 在 的, 否 则 将 会 出 错 5) 在 打 开 一 个 文 件 时, 如 果 出 错,fopen 将 返 回 一 个 空 指 针 值 NULL 在 程 序 中 可 以 用 这 一 信 息 来 判 别 是 否 完 成 打 开 文 件 的 工 作, 并 作 相 应 的 处 理 因 此 常 用 以 下 程 序 段 打 开 文 件 : 6) if((fp=fopen("c:\\hzk16","rb")==null) printf("\nerror on open c:\\hzk16 file!"); getch(); exit(1); 这 段 程 序 的 意 义 是, 如 果 返 回 的 指 针 为 空, 表 示 不 能 打 开 C 盘 根 目 录 下 的 hzk16 文 件, 则 给 出 提 示 信 息 error on open c:\ hzk16 file!, 下 一 行 getch() 的 功 能 是 从 键 盘 输 入 一 个 字 符, 但 不 在 屏 幕 上 显 示 在 这 里, 该 行 的 作 用 是 等 待, 只 有 当 用 户 从 键 盘 敲 任 一 键 时, 程 序 才 继 续 执 行, 因 此 用 户 可 利 用 这 个 等 待 时 间 阅 读 出 错 提 示 敲 键 后 执 行 exit(1) 退 出 程 序 7) 把 一 个 文 本 文 件 读 入 内 存 时, 要 将 ASCII 码 转 换 成 二 进 制 码, 而 把 文 件 以 文 本 方 式 写 入 磁 盘 时, 也 要 把 二 进 制 码 转 换 成 ASCII 码, 因 此 文 本 文 件 的 读 写 要 花 费 较 多 的 转 换 时 间 对 二 进 制 文 件 的 读 写 不 存 在 这 种 转 换 8) 标 准 输 入 文 件 ( 键 盘 ), 标 准 输 出 文 件 ( 显 示 器 ), 标 准 出 错 输 出 ( 出 错 信 息 ) 是 由 系 统 打 开 的, 可 直 接 使 用 文 件 关 闭 函 数 (fclose 函 数 ) 文 件 一 旦 使 用 完 毕, 应 用 关 闭 文 件 函 数 把 文 件 关 闭, 以 避 免 文 件 的 数 据 丢 失 等 错 误 fclose 函 数 调 用 的 一 般 形 式 是 : fclose( 文 件 指 针 ); 第 197 页

198 例 如 : fclose(fp); 正 常 完 成 关 闭 文 件 操 作 时,fclose 函 数 返 回 值 为 0 如 返 回 非 零 值 则 表 示 有 错 误 发 生 13.4 文 件 的 读 写 对 文 件 的 读 和 写 是 最 常 用 的 文 件 操 作 在 C 语 言 中 提 供 了 多 种 文 件 读 写 的 函 数 : 字 符 读 写 函 数 :fgetc 和 fputc 字 符 串 读 写 函 数 :fgets 和 fputs 数 据 块 读 写 函 数 :freed 和 fwrite 格 式 化 读 写 函 数 :fscanf 和 fprinf 下 面 分 别 予 以 介 绍 使 用 以 上 函 数 都 要 求 包 含 头 文 件 stdio.h 字 符 读 写 函 数 fgetc 和 fputc 字 符 读 写 函 数 是 以 字 符 ( 字 节 ) 为 单 位 的 读 写 函 数 每 次 可 从 文 件 读 出 或 向 文 件 写 入 一 个 字 符 1. 读 字 符 函 数 fgetc fgetc 函 数 的 功 能 是 从 指 定 的 文 件 中 读 一 个 字 符, 函 数 调 用 的 形 式 为 : 字 符 变 量 =fgetc( 文 件 指 针 ); 例 如 : ch=fgetc(fp); 其 意 义 是 从 打 开 的 文 件 fp 中 读 取 一 个 字 符 并 送 入 ch 中 对 于 fgetc 函 数 的 使 用 有 以 下 几 点 说 明 : 1) 在 fgetc 函 数 调 用 中, 读 取 的 文 件 必 须 是 以 读 或 读 写 方 式 打 开 的 2) 读 取 字 符 的 结 果 也 可 以 不 向 字 符 变 量 赋 值, 例 如 : fgetc(fp); 但 是 读 出 的 字 符 不 能 保 存 3) 在 文 件 内 部 有 一 个 位 置 指 针 用 来 指 向 文 件 的 当 前 读 写 字 节 在 文 件 打 开 时, 该 指 针 总 是 指 向 文 件 的 第 一 个 字 节 使 用 fgetc 函 数 后, 该 位 置 指 针 将 向 后 移 动 一 个 字 节 因 此 可 连 续 多 次 使 用 fgetc 函 数, 读 取 多 个 字 符 应 注 意 文 件 指 针 和 文 件 内 部 的 位 置 指 针 不 是 一 回 事 文 件 指 针 是 指 向 整 个 文 件 的, 须 在 程 序 中 定 义 说 明, 只 要 不 重 新 赋 值, 文 件 指 针 的 值 是 不 变 的 文 件 内 部 的 位 置 指 针 用 以 指 示 文 件 内 部 的 当 前 读 写 位 置, 每 读 写 一 次, 该 指 针 均 向 后 移 动, 它 不 需 在 程 序 中 定 义 说 明, 而 是 由 系 统 自 动 设 置 的 例 13.1 读 入 文 件 c1.doc, 在 屏 幕 上 输 出 #include<stdio.h> main() FILE *fp; char ch; if((fp=fopen("d:\\jrzh\\example\\c1.txt","rt"))==null) 第 198 页

199 printf("\ncannot open file strike any key exit!"); getch(); exit(1); ch=fgetc(fp); while(ch!=eof) putchar(ch); ch=fgetc(fp); fclose(fp); 本 例 程 序 的 功 能 是 从 文 件 中 逐 个 读 取 字 符, 在 屏 幕 上 显 示 程 序 定 义 了 文 件 指 针 fp, 以 读 文 本 文 件 方 式 打 开 文 件 d:\\jrzh\\example\\ex1_1.c, 并 使 fp 指 向 该 文 件 如 打 开 文 件 出 错, 给 出 提 示 并 退 出 程 序 程 序 第 12 行 先 读 出 一 个 字 符, 然 后 进 入 循 环, 只 要 读 出 的 字 符 不 是 文 件 结 束 标 志 ( 每 个 文 件 末 有 一 结 束 标 志 EOF) 就 把 该 字 符 显 示 在 屏 幕 上, 再 读 入 下 一 字 符 每 读 一 次, 文 件 内 部 的 位 置 指 针 向 后 移 动 一 个 字 符, 文 件 结 束 时, 该 指 针 指 向 EOF 执 行 本 程 序 将 显 示 整 个 文 件 2. 写 字 符 函 数 fputc fputc 函 数 的 功 能 是 把 一 个 字 符 写 入 指 定 的 文 件 中, 函 数 调 用 的 形 式 为 : fputc( 字 符 量, 文 件 指 针 ); 其 中, 待 写 入 的 字 符 量 可 以 是 字 符 常 量 或 变 量, 例 如 : fputc('a',fp); 其 意 义 是 把 字 符 a 写 入 fp 所 指 向 的 文 件 中 对 于 fputc 函 数 的 使 用 也 要 说 明 几 点 : 1) 被 写 入 的 文 件 可 以 用 写 读 写 追 加 方 式 打 开, 用 写 或 读 写 方 式 打 开 一 个 已 存 在 的 文 件 时 将 清 除 原 有 的 文 件 内 容, 写 入 字 符 从 文 件 首 开 始 如 需 保 留 原 有 文 件 内 容, 希 望 写 入 的 字 符 以 文 件 末 开 始 存 放, 必 须 以 追 加 方 式 打 开 文 件 被 写 入 的 文 件 若 不 存 在, 则 创 建 该 文 件 2) 每 写 入 一 个 字 符, 文 件 内 部 位 置 指 针 向 后 移 动 一 个 字 节 3) fputc 函 数 有 一 个 返 回 值, 如 写 入 成 功 则 返 回 写 入 的 字 符, 否 则 返 回 一 个 EOF 可 用 此 来 判 断 写 入 是 否 成 功 例 13.2 从 键 盘 输 入 一 行 字 符, 写 入 一 个 文 件, 再 把 该 文 件 内 容 读 出 显 示 在 屏 幕 上 #include<stdio.h> main() FILE *fp; char ch; if((fp=fopen("d:\\jrzh\\example\\string","wt+"))==null) printf("cannot open file strike any key exit!"); 第 199 页

200 getch(); exit(1); printf("input a string:\n"); ch=getchar(); while (ch!='\n') fputc(ch,fp); ch=getchar(); rewind(fp); ch=fgetc(fp); while(ch!=eof) putchar(ch); ch=fgetc(fp); printf("\n"); fclose(fp); 程 序 中 第 6 行 以 读 写 文 本 文 件 方 式 打 开 文 件 string 程 序 第 13 行 从 键 盘 读 入 一 个 字 符 后 进 入 循 环, 当 读 入 字 符 不 为 回 车 符 时, 则 把 该 字 符 写 入 文 件 之 中, 然 后 继 续 从 键 盘 读 入 下 一 字 符 每 输 入 一 个 字 符, 文 件 内 部 位 置 指 针 向 后 移 动 一 个 字 节 写 入 完 毕, 该 指 针 已 指 向 文 件 末 如 要 把 文 件 从 头 读 出, 须 把 指 针 移 向 文 件 头, 程 序 第 19 行 rewind 函 数 用 于 把 fp 所 指 文 件 的 内 部 位 置 指 针 移 到 文 件 头 第 20 至 25 行 用 于 读 出 文 件 中 的 一 行 内 容 例 13.3 把 命 令 行 参 数 中 的 前 一 个 文 件 名 标 识 的 文 件, 复 制 到 后 一 个 文 件 名 标 识 的 文 件 中, 如 命 令 行 中 只 有 一 个 文 件 名 则 把 该 文 件 写 到 标 准 输 出 文 件 ( 显 示 器 ) 中 #include<stdio.h> main(int argc,char *argv[]) FILE *fp1,*fp2; char ch; if(argc==1) printf("have not enter file name strike any key exit"); getch(); exit(0); if((fp1=fopen(argv[1],"rt"))==null) printf("cannot open %s\n",argv[1]); getch(); 第 200 页

201 exit(1); if(argc==2) fp2=stdout; else if((fp2=fopen(argv[2],"wt+"))==null) printf("cannot open %s\n",argv[1]); getch(); exit(1); while((ch=fgetc(fp1))!=eof) fputc(ch,fp2); fclose(fp1); fclose(fp2); 本 程 序 为 带 参 的 main 函 数 程 序 中 定 义 了 两 个 文 件 指 针 fp1 和 fp2, 分 别 指 向 命 令 行 参 数 中 给 出 的 文 件 如 命 令 行 参 数 中 没 有 给 出 文 件 名, 则 给 出 提 示 信 息 程 序 第 18 行 表 示 如 果 只 给 出 一 个 文 件 名, 则 使 fp2 指 向 标 准 输 出 文 件 ( 即 显 示 器 ) 程 序 第 25 行 至 28 行 用 循 环 语 句 逐 个 读 出 文 件 1 中 的 字 符 再 送 到 文 件 2 中 再 次 运 行 时, 给 出 了 一 个 文 件 名, 故 输 出 给 标 准 输 出 文 件 stdout, 即 在 显 示 器 上 显 示 文 件 内 容 第 三 次 运 行, 给 出 了 二 个 文 件 名, 因 此 把 string 中 的 内 容 读 出, 写 入 到 OK 之 中 可 用 DOS 命 令 type 显 示 OK 的 内 容 字 符 串 读 写 函 数 fgets 和 fputs 1. 读 字 符 串 函 数 fgets 函 数 的 功 能 是 从 指 定 的 文 件 中 读 一 个 字 符 串 到 字 符 数 组 中, 函 数 调 用 的 形 式 为 : fgets( 字 符 数 组 名,n, 文 件 指 针 ); 其 中 的 n 是 一 个 正 整 数 表 示 从 文 件 中 读 出 的 字 符 串 不 超 过 n-1 个 字 符 在 读 入 的 最 后 一 个 字 符 后 加 上 串 结 束 标 志 '\0' 例 如 : fgets(str,n,fp); 的 意 义 是 从 fp 所 指 的 文 件 中 读 出 n-1 个 字 符 送 入 字 符 数 组 str 中 例 13.4 从 string 文 件 中 读 入 一 个 含 10 个 字 符 的 字 符 串 #include<stdio.h> main() FILE *fp; char str[11]; if((fp=fopen("d:\\jrzh\\example\\string","rt"))==null) printf("\ncannot open file strike any key exit!"); getch(); exit(1); 第 201 页

202 fgets(str,11,fp); printf("\n%s\n",str); fclose(fp); 本 例 定 义 了 一 个 字 符 数 组 str 共 11 个 字 节, 在 以 读 文 本 文 件 方 式 打 开 文 件 string 后, 从 中 读 出 10 个 字 符 送 入 str 数 组, 在 数 组 最 后 一 个 单 元 内 将 加 上 '\0', 然 后 在 屏 幕 上 显 示 输 出 str 数 组 输 出 的 十 个 字 符 正 是 例 13.1 程 序 的 前 十 个 字 符 对 fgets 函 数 有 两 点 说 明 : 1) 在 读 出 n-1 个 字 符 之 前, 如 遇 到 了 换 行 符 或 EOF, 则 读 出 结 束 2) fgets 函 数 也 有 返 回 值, 其 返 回 值 是 字 符 数 组 的 首 地 址 2. 写 字 符 串 函 数 fputs fputs 函 数 的 功 能 是 向 指 定 的 文 件 写 入 一 个 字 符 串, 其 调 用 形 式 为 : fputs( 字 符 串, 文 件 指 针 ); 其 中 字 符 串 可 以 是 字 符 串 常 量, 也 可 以 是 字 符 数 组 名, 或 指 针 变 量, 例 如 : fputs( abcd,fp); 其 意 义 是 把 字 符 串 abcd 写 入 fp 所 指 的 文 件 之 中 例 13.5 在 例 13.2 中 建 立 的 文 件 string 中 追 加 一 个 字 符 串 #include<stdio.h> main() FILE *fp; char ch,st[20]; if((fp=fopen("string","at+"))==null) printf("cannot open file strike any key exit!"); getch(); exit(1); printf("input a string:\n"); scanf("%s",st); fputs(st,fp); rewind(fp); ch=fgetc(fp); while(ch!=eof) putchar(ch); ch=fgetc(fp); printf("\n"); fclose(fp); 第 202 页

203 本 例 要 求 在 string 文 件 末 加 写 字 符 串, 因 此, 在 程 序 第 6 行 以 追 加 读 写 文 本 文 件 的 方 式 打 开 文 件 string 然 后 输 入 字 符 串, 并 用 fputs 函 数 把 该 串 写 入 文 件 string 在 程 序 15 行 用 rewind 函 数 把 文 件 内 部 位 置 指 针 移 到 文 件 首 再 进 入 循 环 逐 个 显 示 当 前 文 件 中 的 全 部 内 容 数 据 块 读 写 函 数 fread 和 fwtrite C 语 言 还 提 供 了 用 于 整 块 数 据 的 读 写 函 数 可 用 来 读 写 一 组 数 据, 如 一 个 数 组 元 素, 一 个 结 构 变 量 的 值 等 读 数 据 块 函 数 调 用 的 一 般 形 式 为 : fread(buffer,size,count,fp); 写 数 据 块 函 数 调 用 的 一 般 形 式 为 : fwrite(buffer,size,count,fp); 其 中 : buffer 是 一 个 指 针, 在 fread 函 数 中, 它 表 示 存 放 输 入 数 据 的 首 地 址 在 fwrite 函 数 中, 它 表 示 存 放 输 出 数 据 的 首 地 址 size 表 示 数 据 块 的 字 节 数 count 表 示 要 读 写 的 数 据 块 块 数 fp 表 示 文 件 指 针 例 如 : fread(fa,4,5,fp); 其 意 义 是 从 fp 所 指 的 文 件 中, 每 次 读 4 个 字 节 ( 一 个 实 数 ) 送 入 实 数 组 fa 中, 连 续 读 5 次, 即 读 5 个 实 数 到 fa 中 例 13.6 从 键 盘 输 入 两 个 学 生 数 据, 写 入 一 个 文 件 中, 再 读 出 这 两 个 学 生 的 数 据 显 示 在 屏 幕 上 #include<stdio.h> struct stu char name[10]; int num; int age; char addr[15]; boya[2],boyb[2],*pp,*qq; main() FILE *fp; char ch; int i; pp=boya; qq=boyb; if((fp=fopen("d:\\jrzh\\example\\stu_list","wb+"))==null) 第 203 页

204 printf("cannot open file strike any key exit!"); getch(); exit(1); printf("\ninput data\n"); for(i=0;i<2;i++,pp++) scanf("%s%d%d%s",pp->name,&pp->num,&pp->age,pp->addr); pp=boya; fwrite(pp,sizeof(struct stu),2,fp); rewind(fp); fread(qq,sizeof(struct stu),2,fp); printf("\n\nname\tnumber age addr\n"); for(i=0;i<2;i++,qq++) printf("%s\t%5d%7d %s\n",qq->name,qq->num,qq->age,qq->addr); fclose(fp); 本 例 程 序 定 义 了 一 个 结 构 stu, 说 明 了 两 个 结 构 数 组 boya 和 boyb 以 及 两 个 结 构 指 针 变 量 pp 和 qq pp 指 向 boya,qq 指 向 boyb 程 序 第 16 行 以 读 写 方 式 打 开 二 进 制 文 件 stu_list, 输 入 二 个 学 生 数 据 之 后, 写 入 该 文 件 中, 然 后 把 文 件 内 部 位 置 指 针 移 到 文 件 首, 读 出 两 块 学 生 数 据 后, 在 屏 幕 上 显 示 格 式 化 读 写 函 数 fscanf 和 fprintf fscanf 函 数,fprintf 函 数 与 前 面 使 用 的 scanf 和 printf 函 数 的 功 能 相 似, 都 是 格 式 化 读 写 函 数 两 者 的 区 别 在 于 fscanf 函 数 和 fprintf 函 数 的 读 写 对 象 不 是 键 盘 和 显 示 器, 而 是 磁 盘 文 件 这 两 个 函 数 的 调 用 格 式 为 : fscanf( 文 件 指 针, 格 式 字 符 串, 输 入 表 列 ); fprintf( 文 件 指 针, 格 式 字 符 串, 输 出 表 列 ); 例 如 : fscanf(fp,"%d%s",&i,s); fprintf(fp,"%d%c",j,ch); 用 fscanf 和 fprintf 函 数 也 可 以 完 成 例 10.6 的 问 题 修 改 后 的 程 序 如 例 10.7 所 示 例 13.7 用 fscanf 和 fprintf 函 数 成 例 10.6 的 问 题 #include<stdio.h> struct stu char name[10]; int num; int age; char addr[15]; boya[2],boyb[2],*pp,*qq; 第 204 页

205 main() FILE *fp; char ch; int i; pp=boya; qq=boyb; if((fp=fopen("stu_list","wb+"))==null) printf("cannot open file strike any key exit!"); getch(); exit(1); printf("\ninput data\n"); for(i=0;i<2;i++,pp++) scanf("%s%d%d%s",pp->name,&pp->num,&pp->age,pp->addr); pp=boya; for(i=0;i<2;i++,pp++) fprintf(fp,"%s %d %d %s\n",pp->name,pp->num,pp->age,pp-> addr); rewind(fp); for(i=0;i<2;i++,qq++) fscanf(fp,"%s %d %d %s\n",qq->name,&qq->num,&qq->age,qq->addr); printf("\n\nname\tnumber age addr\n"); qq=boyb; for(i=0;i<2;i++,qq++) printf("%s\t%5d %7d %s\n",qq->name,qq->num, qq->age, qq->addr); fclose(fp); 与 例 10.6 相 比, 本 程 序 中 fscanf 和 fprintf 函 数 每 次 只 能 读 写 一 个 结 构 数 组 元 素, 因 此 采 用 了 循 环 语 句 来 读 写 全 部 数 组 元 素 还 要 注 意 指 针 变 量 pp,qq 由 于 循 环 改 变 了 它 们 的 值, 因 此 在 程 序 的 25 和 32 行 分 别 对 它 们 重 新 赋 予 了 数 组 的 首 地 址 13.5 文 件 的 随 机 读 写 前 面 介 绍 的 对 文 件 的 读 写 方 式 都 是 顺 序 读 写, 即 读 写 文 件 只 能 从 头 开 始, 顺 序 读 写 各 个 数 据 但 在 实 际 问 题 中 常 要 求 只 读 写 文 件 中 某 一 指 定 的 部 分 为 了 解 决 这 个 问 题 可 移 动 文 件 内 部 的 位 置 指 针 到 需 要 读 写 的 位 置, 再 进 行 读 写, 这 种 读 写 称 为 随 机 读 写 实 现 随 机 读 写 的 关 键 是 要 按 要 求 移 动 位 置 指 针, 这 称 为 文 件 的 定 位 第 205 页

206 文 件 定 位 移 动 文 件 内 部 位 置 指 针 的 函 数 主 要 有 两 个, 即 rewind 函 数 和 fseek 函 数 rewind 函 数 前 面 已 多 次 使 用 过, 其 调 用 形 式 为 : rewind( 文 件 指 针 ); 它 的 功 能 是 把 文 件 内 部 的 位 置 指 针 移 到 文 件 首 下 面 主 要 介 绍 fseek 函 数 fseek 函 数 用 来 移 动 文 件 内 部 位 置 指 针, 其 调 用 形 式 为 : fseek( 文 件 指 针, 位 移 量, 起 始 点 ); 其 中 : 文 件 指 针 指 向 被 移 动 的 文 件 位 移 量 表 示 移 动 的 字 节 数, 要 求 位 移 量 是 long 型 数 据, 以 便 在 文 件 长 度 大 于 64KB 时 不 会 出 错 当 用 常 量 表 示 位 移 量 时, 要 求 加 后 缀 L 起 始 点 表 示 从 何 处 开 始 计 算 位 移 量, 规 定 的 起 始 点 有 三 种 : 文 件 首, 当 前 位 置 和 文 件 尾 其 表 示 方 法 如 下 表 起 始 点 表 示 符 号 数 字 表 示 文 件 首 SEEK_SET 0 当 前 位 置 SEEK_CUR 1 文 件 末 尾 SEEK_END 2 例 如 : fseek(fp,100l,0); 其 意 义 是 把 位 置 指 针 移 到 离 文 件 首 100 个 字 节 处 还 要 说 明 的 是 fseek 函 数 一 般 用 于 二 进 制 文 件 在 文 本 文 件 中 由 于 要 进 行 转 换, 故 往 往 计 算 的 位 置 会 出 现 错 误 文 件 的 随 机 读 写 在 移 动 位 置 指 针 之 后, 即 可 用 前 面 介 绍 的 任 一 种 读 写 函 数 进 行 读 写 由 于 一 般 是 读 写 一 个 数 据 据 块, 因 此 常 用 fread 和 fwrite 函 数 下 面 用 例 题 来 说 明 文 件 的 随 机 读 写 例 13.8 在 学 生 文 件 stu_list 中 读 出 第 二 个 学 生 的 数 据 #include<stdio.h> struct stu char name[10]; int num; int age; char addr[15]; boy,*qq; main() FILE *fp; char ch; 第 206 页

207 int i=1; qq=&boy; if((fp=fopen("stu_list","rb"))==null) printf("cannot open file strike any key exit!"); getch(); exit(1); rewind(fp); fseek(fp,i*sizeof(struct stu),0); fread(qq,sizeof(struct stu),1,fp); printf("\n\nname\tnumber age addr\n"); printf("%s\t%5d %7d %s\n",qq->name,qq->num,qq->age, qq->addr); 文 件 stu_list 已 由 例 13.6 的 程 序 建 立, 本 程 序 用 随 机 读 出 的 方 法 读 出 第 二 个 学 生 的 数 据 程 序 中 定 义 boy 为 stu 类 型 变 量,qq 为 指 向 boy 的 指 针 以 读 二 进 制 文 件 方 式 打 开 文 件, 程 序 第 22 行 移 动 文 件 位 置 指 针 其 中 的 i 值 为 1, 表 示 从 文 件 头 开 始, 移 动 一 个 stu 类 型 的 长 度, 然 后 再 读 出 的 数 据 即 为 第 二 个 学 生 的 数 据 13.6 文 件 检 测 函 数 C 语 言 中 常 用 的 文 件 检 测 函 数 有 以 下 几 个 文 件 结 束 检 测 函 数 feof 函 数 调 用 格 式 : feof( 文 件 指 针 ); 功 能 : 判 断 文 件 是 否 处 于 文 件 结 束 位 置, 如 文 件 结 束, 则 返 回 值 为 1, 否 则 为 读 写 文 件 出 错 检 测 函 数 ferror 函 数 调 用 格 式 : ferror( 文 件 指 针 ); 功 能 : 检 查 文 件 在 用 各 种 输 入 输 出 函 数 进 行 读 写 时 是 否 出 错 如 ferror 返 回 值 为 0 表 示 未 出 错, 否 则 表 示 有 错 文 件 出 错 标 志 和 文 件 结 束 标 志 置 0 函 数 clearerr 函 数 调 用 格 式 : 第 207 页

208 clearerr( 文 件 指 针 ); 功 能 : 本 函 数 用 于 清 除 出 错 标 志 和 文 件 结 束 标 志, 使 它 们 为 0 值 13.7 C 库 文 件 C 系 统 提 供 了 丰 富 的 系 统 文 件, 称 为 库 文 件,C 的 库 文 件 分 为 两 类, 一 类 是 扩 展 名 为 ".h" 的 文 件, 称 为 头 文 件, 在 前 面 的 包 含 命 令 中 我 们 已 多 次 使 用 过 在 ".h" 文 件 中 包 含 了 常 量 定 义 类 型 定 义 宏 定 义 函 数 原 型 以 及 各 种 编 译 选 择 设 置 等 信 息 另 一 类 是 函 数 库, 包 括 了 各 种 函 数 的 目 标 代 码, 供 用 户 在 程 序 中 调 用 通 常 在 程 序 中 调 用 一 个 库 函 数 时, 要 在 调 用 之 前 包 含 该 函 数 原 型 所 在 的 ".h" 文 件 下 面 给 出 Turbo C 的 全 部 ".h" 文 件 Turbo C 头 文 件 ALLOC.H 说 明 内 存 管 理 函 数 ( 分 配 释 放 等 ) ASSERT.H 定 义 assert 调 试 宏 BIOS.H 说 明 调 用 IBM PC ROM BIOS 子 程 序 的 各 个 函 数 CONIO.H 说 明 调 用 DOS 控 制 台 I/O 子 程 序 的 各 个 函 数 CTYPE.H 包 含 有 关 字 符 分 类 及 转 换 的 名 类 信 息 ( 如 isalpha 和 toascii 等 ) DIR.H 包 含 有 关 目 录 和 路 径 的 结 构 宏 定 义 和 函 数 DOS.H 定 义 和 说 明 MSDOS 和 8086 调 用 的 一 些 常 量 和 函 数 ERRON.H 定 义 错 误 代 码 的 助 记 符 FCNTL.H 定 义 在 与 open 库 子 程 序 连 接 时 的 符 号 常 量 FLOAT.H 包 含 有 关 浮 点 运 算 的 一 些 参 数 和 函 数 GRAPHICS.H 说 明 有 关 图 形 功 能 的 各 个 函 数, 图 形 错 误 代 码 的 常 量 定 义, 正 对 不 同 驱 动 程 序 的 各 种 颜 色 值, 及 函 数 用 到 的 一 些 特 殊 结 构 IO.H 包 含 低 级 I/O 子 程 序 的 结 构 和 说 明 LIMIT.H 包 含 各 环 境 参 数 编 译 时 间 限 制 数 的 范 围 等 信 息 MATH.H 说 明 数 学 运 算 函 数, 还 定 了 HUGE VAL 宏, 说 明 了 matherr 和 matherr 子 程 序 用 到 的 特 殊 结 构 MEM.H 说 明 一 些 内 存 操 作 函 数 ( 其 中 大 多 数 也 在 STRING.H 中 说 明 ) PROCESS.H 说 明 进 程 管 理 的 各 个 函 数,spawn 和 EXEC 函 数 的 结 构 说 明 SETJMP.H 定 义 longjmp 和 setjmp 函 数 用 到 的 jmp buf 类 型, 说 明 这 两 个 函 数 SHARE.H 定 义 文 件 共 享 函 数 的 参 数 SIGNAL.H 定 义 SIG[ZZ(Z] [ZZ)]IGN 和 SIG[ZZ(Z] [ZZ)]DFL 常 量, 说 明 rajse 和 signal 两 个 函 数 STDARG.H 定 义 读 函 数 参 数 表 的 宏 ( 如 vprintf,vscarf 函 数 ) STDDEF.H 定 义 一 些 公 共 数 据 类 型 和 宏 STDIO.H 定 义 Kernighan 和 Ritchie 在 Unix System V 中 定 义 的 标 准 和 扩 展 的 类 型 和 宏 还 定 义 标 准 I/O 预 定 义 流 :stdin,stdout 和 stderr, 说 明 I/O 流 子 程 序 STDLIB.H 说 明 一 些 常 用 的 子 程 序 : 转 换 子 程 序 搜 索 / 排 序 子 程 序 等 STRING.H 说 明 一 些 串 操 作 和 内 存 操 作 函 数 SYS\STAT.H 定 义 在 打 开 和 创 建 文 件 时 用 到 的 一 些 符 号 常 量 SYS\TYPES.H 说 明 ftime 函 数 和 timeb 结 构 SYS\TIME.H 定 义 时 间 的 类 型 time[zz(z] [ZZ)]t 第 208 页

209 TIME.H 定 义 时 间 转 换 子 程 序 asctime localtime 和 gmtime 的 结 构,ctime difftime gmtime localtime 和 stime 用 到 的 类 型, 并 提 供 这 些 函 数 的 原 型 VALUE.H 定 义 一 些 重 要 常 量, 包 括 依 赖 于 机 器 硬 件 的 和 为 与 Unix System V 相 兼 容 而 说 明 的 一 些 常 量, 包 括 浮 点 和 双 精 度 值 的 范 围 13.8 本 章 小 结 1. C 系 统 把 文 件 当 作 一 个 流, 按 字 节 进 行 处 理 2. C 文 件 按 编 码 方 式 分 为 二 进 制 文 件 和 ASCII 文 件 3. C 语 言 中, 用 文 件 指 针 标 识 文 件, 当 一 个 文 件 被 打 开 时, 可 取 得 该 文 件 指 针 4. 文 件 在 读 写 之 前 必 须 打 开, 读 写 结 束 必 须 关 闭 5. 文 件 可 按 只 读 只 写 读 写 追 加 四 种 操 作 方 式 打 开, 同 时 还 必 须 指 定 文 件 的 类 型 是 二 进 制 文 件 还 是 文 本 文 件 6. 文 件 可 按 字 节, 字 符 串, 数 据 块 为 单 位 读 写, 文 件 也 可 按 指 定 的 格 式 进 行 读 写 7. 文 件 内 部 的 位 置 指 针 可 指 示 当 前 的 读 写 位 置, 移 动 该 指 针 可 以 对 文 件 实 现 随 机 读 写 第 209 页

《C语言基础入门》课程教学大纲

《C语言基础入门》课程教学大纲 C 语 言 开 发 入 门 教 程 课 程 教 学 大 纲 课 程 编 号 :201409210011 学 分 :5 学 分 学 时 :58 学 时 ( 其 中 : 讲 课 学 时 :39 学 时 上 机 学 时 :19 学 时 ) 先 修 课 程 : 计 算 机 导 论 后 续 课 程 :C++ 程 序 设 计 适 用 专 业 : 信 息 及 其 计 算 机 相 关 专 业 开 课 部 门 : 计

More information

I

I 机 电 一 级 注 册 建 造 师 继 续 教 育 培 训 广 东 培 训 点 网 上 报 名 操 作 使 用 手 册 (2013 年 1 月, 第 一 版 ) 第 一 章 个 人 注 册 与 个 人 信 息 管 理 1. 个 人 注 册 ( 请 每 人 只 申 请 一 个 注 册 号, 如 果 单 位 批 量 报 班 单 位 帮 申 请 注 册, 不 需 个 人 再 注 册 ) 首 次 报 班,

More information

说 明 为 了 反 映 教 运 行 的 基 本 状 态, 为 校 和 院 制 定 相 关 政 策 和 进 行 教 建 设 与 改 革 提 供 据 依 据, 校 从 程 资 源 ( 开 类 别 开 量 规 模 ) 教 师 结 构 程 考 核 等 维 度, 对 2015 年 春 季 期 教 运 行 基

说 明 为 了 反 映 教 运 行 的 基 本 状 态, 为 校 和 院 制 定 相 关 政 策 和 进 行 教 建 设 与 改 革 提 供 据 依 据, 校 从 程 资 源 ( 开 类 别 开 量 规 模 ) 教 师 结 构 程 考 核 等 维 度, 对 2015 年 春 季 期 教 运 行 基 内 部 资 料 东 北 师 范 大 教 运 行 基 本 状 态 据 报 告 2015 年 春 季 期 教 务 处 2015 年 10 月 27 日 说 明 为 了 反 映 教 运 行 的 基 本 状 态, 为 校 和 院 制 定 相 关 政 策 和 进 行 教 建 设 与 改 革 提 供 据 依 据, 校 从 程 资 源 ( 开 类 别 开 量 规 模 ) 教 师 结 构 程 考 核 等 维 度,

More information

第2章 数据类型、常量与变量

第2章  数据类型、常量与变量 第 2 章 数 据 类 型 常 量 与 变 量 在 计 算 机 程 序 中 都 是 通 过 值 (value) 来 进 行 运 算 的, 能 够 表 示 并 操 作 值 的 类 型 为 数 据 类 型 在 本 章 里 将 会 介 绍 JavaScript 中 的 常 量 (literal) 变 量 (variable) 和 数 据 类 型 (data type) 2.1 基 本 数 据 类 型 JavaScript

More information

龚 亚 夫 在 重 新 思 考 基 础 教 育 英 语 教 学 的 理 念 一 文 中 援 引 的 观 点 认 为 当 跳 出 本 族 语 主 义 的 思 维 定 式 后 需 要 重 新 思 考 许 多 相 连 带 的 问 题 比 如 许 多 发 音 的 细 微 区 别 并 不 影 响 理 解 和

龚 亚 夫 在 重 新 思 考 基 础 教 育 英 语 教 学 的 理 念 一 文 中 援 引 的 观 点 认 为 当 跳 出 本 族 语 主 义 的 思 维 定 式 后 需 要 重 新 思 考 许 多 相 连 带 的 问 题 比 如 许 多 发 音 的 细 微 区 别 并 不 影 响 理 解 和 语 音 语 篇 语 感 语 域 林 大 津 毛 浩 然 改 革 开 放 以 来 的 英 语 热 引 发 了 大 中 小 学 英 语 教 育 整 体 规 划 问 题 在 充 分 考 虑 地 区 学 校 和 个 体 差 异 以 及 各 家 观 点 的 基 础 上 遵 循 实 事 求 是 逐 级 定 位 逐 层 分 流 因 材 施 教 的 原 则 本 研 究 所 倡 导 的 语 音 语 篇 语 感 语 域

More information

<433A5C446F63756D656E747320616E642053657474696E67735C41646D696E6973747261746F725CD7C0C3E65CC2DBCEC4CFB5CDB3CAB9D3C3D6B8C4CFA3A8BCF2BBAFA3A95CCAB9D3C3D6B8C4CF31302D31392E646F63>

<433A5C446F63756D656E747320616E642053657474696E67735C41646D696E6973747261746F725CD7C0C3E65CC2DBCEC4CFB5CDB3CAB9D3C3D6B8C4CFA3A8BCF2BBAFA3A95CCAB9D3C3D6B8C4CF31302D31392E646F63> ( 一 ) 系 统 整 体 操 作 流 程 简 述 3 ( 二 ) 系 统 中 各 角 色 操 作 功 能 说 明 5 1. 学 院 管 理 员 5 2. 教 学 院 长 8 3. 指 导 教 师 10 4. 答 辩 组 组 长 12 5. 学 生 12 6. 系 统 管 理 员 15 ( 一 ) 论 文 系 统 常 见 问 题 16 ( 二 ) 论 文 查 重 常 见 问 题 22 1 2 主

More information

修改版-操作手册.doc

修改版-操作手册.doc 职 称 信 息 系 统 升 级 指 南 须 使 用 IE9 及 其 以 上 版 本 浏 览 器 或 谷 歌 浏 览 器 登 录 www.njrs.gov.cn 南 京 市 职 称 ( 职 业 资 格 ) 工 作 领 导 小 组 办 公 室 2016 年 5 月 目 录 一 申 报 人 员 操 作 指 南...1 1.1 职 称 初 定 申 报...1 1.1.1 职 称 初 定 基 础 信 息 填

More information

文 化 记 忆 传 统 创 新 与 节 日 遗 产 保 护 根 据 德 国 学 者 阿 斯 曼 的 文 化 记 忆 理 论 仪 式 与 文 本 是 承 载 文 化 记 忆 的 两 大 媒 体 在 各 种 仪 式 行 为 中 节 日 以 其 高 度 的 公 共 性 有 组 织 性 和 历 史 性 而 特 别 适 用 于 文 化 记 忆 的 储 存 和 交 流 节 日 的 文 化 功 能 不 仅 在 于

More information

何 秋 琳 张 立 春 视 觉 学 习 研 究 进 展 视 觉 注 意 视 觉 感 知

何 秋 琳 张 立 春 视 觉 学 习 研 究 进 展 视 觉 注 意 视 觉 感 知 第 卷 第 期 年 月 开 放 教 育 研 究 何 秋 琳 张 立 春 华 南 师 范 大 学 未 来 教 育 研 究 中 心 广 东 广 州 随 着 图 像 化 技 术 和 电 子 媒 体 的 发 展 视 觉 学 习 也 逐 步 发 展 为 学 习 科 学 的 一 个 研 究 分 支 得 到 研 究 人 员 和 教 育 工 作 者 的 广 泛 关 注 基 于 此 作 者 试 图 对 视 觉 学 习

More information

Microsoft Word - 第7章 图表反转形态.doc

Microsoft Word - 第7章 图表反转形态.doc 第 七 章 图 表 反 转 形 态 我 们 知 道 市 场 趋 势 共 有 三 种 : 上 升 趋 势 下 降 趋 势 和 横 向 整 理 市 场 的 价 格 波 动 都 是 运 行 在 这 三 种 趋 势 中, 所 有 的 走 势 都 是 这 三 种 趋 势 的 排 列 组 合 如 图 市 场 趋 势 结 构 示 意 图 7-1 所 示 市 场 趋 势 结 构 示 意 图 7-1 图 市 场 趋

More information

HSK( 一 级 ) 考 查 考 生 的 日 常 汉 语 应 用 能 力, 它 对 应 于 国 际 汉 语 能 力 标 准 一 级 欧 洲 语 言 共 同 参 考 框 架 (CEF) A1 级 通 过 HSK( 一 级 ) 的 考 生 可 以 理 解 并 使 用 一 些 非 常 简 单 的 汉 语

HSK( 一 级 ) 考 查 考 生 的 日 常 汉 语 应 用 能 力, 它 对 应 于 国 际 汉 语 能 力 标 准 一 级 欧 洲 语 言 共 同 参 考 框 架 (CEF) A1 级 通 过 HSK( 一 级 ) 的 考 生 可 以 理 解 并 使 用 一 些 非 常 简 单 的 汉 语 新 汉 语 水 平 考 试 HSK 为 使 汉 语 水 平 考 试 (HSK) 更 好 地 服 务 于 汉 语 学 习 者, 中 国 国 家 汉 办 组 织 中 外 汉 语 教 学 语 言 学 心 理 学 和 教 育 测 量 学 等 领 域 的 专 家, 在 充 分 调 查 了 解 海 外 实 际 汉 语 教 学 情 况 的 基 础 上, 吸 收 原 有 HSK 的 优 点, 借 鉴 近 年 来 国

More information

,,,,, :,, (.,, );, (, : ), (.., ;. &., ;.. &.., ;, ;, ),,,,,,, ( ) ( ),,,,.,,,,,, : ;, ;,.,,,,, (., : - ),,,, ( ),,,, (, : ),, :,

,,,,, :,, (.,, );, (, : ), (.., ;. &., ;.. &.., ;, ;, ),,,,,,, ( ) ( ),,,,.,,,,,, : ;, ;,.,,,,, (., : - ),,,, ( ),,,, (, : ),, :, : 周 晓 虹 : - -., - - - -. :( ), -,.( ),,, -. - ( ).( ) ', -,,,,, ( ).( ),,, -., '.,, :,,,, :,,,, ,,,,, :,, (.,, );, (, : ), (.., ;. &., ;.. &.., ;, ;, ),,,,,,, ( ) ( ),,,,.,,,,,, : ;, ;,.,,,,, (., : - ),,,,

More information

导 数 和 微 分 的 概 念 导 数 的 几 何 意 义 和 物 理 意 义 函 数 的 可 导 性 与 连 续 性 之 间 的 关 系 平 面 曲 线 的 切 线 和 法 线 导 数 和 微 分 的 四 则 运 算 基 本 初 等 函 数 的 导 数 复 合 函 数 反 函 数 隐 函 数 以

导 数 和 微 分 的 概 念 导 数 的 几 何 意 义 和 物 理 意 义 函 数 的 可 导 性 与 连 续 性 之 间 的 关 系 平 面 曲 线 的 切 线 和 法 线 导 数 和 微 分 的 四 则 运 算 基 本 初 等 函 数 的 导 数 复 合 函 数 反 函 数 隐 函 数 以 2015 年 考 研 数 学 二 考 试 大 纲 考 试 科 目 : 高 等 数 学 线 性 代 数 考 试 形 式 和 试 卷 结 构 一 试 卷 满 分 及 考 试 时 间 试 卷 满 分 为 150 分, 考 试 时 间 为 180 分 钟. 二 答 题 方 式 答 题 方 式 为 闭 卷 笔 试. 三 试 卷 内 容 结 构 高 等 教 学 约 78% 线 性 代 数 约 22% 四 试 卷

More information

登录、注册功能的测试用例设计.doc

登录、注册功能的测试用例设计.doc 注 册 登 陆 测 试 用 例 和 修 改 密 码 测 试 用 例 完 整 版 摘 自 网 络, 狗 狗 整 理 [email protected] 修 改 历 史 日 期 版 本 作 者 修 改 内 容 评 审 号 变 更 控 制 号 2010-11-25 1.0 初 稿 2011-09-17 2.0 整 理 一 注 册 测 试 用 例 序 号 : 1 控 件 名 称 : 功 能 描 述 : 注 册 编

More information

0 年 上 半 年 评 价 与 考 核 细 则 序 号 部 门 要 素 值 考 核 内 容 考 核 方 式 考 核 标 准 考 核 ( 扣 原 因 ) 考 评 得 3 安 全 生 产 目 30 无 同 等 责 任 以 上 道 路 交 通 亡 人 事 故 无 轻 伤 责 任 事 故 无 重 大 质 量

0 年 上 半 年 评 价 与 考 核 细 则 序 号 部 门 要 素 值 考 核 内 容 考 核 方 式 考 核 标 准 考 核 ( 扣 原 因 ) 考 评 得 3 安 全 生 产 目 30 无 同 等 责 任 以 上 道 路 交 通 亡 人 事 故 无 轻 伤 责 任 事 故 无 重 大 质 量 0 年 上 半 年 评 价 与 考 核 细 则 序 号 部 门 要 素 值 考 核 内 容 考 核 方 式 考 核 标 准 无 同 等 责 任 以 上 道 路 交 通 亡 人 事 故 3 无 轻 伤 责 任 事 故 目 标 30 及 事 无 重 大 质 量 工 作 过 失 故 管 无 其 他 一 般 责 任 事 故 理 在 公 司 文 明 环 境 创 建 中, 无 工 作 过 失 及 被 追 究 的

More information

<4D6963726F736F667420576F7264202D2032303133C4EAB9A4B3CCCBB6CABFCAFDD1A7D7A8D2B5BFCEBFBCCAD4B4F3B8D9D3EBD2AAC7F3>

<4D6963726F736F667420576F7264202D2032303133C4EAB9A4B3CCCBB6CABFCAFDD1A7D7A8D2B5BFCEBFBCCAD4B4F3B8D9D3EBD2AAC7F3> 工 程 硕 士 数 学 考 试 大 纲 与 要 求 ( 包 括 高 等 数 学 和 线 性 代 数 ) 一 函 数 极 限 与 连 续 第 一 部 分 : 高 等 数 学 考 试 内 容 函 数 的 概 念 及 表 示 法 函 数 的 有 界 性 单 调 性 周 期 性 和 奇 偶 性 复 合 函 数 反 函 数 分 段 函 数 和 隐 函 数 基 本 初 等 函 数 的 性 质 及 其 图 形 初

More information

一 公 共 卫 生 硕 士 专 业 学 位 论 文 的 概 述 学 位 论 文 是 对 研 究 生 进 行 科 学 研 究 或 承 担 专 门 技 术 工 作 的 全 面 训 练, 是 培 养 研 究 生 创 新 能 力, 综 合 运 用 所 学 知 识 发 现 问 题, 分 析 问 题 和 解 决

一 公 共 卫 生 硕 士 专 业 学 位 论 文 的 概 述 学 位 论 文 是 对 研 究 生 进 行 科 学 研 究 或 承 担 专 门 技 术 工 作 的 全 面 训 练, 是 培 养 研 究 生 创 新 能 力, 综 合 运 用 所 学 知 识 发 现 问 题, 分 析 问 题 和 解 决 上 海 市 公 共 卫 生 硕 士 专 业 学 位 论 文 基 本 要 求 和 评 价 指 标 体 系 ( 试 行 ) 上 海 市 学 位 委 员 会 办 公 室 二 O 一 二 年 三 月 一 公 共 卫 生 硕 士 专 业 学 位 论 文 的 概 述 学 位 论 文 是 对 研 究 生 进 行 科 学 研 究 或 承 担 专 门 技 术 工 作 的 全 面 训 练, 是 培 养 研 究 生 创

More information

(2015-2016-2)-0004186-04205-1 140242 信 号 与 系 统 Ⅰ 学 科 基 础 必 修 课 37 37 1 教 203 17 周 2016 年 06 月 13 日 (08:00-09:35) (2015-2016-2)-0004186-04205-1 141011

(2015-2016-2)-0004186-04205-1 140242 信 号 与 系 统 Ⅰ 学 科 基 础 必 修 课 37 37 1 教 203 17 周 2016 年 06 月 13 日 (08:00-09:35) (2015-2016-2)-0004186-04205-1 141011 关 于 2015-2016 学 年 第 二 学 期 期 末 周 内 考 试 时 间 地 点 安 排 选 课 课 号 班 级 名 称 课 程 名 称 课 程 性 质 合 考 人 数 实 际 人 数 考 试 教 室 考 试 段 考 试 时 间 (2015-2016-2)-0006178-04247-1 130101 测 试 技 术 基 础 学 科 基 础 必 修 课 35 35 1 教 401 17 周

More information

目 录 关 于 图 标... 3 登 陆 主 界 面... 3 工 单 管 理... 5 工 单 列 表... 5 搜 索 工 单... 5 工 单 详 情... 6 创 建 工 单... 9 设 备 管 理 巡 检 计 划 查 询 详 情 销 售 管

目 录 关 于 图 标... 3 登 陆 主 界 面... 3 工 单 管 理... 5 工 单 列 表... 5 搜 索 工 单... 5 工 单 详 情... 6 创 建 工 单... 9 设 备 管 理 巡 检 计 划 查 询 详 情 销 售 管 宝 汇 德 Turbocare 微 服 务 系 统 客 户 操 作 手 册 Version 2.0 北 京 宝 汇 德 技 术 服 务 器 有 限 公 司 技 术 研 发 部 目 录 关 于 图 标... 3 登 陆 主 界 面... 3 工 单 管 理... 5 工 单 列 表... 5 搜 索 工 单... 5 工 单 详 情... 6 创 建 工 单... 9 设 备 管 理... 10 巡

More information

 编号:

 编号: 编 号 : 企 业 内 高 技 能 人 才 培 养 评 价 实 施 方 案 ( 仅 适 用 于 企 业 特 有 行 业 特 有 工 种 ) 实 施 单 位 ( 公 章 ) 申 报 日 期 年 _ 月 日 1 企 业 内 高 技 能 人 才 培 养 评 价 项 目 实 施 方 案 申 报 表 项 目 名 称 等 级 项 目 性 质 课 时 申 报 单 位 联 系 人 通 讯 地 址 电 话 手 机 电

More information

Microsoft Word - 第3章.doc

Microsoft Word - 第3章.doc 52 5 天 通 过 职 称 计 算 机 考 试 ( 考 点 视 频 串 讲 + 全 真 模 拟 ) Word 2003 中 文 字 处 理 ( 第 2 版 ) 第 3 章 3 字 符 格 式 需 要 掌 握 的 考 点 字 体 字 形 和 字 号 的 设 置 ; 上 标 下 标 空 心 字 等 字 体 效 果 的 使 用 ; 字 符 间 距 的 调 整 ; 改 变 字 符 颜 色 底 纹 添 加

More information

类 似 地, 又 可 定 义 变 下 限 的 定 积 分 : ( ). 与 ψ 统 称 为 变 限 积 分. f ( ) d f ( t) dt,, 注 在 变 限 积 分 (1) 与 () 中, 不 可 再 把 积 分 变 量 写 成 的 形 式 ( 例 如 ) 以 免 与 积 分 上 下 限 的

类 似 地, 又 可 定 义 变 下 限 的 定 积 分 : ( ). 与 ψ 统 称 为 变 限 积 分. f ( ) d f ( t) dt,, 注 在 变 限 积 分 (1) 与 () 中, 不 可 再 把 积 分 变 量 写 成 的 形 式 ( 例 如 ) 以 免 与 积 分 上 下 限 的 5 ( 一 ) 微 积 分 学 基 本 定 理 当 函 数 的 可 积 性 问 题 告 一 段 落, 并 对 定 积 分 的 性 质 有 了 足 够 的 认 识 之 后, 接 着 要 来 解 决 一 个 以 前 多 次 提 到 过 的 问 题 在 定 积 分 形 式 下 证 明 连 续 函 数 必 定 存 在 原 函 数. 一 变 限 积 分 与 原 函 数 的 存 在 性 设 f 在 [,] 上

More information

Template BR_Rec_2005.dot

Template BR_Rec_2005.dot ITU-R BT.1789 建 议 书 1 ITU-R BT.1789 建 议 书 在 分 组 视 频 传 输 中 利 用 传 输 误 码 信 息 重 建 接 收 视 频 的 方 法 (ITU-R 44/6 和 ITU-R 109/6 课 题 ) (2007 年 ) 范 围 本 建 议 书 对 业 务 提 供 商 重 建 接 收 视 频 的 方 法 做 了 详 细 介 绍, 以 便 利 用 传 输

More information

科 学 出 版 社 科 学 出 版 社 前 言 本 书 是 针 对 普 通 高 等 院 校 经 济 类 和 工 商 管 理 类 本 科 专 业 财 务 管 理 学 的 教 学 需 求, 结 合 教 育 部 经 济 管 理 类 本 科 财 务 管 理 学 课 程 教 学 大 纲 编 写 而 成 的 本 书 执 笔 者 都 是 长 期 工 作 在 财 务 管 理 教 学 一 线 的 专 业 教 师,

More information

评 委 : 李 炎 斌 - 个 人 技 术 标 资 信 标 初 步 审 查 明 细 表 序 号 投 标 单 位 投 标 函 未 按 招 标 文 件 规 定 填 写 漏 填 或 内 容 填 写 错 误 的 ; 不 同 投 标 人 的 投 标 文 件 由 同 一 台 电 脑 或 同 一 家 投 标 单

评 委 : 李 炎 斌 - 个 人 技 术 标 资 信 标 初 步 审 查 明 细 表 序 号 投 标 单 位 投 标 函 未 按 招 标 文 件 规 定 填 写 漏 填 或 内 容 填 写 错 误 的 ; 不 同 投 标 人 的 投 标 文 件 由 同 一 台 电 脑 或 同 一 家 投 标 单 评 委 : 李 炎 斌 - 个 人 清 标 评 审 明 细 表 评 审 因 素 序 号 投 标 单 位 清 标 评 审 1 深 圳 市 创 捷 科 技 有 限 合 格 2 四 川 川 大 智 胜 软 件 股 份 有 限 合 格 3 北 京 航 天 长 峰 科 技 工 业 集 团 有 限 公 司 合 格 4 深 圳 中 兴 力 维 技 术 有 限 合 格 5 深 圳 键 桥 通 讯 技 术 股 份 有

More information

<4D F736F F D D323630D6D0B9FAD3A6B6D4C6F8BAF2B1E4BBAFB5C4D5FEB2DFD3EBD0D0B6AF C4EAB6C8B1A8B8E6>

<4D F736F F D D323630D6D0B9FAD3A6B6D4C6F8BAF2B1E4BBAFB5C4D5FEB2DFD3EBD0D0B6AF C4EAB6C8B1A8B8E6> 中 国 应 对 气 候 变 化 的 政 策 与 行 动 2013 年 度 报 告 国 家 发 展 和 改 革 委 员 会 二 〇 一 三 年 十 一 月 100% 再 生 纸 资 源 目 录 前 言... 1 一 应 对 气 候 变 化 面 临 的 形 势... 3 二 完 善 顶 层 设 计 和 体 制 机 制... 4 三 减 缓 气 候 变 化... 8 四 适 应 气 候 变 化... 20

More information

第二讲 数列

第二讲   数列 Togisu XueD Persolized Eduio Developme Ceer 高 考 中 不 等 式 问 题 的 解 决 方 法 通 润 达 久 王 力 前 言 : 近 年 来 不 等 式 问 题 正 越 来 越 多 的 出 现 在 调 研 题 和 高 考 试 题 中 而 且 大 多 出 现 在 江 苏 高 考 的 填 空 压 轴 题 中 是 高 考 考 察 的 重 点 和 难 点 由 于

More information

马 克 思 主 义 公 正 观 的 基 本 向 度 及 方 法 论 原 则!! # #

马 克 思 主 义 公 正 观 的 基 本 向 度 及 方 法 论 原 则!! # # 马 克 思 主 义 公 正 观 的 基 本 向 度 及 方 法 论 原 则 马 俊 峰 在 社 会 公 正 问 题 的 大 讨 论 中 罗 尔 斯 诺 齐 克 哈 耶 克 麦 金 泰 尔 等 当 代 西 方 思 想 家 的 论 述 被 反 复 引 用 和 申 说 而 将 马 克 思 恩 格 斯 等 经 典 作 家 的 观 点 置 于 一 种 被 忽 视 甚 至 被 忘 却 的 状 态 形 成 这 种

More information

张 荣 芳 中 山 大 学 历 史 系 广 东 广 州 张 荣 芳 男 广 东 廉 江 人 中 山 大 学 历 史 系 教 授 博 士 生 导 师 我 们 要 打 破 以 前 学 术 界 上 的 一 切 偶 像 以 前 学 术 界 的 一 切 成 见 屏 除 我 们 要 实 地 搜 罗 材 料 到 民 众 中 寻 方 言 到 古 文 化 的 遗 址 去 发 掘 到 各 种 的 人 间 社 会 去

More information

2006年顺德区高中阶段学校招生录取分数线

2006年顺德区高中阶段学校招生录取分数线 2014 年 顺 德 区 高 中 阶 段 学 校 考 试 提 前 批 第 一 批 第 二 批 学 校 录 取 根 据 佛 山 市 办 提 供 的 考 生 数 据, 现 将 我 区 2014 年 高 中 阶 段 学 校 考 试 提 前 批 第 一 批 第 二 批 学 校 的 录 取 公 布 如 下 : 一 顺 德 一 中 录 取 分 第 1 志 愿, 总 分 585, 综 合 表 现 评 价 A, 考

More information

目 录 一 系 统 访 问... 1 二 门 户 首 页 申 报 用 户 审 核 用 户... 2 三 系 统 登 录 用 户 名 密 码 登 录 新 用 户 注 册 用 户 登 录 已 注 册 用

目 录 一 系 统 访 问... 1 二 门 户 首 页 申 报 用 户 审 核 用 户... 2 三 系 统 登 录 用 户 名 密 码 登 录 新 用 户 注 册 用 户 登 录 已 注 册 用 水 路 运 输 建 设 综 合 管 理 信 息 系 统 - 门 户 系 统 用 户 手 册 二 零 一 五 年 十 一 月 目 录 一 系 统 访 问... 1 二 门 户 首 页... 1 1. 申 报 用 户... 1 2. 审 核 用 户... 2 三 系 统 登 录... 4 1. 用 户 名 密 码 登 录... 4 1.1 新 用 户 注 册... 4 1.2 用 户 登 录... 7

More information

深圳市新亚电子制程股份有限公司

深圳市新亚电子制程股份有限公司 证 券 代 码 :002388 证 券 简 称 : 新 亚 制 程 公 告 编 号 :2016-053 深 圳 市 新 亚 电 子 制 程 股 份 有 限 公 司 2016 年 第 二 次 临 时 股 东 大 会 决 议 公 告 本 公 司 及 董 事 会 全 体 成 员 保 证 公 告 内 容 真 实 准 确 和 完 整, 不 存 在 虚 假 记 载 误 导 性 陈 述 或 者 重 大 遗 漏 特

More information

1600 1000 40 50 2030 2000 采 取 行 动 的 机 会 90% 开 拓 成 功 的 道 路 2

1600 1000 40 50 2030 2000 采 取 行 动 的 机 会 90% 开 拓 成 功 的 道 路 2 简 略 版 本 :2015 3 10 2016 2021 全 球 卫 生 部 门 病 毒 性 肝 炎 战 略 2016 2021 2015 3 12 2012 2010 2014 2015 2016 2021 140 55% 35% 5 15% 5 20% 2.4 1.3 1.5 1 1600 1000 40 50 2030 2000 采 取 行 动 的 机 会 90% 开 拓 成 功 的 道 路

More information

Microsoft Word - 文件汇编.doc

Microsoft Word - 文件汇编.doc 北 京 市 中 医 管 理 局 二 一 五 年 四 月 ... 1... 18 2015... 30 京 中 医 政 字 [2014]160 号 1 2 一 充 分 认 识 中 医 健 康 乡 村 建 设 工 作 的 重 要 意 义 二 建 立 健 全 工 作 保 障 机 制 2014 12 15 三 做 好 工 作 启 动 的 准 备 事 宜 1 2014 12 15 5-10 2014 12 15

More information

第二部分 阅读理解(Part II Reabing Comprehension)

第二部分  阅读理解(Part II Reabing Comprehension) 吉 林 省 成 人 本 科 学 士 学 位 日 语 统 一 考 试 大 纲 总 则 为 适 应 成 人 高 等 教 育 本 科 毕 业 生 申 请 学 士 学 位 外 语 统 一 考 试 的 要, 根 据 国 务 院 学 位 委 员 会 关 于 授 予 成 人 高 等 教 育 本 科 毕 业 生 学 士 学 位 暂 行 规 定 和 国 务 院 学 位 委 员 会 原 国 家 教 育 委 员 会 关

More information

正 规 培 训 达 规 定 标 准 学 时 数, 并 取 得 结 业 证 书 二 级 可 编 程 师 ( 具 备 以 下 条 件 之 一 者 ) (1) 连 续 从 事 本 职 业 工 作 13 年 以 上 (2) 取 得 本 职 业 三 级 职 业 资 格 证 书 后, 连 续 从 事 本 职 业

正 规 培 训 达 规 定 标 准 学 时 数, 并 取 得 结 业 证 书 二 级 可 编 程 师 ( 具 备 以 下 条 件 之 一 者 ) (1) 连 续 从 事 本 职 业 工 作 13 年 以 上 (2) 取 得 本 职 业 三 级 职 业 资 格 证 书 后, 连 续 从 事 本 职 业 1. 职 业 概 况 1.1 职 业 名 称 可 编 程 师 1.2 职 业 定 义 可 编 程 师 国 家 职 业 标 准 从 事 可 编 程 序 控 制 器 (PLC) 选 型 编 程, 并 对 应 用 进 行 集 成 和 运 行 管 理 的 人 员 1.3 职 业 等 级 本 职 业 共 设 四 个 等 级, 分 别 为 : 四 级 可 编 程 师 ( 国 家 职 业 资 格 四 级 ) 三

More information

教师上报成绩流程图

教师上报成绩流程图 教 务 管 理 系 统 使 用 说 明 学 生 端 用 户 1 在 校 内 任 何 一 台 连 接 校 园 网 的 计 算 机 上 登 录 教 务 处 主 页 教 务 处 主 页 地 址 : http://jw.stdu.edu.cn/homepage 随 后 点 击 按 钮 ( 见 下 图 所 示 ), 即 可 进 入 综 合 教 务 管 理 系 统 2 在 综 合 教 务 管 理 区 域 内 键

More information

18 上 报 该 学 期 新 生 数 据 至 阳 光 平 台 第 一 学 期 第 四 周 至 第 六 周 19 督 促 学 习 中 心 提 交 新 增 专 业 申 请 第 一 学 期 第 四 周 至 第 八 周 20 编 制 全 国 网 络 统 考 十 二 月 批 次 考 前 模 拟 题 第 一 学

18 上 报 该 学 期 新 生 数 据 至 阳 光 平 台 第 一 学 期 第 四 周 至 第 六 周 19 督 促 学 习 中 心 提 交 新 增 专 业 申 请 第 一 学 期 第 四 周 至 第 八 周 20 编 制 全 国 网 络 统 考 十 二 月 批 次 考 前 模 拟 题 第 一 学 1 安 排 组 织 全 国 网 络 统 考 九 月 批 次 网 上 考 前 辅 导 第 一 学 期 第 一 周 统 考 考 前 半 个 月 2 下 发 全 国 网 络 统 考 九 月 批 次 准 考 证 第 一 学 期 第 一 周 导 出 下 半 年 成 人 本 科 学 士 学 位 英 语 统 一 考 试 报 考 3 信 息 第 一 学 期 第 一 周 4 教 学 计 划 和 考 试 计 划 上 网,

More information

<4D6963726F736F667420576F7264202D20BFC9B1E0B3CCD0F2BFD8D6C6CFB5CDB3C9E8BCC6CAA6B9FABCD2D6B0D2B5B1EAD7BC2E646F63>

<4D6963726F736F667420576F7264202D20BFC9B1E0B3CCD0F2BFD8D6C6CFB5CDB3C9E8BCC6CAA6B9FABCD2D6B0D2B5B1EAD7BC2E646F63> 国 家 职 业 标 准 1 可 编 程 序 控 制 系 统 设 计 师 国 家 职 业 标 准 1. 职 业 概 况 1.1 职 业 名 称 可 编 程 序 控 制 系 统 设 计 师 1.2 职 业 定 义 从 事 可 编 程 序 控 制 器 (PLC) 选 型 编 程, 并 对 应 用 系 统 进 行 设 计 集 成 和 运 行 管 理 的 人 员 1.3 职 业 等 级 本 职 业 共 设 四

More information

定 位 和 描 述 : 程 序 设 计 / 办 公 软 件 高 级 应 用 级 考 核 内 容 包 括 计 算 机 语 言 与 基 础 程 序 设 计 能 力, 要 求 参 试 者 掌 握 一 门 计 算 机 语 言, 可 选 类 别 有 高 级 语 言 程 序 设 计 类 数 据 库 编 程 类

定 位 和 描 述 : 程 序 设 计 / 办 公 软 件 高 级 应 用 级 考 核 内 容 包 括 计 算 机 语 言 与 基 础 程 序 设 计 能 力, 要 求 参 试 者 掌 握 一 门 计 算 机 语 言, 可 选 类 别 有 高 级 语 言 程 序 设 计 类 数 据 库 编 程 类 全 国 计 算 机 等 级 考 试 调 整 方 案 2011 年 7 月, 教 育 部 考 试 中 心 组 织 召 开 了 第 五 届 全 国 计 算 机 等 级 考 试 (NCRE) 考 委 会 会 议, 会 议 完 成 NCRE 考 委 会 换 届 选 举, 并 确 定 了 下 一 步 改 革 和 发 展 的 目 标 在 新 的 历 史 时 期,NCRE 将 以 保 持 稳 定 为 前 提 以

More information

评 委 : 徐 岩 宇 - 个 人 技 术 标 资 信 标 初 步 审 查 明 细 表 序 号 投 标 单 位 投 标 函 未 按 招 标 文 件 规 定 填 写 漏 填 或 内 容 填 写 错 误 的 ; 不 同 投 标 人 的 投 标 文 件 由 同 一 台 电 脑 或 同 一 家 投 标 单

评 委 : 徐 岩 宇 - 个 人 技 术 标 资 信 标 初 步 审 查 明 细 表 序 号 投 标 单 位 投 标 函 未 按 招 标 文 件 规 定 填 写 漏 填 或 内 容 填 写 错 误 的 ; 不 同 投 标 人 的 投 标 文 件 由 同 一 台 电 脑 或 同 一 家 投 标 单 评 委 : 徐 岩 宇 - 个 人 清 标 评 审 明 细 表 评 审 因 素 序 号 投 标 单 位 清 标 评 审 1 深 圳 市 创 捷 科 技 有 限 合 格 2 四 川 川 大 智 胜 软 件 股 份 有 限 合 格 3 北 京 航 天 长 峰 科 技 工 业 集 团 有 限 公 司 合 格 4 深 圳 中 兴 力 维 技 术 有 限 合 格 5 深 圳 键 桥 通 讯 技 术 股 份 有

More information

世华财讯模拟操作手册

世华财讯模拟操作手册 第 一 部 分 : 股 票 模 拟 操 作 部 分 1. 登 录 与 主 界 面 1.1 登 录 学 生 在 桌 面 上, 打 开 世 华 文 件 夹, 直 接 双 击 文 件 夹 中 的 快 捷 图 标, 系 统 弹 出 世 华 财 讯 模 拟 股 票 交 易 系 统 ( 客 户 端 ) 窗 口, 如 图 1.1 所 示 图 1.1 请 输 入 登 录 名 称 及 密 码, 单 击 确 认 登 录

More information

3 复 试 如 何 准 备 4 复 试 成 绩 计 算 5 复 试 比 例 6 复 试 类 型 7 怎 么 样 面 对 各 种 复 试 04 05

3 复 试 如 何 准 备 4 复 试 成 绩 计 算 5 复 试 比 例 6 复 试 类 型 7 怎 么 样 面 对 各 种 复 试 04 05 1 复 试 流 程 2 复 试 考 查 形 式 02 03 3 复 试 如 何 准 备 4 复 试 成 绩 计 算 5 复 试 比 例 6 复 试 类 型 7 怎 么 样 面 对 各 种 复 试 04 05 2 怎 样 给 导 师 留 下 良 好 的 第 一 印 象 把 握 进 门 时 机 1 面 试 中 穿 着 的 瞒 天 过 海 3 无 声 胜 有 声 的 肢 体 语 言 育 4 眼 睛 是 心

More information

<433A5C55736572735C6B73625C4465736B746F705CB9FABCCAD6D0D2BDD2A9D7A8D2B5B8DFBCB6BCBCCAF5D6B0B3C6C6C0C9F3C9EAC7EBD6B8C4CFA3A832303136CDA8D3C3B0E6A3A92E646F63>

<433A5C55736572735C6B73625C4465736B746F705CB9FABCCAD6D0D2BDD2A9D7A8D2B5B8DFBCB6BCBCCAF5D6B0B3C6C6C0C9F3C9EAC7EBD6B8C4CFA3A832303136CDA8D3C3B0E6A3A92E646F63> 附 件 1 国 际 中 药 专 业 高 级 技 术 职 称 评 审 条 件 及 报 名 材 料 一 系 列 ( 一 ) 中 1 高 级 专 科 ( 副 ) 高 级 专 科 ( 副 ) 1 取 得 中 专 科 职 称 后, 独 立 从 事 中 临 床 实 践 5 年 以 上 2 取 得 中 博 士 学 位 后, 临 床 实 践 2 年 以 上 3 取 得 中 硕 士 学 位 后, 临 床 实 践 7

More information

用节点法和网孔法进行电路分析

用节点法和网孔法进行电路分析 运 用 节 点 法 和 网 孔 法 进 行 电 路 分 析 众 所 周 知, 运 用 基 尔 霍 夫 定 律 和 欧 姆 定 律, 我 们 可 以 对 任 何 一 个 电 路 进 行 分 析, 以 确 定 其 运 行 条 件 ( 电 流 和 电 压 值 ) 一 般 电 路 分 析 的 难 点 在 于 用 最 少 的 联 立 方 程 描 述 电 路 的 运 行 特 性 在 这 一 讲 里, 我 们 将

More information

附 件 : 上 海 市 建 筑 施 工 企 业 施 工 现 场 项 目 管 理 机 构 关 键 岗 位 人 员 配 备 指 南 二 一 四 年 九 月 十 一 日 2

附 件 : 上 海 市 建 筑 施 工 企 业 施 工 现 场 项 目 管 理 机 构 关 键 岗 位 人 员 配 备 指 南 二 一 四 年 九 月 十 一 日 2 公 开 上 海 市 城 乡 建 设 和 管 理 委 员 会 文 件 沪 建 管 2014 758 号 上 海 市 城 乡 建 设 和 管 理 委 员 会 关 于 印 发 上 海 市 建 筑 施 工 企 业 施 工 现 场 项 目 管 理 机 构 关 键 岗 位 人 员 配 备 指 南 的 通 知 各 区 县 建 设 和 交 通 委 员 会 : 为 进 一 步 加 强 对 建 设 工 程 施 工 现

More information

全国建筑市场注册执业人员不良行为记录认定标准(试行).doc

全国建筑市场注册执业人员不良行为记录认定标准(试行).doc - 1 - - 2 - 附 件 全 国 建 筑 市 场 注 册 执 业 人 员 不 良 记 录 认 定 标 准 ( 试 行 ) 说 明 为 了 完 善 建 筑 市 场 注 册 执 业 人 员 诚 信 体 系 建 设, 规 范 执 业 和 市 场 秩 序, 依 据 相 关 法 律 法 规 和 部 门 规 章, 根 据 各 行 业 特 点, 我 部 制 订 了 全 国 建 筑 市 场 注 册 执 业 人

More information

生产支援功能 使用说明书(IP-110 篇)

生产支援功能 使用说明书(IP-110 篇) 生 产 支 援 功 能 使 用 说 明 书 (IP-110 篇 ) 目 录!. 前 言...1 1. 概 要...1 2. 基 本 操 作 方 法...3 2-1. 信 息 模 式 和 通 常 缝 制 模 式 的 变 换...3 2-2. 信 息 模 式...4 2-3. 通 常 缝 制 模 式...5 @. 设 定 篇...6 1. 首 次 使 用 生 产 支 援 功 能 时 的 设 定 方 法...6

More information

金 不 少 于 800 万 元, 净 资 产 不 少 于 960 万 元 ; (3) 近 五 年 独 立 承 担 过 单 项 合 同 额 不 少 于 1000 万 元 的 智 能 化 工 程 ( 设 计 或 施 工 或 设 计 施 工 一 体 ) 不 少 于 2 项 ; (4) 近 三 年 每 年

金 不 少 于 800 万 元, 净 资 产 不 少 于 960 万 元 ; (3) 近 五 年 独 立 承 担 过 单 项 合 同 额 不 少 于 1000 万 元 的 智 能 化 工 程 ( 设 计 或 施 工 或 设 计 施 工 一 体 ) 不 少 于 2 项 ; (4) 近 三 年 每 年 工 程 设 计 与 施 工 资 质 标 准 一 总 则 建 筑 智 能 化 工 程 设 计 与 施 工 资 质 标 准 ( 一 ) 为 了 加 强 对 从 事 建 筑 智 能 化 工 程 设 计 与 施 工 企 业 的 管 理, 维 护 建 筑 市 场 秩 序, 保 证 工 程 质 量 和 安 全, 促 进 行 业 健 康 发 展, 结 合 建 筑 智 能 化 工 程 的 特 点, 制 定 本 标

More information

全国教师资格认定管理信息系统

全国教师资格认定管理信息系统 操 作 说 明 一 教 师 资 格 认 定 申 请 人 1 : 1. 未 参 加 全 国 统 考 申 请 人 2.1 登 录 未 参 加 全 国 统 考 申 请 人 网 上 报 名 系 统 登 录 中 国 教 师 资 格 网 (http://www.jszg.edu.cn), 未 参 加 全 国 统 考 申 请 人 有 两 种 途 径 进 入 报 名 系 统 第 一 种 途 径 : 点 击 网 站

More information

反 学 校 文 化 与 阶 级 再 生 产 小 子 与 子 弟 之 比 较 周 潇 作 者 通 过 对 北 京 某 打 工 子 弟 学 校 的 田 野 调 查 后 发 现 在 农 民 工 子 弟 中 间 盛 行 着 类 似 学 做 工 中 所 描 述 的 工 人 阶 级 小 子 的 反 学 校 文 化 但 是 由 于 制 度 安 排 与 社 会 条 件 的 差 异 子 弟 与 小 子 的 反 学 校

More information

微 积 分 ( 二 ) 教 学 大 纲 2 (2010 版 ) 课 程 编 码 :110861 课 程 名 称 : 微 积 分 学 时 / 学 分 :36/2 先 修 课 程 : 初 等 数 学 立 体 几 何 平 面 解 析 几 何 微 积 分 ( 一 ) 适 用 专 业 : 人 力 资 源 管

微 积 分 ( 二 ) 教 学 大 纲 2 (2010 版 ) 课 程 编 码 :110861 课 程 名 称 : 微 积 分 学 时 / 学 分 :36/2 先 修 课 程 : 初 等 数 学 立 体 几 何 平 面 解 析 几 何 微 积 分 ( 一 ) 适 用 专 业 : 人 力 资 源 管 微 积 分 ( 二 ) 教 学 大 纲 2 (2010 版 ) 课 程 编 码 :110861 课 程 名 称 : 微 积 分 学 时 / 学 分 :36/2 先 修 课 程 : 初 等 数 学 立 体 几 何 平 面 解 析 几 何 微 积 分 ( 一 ) 适 用 专 业 : 人 力 资 源 管 理 等 专 业 开 课 教 研 室 : 大 学 数 学 教 研 室 执 笔 : 庄 乐 森 审 定 :

More information

中 中 中 中 部 中 岗 位 条 件 历 其 它 历 史 师 地 理 师 生 物 师 体 与 健 康 师 04 05 06 07 从 事 中 历 史 工 从 事 中 地 理 工 从 事 中 生 物 工 从 事 中 体 与 健 康 工 2. 课 程 与 论 ( 历 史 ); 2. 科 ( 历 史 )

中 中 中 中 部 中 岗 位 条 件 历 其 它 历 史 师 地 理 师 生 物 师 体 与 健 康 师 04 05 06 07 从 事 中 历 史 工 从 事 中 地 理 工 从 事 中 生 物 工 从 事 中 体 与 健 康 工 2. 课 程 与 论 ( 历 史 ); 2. 科 ( 历 史 ) 中 中 中 部 中 26 年 系 统 事 业 公 开 计 划 岗 位 条 件 历 其 它 数 师 英 语 师 物 理 师 02 0 从 事 中 数 工 从 事 中 英 语 工 从 事 中 物 理 工 2. 课 程 与 论 ( 数 ); 2. 科 ( 数 );. 数 ; 4. 基 础 数 ; 5. 计 算 数 ; 6. 概 率 论 与 数 理 统 计 ; 7. 应 用 数 ; 8. 数. 课 程 与

More information

Microsoft Word - 资料分析练习题09.doc

Microsoft Word - 资料分析练习题09.doc 行 测 高 分 冲 刺 练 习 题 资 料 分 析 ( 共 15 题, 参 考 时 限 10 分 钟 ) 材 料 题 - 1 2012 年 1 月 某 小 区 成 交 的 二 手 房 中, 面 积 为 60 平 方 米 左 右 的 住 宅 占 总 销 售 套 数 的 ( ) A.25% B.35% C.37.5% 长 沙 市 雨 花 区 侯 家 塘 佳 天 国 际 大 厦 北 栋 20 楼 第 1

More information

<4D6963726F736F667420576F7264202D20B9D8D3DAB0BABBAAA3A8C9CFBAA3A3A9D7D4B6AFBBAFB9A4B3CCB9C9B7DDD3D0CFDEB9ABCBBE32303132C4EAC4EAB6C8B9C9B6ABB4F3BBE1B7A8C2C9D2E2BCFBCAE92E646F6378>

<4D6963726F736F667420576F7264202D20B9D8D3DAB0BABBAAA3A8C9CFBAA3A3A9D7D4B6AFBBAFB9A4B3CCB9C9B7DDD3D0CFDEB9ABCBBE32303132C4EAC4EAB6C8B9C9B6ABB4F3BBE1B7A8C2C9D2E2BCFBCAE92E646F6378> 上 海 德 载 中 怡 律 师 事 务 所 关 于 昂 华 ( 上 海 ) 自 动 化 工 程 股 份 有 限 公 司 二 〇 一 二 年 年 度 股 东 大 会 法 律 意 见 书 上 海 德 载 中 怡 律 师 事 务 所 上 海 市 银 城 中 路 168 号 上 海 银 行 大 厦 1705 室 (200120) 电 话 :8621-5012 2258 传 真 :8621-5012 2257

More information

作 为 生 产 者 式 文 本 的 女 性 主 义 通 俗 小 说 梅 丽 本 文 借 鉴 文 化 研 究 理 论 家 约 翰 费 斯 克 的 生 产 者 式 文 本 这 一 概 念 考 察 女 性 主 义 通 俗 小 说 的 文 本 特 征 写 作 策 略 和 微 观 政 治 意 义 女 性 主 义 通 俗 小 说 通 过 对 传 统 通 俗 小 说 的 挪 用 和 戏 仿 传 播 女 性 主 义

More information

云信Linux SSH认证代理用户手册

云信Linux SSH认证代理用户手册 Windows 主 机 登 录 保 护 (RDP) 管 理 员 配 置 手 册 V1.0 云 信 事 业 部 飞 天 诚 信 科 技 股 份 有 限 公 司 www.cloudentify.com 章 节 目 录 第 1 章 管 理 平 台 配 置 说 明... 1 1.1 注 册... 1 1.2 登 录... 3 1.3 添 加 应 用... 4 1.4 添 加 用 户... 7 1.5 激 活

More information

( 二 ) 现 行 统 一 高 考 制 度 不 利 于 培 养 人 的 创 新 精 神,,,,,,,,,,,,, [ ],,,,,,,,,,, :, ;,,,,,,? ( 三 ) 现 行 统 一 高 考 制 度 不 利 于 全 体 学 生 都 获 得 全 面 发 展,, [ ],,,,,,,,,,,

( 二 ) 现 行 统 一 高 考 制 度 不 利 于 培 养 人 的 创 新 精 神,,,,,,,,,,,,, [ ],,,,,,,,,,, :, ;,,,,,,? ( 三 ) 现 行 统 一 高 考 制 度 不 利 于 全 体 学 生 都 获 得 全 面 发 展,, [ ],,,,,,,,,,, ( ) ( )... 李 雪 岩, 龙 耀 (. 广 西 民 族 大 学 商 学 院, 广 西 南 宁 ;. 中 山 大 学 教 育 学 院, 广 东 广 州 ) : 高 等 教 育 是 专 业 教 育 高 考 是 为 高 等 教 育 服 务 的, 是 为 高 等 专 业 教 育 选 拔 有 专 业 培 养 潜 质 的 人 才 现 行 高 考 制 度 忽 略 专 业 潜 质 的 因 素, 过 份 强

More information

珠江钢琴股东大会

珠江钢琴股东大会 证 券 代 码 :002678 证 券 简 称 : 珠 江 钢 琴 公 告 编 号 :2015-038 广 州 珠 江 钢 琴 集 团 股 份 有 限 公 司 2015 年 年 度 股 东 大 会 决 议 公 告 本 公 司 及 董 事 会 全 体 成 员 保 证 信 息 披 露 的 内 容 真 实 准 确 完 整, 没 有 虚 假 记 载 误 导 性 陈 述 或 重 大 遗 漏 特 别 提 示 :

More information

课程类 别

课程类 别 美 声 演 唱 方 向 培 养 方 案 一 培 养 目 标 本 方 向 要 求 学 生 德 智 体 美 全 面 发 展, 培 养 能 在 文 艺 团 体 从 事 声 乐 演 唱 及 能 在 艺 术 院 校 从 事 本 方 向 教 学 的 高 级 门 人 才 二 培 养 规 格 本 方 向 学 生 应 系 统 掌 握 声 乐 演 唱 方 面 的 理 论 和 技 能, 具 备 较 高 的 声 乐 演 唱

More information

(Microsoft Word - NCRE\314\345\317\265\265\367\325\37313\324\27221\272\3051.doc)

(Microsoft Word - NCRE\314\345\317\265\265\367\325\37313\324\27221\272\3051.doc) 川 教 考 院 2013 21 号 全 国 计 算 机 等 级 考 试 调 整 方 案 2011 年 7 月, 教 育 部 考 试 中 心 组 织 召 开 了 第 五 届 全 国 计 算 机 等 级 考 试 NCRE 考 委 会 会 议, 会 议 完 成 NCRE 考 委 会 换 届 选 举, 并 确 定 了 下 一 步 改 革 和 发 展 的 目 标 在 新 的 历 史 时 期,NCRE 将 以

More information

公 开 刊 物 须 有 国 内 统 一 刊 (CN), 发 表 文 章 的 刊 物 需 要 在 国 家 新 闻 出 版 广 电 总 局 (www.gapp.gov.cn 办 事 服 务 便 民 查 询 新 闻 出 版 机 构 查 询 ) 上 能 够 查 到 刊 凡 在 有 中 国 标 准 书 公 开

公 开 刊 物 须 有 国 内 统 一 刊 (CN), 发 表 文 章 的 刊 物 需 要 在 国 家 新 闻 出 版 广 电 总 局 (www.gapp.gov.cn 办 事 服 务 便 民 查 询 新 闻 出 版 机 构 查 询 ) 上 能 够 查 到 刊 凡 在 有 中 国 标 准 书 公 开 杭 教 人 2014 7 杭 州 市 教 育 局 关 于 中 小 学 教 师 系 列 ( 含 实 验 教 育 管 理 ) 晋 升 高 级 专 业 技 术 资 格 有 关 论 文 要 求 的 通 知 各 区 县 ( 市 ) 教 育 局 ( 社 发 局 ), 直 属 学 校 ( 单 位 ), 委 托 单 位 : 为 进 一 步 规 范 杭 州 市 中 小 学 教 师 系 列 ( 含 实 验 教 育 管

More information

超 级 玛 丽 JAVA 小 游 戏 测 试 报 告 1. 导 言 1.1 编 写 目 的 该 文 档 的 目 的 是 描 述 超 级 玛 丽 JAVA 小 游 戏 的 系 统 测 试 的 总 结 报 告, 其 主 要 内 容 包 括 : 系 统 环 境 的 介 绍 功 能 的 实 现 的 测 试

超 级 玛 丽 JAVA 小 游 戏 测 试 报 告 1. 导 言 1.1 编 写 目 的 该 文 档 的 目 的 是 描 述 超 级 玛 丽 JAVA 小 游 戏 的 系 统 测 试 的 总 结 报 告, 其 主 要 内 容 包 括 : 系 统 环 境 的 介 绍 功 能 的 实 现 的 测 试 超 级 玛 丽 游 戏 测 试 报 告 目 录 1. 导 言... 2 1.1 编 写 目 的... 2 1.2 项 目 范 围... 2 1.3 参 考 资 料... 2 1.4 缩 写 说 明... 2 1.5 术 语 定 义... 2 1.6 版 本 更 新 信 息... 3 2. 测 试 设 计... 3 2.1 测 试 要 点... 3 2.2 测 试 时 间 地 点 人 员... 3 2.3

More information

<443A5C6D B5C30312EB9A4D7F7CEC4B5B55C30322EBACFCDACCEC4B5B55C C30342EC8CBC9E7CCFC5C31332ECFEEC4BFC5E0D1B55C E30385C322EB2D9D7F7CAD6B2E12E646F63>

<443A5C6D B5C30312EB9A4D7F7CEC4B5B55C30322EBACFCDACCEC4B5B55C C30342EC8CBC9E7CCFC5C31332ECFEEC4BFC5E0D1B55C E30385C322EB2D9D7F7CAD6B2E12E646F63> 浙 江 职 业 能 力 建 设 信 息 系 统 职 业 技 能 鉴 定 考 务 管 理 用 户 操 作 手 册 二 〇 一 五 年 八 月 目 录 0. 系 统 概 述...3 0.0. 简 要 概 述...3 0.1. 业 务 流 程 图... 3 1. 考 生 网 上 报 名... 3 1.0. 考 生 用 户 注 册 登 录... 5 1.1. 报 名 及 下 载 打 印 报 名 申 请 表...7

More information

伊 犁 师 范 学 院 611 语 言 学 概 论 全 套 考 研 资 料 <2016 年 最 新 考 研 资 料 > 2-2 语 言 学 纲 要 笔 记, 由 考 取 本 校 本 专 业 高 分 研 究 生 总 结 而 来, 重 点 突 出, 借 助 此 笔 记 可 以 大 大 提 高 复 习 效

伊 犁 师 范 学 院 611 语 言 学 概 论 全 套 考 研 资 料 <2016 年 最 新 考 研 资 料 > 2-2 语 言 学 纲 要 笔 记, 由 考 取 本 校 本 专 业 高 分 研 究 生 总 结 而 来, 重 点 突 出, 借 助 此 笔 记 可 以 大 大 提 高 复 习 效 伊 犁 师 范 学 院 611 语 言 学 概 论 全 套 考 研 资 料 ......2 伊 犁 师 范 学 院 802 文 学 概 论 全 套 考 研 资 料 ......2 伊 犁 师 范 学 院 702 普 通 物 理 全 套 考 研 资 料 ......3 伊 犁

More information

自 服 务 按 钮 无 法 访 问 新 系 统 的 自 服 务 页 面 因 此 建 议 用 户 从 信 网 中 心 (http://nc.tju.edu.cn) 主 页, 右 下 角 位 置 的 常 用 下 载, 或 校 园 网 用 户 自 服 务 (http://g.tju.edu.cn) 首 页

自 服 务 按 钮 无 法 访 问 新 系 统 的 自 服 务 页 面 因 此 建 议 用 户 从 信 网 中 心 (http://nc.tju.edu.cn) 主 页, 右 下 角 位 置 的 常 用 下 载, 或 校 园 网 用 户 自 服 务 (http://g.tju.edu.cn) 首 页 校 园 网 认 证 计 费 系 统 变 更 说 明 及 使 用 帮 助 为 提 高 校 园 网 的 可 靠 性 和 可 用 性, 提 升 用 户 的 上 网 体 验, 同 时 也 为 解 决 近 期 校 园 网 无 法 认 证 或 登 录 页 面 弹 出 缓 慢 的 问 题, 信 网 中 心 于 近 期 对 校 园 网 认 证 计 费 系 统 进 行 升 级 切 换 现 将 升 级 后 新 系 统

More information

工 程 勘 察 资 质 标 准 根 据 建 设 工 程 勘 察 设 计 管 理 条 例 和 建 设 工 程 勘 察 设 计 资 质 管 理 规 定, 制 定 本 标 准 一 总 则 ( 一 ) 本 标 准 包 括 工 程 勘 察 相 应 专 业 类 型 主 要 专 业 技 术 人 员 配 备 技 术

工 程 勘 察 资 质 标 准 根 据 建 设 工 程 勘 察 设 计 管 理 条 例 和 建 设 工 程 勘 察 设 计 资 质 管 理 规 定, 制 定 本 标 准 一 总 则 ( 一 ) 本 标 准 包 括 工 程 勘 察 相 应 专 业 类 型 主 要 专 业 技 术 人 员 配 备 技 术 住 房 和 城 乡 建 设 部 关 于 印 发 工 程 勘 察 资 质 标 准 的 通 知 建 市 [2013]9 号 各 省 自 治 区 住 房 和 城 乡 建 设 厅, 北 京 市 规 划 委, 天 津 上 海 市 建 设 交 通 委, 重 庆 市 城 乡 建 设 委, 新 疆 生 产 建 设 兵 团 建 设 局, 总 后 基 建 营 房 部 工 程 局, 国 务 院 有 关 部 门 建 设 司,

More information

第 一 部 分 MagiCAD for Revit 安 装 流 程

第 一 部 分 MagiCAD for Revit 安 装 流 程 MagiCAD 软 件 安 装 流 程 MagiCAD v2015.4 for Revit 广 联 达 软 件 股 份 有 限 公 司 BIM 中 心 编 写 2015 年 06 月 第 一 部 分 MagiCAD for Revit 安 装 流 程 一 安 装 前 需 要 确 认 的 内 容 安 装 MagiCAD 程 序 之 前, 请 您 先 确 定 以 下 事 宜 1. 当 前 用 户 账 户

More information

一 从 分 封 制 到 郡 县 制 一 从 打 虎 亭 汉 墓 说 起

一 从 分 封 制 到 郡 县 制 一 从 打 虎 亭 汉 墓 说 起 县 乡 两 级 的 政 治 体 制 改 革 如 何 建 立 民 主 的 合 作 新 体 制 县 乡 人 大 运 行 机 制 研 究 课 题 组 引 言 一 从 分 封 制 到 郡 县 制 一 从 打 虎 亭 汉 墓 说 起 二 密 县 在 周 初 是 两 个 小 国 密 国 和 郐 国 三 密 县 的 第 一 任 县 令 卓 茂 四 明 清 时 代 的 密 县 二 从 集 中 的 动 员 体

More information

《应用数学Ⅰ》教学大纲

《应用数学Ⅰ》教学大纲 高 等 数 学 教 学 大 纲 学 时 数 :124 学 时. 适 用 专 业 : 计 算 机 系 电 子 系 建 工 系 机 电 系 各 专 业. 参 加 讨 论 人 员 : 数 学 研 究 室 全 体 成 员. 执 笔 人 : 朱 玉 清 审 定 人 : 许 洪 范 编 写 日 期 :2001 年 5 月 至 2001 年 11 月.2003 年 3 至 5 月 进 一 步 修 订. 高 等 数

More information

Microsoft PowerPoint - plan03.ppt

Microsoft PowerPoint - plan03.ppt 声 明 和 定 义 严 格 说, 声 明 (declaration) 和 定 义 (definition) 不 一 样 声 明 : 定 义 : 说 明 一 个 事 物 的 存 在 和 它 的 一 些 属 性, 例 如 变 量 与 其 类 型 根 据 声 明 可 以 确 定 被 声 明 事 物 的 使 用 方 式 对 象 声 明 并 不 实 际 建 立 对 象 例 如 :C 语 言 的 外 部 (extern)

More information

ETF、分级基金规模、份额变化统计20130816

ETF、分级基金规模、份额变化统计20130816 ETF 分 级 基 金 规 模 份 额 变 化 统 计 截 至 上 周 末, 全 市 场 股 票 型 ETF 规 模 约 1451 亿, 份 额 约 1215 亿,ETF 总 份 额 及 规 模 的 周 变 动 值 分 别 为 -23-44 亿, 份 额 与 规 模 均 下 降 ; 分 级 基 金 规 模 约 438 亿, 份 额 572 亿, 总 份 额 及 规 模 的 周 变 动 值 分 别 为

More information

4 进 入 交 互 区 设 置 的 组 件 管 理, 在 组 件 管 理 中, 教 师 可 以 选 择 课 程 空 间 中 的 所 有 组 件, 并 通 过 点 击 启 用 或 不 启 用 选 定 组 件 在 课 程 空 间 中 的 显 示 5 进 入 工 作 室 管 理 的 工 作 室 首 页,

4 进 入 交 互 区 设 置 的 组 件 管 理, 在 组 件 管 理 中, 教 师 可 以 选 择 课 程 空 间 中 的 所 有 组 件, 并 通 过 点 击 启 用 或 不 启 用 选 定 组 件 在 课 程 空 间 中 的 显 示 5 进 入 工 作 室 管 理 的 工 作 室 首 页, 网 络 教 育 新 平 台 教 师 使 用 简 易 手 册 一 登 录 教 师 工 作 室 1 打 开 西 南 科 技 大 学 网 络 教 育 教 学 教 务 新 平 台 主 页 面 :http://www.swust.net.cn/ 2 在 主 页 面 左 边 的 登 陆 区 中, 用 户 名 和 密 码 处 分 别 输 入 自 己 的 用 户 名 ( 教 师 ID 号 ) 和 密 码 ( 初 始

More information

名 称 生 命 科 学 学 院 083001 环 境 科 学 1 生 物 学 仅 接 收 院 内 调 剂, 初 试 分 数 满 足 我 院 生 物 学 复 试 最 低 分 数 线 生 命 科 学 学 院 071300 生 态 学 5 生 态 学 或 生 物 学 生 命 科 学 学 院 040102

名 称 生 命 科 学 学 院 083001 环 境 科 学 1 生 物 学 仅 接 收 院 内 调 剂, 初 试 分 数 满 足 我 院 生 物 学 复 试 最 低 分 数 线 生 命 科 学 学 院 071300 生 态 学 5 生 态 学 或 生 物 学 生 命 科 学 学 院 040102 华 中 师 范 大 学 2016 年 接 收 校 内 外 优 秀 硕 士 研 究 生 调 剂 信 息 表 名 称 经 济 与 工 商 管 理 学 院 020101 政 治 经 济 学 1 经 济 学 类 毕 业 学 校 与 报 考 学 校 不 低 于 我 校 办 学 层 次 经 济 与 工 商 管 理 学 院 020105 世 界 经 济 学 1 经 济 学 类 毕 业 学 校 与 报 考 学 校

More information

Microsoft Word - 中节能_工业项目节能评估审查导则Draft.doc

Microsoft Word - 中节能_工业项目节能评估审查导则Draft.doc 0 -------------------------------------------------------------------------------- 2 ----------------------------------------------------------------------------- 2 节 评 ----------------------------------------------------------------------------------------------------

More information

操作手册

操作手册 企 业 网 上 银 行 使 用 手 册 ( 智 信 版 ) 中 国 农 业 银 行 股 份 有 限 公 司 重 庆 市 分 行 目 录 使 用 网 上 银 行 前 务 必 了 解 的 信 息... 3 1. 基 本 功 能... 3 2. 网 银 操 作 员... 3 3. 登 录 方 式... 3 4. 特 别 提 醒... 3 快 速 使 用 指 南... 4 1. 注 册 用 户... 4 2.

More information

第三章 作业

第三章  作业 - 在 题 图 - 中, 若 电 压 源 U V, 电 阻, 试 在 图 示 参 考 方 向 下 求 支 路 电 流 I Us I 题 图 - 以 电 压 源 为 参 考 方 向,I=-A - 求 图 - 各 支 路 中 未 知 量 的 值 4V V =? A U=? V A U=? A V a b c a =(-4)/=Ω b U=+ =4V c U=4V 题 图 - - 在 题 图 -a b 所

More information

untitled

untitled ( 一 ) 深 刻 认 识 学 习 教 育 的 重 大 意 义 : - 3 - ( 二 ) 明 确 学 习 教 育 的 任 务 目 标 ( 三 ) 把 握 特 点 方 法 - 4 - ( 四 ) 坚 持 六 项 原 则 在 - 5 - ( 五 ) 着 力 解 决 问 题 - 6 - - 7 - - 8 - ( 一 ) 学 党 章 党 规, 进 一 步 明 确 党 员 标 准 树 立 行 为 规 范

More information

Cybozu Garoon 3 管理员手册

Cybozu Garoon 3 管理员手册 附 录 D 数 据 的 输 入 样 式 数 据 的 种 类 和 输 入 字 符 的 值 等, 在 Garoon3 的 页 面 输 入 的 数 据 样 式 如 下 所 示 基 本 系 统 客 户 信 息 法 人 姓 名 字 符 串 ( 00 法 人 姓 名 ( 拼 音 ) 字 符 串 ( 00 图 标 (URL) 字 符 串 ( 255 应 用 程 序 新 名 称 字 符 串 ( 00 用 户 姓 名

More information

上证指数

上证指数 上 证 与 修 正 方 法 一 ( 一 ) 计 算 公 式 1. 上 证 指 数 系 列 均 采 用 派 许 加 权 综 合 价 格 指 数 公 式 计 算 2. 上 证 180 指 数 上 证 50 指 数 等 以 成 份 股 的 调 整 股 本 数 为 权 数 进 行 加 权 计 算, 计 算 公 式 为 : 报 告 期 指 数 =( 报 告 期 样 本 股 的 调 整 市 值 / 基 期 )

More information

第3章 创建数据库

第3章 创建数据库 第 3 章 创 建 数 据 库 要 点 3.1 Access 2002 开 发 环 境 3.2 数 据 库 的 创 建 3.3 创 建 表 3.4 字 段 操 作 3.5 设 定 表 关 系 3.6 操 作 记 录 3.7 数 据 的 导 入 和 导 出 3.1 Access 2002 开 发 环 境 Access 与 许 多 常 用 的 数 据 库 管 理 系 统, 如 Access 常 用 的

More information

抗 日 战 争 研 究 年 第 期

抗 日 战 争 研 究 年 第 期 田 子 渝 武 汉 抗 战 时 期 是 国 共 第 二 次 合 作 的 最 好 时 期 在 国 共 合 作 的 基 础 上 出 现 了 抗 日 救 亡 共 御 外 侮 的 局 面 这 个 大 好 局 面 的 出 现 与 中 共 长 江 局 的 丰 功 伟 绩 是 分 不 开 的 但 长 期 以 来 由 于 有 一 个 王 明 的 右 倾 错 误 直 接 影 响 了 对 它 的 全 面 科 学 准 确

More information

3 月 30 日 在 中 国 证 券 报 上 海 证 券 报 证 券 时 报 证 券 日 报 和 上 海 证 券 交 易 所 网 站 上 发 出 召 开 本 次 股 东 大 会 公 告, 该 公 告 中 载 明 了 召 开 股 东 大 会 的 日 期 网 络 投 票 的 方 式 时 间 以 及 审

3 月 30 日 在 中 国 证 券 报 上 海 证 券 报 证 券 时 报 证 券 日 报 和 上 海 证 券 交 易 所 网 站 上 发 出 召 开 本 次 股 东 大 会 公 告, 该 公 告 中 载 明 了 召 开 股 东 大 会 的 日 期 网 络 投 票 的 方 式 时 间 以 及 审 北 京 市 君 致 律 师 事 务 所 关 于 浪 潮 软 件 股 份 有 限 公 司 2015 年 度 股 东 大 会 的 法 律 意 见 书 致 : 浪 潮 软 件 股 份 有 限 公 司 北 京 市 君 致 律 师 事 务 所 ( 以 下 简 称 本 所 ) 受 浪 潮 软 件 股 份 有 限 公 司 ( 以 下 简 称 公 司 ) 的 委 托, 指 派 律 师 出 席 2016 年 4 月

More information

物 流 从 业 人 员 职 业 能 力 等 级 证 书 分 为 四 个 级 别, 分 别 为 初 级 助 理 级 中 级 和 高 级 ; 采 购 从 业 人 员 职 业 能 力 等 级 证 书 分 为 三 个 级 别, 分 别 为 中 级 高 级 和 注 册 级 请 各 有 关 单 位 按 照 通

物 流 从 业 人 员 职 业 能 力 等 级 证 书 分 为 四 个 级 别, 分 别 为 初 级 助 理 级 中 级 和 高 级 ; 采 购 从 业 人 员 职 业 能 力 等 级 证 书 分 为 三 个 级 别, 分 别 为 中 级 高 级 和 注 册 级 请 各 有 关 单 位 按 照 通 物 联 培 字 2016 16 号 各 有 关 单 位 : 为 适 应 国 家 一 带 一 路 战 略 实 施 和 物 流 产 业 转 型 升 级 对 人 才 的 新 要 求, 确 保 物 流 采 购 人 才 培 养 工 作 有 序 衔 接 和 持 续 健 康 发 展, 参 照 国 际 惯 例, 中 国 物 流 与 采 购 联 合 会 ( 以 下 简 称 中 物 联 ) 经 研 究 决 定, 以 物

More information

<4D6963726F736F667420576F7264202D2050485035C3E6CFF2B6D4CFF3A3A8B5DAC8FDD5C220C0E0CCD8D0D4A3A92E646F63>

<4D6963726F736F667420576F7264202D2050485035C3E6CFF2B6D4CFF3A3A8B5DAC8FDD5C220C0E0CCD8D0D4A3A92E646F63> 第 三 章 PHP5 面 向 对 象 高 级 类 特 性 这 一 周 来 正 好 白 天 没 课, 赶 出 来 这 章 宝 宝 出 生 将 近 一 个 月, 快 10 斤 重 了 宝 宝 快 张 大, 你 想 编 程 么? 宝 宝 妈 说, 做 这 个 行 业 太 累 了 刀 客 羽 朋 于 石 家 庄 2006-11-23 1 目 录 3.1 static 变 量 方 法...3 3.1.1 静

More information

中 国 软 科 学 年 第 期!!!

中 国 软 科 学 年 第 期!!! 山 寨 模 式 的 形 成 机 理 及 其 对 组 织 创 新 的 启 示 山 寨 模 式 的 形 成 机 理 及 其 对 组 织 创 新 的 启 示 陶 厚 永 李 燕 萍 骆 振 心 武 汉 大 学 经 济 与 管 理 学 院 武 汉 大 学 中 国 产 学 研 合 作 问 题 研 究 中 心 湖 北 武 汉 北 京 大 学 经 济 研 究 所 光 华 天 成 博 士 后 工 作 站 北 京 本

More information

¹ º ¹ º 农 业 流 动 人 口 是 指 户 口 性 质 为 农 业 户 口 在 流 入 地 城 市 工 作 生 活 居 住 一 个 月 及 以 上 的 流 动 人 口 非 农 流 动 人 口 是 指 户 口 性 质 为 非 农 户 口 在 流 入 地 城 市 工 作 生 活 居 住 一 个

¹ º ¹ º 农 业 流 动 人 口 是 指 户 口 性 质 为 农 业 户 口 在 流 入 地 城 市 工 作 生 活 居 住 一 个 月 及 以 上 的 流 动 人 口 非 农 流 动 人 口 是 指 户 口 性 质 为 非 农 户 口 在 流 入 地 城 市 工 作 生 活 居 住 一 个 ¹ 改 革 开 放 年 来 人 口 流 动 规 模 持 续 增 加 对 我 国 社 会 经 济 的 持 续 发 展 起 到 了 重 要 作 用 为 全 面 了 解 我 国 流 动 人 口 生 存 状 况 准 确 把 握 流 动 人 口 发 展 规 律 和 趋 势 不 断 加 强 流 动 人 口 服 务 管 理 引 导 人 口 有 序 流 动 合 理 分 布 国 家 人 口 计 生 委 于 年 月 启

More information

<4D F736F F D20322EC9F3BACBC8CBD4B1D7CAB8F1D7A2B2E1B9DCC0EDB9E6B7B6B8BDB1ED2E646F63>

<4D F736F F D20322EC9F3BACBC8CBD4B1D7CAB8F1D7A2B2E1B9DCC0EDB9E6B7B6B8BDB1ED2E646F63> 审 核 人 员 资 格 管 理 规 范 版 次 :F/0 附 表 1: QMS/EMS/OHSMS 管 理 体 系 审 核 员 通 用 要 求 申 请 条 件 初 次 综 合 素 质 考 核 越 级 晋 升 条 件 实 习 审 核 员 审 核 员 主 任 审 核 员 1. 高 等 教 育 : 大 学 本 科 以 上 学 历, 或 大 专 学 历 及 相 2. 工 作 1 : ; 3. 专 业 工 作

More information

第 四 条 建 设 单 位 对 可 能 产 生 职 业 病 危 害 的 建 设 项 目, 应 当 依 照 本 办 法 向 安 全 生 产 监 督 管 理 部 门 申 请 职 业 卫 生 三 同 时 的 备 案 审 核 审 查 和 竣 工 验 收 建 设 项 目 职 业 卫 生 三 同 时 工 作 可

第 四 条 建 设 单 位 对 可 能 产 生 职 业 病 危 害 的 建 设 项 目, 应 当 依 照 本 办 法 向 安 全 生 产 监 督 管 理 部 门 申 请 职 业 卫 生 三 同 时 的 备 案 审 核 审 查 和 竣 工 验 收 建 设 项 目 职 业 卫 生 三 同 时 工 作 可 第 51 号 建 设 项 目 职 业 卫 生 三 同 时 监 督 管 理 暂 行 办 法 已 经 2012 年 3 月 6 日 国 家 安 全 生 产 监 督 管 理 总 局 局 长 办 公 会 议 审 议 通 过, 现 予 公 布, 自 2012 年 6 月 1 日 起 施 行 国 家 安 全 生 产 监 督 管 理 总 局 骆 琳 二 一 二 年 四 月 二 十 七 日 建 设 项 目 职 业

More information