1、最 新C 语 言 程 序 设 计 教 程刘 正 林 周 纯 杰 编著华 中 科 技 大 学 出 版 社中 飞 队内 容 简 介本 书 以 最 新 ANSI C+ 标 准 作 为 准 则 , 以 国 内 外 广 为 流 行 的 、 美 国 Microsoft 公司开发的 Visual C+ 为语言蓝本,系统地讲授 C+模 块 化 语 言 的 基 础 部 分 , 即 C 语 言 作 为 最 新 ANSI C+内 核 的 基 本 语 法 和 程 序 设 计 方 法 , 扬弃了 C 语言老版本的一些非标准内容,按照“循序渐进,突出重点,深入浅 出 , 融 会 贯 通 ”的 教 学 原 则 , 编 写
2、成 自 成 体 系 的 C 语 言 教 科 书 ; 每 章 都 有 小 结 , 归 纳 出 必 须 掌 握 的 重 点 内 容 , 并 附 有 大 量 的 习 题 , 以 加 深 读 者 对 重 点 内 容 的 理解;本书可作为大专院校理、工科各专业学生学习“C 语言程序设计”的 教 科 书 , 也 可 供 广 大 电 脑 爱 好 者 作 为 自 学 C 和 C+语言的教材和参考书。图书在版编目(CIP)数据最新 C 语 言 程 序 设 计 教 程 /刘 正 林 周纯杰 编 著 武 汉 : 华 中 科 技 大 学 出 版 社 , 2003 年 2 月ISBN 7-5609-2884-6/TP3
3、12C. J . 刘 周 .最新 C 语言程序设计教程 刘正林 周 纯 杰 编著责任编辑:吴锐涛 封面设计:刘 卉责任校对:陈元玉 责任监印:出版发行:华中科技大学出版社 武昌喻家山 邮编:430074 电话:(027)87542624 经销:新华书店湖北发行所录排:华中科技大学惠友科技文印中心 电话:(027)87543977 印刷:开本:787960 1/16 印张: 字数:版次:2003 年 2 月第 1 版 印次:2003 年 2 月第 1 次印刷 印数:ISBN 7-5609-2884-6/TP312C/ 定价:24.80元(本书若有印装质量问题,请向出版社发行部调换)前 言崭新的
4、21 世纪,以现代电子信息产业为龙头的全球经济一体化浪潮正席卷世界,这 是 当 今 人 类 所 面 临 的 巨 大 挑 战 , 人 们 将 认 真 面 对 挑 战 的 内 涵 和 挑 战 所 带 来 的 机 遇 。 而 以 IT(Information Technology)技 术 为 基 础 的 信 息 产 业 正 深 入 到 人 类 社 会 生 活 的 方 方 面面,无论是生产制造、商业、国防和科技等领域,还是第三产业,计算机软件现己成为 担当重任的核心力量,互联网和软件己成为推动新经济发展的重要基础。因此,计算机软 件技术将是各类专业的大专生、 本科生和研究生所必备的基础知识。 面向对象
5、的程序设计 是软件技术的一场革命, 必将成为 21 世纪普遍采用的软件开发方法 。 C+是面向对象程序 设 计 的 第 一 个 大 众 化 设 计 语 言 版 本 , 是 当 前 学 习 面 向 对 象 程 序 设 计 方 法 的 首 选 语 言 。 C+ 是著名 C 语 言 的 面 向 对 象 扩 展 , C 语言最初设计时,是作为一种面向系统软件(操作系统 Operating System 和语言处理系统)的开发语言,即是用来代替汇编语言的,但是由 于它强大的生命力,在事务处理、科学计算、工业控制和数据库技术等各个方面都得到了 广泛应用。即便进入到以计算机网络为核心的信息时代,C 语言仍然
6、是作为通用的汇编语 言使用, 用以开发 软 (件) 、 硬 (件) 结合的程序, 如实时监控程序、 控制程序和设备驱 动 程 序 等 。 而 C+是 C 语 言 的 超 集 , 它 保 留 了 C 的 所 有 组 成 部 分 而 与 其 完 全 兼 容 , 既 可 以 做 传统的结构化程序设计,又能进行面向对象程序设计,是当今世界最为流行的面向对象程 序设计语言。本书以最新 ANSI(American National Standards Institute) C+标 准 为 准 则,以美国 Microsoft 公司开发的 Visual C+ 6.0 为语言蓝本,重点介绍 C+程序 设计语言的
7、主要语法和模块结构化基础,并讲解 C 和 C+的 不 同 点 , 使 学 生 能 自 觉 扬 弃 C 语言老版本的一些非标准内容,将 C 语言老版本程序快捷地修改成符合最新 ANSI C+标 准的实用程序,其目的是便于学生尽快掌握像 Visual C+和 C+ Builder 这些优秀可 视化的应用程序开发工具,快速冲向计算机应用领域的前沿,成为各类专业从事计算机应 用、具有相当的应用软件开发能力的技术人才,为进一步学习完全面向对象、面向计算机 网络的 Java 语言打下牢固的基础。由于面向对象程序设计方法与传统结构化程序设计方 法在思维方式、核心概念、编程技术等方面差别很大,新概念、新技术和
8、新的专业术语较 多,为了使学生便于学习,我们总结了多年教学和科研的实践经验,根据“循序渐进,突 出重点,深入浅出,融会贯通”的教学原则,对内容进行了精选,强化如函数及其参数、 指针和引用、链表和排序等重要概念,舍去了如联合体和保护型继承之类的一些即将退化 或应用很少的概念,并编写成自成体系的 C+教 科 书 形 式 。本书以“实用、创新、深入浅出、通俗易懂”为特色,讲述思路清晰,层次分明,逻辑 性 强 , 可 作 为 目 前 各 大 专 院 校 己 开 设 的 “C 语 言 程 序 设 计 ”课 程 的 教 材 , 取 名 为 最 新 C 语言程序设计教程 , 以 取代那些内容老化的教材。 为
9、便于理解, 本书不生硬翻译国外的语 言手册,力戒使用晦涩难懂的语言,对于日新月异的计算机领域的许多新专业术语则采用II 最新 C 语言程序设计教程通俗易懂的大众化语言讲述,对核心概念做到图文并茂并必举实例加以说明。 作者发扬“蜜蝉采蜜”的精神,一方面总结多年教学和科研的成果,另一方面广泛收集国内外最新发展动态和应用实例,并经过消化和吸收,在理解的基础上,根据“循序渐 进,重点突出”的教学原则,以“面向对象方法及其理论”为基础,酿造成“思路新颖, 重点突出,逻辑清晰,易学易用”的知识奉献给读者,这是作者的创新之举。应用软件的开发是从事计算机应用的各类专业技术人员的大舞台,它是由从事计算机 应用的
10、各类专业人员来完成的。这部分人员多数毕业于非计算机专业,不仅人数众多,而 且分布在广阔的各类应用领域内,他们既具有扎实的本专业基础理论知识和丰富的实践经 验,又熟悉计算机应用技术方面的知识,善于用计算机作为强有力的辅助工具去完成本应 用领域内的各种任务,在计算机应用领域内发挥着其他人才无法替代的重要作用,是应用 领域不可缺少的基本力量。 因此, 对非计算机专业的技术人员普及面向对象程序设 计 (O OP, Object-Oriented Programming) 的 基 础 知 识 是 当 前 刻 不 容 缓 的 任 务 。 本 教 材 以 此 为 编写宗旨,因此,适用于大专院校理、工科各类专
11、业学生作为“C 语言程序设计”和“面 向对象程序设计”两口课程的教科书,也适合于广大电脑爱好者选作自学 C 和 C+语 言 的 教材和参考书。在内容安排上也有深有浅,适用于各个层次的读者,既适合于以前从未接 触过 C 和 C+的 初 学 者 , 也 适 合 于 具 有 一 定 编 程 基 础 的 读 者 作 为 学 习 面 向 对 象 程 序 设 计 方 法,提高编程能力的教材和参考书。20 世纪末叶在因特网上风起云涌的编程世界语 Java, 是 由 C+ 发展而来的,保留 了大部分 C+内 容 , 是 面 向 计 算 机 网 络 、 完 全 面 向 对 象 的 程 序 设 计 语 言 , 也
12、 可 以 说 , 它 是 C+为 适 应 像 互 联 网 这 类 新 环 境 而 产 生 的 一 个 性 能 优 良 的 新 变 种 。 当 前 在 媒 体 的 炒 作 下 , Java 似乎有即刻取代 C+的 趋 势 , 但 客 观 现 实 并 非 如 此 。 Java 虽 然 显 得 那 么 娇 美 、 那 么 光彩照人,但毕竟还年轻,还需要经历一个不断完善的发展过程,并在激烈的竞争中不断 地 成 长 壮 大 。 例 如 , Java 在 PC 机上的执行速度(通常其执行时间是 C+的 20 倍)就是 阻 碍 它 普及 推 广 的 拦路虎 , 因 此“革 命 尚 未成功 , 同 志仍需 努
13、 力 ! ”。而 且 , 任何一 种 技 术 要想主宰或垄断未来的计算机领域是不可能的, 不管是操作系统也好, 语言处理系统也好, 还是应用程序的开发软件也罢,都将呈现多种技术并驾齐驱、各显神通的格局,这是事物 发 展 的 必 然 趋 势 , 是 不 以 人 们 的 意 志 为 转 移 的 客 观 规 律 。 于 是 有 人 提 出 了 : “学 好 VC(Visual C+)、 VB( Visual Basic) 和 Java, 走 遍 天 下 都 不 怕 ”的 口 号 , 在 这 里 作者愿与读者共同努力,去开拓计算机应用的新领域!作者 刘正林 周纯杰2003 年元旦于喻园目 录第 1 章
14、 概论 (1)1.1 C 语言的入门知识 .(1)1.1.1 计 算 机 中 的 数 据 和 编 码 系 统 (1)1.1.2 计算机的基础知识 (7)1.1.3 从 C 到 C+ .(10)1.1.4 计算机系统的层次结构 (11)1.1.5 C 和 C+的 特 征 (15)1.2 Visual C+V6.0 使用方法 .(29)1.2.1 源 程 序 的 编 辑 、 存 储 和 建 立 (29)1.2.2 编 译 、 链 接 和 运 行 源 程 序 (31)1.2.3 关闭源程序 (34)1.2.4 调 试 器 Debugger 的使用方法 .(34)1.2.5 查找信息 (35)1.2.
15、6 建立工程文件 (35)小结 .(36)习题 1 (37)第 2 章 数据类型、运算符和表达式 (39)2.1 基 本 数 据 类 型 (39)2.2 变量和常量 (41)2.2.1 变量 (41)2.2.2 常量 (48)2.2.3 数 据 类 型 的 自 动 转 换 和 强 制 转 换 (53)2.3 运 算 符 和 表 达 式 (57)2.3.1 算 术 运 算 符 和 算 术 表 达 式 (58)2.3.2 关 系 运 算 符 和 关 系 表 达 式 (59)2.3.3 逻 辑 运 算 符 和 位 逻 辑 运 算 符 (61)2.3.4 赋 值 运 算 符 和 增 减 运 算 符 (
16、71)2.3.5 条 件 语 句 、 条 件 运 算 符 及 条 件 表 达 式 (74)2.3.6 运 算 符 的 优 先 级 和 结 合 规 则 (81)2.4 格式化输入/输出函数 (85)2.4.1 格式化输出函数 (85)2.4.2 格式化输入函数 (93)2 最新 C 语言程序设计教程小结 .(97)习题 2 (98)第 3 章 语句和流程控制 .(104)3.1 语句 (104)3.1.1 表达式语句 (104)3.1.2 复合语句 (105)3.1.3 流程控制语句 (106)3.2 while 语句和 do while 语句 .(107)3.2.1 while 语句 .(10
17、7)3.2.2 do while 语句 .(110)3.3 for 语句 (115)3.3.1 for 语句的控制流程 (115)3.3.2 嵌 套 的 for 语句 .(118)3.4 其 他 流 程 控 制 语 句 (121)3.4.1 switch 语句 (121)3.4.2 跳转语句 (127)小结 .(132)习题 3 (133)第 4 章 数组与指针 (137)4.1 数组 (137)4.1.1 数组的定义 (137)4.1.2 字符数组 (138)4.2 变 量 的 地 址 和 指 针 变 量 (140)4.2.1 变量的地址 (140)4.2.2 指针变量 (141)4.2.3
18、 指针的定义 (143)4.3 指针和数组 (145)4.3.1 指向数组元素的指针 (145)4.3.2 指针与数组的关系 (146)4.4 指针的运算 (149)4.4.1 指针的赋值运算 (150)4.4.2 指针的算术运算 (152)4.4.3 指针的关系运算 (157)4.4.4 应用举例 (157)小结 .(163)习题 4 (163)3目 录第 5 章 函数 (168)5.1 函数的定义 (168)5.1.1 函数的定义格式 (168)5.1.2 函数的说明 (170)5.2 变 量 的 存 储 类 型 (173)5.2.1 自动变量 (173)5.2.2 外部变量 (176)5
19、.2.3 静态变量 (180)5.2.4 寄存器变量 (183)5.3 函数的调用 (184)5.3.1 函数的调用格式 (185)5.3.2 函 数 调 用 时 参 数 间 的 传 递 方 式 (186)5.3.3 指 针 和 数 组 作 为 函 数 的 参 数 (189)5.4 外 部 函 数 和 静 态 ( 内 部 ) 函 数 (200)5.5 函 数 的 递 归 调 用 (201)5.6 预 处 理 命 令 ( 条 件 编 译 命 令 ) (203)5.6.1 条件编译命令的格式 (203)5.6.2 内部链接和外部链接 (204)小结 .(208)习题 5 (209)第 6 章 复杂
20、的数据结构和函数调用 (216)6.1 main( )函数 .(216)6.2 指 针 数 组 和 多 级 指 针 (217)6.2.1 指针数组 (217)6.2.2 多级指针 (220)6.3 多维数组 (223)6.3.1 多维数组的定义 (223)6.3.2 二维数组 (223)6.4 数组指针 (231)6.4.1 数组指针的定义 (231)6.4.2 数 组 指 针 作 为 函 数 的 参 数 传 递 二 维 数 组 (233)6.5 指针函数 (235)6.5.1 指针函数的定义 (235)6.5.2 动态存储技术 (236)6.6 函数指针 (239)6.6.1 函 数 的 入
21、 口 地 址 和 函 数 指 针 的 定 义 (239)6.6.2 函 数 指 针 作 为 函 数 的 参 数 (241)4 最新 C 语言程序设计教程6.6.3 函 数 指 针 数 组 和 二 级 函 数 指 针 (243)小结 .(245)习题 6 (246)第 7 章 结构体 .(253)7.1 结 构 体 的 定 义 和 结 构 变 量 的 说 明 (253)7.1.1 结构体的定义 (253)7.1.2 结构变量的定义 (254)7.2 结 构 数 组 和 结 构 指 针 (256)7.2.1 结构数组 (256)7.2.2 结构指针 (258)7.3 结 构 体 的 运 算 (25
22、9)7.3.1 结构体的运算 (259)7.3.2 结构体在函数间的传递 (265)7.3.3 位字段结构体 (267)7.4 类 型 定 义 语 句 typedef (269)7.4.1 用 typedef 语句定义新类型名 .(269)7.4.2 新类型名的应用 (270)7.5 结 构 型 函 数 和 结 构 指 针 型 函 数 (272)7.5.1 结构型函数 (272)7.5.2 结构指针型函数 (272)7.5.3 用结构体处理链表 (273)7.6 枚举类型 (283)7.6.1 枚 举 类 型 的 定 义 和 枚 举 变 量 的 说 明 (283)7.6.2 枚举类型的应用 (
23、285)小结 .(286)习题 7 (287)第 8 章 标准函数 .(296)8.1 文 件 的 存 取 操 作 (296)8.1.1 文件和缓冲型文件系统 (296)8.1.2 打开流文件 (297)8.1.3 流 文 件 的 读 /写 .(300)8.1.4 关闭流文件函数 (301)8.1.5 文件指针 (301)8.1.6 应用举例 (302)8.2 标准函数库 (311)8.2.1 文 件 的 字 符 和 字 符 串 I/O 操作函数 .(311)5目 录8.2.2 文 件 的 格 式 化 I/O 操作函数 .(313)8.2.3 其他标准函数 (314)小结 .(317)习题 8
24、 (317)附录 ASCII 码表 (321)6 最新 C 语言程序设计教程第 1 章 概 论1.1 C 语言的入门知识C 语言和由它发展而来的 C+是 当 今 计 算 机 界 最 流 行 的 两 种 程 序 设 计 语 言 , 是 两 种 重 要 的 编 程 工 具 。 C 语 言 最 初 设 计 时 , 是 作 为 一 种 面 向 系 统 软 件 ( 操 作 系 统 和 语 言 处 理 系 统 ) 的开发语言,是用来代替汇编语言的,但是由于它强大的生命力,后来在事务处理、科学 计算、工业控制和数据库技术等各个方面都得到了广泛应用。即使进入到以计算机网络为 核心的信息时代, C 语言仍然是作
25、为通用的汇编语言使用 , 用以开发软 (件) 、 硬 (件) 结 合的程序,如实时监控程序、系统控制程序和设备驱动程序等。当前作为理工科各类专业 本科生的计算机基础课程“C 语言程序设计”应按照最新的 ANSI( America National Standard Institute, 美国国家标准局) C+标准的基础内核为准则来讲授, 因为该标 准己成为当今世界公认的 C+工 业 标 准 , 重 点 介 绍 C+程 序 设 计 语 言 的 主 要 语 法 和 模 块 结 构 化 基 础 知 识 , 引 导 学 生 自 觉 扬 弃 C 语 言 老 版 本 的 一 些 非 标 准 内 容 , 将
26、 C 语 言 老 版 本 的 程 序快捷地修改成符合最新的 ANSI C+标 准 的 实 用 程 序 。 为 此 , 我 们 首 先 介 绍 一 些 计 算 机 的基础知识,为讲解 C 和 C+做 好 必 要 的 准 备 。1.1.1 计算机中的数据和编码系统人们最习惯和熟悉的计数和运算方式是十进制,即逢十进一。但在计算机内,数是以 电子器件的物理状态来表示的,而这些器件只具有两种不同且又能相互转换的稳定状态, 例如,晶体管的断开(O FF)和接通( ON) ,因而 采用二进制数(1 和 0) 比较方使。1. 数 的 多 项 式 表 示数是表示现实世界中事物的量的基本数学概念,任何数都能用以
27、R 为基数的多项式表 示:NR = Kn Rn + Kn - 1 Rn 1 + . + Ki Ri + . + K1 R+ K0 R0 + K-1 R-1 + . + K-i R-i + . + K-m R-m其中,R 称为基数,表示 R 进 制 。 如 R = 2 为二进制,R = 8 为八进制,R = 10 为十进 制,R = 16 为十六进制等, Ki 为多项式的系数,它的取值范围为 0 ( R - 1) , n 和 m 为军指数,均为正整数。为了简化问题,假定 NR 是一个整数,则上式变为:NR = Kn Rn + Kn - 1 Rn 1 + . + Ki Ri+ . + K1 R+
28、K0 R0 ( 1-1)为适应不同的应用场合,计算机可分别采用二进制、八进制、十进制和十六进制等。为方 使人们的习惯,计算机输入数据或者输出数据均采用十进制。然而计算机内存放数据都采 用二进制,但由于表示同一个数二进制比十进制的位数要长得多,人们在研究计算机原理 时很不方使,因而多采用十六进制,十六进制与二进制之间的转换非常简单,但位数却缩 短了很多。式 1-1 是 表 示 正 整 数 的 一 个 通 用 表 达 式 。2 最新 C 语言程序设计教程为 了 区 别 各 种 进 制 , 对 于 二 进 制 ( Binary, R = 2) , 我 们 把 多 项 式 系 数 Ki 改 为 用Bi
29、nary 的第 1 个字母 Bi 表示,则式 1-1 变 为 :NR = Bn 2n + Bn - 1 2n 1 + . + Bi 2i+ . + B1 2 + B0 B0 ( 1-2)对于十进制(D ecimal,R = 10) ,将多项式系数 Ki 改为用 Decimal 的第 1 个字母Di 表示,则式 1-1 变 为 :NR = Dn 10n + Dn - 1 10n 1 + . + Di 10i+ . + D1 10 + D0 100 ( 1-3)数是客观存在的量的描述,而各种进制是人们计数的一种方法,因此,同一个数可用 不同的进制表示,其数值是相等的。2. 二进制数(1) 二进制数
30、的特点。 十进制数的每个位有 09 十 个不同的数字符 号 (也称为 “数码” ) ,并且 “逢十进一” 。 而二 进制数具有如下两个特点: 其 一 是 具 有 两 个 不 同 的 数 字 符 号 , 即 1 和 0: 其 二 是逢二进一。如图 1.1 所示的二进制数 B 为图 1.1 整数 94 的二进制码 01011110B下标 B 为 Binary 的第 1 个 字 母 , 表 示 二 进 制 数 ,由式 1-2 则 有(并且为了与微型计算机原理保持一致,多项式系数用小写字母 bi 表示) : B = b727 + b626 + b525 + b424 + b323 + b222 + b
31、121 + b020= 027 + 126 + 025 + 124 + 123 + 122 + 121 + 020= 64 + 16 + 8 + 4 + 2 = 94通 常 , 二 进 制 数 也 称 为 二 进 制 码 , 把 每 个 二 进 制 位 叫 做 一 个 bit, 并 用 bx 表 示 , 其 下 标 x( = 0, 1, 2, ., 7) 是 从 右 至 左 的 位 序 号 , 即 b0、 b1、 b2、 b3、 b4、 b5、 b6、 b7 ,它们都只能取两个数字符号 1 和 0。 但 同 一 个 数 字 符 号 在 不 同 的 二 进 制 数 位 上 具 有 不 同 的 数
32、值, 称为该二进制位的权重值 , 如 b0 的权重值为 1、 b1 的权重值为 2、 b2 的权重值为 4、 b3 的权重值为 8、b 4 的权重值为 16、 、 b7 的 权 重 值 为 128 等 , 显 然 , 各 数 位 的 权 重 值是 2 的正次军,军指数就是位序号。这就像用 1 克、2 克、4 克和 8 克的陆码在天平上可以秤质量为 1 克 16 克 的 物 体 , b0 位相当于 1 克 陆 码 , b1 位 相 当 于 2 克 陆 码 , b2 位相当于 4 克陆码。那么,7 克的物体需要加上 1 克、2 克和 4 克的陆码,与此对应就 是 b0、 b1 和 b2 为 1,
33、其 他 二 进 制 位 为 0, 而 12 克的物体要加上 4 克和 8 克 的 陆 码 , 与 此 对应 b2 和 b3 为 1,其他二进制位为 0。(2) 二 翻 十 运 算 。 所 谓 二 翻 十 运 算 就 是 把 二 进 制 数 转 换 成 十 进 制 数 。 对 于 一 个 数 dec,由式 1-2 可 写 成 :dec = bn 2n + bn-1 2n-1 + . + b1 2 + b0 ( 1-4) 式中 bn, bn-1, ., b1, b0 均为二进制数。若二进制数的位数为 m(如 8 位 ), m 个 bits 可 表 示 2m 个 二 进 制 数 , 其 数 值 范
34、围 是 0( 2m 1) ,如 0 ( 28 1) = 255。若表示最大数值 255 的二进制码,其 8 个bits 都是 1, 即 :3 第 1 章 概论8 个 bits1111, 1111 = 28 1一般来说,m 位二进制数所表示的最大数值的二进制码,其 m 个 bits 都是 1, 即 :m 个 bits1111, ., 1111 = 2m 1+ 1 2m 0000, ., 0000溢出位 数 越 多 表 示 数 的 范 围 越 大 。 若 最 大 数 值 再 加 1 则 m 位 都 变 成 0, 并 向 m+1 位 进 位 , 这 种 现象称为“溢出” 。通俗 地说,就是 m 位二
35、进制数己装满了,则溢出一个 2m 数值后, 再 从 零开始计数,该数值就是 m 位 二 进 制 计 数 的 容 量 , 即 可 表 示 二 进 制 数 的 个 数 为 2m 个。(3) 十翻二运算。十翻二运算就是把十进制数转换成二进制数。其方法是:将式 1 -4用 2 除的整 数商(丢掉小数部分保留整数部分的商 ) ,即第 1 次用 2 除 的商 dec/2 = bn2n-1 + bn-12n-2 + .+ b1所得的余数为 dec % 2 = b0第 2 次用 2 除的商dec / 2 = bn 2n-2 + bn-1 2n-1 + .+ b2所得的余数为 dec % 2 = b1 直到求得
36、 bn。例如: 94 / 2 = 47, 94 % 2 = b0 = 0: 47 / 2 = 23, 47 % 2 = b1 = 1: 23 / 2 = 11, 23 % 2 = b2 = 1: 11 / 2 = 5, 11 % 2 = b3 = 1: 5 / 2 = 2,5 % 2 = b4 = 1: 2 / 2 = 1,2 % 2 = b5 = 0: 1 / 2 = 0,1 % 2 = b6 = 1: 0 / 2 = 0,0 % 2 = b7 = 0。 所以有 94 = 0101,1110顺使指出,存放在计算机中的数值都是二进制形式,称为二进制码,即以二进制形式 的数码来表示数值信息。用键
37、盘敲入的十进制数需经十翻二运算转换成二进制数存入计算 机,而计算机内的二进制形式计算结果则需经二翻十运算变成十进制数,输出显示在计算 机的屏幕上,这个过程是由计算机的操作系统自动完成的。3. 十 六 进 制 数) 十 六 进 制 数 的 特 点 。 由 于 二 进 制 数 较 长 , 因 而 阅 读 和 书 写 困 难 , 且 容 易 出 错 。 然 而4 位二进制数可以用一位十六进制数来表示,它们之间具有直接的、惟一的对应关系,如表 1.1 所 示 。 由 此 可 知 , 十 六 进 制 数 具 有 两 个 特 点 :4 最新 C 语言程序设计教程表 1.1 十进制、二进制和十六进制对照表
38、具有 16 个 不 同 的 数 字 符 号 , 除 了 数字 0 9 外,还有 A、B、 C、D、E、F 等 6 个 英 文 字 母 : 逢十六进一。从表 1.1 可 知, 二进制数和十六进制数之间的转换非常简捷方使,即 4 位二进 制数可以用一位十六进制数来表示。 例如: 94 = 0101,1110 = 5E( H)其中,H 是 Hexadecimal( 十 六 进制的)第 1 个字母,在计算机领域中用以 标明十六进制数。) 十 六 进 制 数 转 换 成 十 进 制 数 。 例 如,4 位十六进制数转换为十进制数的转 换公式为例如:dec = hex3 163 + hex2 162 +
39、hex1 16 + hex0 (1-5)80AF(H) = 8 163 + 0 162 + A 16 + F= 32768 + 0 + 160 + 15 = 32943) 十进制数转换成十六进制数。与二进制类似,转换方法是把十进制数不断地用 16 去 除 , 得 到 整 数 商 和 余 数 , 第 1 次 所 得 的 余 数 作 为 最 低 有 效 位 数 值 hex0: 接 着 , 用 所 得 的 整数商除以 16, 所 得 的 余 数 则 为 第 一 位 有 效 位 数 值 hex1, , 直 到 所 得 的 整 数 商 等 于 零为止,得到最高有效位数值 hex3。 例 如 : 3294
40、3 / 16 = 2058, 32943 % 16 = 15 = F(H): 2058 / 16 = 128, 2058 % 16 = 10 = A(H): 128 / 16 = 8, 128 % 16 = 0(H): 8/16 = 0,8 % 16 = 8(H)。需要指出的是,尽管在计算机领域广泛地采用十六进制数来简捷地表示二进制数,但存放 在任何计算机内的数据仍然是二进制数形式。4. 二 进 制 数 的 原 码 、 反 码 和 补 码) 符 号 位 。 以 上 的 整 数 都 是 无 符 号 整 数 , 每 个 位 ( bit) 进 行 加 法 运 算 的 规 则 为 : 0 + 0 =
41、0, 1 + 0 = 1,0 + 1 = 1,1 + 1 = 0( 向高一位进 一) ,1 + 1 + 1(低 一 位的进位)= 1(向高一位进一) 。带 符 号 的 整 数 在 计 算 机 内 如 何 表 示 呢 ? 通 常 取 一 个 二 进 制 数 的 最 高 位 为 符 号 位 , 1 表 示 负 号 , 0 表 示 正 号 。 如 图 1.2 所 示 , 一 个 8bits 二 进 制 数 的 最 高 位 是 b7, 其 后 7 个 bits 是 它 的 数 值 。 如 此 类 推 , 一 个 16bits 二 进 制 数 的 最 高 位 是 b15, 其 后 15bits 是 它
42、的 数 值 。 一 般 地 说 , 一 个 m 个 二 进 制 位 的 数 , 其 最 高 位 是 bm, 其 后 m 个 二 进 制 位 数 是 它 的 数 值 。这 种 表 示 法 称 为 原 码 , 原 码 表 示 法 中 +94 和 -94 的数值位都相同,而符号位不同。原 码表示法简单易懂,但对带符号数的运算却不方使,如一个正整数加上一个负整数,一般5 第 1 章 概论地说, 两异号数相加 (或说两同号数相减) , 就 要做减法。 为了把减法运算转换成加法运算 就引入了反码和补码的概念。图 1.2 94 和 94 的原码表示法 图 1.3 原码和反码之间的关系) 反 码 。 一 个
43、二 进 制 数 逐 位 取 反 , 即 把 0 变成 1, 把 1 变成 0, 所 得 到 的 二 进 制 数 就 是原来二进制数的反码。如一个 8 位二进制数 B,如图 1.3 所 示 , 其 原 码 用 B 原 表 示 , 反 码用 B 反 表 示 。 由 图 1.3 可得原码和反码之间的关系为B 反 = (28 1) - B 原一般地,一个 m 位 二 进 制 数 原 码 和 反 码 之 间 的 关 系 为B 反 = (2m 1) - B 原 ( 1-6) 补码。将反码再加 1 则就得到该二进制数的补码。由式 1-6 可得:B 补 = B 反 + 1 = 2m - B 原 ( 1-7)
44、式 1-7 是 经 过 数 学 严 格 证 明 的 重 要 公 式 。5. 利 用 补 码 将 减 法 运 算 转 换 成 加 法 运 算二进制运算法则规定:一个正整数的补码就是它的原码,一个负整数的补码则为它的 反码加 1 ,并且,把符号位也看成一位二进制数,在进行各种运算(包括变补运算、加法 运算等) 时一起参加运算。 由数学严格证明可知, 按上述二进制运算法则所得的计算结果, 其 最 高 位 仍 然 是 符 号 位 , 不 需 对 它 另 行 处 理 , 计 算 得 1 表 示 结 果 为 负 , 得 0 则表示结果为 正,因此,可以说参加运算的数(称为运算量)都以补码形式表示,所得的结
45、果也是以补 码形式表示的。例如:(-94)补 = (- (94)补 = (-(94)原 )补= (0 1 0 1,1 1 1 0)补 = 1 0 1 0,0 0 1 0即 可 以 把 -94 看成由两部分(负号和绝对值)组成,负号可看成是求该数绝对值补码的运 算符,这种运算称为“变补”运算:由于绝对值肯定是正整数,其补码就是原码。因此, 若二进制数的位数为 m(如 8 位) , m 个 bits 可表示 2m 个二进制数, 其表示的 数 值 范 围 是 -2m-1 2m-1 1,如一个 8 位 二 进 制 数 的 表 示 的 数 值 范 围 为 : -27 27 1 =-128 127。如此类
46、推,一个 16bits 二 进 制 数 的 数 值 范 围 -215 (215 1), 即 -32768 32767。 一般地说,一个 m 个 二 进 制 位 的 数 , 其 数 值 范 围 为 : -2m-1 (2m-1 1)。 这样一来,就可以把减法运算变成加法运算,如一个正整数减去另一个正整数可以看成加上一个负正整数,即 A - B = A + (-B), 由 式 1-7 则有: 溢出A 原 - B 原 = A 原 - (2m B 补 ) = A 原 + B 补 - 2m例 如 : 94 1 = 94 + (-1) = 94 + (-1)补 - 2m6 最新 C 语言程序设计教程18 原
47、 = 0 0 0 1 , 0 0 1 0变反 1 1 1 0 , 1 1 0 1加 1 后 得 (-18)补 = 1 1 1 0 , 1 1 1 0若再变补一次:变反 0 0 0 1 , 0 0 0 1+1 0 0 0 1 , 0 0 1 01 原 = 0 0 0 0 , 0 0 0 194 原 = 0 1 0 1 , 1 1 1 0 变补+ (-1)补 = 1 1 1 1 , 1 1 1 194 1 = 0 1 0 1 , 1 1 0 1 = 93又如:-A + B = (-A) + B,即: 溢 出-A 原 + B 原 = (2m A 补 ) + B 原 = A 补 + B 原 - 2m综
48、上所述, 在一个运算式中每当遇到一次负号, 则把整数运算量的二进制码变补一次。 显 然 , 如 果 将 原 码 变 补 两 次 其 结 果 仍 为 原 码 , 如 一 个 正 整 数 18, 在 它 前 面 加 一 个 负 号 则 变 为 -18, 求 -18 的补码即将 18 的 二 进 制 码 变 反 加 1,即:这 就 相 当 于 : -(-18) = 18, 一 般 来 说 :A - (-B) = A + B因此,把一个带符号整数的符号位也看成一位二进制数,在进行各种运算(包括变补 运算、加法运算等)时一起参加运算,运算结果的符号位不需另行处理,并且可以把减法 运算用加一个补码的加法运
49、算来代替,这与代数学中的“减一个正数等于加一个负数”的 规律是一致的。因此,一个整数运算量每遇到一个负号时就将它的二进制码变补一次,而 实际做的都是加法运算,只要在整数运算量所能表示的数值范围内都会得到正确的结果, 这些运算规则都得到了计算机数学的证明,可放心地使用。这种把减法运算转换成加法运 算的例子在日常生活中是常见的,例如当标准时间是 6 点整而时钟却指在 10 点时,有两种校准办法:一种是把时针从 10 点反时针方向拨回 4 个小时校准到 6 点,这显然是一种减法运算,即 10 4 = 6:另一种是将时针从 10 点顺时针方向拨 8 个小时也同样可以校准到 6 点,这种校准办法是加法运算,即 10 + 8 = 12 + 6。由于钟