当前位置:首页 >> 计算机软件及应用 >>

C语言专升本辅导


C 语言程序设计详解

1

第一章
一、主要知识点 (一 ) 程 序 设 计 语 言 的 发 展 1、 机 器 语 言 设计语言

C 语言程序设计初步

2、 汇 编 语 言

3、 面 向 过 程 的 语 言

4、 面 向 对 象 的 程 序

(二 ) C 程 序 设 计 语 言 的 执 行 过 程 1、 编 辑 2、 编 译 3、 连 接 4、 执 行

(三 ) 用 库 函 数 组 装 C 程 序 例 1 : 计 算 2.1715 的 正 弦 值 。 #inc lude “ ma th.h” main ( { floa t a ; a=sin(2.1715 ); prin tf(“%f\n”,a ); } 详解: 1、 在 本 例 中 用 到 的 sin 函 数 称 为 数 学 函 数 , 它 是 为 了 用 户 使 用 方 便 , 由 一 批厂家开发编写的函数,并不是 C 语言的一部分。在使用数学函数时,往往要 用 到 函 数 执 行 时 所 需 的 一 些 信 息 ( 例 如 宏 定 义 ) 这 些 信 息 包 含 在 “ ma th.h ” 中 。 , 因 此 在 程 序 开 头 用 # inc lude “ ma th.h”将 有 关 的 标 头 文 件 包 括 到 程 序 中 。 2、 一 个 C 语 言 源 程 序 文 件 由 一 个 或 多 个 函 数 组 成 , C 语 言 的 基 本 组 成 单 位 是 函 数 。 一 个 完 整 的 C 语 言 程 序 有 且 只 有 一 个 称 为 主 函 数 的 ma in 函 数 , 程 序 总 是 从 ma in 函 数 开 始 执 行 , 调 用 其 它 函 数 后 再 回 到 ma in 函 数 , 在 main 函 数 中 结 束整个程序的运行。 3、 main 是 函 数 名 称 , 没 有 参 数 可 以 不 写 , 但 圆 括 号 不 能 省 略 , main( ) 后 面 有 一 对 花 括 号 , 花 括 号 内 的 部 分 称 为 函 数 体 , main 函 数 可 以 在 程 序 的 任 意 位 置。 /*定 义 a 为 实 型 变 量 */ /*调 用 sin 函 数 */ /*调 用 printf 函 数 , 输 出 a 的 值 */ )

C 语言程序设计详解

2

4、 C 规 定 每 个 语 句 以 分 号 ( ; 结 束 , 分 号 是 语 句 不 可 缺 少 的 组 成 部 分 , 每 ) 行中可以写多条语句。 5 、 /*与 */ 之 间 为 注 释 信 息 , 对 程 序 运 行 结 果 不 发 生 影 响 , 也 不 被 编 译 , 注 释说明可以放在语句的任意位置。 6、 flo at a; 此 语 句 是 把 a 定 义 为 一 个 实 型 变 量 。 7、 C 语 言 本 身 没 有 输 入 、 输 出 语 句 , 本 例 使 用 prinft 函 数 输 出 数 据 。 prin ft 函 数 的 括 号 内 包 括 两 部 分 内 容 :双 引 号 内 的 部 分 、双 引 号 外 的 部 分 。双 引 号 内 的 部分是“格式字符串” 用于指定输出双引号外的变量的打印格式。此例中双引 , 号 中 有 一 个 ”%f”,它 是 输 出 一 个 保 留 小 数 点 后 6 位 数 字 的 格 式 字 符 ,小 数 点 前 的 位数不指定。 二、练习 (一 ) 选 择 题 1、 以 下 叙 述 正 确 的 是 _C___。 ( A) 在 C 程 序 中 , main 函 数 必 须 位 于 程 序 的 最 前 面 ( B) C 程 序 的 每 行 中 只 能 写 一 条 语 句 ( C) C 语 言 本 身 没 有 输 入 输 出 语 句 ( D) 在 对 一 个 C 程 序 进 行 编 译 的 过 程 中 , 可 发 现 注 释 中 的 拼 写 错 误 2、 C 语 言 规 定 : 在 一 个 源 程 序 中 , main 函 数 的 位 置 ___C_。 ( A) 必 须 在 最 开 始 ( B) 必 须 在 系 统 调 用 库 函 数 的 后 面 ( C) 可 以 任 意 ( D) 必 须 在 最 后 3、 一 个 C 语 言 程 序 是 由 ____B。 ( A) 一 个 主 程 序 和 若 干 子 程 序 组 成 ( B) 函 数 组 成 ( C) 若 干 过 程 组 成 ( D) 若 干 子 程 序 组 成 4、 一 个 C 程 序 的 执 行 是 从 A____。 ( A) 本 程 序 的 ma in 函 数 开 始 , 到 main 函 数 结 束 ( B) 本 程 序 文 件 的 第 一 个 函 数 开 始 , 到 本 程 序 文 件 的 最 后 一 个 函 数 结 束

C 语言程序设计详解
( C) 本 程 序 的 ma in 函 数 开 始 , 到 本 程 序 文 件 的 最 后 一 个 函 数 结 束 ( D) 本 程 序 文 件 的 第 一 个 函 数 开 始 , 到 本 程 序 ma in 函 数 结 束 5、 以 下 叙 述 不 正 确 的 是 __D__。 ( A) 一 个 C 源 程 序 可 由 一 个 或 多 个 函 数 组 成 ( B) 一 个 C 源 程 序 必 须 包 含 一 个 main 函 数 ( C) C 程 序 的 基 本 组 成 单 位 是 函 数 ( D) 在 C 程 序 中 , 注 释 说 明 只 能 位 于 一 条 语 句 后 面 (二 ) 填 空 题 : 1、 一 个 C 源 程 序 中 至 少 包 括 一 个 __ ma in 函 数 ____。

3

2 、 在 一 个 C 源 程 序 中 , 注 释 部 分 两 侧 的 分 界 符 分 别 为 ____/*____ 和 _ */_______ 。

第二章
一、主要知识点 (一 ) C 的 基 本 数 据 类 型 节

数据描述与基本操作

短 整 型 ( short) 整型 整型 长整型 (in t) (long )

基本类型

字 符 型 (cha r)

实 型 ( 浮 点 型 ) 单 精 度 型 (flo at) 枚举类型 数据类型 构造类型 数组类型 结 构 类 型 (struct) 指针类型 空 类 型 (vo id) (二 ) 常 量 和 符 号 常 量 1、 常 量 定 义 : 在 程 序 运 行 过 程 中 , 其 值 不 能 被 改 变 的 量 称 为 常 量 。 常 量 常 区 分 不 同 的 类 型 , 如 1 2、 0、 -3 为 整 型 常 量 , ’a’、 ’D’为 字 符 常 量 。 2、 符 号 常 量 : 用 一 个 标 识 符 代 表 一 个 常 量 的 , 称 为 符 号 常 量 , 即 标 识 符 形 共 用 类 型 (un ion) 文 件 类 型 (FILE ) 双 精 度 型 (do uble )

C 语言程序设计详解

4

式的常量。常量不同于变量,它的值在作用域内不能改变,也不能再被赋值。 例 1: 已 知 商 品 的 单 价 及 数 量 求 商 品 的 总 价 值 。 #define ma in ( { int nu m=10, to ta l; total=nu m*P R ICE; prin tf(“ to tal=%d ”,to ta l); } 输 出 结 果 : tota l=300 详解: 1、 程 序 中 用 #de fine 命 令 行 定 义 P RICE 代 表 常 量 30, 此 后 凡 在 此 文 件 中 出 现 的 P RICE 都 代 表 30, 可 以 和 常 量 一 样 进 行 运 算 。 2、符 号 常 量 不 同 于 变 量 ,它 的 值 在 其 作 用 域 内 不 能 改 变 ,也 不 能 再 被 赋 值 。 如 再 用 以 下 赋 值 语 句 给 P RICE 赋 值 : P RICE=40;是 错 误 的 。 (三 ) 变 量 1、 变 量 定 义 : 其 值 可 以 改 变 的 量 称 为 变 量 。 2、 标 识 符 的 命 名 规 范 和 其 它 高 级 语 言 一 样 ,用 来 标 识 变 量 名 、符 号 常 量 名 、函 数 名 、数 组 名 、类 型名、文件名的有效字符序列称为标识符,C语言中的标识符命名规范为: ① 变 量 名 只 能 由 字 母 、数 字 和 下 划 线 三 种 字 符 组 成 ,且 第 一 个 字 符 必 须 为 字 母或下划线。 ②C 语言中标识符的长度(字符个数)无统一规定,随系统而不同。许多系 统 ( 如 IBM P C 的 MS C) 取 前 7 个 字 符 , 假 如 程 序 中 出 现 的 变 量 名 长 度 大 于 7 个字符,则只有前面 7 个字符有效,后面的不被识别。 ③ C 语 言 有 32 个 关 键 字( 例 如 if、e lse、wh ile)它 们 已 有 专 门 含 义 ,不 应 用 采用与它们同名的变量名。 ④C 语言将大写字母和小写字母认为是两个不同字。 例 2: 在 下 列 符 号 中 , 可 以 选 用 哪 些 作 变 量 名 ? 哪 些 不 可 以 ? a3B 3aB ∏ +a -b *x $ _b 5_ if nex t_ day e _2 O K? ) P RICE 30

C 语言程序设计详解
integer MAXNUMBER a3B i*j n ext_ da y e_2

5

答 案 : _b5_

MAXNUMBER 可 作 变 量 名 , 其 它

的作变量名不可以。 详解: ① MAXNUMBER 可 作 变 量 名 。 习 惯 上 符 号 常 量 名 用 大 写 , 变 量 名 用 小 写 以 示区别,但大写字母作变量名并无错误。 ② if、 in tege r 属 于 保 留 字 , 保 留 字 不 可 作 变 量 名 。 ③∏ +a -b *x $ O K? i*j 不 可 作 变 量 名 ,因 为 变 量 名 只 能 由 字 母 、

数字和下划线三种字符组成。 ④ 3aB 不 可 作 变 量 名 , 因 为 变 量 名 的 第 一 个 字 母 必 须 为 字 母 或 下 划 线 。 (四 ) 整 型 数 据 1、 整 型 常 量 整型常量即整常数。C 语言整常数可用以下三种表示形式。 ① 十 进 制 表 示 。 如 231 、 -56.478 ② 八 进 制 表 示 。 以
8 =1 *8 2

0 开 头 的 数 是 八 进 制 数 。 如

012 3 即 ( 12 3 )

+2 *8 1 +3 *8 0 =64+16+3=83。

③ 十 六 进 制 表 示 。 以 0x 开 头 的 数 是 16 进 制 。 如 0x123 即 ( 123 )
1 6 =1 *16 2

+2 *1 6 1 +3 *16 0 =256+32+3=291。

2、 整 型 变 量 整型变量分为:基本型、短整型、长整型、和无符号型四种。 ① 基 本 型 , 以 in t 表 示 ② 短 整 型 , 以 short in t 表 示 或 以 short 表 示 ③ 长 整 型 , 以 long in t 表 示 , 或 以 long 表 示 ④ 无 符 号 型 ,存 储 单 元 中 全 部 二 进 制 位 (bit)用 作 存 放 数 本 身 ,而 不 包 括 符 号 。 无 符 号 型 中 又 分 为 无 符 号 整 型 、无 符 号 短 整 型 和 无 符 号 长 整 型 ,分 别 以 unsigned int 、 un sign ed sho rt 和 unsigned long 表 示 。 3、 整 型 数 据 的 取 值 范 围 C 标 准 没 有 具 体 规 定 各 类 型 所 占 内 存 字 节 数 ,各 种 机 器 处 理 上 有 所 不 同 ,以 IBM P C 为 例 , 数 的 范 围 如 表 2.1 所 示 。
表 2.1

C 语言程序设计详解
所占位数 Int short[in t] Long [in t] Unsigned [in t] Unsigned short Unsigned long 16 16 32 16 16 32 -32768~ 3276 7 -32768~ 3276 7 数的范围

6
即 -2 1 5 ~ ( 2 1 5 -1) 即 -2 1 5 ~ ( 2 1 5 -1) 即 -2 3 1 ~ ( 2 3 1 -1 ) 即 0~ ( 2 1 6 -1) 即 0~ ( 2 1 6 -1) 即 0~ ( 2 3 2 -1)

-2147483648 ~ 214748 3647 0~ 65535 0~ 65535 0~ 4294967295

4、 整 型 常 量 的 分 类 ① 一 个 整 常 量 ,如 果 其 值 在 -32768 ~ 32767 范 围 内 ,认 为 它 是 in t 型 ,它 可 以 赋 值 给 in t 型 和 long in t 型 变 量 。 ② 一 个 整 常 量 , 如 果 其 值 超 过 了 上 述 范 围 , 而 在 -2147 483648 ~ 2147483647 范 围 内 , 则 认 为 它 是 long in t 型 , 可 以 将 它 赋 值 给 一 个 long in t 型 变 量 。 ③ 如 果 某 一 计 算 机 系 统 的 C 版 本 确 定 的 sho rt in t 与 in t 型 在 内 存 中 占 据 的 长 度 相 同 , 则 一 个 in t 型 的 常 量 出 同 时 一 个 sho rt in t 型 常 量 。 ④ 常 量 中 无 unsigne d 型 。 一 个 非 负 值 的 整 常 量 可 以 赋 值 给 un sig ned 型 整 变 但 量 , 要 它 的 范 围 不 超 过 变 量 的 取 值 范 围 即 可 。 如 : 50000 赋 给 一 个 unsigned 只 例 将 int 型 变 量 是 可 以 的 , 而 将 70000 赋 给 它 是 不 行 的 ( 溢 出 ) 。 ⑤ 在 一 个 整 常 量 后 面 加 一 个 字 母 l 或 L, 则 认 为 是 long in t 型 常 量 。 (五 ) 实 型 数 据 1、 实 型 常 量 实数在 C 语言中又称为浮点数。实数有两种表示形式: ①十进制形式。它由数字和小数点组成(注意必须有小数点) 例如: 。 0.123、 .123、 1 23.0、 0.0 都 是 十 进 制 数 形 式 。 ② 指 数 形 式 。 如 123.56e4 或 123.56E4 都 代 表 123.56 *10 4 。 但 字 母 e ( 或 E ) 之 前 必 须 有 数 字 , e 后 面 指 数 必 须 为 整 数 。 例 如 : e3 、 2.1e 3.5、 .e 3、 e 等 都 不 是 合法的指数形式。 例 3 : 下 面 四 个 选 项 中 , 均 是 不 合 法 的 浮 点 数 的 选 项 是 _____。 ( A) 160. 0. 12 e3 0.0 ( B) 1 23 ( D) -.e3 2e4.2 .234 .e5 1e3

( C) -.18 123 e4

C 语言程序设计详解
答案:B 详解: ① 160. 形式。 ② e3 2e4.2 . e5 0.1 2 -.18 123e4 0.0 .234

7

1 e3 是 实 数 的 十 进 制 形 式 或 指 数

-.e3 不 是 正 确 的 指 数 形 式 。 因 为 正 确 的 字 母 e( 或 E)

之 前 必 须 有 数 字 , e 后 面 指 数 必 须 为 整 数 。 对 于 数 据 表 示 形 式 .e5 以 及 -.e3, e 前 的 .与 -.不 是 有 效 的 数 字 表 示 形 式 。 ③ 123 是 整 数 形 式 。 2、 实 型 变 量 C 实 型 变 量 分 为 单 精 度 ( float 型 ) 和 双 精 度 ( double 型 ) 两 类 。 在 一 般 系 统 中 , 个 单 精 度 型 数 据 在 内 存 中 占 4 个 字 节 32 位 ) 一 个 double 一 ( , 型 数 据 占 8 个 字 节 。 一 个 单 精 度 型 变 量 能 接 收 7 位 有 效 数 字 , 一 个 double 型 变 量 能 接 收 17 位 有 效 数 字 , 数 值 的 范 围 随 机 器 系 统 而 异 。 在 IBM P C 中 , 单 精 度 实 数 的 范 围 约 为 ± 3 .4 E10 - 3 8 ~ 3.4E10 3 8 ) 双 精 度 实 数 的 范 围 约 为 ±(1.7E10 - 3 0 8 ~ ( , 1.710 3 0 8 )。 例 4: main ( ) { floa t a ; a=111111.666666 ; p rintf(“ %f”, a); } 输 出 结 果 : 111111.640621 详解: ① 一 个 实 型 常 量 不 分 floa t 型 和 doub le 型 。 一 个 实 型 常 量 可 以 赋 给 一 个 floa t 型 或 double 型 变 量 。 根 据 变 量 的 类 型 截 取 实 型 常 量 中 相 应 的 有 效 位 数 字 。 ② 由 于 flo at 型 变 量 只 能 接 收 7 位 有 效 数 字 , 因 此 在 把 111111.666666 赋 给 a 时 ,a 只 接 收 了 111111.6,由 于 输 出 函 数 prin tf 中 的 %f 格 式 表 示 输 出 小 数 点 后 的 6 位 小 数 , 所 以 111111.6 后 的 40621 属 于 无 意 义 数 字 。 ③ 如 果 a 改 为 dou ble 型 , 则 能 全 部 接 收 上 述 12 位 数 字 。 (六 ) 字 符 型 数 据

C 语言程序设计详解
1、 字 符 常 量 :

8

①普通形式的字符常量:用引号(即撇号) 括起来的一个字符, 如 ’a’、 ’D’、 ’$’、 ’? ’等 都 是 字 符 常 量 。 ② 转 义 符 : 以 “ \” 开 头 的 字 符 序 列 。 常 用 的 以 “ \” 开 头 的 特 殊 字 符 见 表 2.2
表 2.2

字符形式 \n \t \v \b \r \f \\ \’ \ddd \xhh

功能 换行 横向跳格 竖向跳格 退格 回车 走纸换页 反斜杠字符 单引号字符 1 到 3 位 8 进进制所代表的字符 1 到 2 位 16 进 制 数 所 代 表 的 字 符

例 5 : 若 有 说 明 语 句 : char c=’\729 ’;则 变 量 c _____。 ( A) 包 含 1 个 字 符 ( C) 包 含 3 个 字 符 答案:D 详 解 : ”\”后 可 以 有 1 到 3 位 8 进 制 所 代 表 的 字 符 , 本 题 中 ” \”后 的 ”72”属 于 8 进 制 所 代 表 的 字 符 , 而 ”9”则 不 属 于 8 进 制 位 所 代 表 的 字 符 , 则 ’\729’中 包 含 了 两 个 字 符 常 量 ’\72 ’和 ’9’。 而 字 符 常 量 是 用 引 号 ( 即 撇 号 ) 括 起 来 的 一 个 字 符 , 所 以 答 案 为 D。 2、 字 符 变 量 字符变量是用来存放字符常量的存储单元。 3、 字 符 数 据 在 内 存 中 的 存 储 形 式 将一个字符常量存放到一个字符变量中, 际上并不是把该字符本身存放到 实 内 存 单 元 中 去 , 而 是 将 该 字 符 的 相 应 的 AS CII 码 值 存 放 到 存 储 单 元 中 去 。 例 6: 将 小 写 字 母 转 换 成 大 写 字 母 ( B) 包 含 2 个 字 符 ( D) 说 明 不 合 法

C 语言程序设计详解
main ( ) { char c1=’a ’; c1=c1 -32 ; printf(“%c”, c1); } 输出结果:A 详解: ① ’a’的 ASCII 码 为 97 , 所 以 c1=’a ’;语 句 的 功 能 是 把 97 赋 值 给 了 c1。 ② c1=c1 -32 ;语 句 的 功 能 是 把 97 -32 的 值 65 赋 值 给 c1。

9

③ prin tf 函 数 中 的 %c 格 式 表 示 以 字 符 方 式 输 出 。 ASCII 码 值 为 65 的 字 符 为 A, 所以运行结果为:A (七 ) 字 符 串 常 量 字 符 常 量 是 用 一 对 双 引 号 括 起 来 的 零 个 或 多 个 字 符 序 列 。 C 规 定 以 字 符 ’\0’ 作 为 字 符 串 结 束 标 志 。 所 以 字 符 串 ”a ”实 际 上 包 含 2 个 字 符 : ’a’、 ’\0 ’, 因 此 下 面的语句: c=”a”; 把一个串赋值给一个字符变量 c 是错误的。 例 7 : 下 面 不 正 确 的 字 符 串 常 量 是 ______ 。 ( A) ’abc’ 答案:A 详 解 : ’abc’是 用 单 引 号 引 来 的 , 所 以 ’abc ’不 是 正 确 的 字 符 串 常 量 。 (八 ) 算 术 运 算 符 和 算 术 表 达 式 1、 基 本 算 术 运 算 符 ①C 语言中有 5 个基本算术运算符: + ( 加 法 运 算 符 。 如 3 +5、 +3) - ( 减 法 运 算 符 。 如 5 -2、 -3 ) * ( 乘 法 运 算 符 , 如 3 *5) / ( 除 法 运 算 符 , 如 5 /3, 5.0 /3) % ( 求 余 运 算 符 , 要 求 %两 侧 均 为 整 型 数 据 ) 例 8 : 在 C 语 言 中 , 要 求 运 算 数 必 须 是 整 型 的 运 算 符 是 ____ 。 ( B) ” 12’12” ( C) ”0” ( D) ” ”

C 语言程序设计详解
( A) / 答案:D ( B) ++ ( C) = ! ( D) %

10

详 解 : 对 于 %运 算 符 来 说 , 要 求 两 侧 均 为 整 型 数 据 , 所 以 表 达 式 3.5%2 与 3%2.0 是 错 误 的 。 例 9: 写 出 下 列 程 序 的 输 出 结 果 main ( ) { prin tf(“%d ,%d \n”,5 /3,5 %3); prin tf(“%d ,%d \n”, -5/-3 , -5%-3); prin tf(“%d ,%d \n”, -5/3 , -5%3); prin tf(“%d ,%d \n”,5 /-3 , 5%-3); } 输出结果: 1, 2 1, -2 -1, -2 -1, 2 详 解 : 两 个 同 号 整 数 相 除 时 结 果 为 正 整 数 , 如 5/3、 -5 /-3 的 结 果 值 为 1。 两 个 异 号 整 数 相 除 时 结 果 为 负 整 数 , 多 数 机 器 采 取 “ 向 零 取 整 ” 法 , 即 -5 /-3= -1, 5/-3= -1 , 但 如 果 参 加 运 算 的 两 个 数 中 有 一 个 数 为 实 数 时 结 果 为 实 数 。 对 于 求 余 ( %) 运 算 , 运 算 结 果 与 第 一 个 数 的 符 号 相 同 。 ② 优 先 级 别 : 先 *、 /、 %后 +、 - ③运算量:双元运算量,%前后必须为整数。 ④左右结合性:自左至右参预运算。 2、 自 加 自 减 运 算 符 ①C 语言中有 4 种形式的自加自减运算符: ++i i+ + --i i- - (先 使 i 加 1 后 使 用 ) (先 使 用 后 使 i 加 1) (先 使 i 减 1 后 使 用 ) (先 使 用 后 使 i 减 1)

C 语言程序设计详解
②优先级别:高于算术运算。

11

例 10 : 若 x 和 n 均 是 int 型 变 量 , 且 x 和 n 的 初 值 均 为 5, 则 计 算 表 达 式 后 x 的 值 为 ______, n 的 值 为 ______。 x+=n++ 答 案 : 10 6

详 解 : 根 据 优 先 级 别 选 运 算 表 达 式 n++, 因 为 n++是 后 缀 表 示 形 式 , 所 以 n 先 参 预 运 算 , 再 运 算 表 达 式 x+=n, 则 x 为 10, 最 后 n 自 加 为 6。 例 11 : main ( { int x, y, m,n ; x=2;y=2 m=x++ *5; n=++y*5 ; prin tf(“%d ,%d,%d ,%d” ,x, y, m,n); } 输 出 结 果 : 3,3,10,15 详 解 : 对 于 后 缀 来 说 是 先 使 用 后 运 算 , 所 以 m 的 值 为 x 在 自 加 以 前 的 2 *5 得 10 赋 值 给 m 后 , x 自 加 变 为 3。 对 于 前 缀 来 说 是 先 运 算 后 使 用 , 所 以 m 的 值 为 x 在 自 加 以 后 的 3 *5 得 15 赋 值 给 n。 ③ 运 算 量 : 单 元 运 算 量 , 此 运 算 量 必 须 为 变 量 , 所 以 表 达 式 5+ + 、 (x+ y)++ 是错误的。 ④左右结合性:自右至左参预运算。 (九 ) 关 系 运 算 1、 C 语 言 提 供 的 关 系 运 算 符 有 : >( 大 于 ) <=( 小 于 或 等 于 ) >=( 大 于 或 等 于 ) ==( 等 于 ) 是 <( 小 于 ) !=( 不 等 于 ) )

2、 优 先 级 别 : 关 系 运 算 符 的 优 先 级 别 低 于 纯 算 术 类 , 高 于 赋 值 类 。 后 两 个 的 优 先 级 小 于 前 四 个 。 如 表 达 式 a+b<c+d 完 全 等 价 于 表 达 式 (a+ b)<(c+d)。 3、运 算 量 :关 系 运 算 符 是 双 元 运 算 符 ,整 型 、实 型 、字 符 都 可 以 参 预 运 算 。

C 语言程序设计详解
4、 左 右 结 合 性 : 从 左 向 右 的 结 合 方 向 5、 关 于 关 系 运 算 符 的 进 一 步 说 明 :

12

① 关 系 表 达 式 的 值 是 整 型 数 0 或 1 ,故 也 可 以 将 其 看 成 一 种 整 型 表 达 式 。 如 : 例 int i=1, j=7,a ; a=i+(j%4!=0); 的 执 行 结 果 为 : a 的 值 为 2。 ② 要 说 明 x 在 区 间 [a,b ]中 , 普 通 数 学 中 使 用 表 达 式 a≤ x≥ b。 但 C 语 言 中 应 写 成 a<=x&&x<=b。 ③ 表 达 式 5>2>7>8 在 数 学 上 是 不 允 许 的 ,而 在 C 中 是 允 许 的 。按 自 左 至 右 求 解。 ④ 字 符 数 据 的 比 较 按 其 ASCII 码 值 进 行 。 ⑤在判定两个浮点数是否相等时,由于存储上的误差,会得出错误的结果。 例如: 1.0/3.0 *3.0==1.0 该 表 达 式 的 值 为 0。 (十 ) 逻 辑 运 算 1、 C 语 言 提 供 的 逻 辑 运 算 符 : &&( 逻 辑 与 ) ||( 逻 辑 或 ) !( 逻 辑 非 )

2 、 优 先 级 别 : &&与 || 的 优 先 级 别 低 于 关 系 运 算 符 , 高 于 条 件 运 算 符 , && 的 优 先 级 别 高 于 ||, 的 优 先 级 别 与 自 加 运 算 符 ( ++) 自 减 运 算 符 ( --) 同 级 。 ! 、 3、 运 算 量 : &&和 ||是 双 元 运 算 符 , 是 单 元 运 算 符 。 ! 例 12 :已 知 x=43,ch=’A’, y=0 ;则 表 达( x>= y&&ch<’B’&&!y)的 值 是 ______。 ( A) 0 答案:C , 详解:C 语言不提供逻辑性数据“真”和“假” 在进行逻辑运算时,结果 不 是 1 就 是 0。 4、左 右 结 合 性 :&&和 ||运 算 符 的 结 合 方 向 为 自 左 至 右 , !的 结 合 方 向 为 自 右 至左。 5、 关 于 逻 辑 运 算 符 的 进 一 步 说 明 : ① 在 一 个 &&表 达 式 中 , 若 &&的 一 端 为 0,则 不 必 再 计 算 另 一 端 , 该 表 达 式 的 ( B) 语 法 错 ( C) 1 ( D) 真 ” “

C 语言程序设计详解
值 肯 定 为 0。

13

② 在 一 个 ||表 达 式 中 , 若 ||的 一 端 为 0,则 不 必 再 计 算 另 一 端 ,该 表 达 式 的 值 肯 定 为 1。 例 13 : 写 出 下 面 程 序 的 输 出 结 果 。 ma in ( ) { int x, y, z; x= y=z=0; ++x&&++ y||++z ; p rintf(“ %d,%d, %d” ,x, y,z ); x= y=z=0; ++x ||++ y&&++z; p rintf(“ %d,%d, %d” ,x, y,z ); } 输出结果: 1, 1, 0 1, 0, 0 详解: ① 因 为 &&的 优 先 级 别 高 于 ||, 所 以 表 达 式 ++x&&++ y||++z 是 一 个 或 表 达 式 , 根 据 ||的 一 端 为 0,则 不 必 再 计 算 另 一 端 的 原 则 , 先 计 算 表 达 式 ++x &&++ y 的 值 为 1,因 为 1 或 任 何 值 都 为 1, 所 以 表 达 式 ++z 没 有 运 算 , 输 出 结 果 为 : 1, 1, 0。 ② 表 达 式 ++x ||++ y&&+ +z 也 是 一 个 或 表 达 式 , 同 样 根 据 ||的 一 端 为 0,则 不 必 再 计 算 另 一 端 的 原 则 , 先 计 算 表 达 式 ++z 的 值 为 1, 因 为 1 或 任 何 值 都 为 1,所 以 表 达 式 ++ y&&++z 没 有 运 算 , 输 出 结 果 为 : 1, 0, 0。 (十 一 ) 赋 值 运 算 1、 基 本 的 赋 值 运 算 符 : =( 将 赋 值 运 算 符 右 侧 的 表 达 式 赋 给 左 侧 的 变 量 ) 2、 自 反 算 术 赋 值 运 算 符 C 语言中有 5 个基本自反算术赋值运算符: + =( a+ =3 等 价 于 a=a+ 3)

C 语言程序设计详解
- =( a- =3 * =( a* =3 / =( a* =3 % =( a% =3 等 价 于 a=a- 3) 等 价 于 a=a* 3) 等 价 于 a=a* 3) 等 价 于 a=a% 3)

14

3、 优 先 级 别 : 赋 值 运 算 符 与 自 反 算 术 赋 值 运 算 符 属 于 同 等 级 别 , 低 于 条 件 运 算 符 , 高 于 逗 号 运 算 符 。 如 对 于 表 达 式 x %= y+3 完 全 等 价 于 x%=(y+3)。 例 14 : 若 有 以 下 定 义 , 则 能 使 值 为 3 的 表 达 式 是 ______。 Int k=7,x=12; ( A) x%=(k%5) ( C) x%=k -k%5 答案:D 详 解 : 表 达 式 (x%=k)-(k%=5)完 全 等 价 于 (x=x %k)-(k=k%5)等 价 于 5 -2, 此 表 达 式 的 结 果 为 3。 4、 运 算 量 : 双 元 运 算 量 , 赋 值 运 算 符 与 自 反 算 术 赋 值 运 算 的 第 一 个 量 必 须 为 变 量 , 且 % =前 后 必 须 为 整 型 数 据 。 如 对 于 表 达 式 a *3+=2 是 错 误 的 。 因 为 此 表 达 式 完 全 等 价 于 (a *3 )=(a *3)+2。 5、 左 右 结 合 性 : 自 右 至 左 参 预 运 算 。 若 且 则 例 15 : a 是 int 型 变 量 , a 的 初 值 为 6 , 计 算 表 达 式 后 a 的 值 为 ______。 a+=a-=a *a 答 案 : -60 详 解 : 表 达 式 从 左 向 右 运 算 , 先 计 算 表 达 式 a=a -36 后 a 为 -30 , 再 计 算 表 达 式 a=a+a 后 a 的 值 变 为 -60。 (十 二 ) 条 件 运 算 : 1、 条 件 运 算 符 的 基 本 形 式 及 功 能 : 条件运算是一种在两个表达式的值中选择一个的操作。它的一般形式为: e1? e2:e3 它 的 操 作 过 程 为 , 若 e 1 为 真 , 则 表 达 式 的 值 为 e2,若 为 假 表 达 式 的 值 为 e3。 2、 优 先 级 别 : 低 于 逻 辑 运 算 , 高 于 赋 值 运 算 。 3、 运 算 量 : 三 元 运 算 量 , e1 一 般 为 算 术 表 达 式 , e2、 e3 可 以 是 任 意 类 型 的 表 达 式 , 条 件 表 达 式 的 值 的 类 型 为 e2 与 e 3 二 者 中 类 型 较 高 的 。 ( B) x%= (k -k%5 ) ( D) (x%=k)-(k %=5)

C 语言程序设计详解

15

例 16 : 若 有 条 件 表 达 式 ( exp) ? a++:b--,则 以 下 表 达 式 中 能 完 全 等 价 于 表 达 式 ( exp) 的 是 ___ ___ 。 答 案 : exp!=0 详 解 : 对 于 表 达 式 e1? e2:e3 , e 1 一 般 为 算 术 表 达 式 、 逻 辑 表 达 式 、 关 系 表 达 式 , 结 果 为 1( 真 ) 或 0( 假 ) 也 可 以 为 数 值 exp, 结 果 为 结 果 为 非 0( 真 ) 。 或 0( 假 ) 在 本 例 中 与 exp 完 全 等 价 的 表 达 式 是 exp!=0。 4、 左 右 结 合 性 : 自 右 至 左 运 算 。 例 17 : 以 下 程 序 的 运 行 结 果 是 _____ _ 。 ma in() { int k=4,a=3,b=2,c=1 ; printf(“%d”,k< a? k:c<b? c:a); } 答案:1 详 解 : 条 件 表 达 式 是 从 右 向 左 运 算 , 所 以 在 本 例 中 先 计 算 表 达 式 c<b? c:a 的 值 , 把 各 数 值 代 入 此 表 达 式 的 值 为 1。 再 计 算 表 达 式 k<a? k:1 的 值 , 因 为 k<a 为 假 , 所 以 整 个 表 达 式 的 值 为 1。 (十 三 ) 逗 号 运 算 1、 逗 号 运 算 符 的 基 本 形 式 及 功 能 : 逗 号 表 达 式 的 一 般 形 式 为 : 表 达 式 1, 表 达 式 2。 逗 号 表 达 式 的 求 解 过 程 是 : 先 求 解 表 达 式 1, 再 求 解 表 达 式 2。 整 个 表 达 式 的 值 是 表 达 式 2 的 值 。 2、 优 先 级 别 : 逗 号 运 算 符 是 所 有 运 算 符 中 级 别 最 低 的 。 例 18 : 以 下 符 合 C 语 言 语 法 的 赋 值 表 达 式 是 ______。 ( A) d=9+e+f=d+9 ( C) d=9+e,e++,d+9 答案:B 解 析 : 表 达 式 d=9+e+f=d+9 中 9+e+f=d+9 是 不 正 确 的 表 示 形 式 , 因 为 赋 值 号 ( =) 左 边 不 能 是 表 达 式 。 表 达 式 d=9+e,e ++,d+9 是 逗 号 表 达 式 , 因 为 赋 值 运 算 符 ( =) 的 优 先 级 别 高 于 逗 号 运 算 符 ( , 。 表 达 式 d=9+e++=d+7 中 9+e++=d+7 ) 是 不 正 确 的 表 达 式 , 因 为 赋 值 号 ( =) 左 边 不 能 是 表 达 式 。 ( B) d=( 9+e,f=d+9) ( D) d=9+e++=d+7

C 语言程序设计详解
3、 运 算 量 : 二 元 运 算 量 。 4、 左 右 结 合 性 : 从 左 向 右 运 算 。

16

例 19 : 假 设 所 有 变 量 均 为 整 型 , 则 表 达 式 a=2,b=5,b++,a+b 的 值 是 ______。 答案:8 根 首 解 析 : 据 逗 号 运 算 符 从 左 向 右 运 算 的 原 则 , 先 把 2 和 5 分 别 赋 值 给 了 a ,b。 再 计 算 表 达 式 b++,b 变 为 6,再 计 算 表 达 式 a +b 的 值 ,最 后 整 个 表 达 式 的 值 是 8。 (十 四 ) 强 制 类 型 转 换 1、 强 制 类 型 一 般 形 式 及 功 能 : 可以利用强制类型转换运算符将一个表达式转换成所需类型。 如: 例 (doub le) a( 将 a 转 换 成 d ouble 类 型 ) 其 一 般 形 式 为 : (类 型 名 )(表 达 式 ) 2、 优 先 级 别 : 强 制 类 型 转 换 运 算 符 与 逻 辑 非 ( ! 、 自 加 ( ++) 自 减 ( --) ) 、 属于同等级别,高于算术运算符。 3、 运 算 量 : 单 元 运 算 量 4、 关 于 强 制 类 型 转 换 运 算 符 的 进 一 步 说 明 : ① 强 制 转 换 表 达 式 时 , 表 达 式 应 该 用 括 号 括 起 来 。 如 果 写 成 (int )x+ y 则 只 将 x 转换成整型,然后与 y 相加。 ② 如 果 x 原 指 定 为 floa t 型 , 行 强 制 类 型 运 算 后 得 到 一 个 in t 型 的 中 间 变 量 , 进 它 的 值 等 于 x 的 整 数 部 分 ( 截 去 小 数 部 分 ) 而 x 的 类 型 不 变 ( 仍 为 floa t 型 ) , 。 例 20: main ( ) { floa t x=3.6 ; int i; i=(in t)x prin tf(“x=%f,i=%d” , x,i); } 输 出 结 果 : x=3.600000, I=3 解 析 : 变 量 x 进 行 强 制 类 型 运 算 后 , 其 类 型 仍 为 floa t 型 , 值 仍 为 3.6。 ( 十 五 ) printf 函 数

C 语言程序设计详解
prin tf 函 数 可 以 输 出 任 意 类 型 的 多 个 数 据 。 1、 printf 函 数 的 一 般 格 式 prin tf(格 式 控 制 ,输 出 表 列 )

17

①“格式控制”是用双引号括起来的字符串,也称“转换控制字符串” 它 , 包 括 两 种 信 息 : 格 式 说 明 和 普 通 字 符 。 格 式 说 明 是 由 “ %” 和 格 式 字 符 组 成 , 如 %d,%f 等 。 它 的 作 用 是 将 输 出 的 数 据 转 换 为 指 定 的 格 式 输 出 。 格 式 说 明 总 是 由 ”%”字 符 开 始 的 。 普 通 字 符 即 需 要 原 样 输 出 的 字 符 。 ② 输 出 表 列 是 指 需 要 输 出 的 一 些 数 据 ,可 以 是 表 达 式 ,它 们 之 间 用“ ,”隔 开 。 2、 格 式 控 制 的 完 整 格 式 : % 0 m.n l或 h 格式字符

下面对组成格式说明的各项加以说明: ① %: 表 示 格 式 说 明 的 起 始 符 号 , 不 可 缺 少 。 ② -: 有 -表 示 左 对 齐 输 出 , 如 省 略 表 示 右 对 齐 输 出 。 ③ 0: 有 0 表 示 指 定 空 位 填 0,如 省 略 表 示 指 定 空 位 不 填 。 ④ m.n: m 指 域 宽 , 即 对 应 的 输 出 项 在 输 出 设 备 上 所 占 的 字 符 数 。 N 指 精 度 。 用 于 说 明 输 出 的 实 型 数 的 小 数 位 数 。 为 指 定 n 时 , 隐 含 的 精 度 为 n=6 位 。 ⑤ l 或 h:l 对 整 型 指 lo ng 型 , 对 实 型 指 doub le 型 。 h 用 于 将 整 型 的 格 式 字 符 修 正 为 sho rt 型 。 3、 格 式 字 符 : 格式字符用以指定输出项的数据类型和输出格式。 ①d 格式:用来输出十进制整数。有以下几种用法: %d: 按 整 型 数 据 的 实 际 长 度 输 出 。 %md:m 为 指 定 的 输 出 字 段 的 宽 度 。如 果 数 据 的 位 数 小 于 m,则 左 端 补 以 空 格 , 若 大 于 m, 则 按 实 际 位 数 输 出 。 %ld: 输 出 长 整 型 数 据 。 ② o 格 式 :以 无 符 号 八 进 制 形 式 输 出 整 数 。对 长 整 型 可 以 用“ %lo”格 式 输 出 。 同 样 也 可 以 指 定 字 段 宽 度 用 “ %mo ” 格 式 输 出 。 例 21 : ma in() { int a= -1 ;

C 语言程序设计详解
p rin tf(“%d,%o”, a,a); } 运 行 结 果 : -1,17777 7

18

程 序 解 析 : -1 在 内 存 单 元 中( 以 补 码 形 式 存 放 )为 (1111111111111111) 2 ,转 换 为 八 进 制 数 为 (1777 77) 8 。 ③ x 格 式 :以 无 符 号 十 六 进 制 形 式 输 出 整 数 。对 长 整 型 可 以 用“ %lx”格 式 输 出 。 同 样 也 可 以 指 定 字 段 宽 度 用 “ %mx” 格 式 输 出 。 ④ u 格 式 :以 无 符 号 十 进 制 形 式 输 出 整 数 。对 长 整 型 可 以 用“ %lu”格 式 输 出 。 同 样 也 可 以 指 定 字 段 宽 度 用 “ %mu ” 格 式 输 出 。 ⑤c 格式:输出一个字符。 ⑥s 格式:用来输出一个串。有几中用法 %s:例 如 :p rin tf(“%s”, ”CHINA”)输 出“ CH IN A”字 符 串( 不 包 括 双 引 号 ) 。 %ms: 输 出 的 字 符 串 占 m 列 , 如 字 符 串 本 身 长 度 大 于 m, 则 突 破 获 m 的 限 制 ,将 字 符 串 全 部 输 出 。 若 串 长 小 于 m, 则 左 补 空 格 。 %-ms: 如 果 串 长 小 于 m, 则 在 m 列 范 围 内 , 字 符 串 向 左 靠 , 右 补 空 格 。 %m.ns:输 出 占 m 列 ,但 只 取 字 符 串 中 左 端 n 个 字 符 。这 n 个 字 符 输 出 在 m 列的右侧,左补空格。 %-m.n s: 其 中 m、 n 含 义 同 上 , n 个 字 符 输 出 在 m 列 范 围 的 左 侧 , 右 补 空 格 。 如 果 n> m, 则 自 动 取 n 值 , 即 保 证 n 个 字 符 正 常 输 出 。 ⑦ f 格 式 :用 来 输 出 实 数( 包 括 单 、双 精 度 ) 以 小 数 形 式 输 出 。有 以 下 几 种 , 用法: %f: 不 指 定 宽 度 , 整 数 部 分 全 部 输 出 并 输 出 6 位 小 数 。 %m.nf: 输 出 共 占 m 列 , 其 中 有 n 位 小 数 , 如 数 值 宽 度 小 于 m 左 端 补 空 格。 %-m. nf: 输 出 共 占 n 列 , 其 中 有 n 位 小 数 , 如 数 值 宽 度 小 于 m 右 端 补 空 格。 ⑧e 格式:以指数形式输出实数。可用以下形式: %e: 数 字 部 分 ( 又 称 尾 数 ) 输 出 6 位 小 数 , 指 数 部 分 占 5 位 或 4 位 。 %m.ne 和 %-m.ne:m、n 和 ” -”字 符 含 义 与 前 相 同 。此 处 n 指 数 据 的 数 字 部 分的小数位数,m 表示整个输出数据所占的宽度。

C 语言程序设计详解

19

⑨ g 格 式 :自 动 选 f 格 式 或 e 格 式 中 较 短 的 一 种 输 出 ,且 不 输 出 无 意 义 的 零 。 4、 关 于 prin tf 函 数 的 进 一 步 说 明 : 如 果 想 输 出 字 符 “ %” ,则 应 该 在 “ 格 式 控 制 ” 字 符 串 中 用 连 续 两 个 %表 示 , 如: prin tf(“%f%%” ,1.0 /3); 输 出 0.333333%。 ( 十 六 ) scanf 函 数 scan f 函 数 可 以 用 来 输 入 任 何 类 型 的 多 个 数 据 。 1、 scan f 函 数 的 一 般 格 式 scanf(格 式 控 制 ,地 址 表 列 ) ① “ 格 式 控 制 ” 的 含 义 同 printf 函 数 。 普 通 字 符 即 需 要 原 样 输 入 的 字 符 。 ② 地 址 表 列 是 指 由 若 干 个 地 址 组 成 的 表 列 , 它 们 之 间 用 “ ,” 隔 开 。 2、 格 式 控 制 的 完 整 格 式 : % * m l或 h 格式字符

① 格 式 字 符 与 p rin tf 函 数 中 的 使 用 方 式 相 同 , %d、 以 %o、 %x、 、 %c %s、 %f、 %e, 无 %u 格 式 、 %g 格 式 。 ②可以指定输入数据所占列宽,系统自动按它截取所需数据。如: scanf(“%3d %3d”, &a,&b); 输 入 : 123456 系 统 自 动 将 123 赋 给 a ,456 赋 给 b。 ③ %后 的 “ *” 附 加 说 明 符 , 用 来 表 示 跳 过 它 相 应 的 数 据 。 例 如 : scanf(“%2d %*3d%2d” , &a,&b ); 如 果 输 入 如 下 信 息 : 1 234567。 将 1 2 赋 给 a , 67 赋 给 b。 第 二 个 数 据 ”345”被 跳 过不赋给任何变量。 ④输入数据时不能规定精度,例如: scanf(“%7. 2f”, &a ); 是 不 合 法 的 , 不 能 企 图 输 入 : 12345.6 7 而 使 a 的 值 为 12345 .67 。 3、 输 入 数 据 流 分 隔 ① 根 据 格 式 字 符 的 含 义 从 输 入 流 中 取 得 数 据 ,当 输 入 流 中 数 据 类 型 与 格 式 字 符要求不符时,就认为这一项结束。如:

C 语言程序设计详解
scanf(“%d %c%f”,&a ,&b,&c); 如果输入如下信息: 1234r1234.5 67

20

则 scan f 函 数 在 接 收 数 据 时 发 现 ”r”类 型 不 匹 配 ,于 是 把 ” 1234”转 换 成 整 型 赋 值 给 a, 把 ” r”赋 给 变 量 b, 最 后 把 ”123 4.56 7”转 换 成 实 型 数 据 赋 给 c。 ② 根 据 格 式 项 中 指 定 的 域 宽 分 隔 出 数 据 项 。 如 语 句 : scanf(“%2d %3f%4 f”, &a,&b, &c); 如果输入如下信息: 123456789012345 则 scan f 函 数 在 接 收 数 据 时 根 据 域 宽 把 1 2 赋 值 给 a,345 赋 值 给 b,6789 赋 值 给 c。 ③ 隐 示 分 隔 符 。 空 格 、 跳 格 符 ( ’\t’) 换 行 符 ( ’\n’) 都 是 C 语 言 认 定 的 数 、 据分隔符。 ④ 显 示 分 隔 符 。 在 sca nf 函 数 的 两 个 格 式 说 明 项 间 有 一 个 或 多 个 普 通 字 符 , 那么在输入数据时,在两个数据之间也必须以这一个或多个字符分隔。如语句: scanf(“a=%d,b=%f,c= %f”, &a,&b ,&c ); 则输入数据应该为: a=1234 ,b=67.8,c=9 8.123 4、 关 于 scan f 函 数 的 进 一 步 说 明 : ① scanf 函 数 中 的 “ 格 式 控 制 ” 后 面 应 当 是 变 量 地 址 , 而 不 应 是 变 量 名 。 例 如 , 如 果 a、 b 为 整 型 变 量 , 则 scanf(“%d, %d”,a ,b); 是 不 对 的 , 应 将 ” a, b ”改 为 ”&a ,&b”。 ② 如 果 在“ 格 式 控 制 ”字 符 串 中 除 了 格 式 说 明 以 外 还 有 其 它 字 符 ,则 在 输 入 数据时应输入与这些字符相同的字符。例如: scanf(“%d, %d”, &a,&b); 输 入 时 应 输 入 : 3, 4 。 3 与 4 之 间 的 逗 号 应 与 scanf 函 数 中 的 “ 格 式 控 制 ” 中 的 逗号相对应,输入其它符号是不对的。 ③ 在 用 “ %c” 格 式 输 入 字 符 时 , 空 格 字 符 和 转 义 字 符 都 作 为 有 效 字 符 输 入 。 scanf(“%c %c%c” ,&c1, &c2,&c 3);

C 语言程序设计详解

21

如 输 入 : a b c 。 字 符 ’a’赋 给 c1,字 符 ( 空 格 ) ’ ’赋 给 c 2,字 符 ’b’ 赋 给 c3。 5、 scan f 的 停 止 与 返 回 ① 格 式 参 数 中 的 格 式 项 用 法 ----正 常 结 束 。 ② 发 生 格 式 项 与 输 入 域 不 匹 配 时 ----不 正 常 退 出 : ( 十 七 ) getchar 、 putch ar 函 数 1、 getch ar 函 数 getcha r 函 数 是 从 终 端 输 入 一 个 字 符 。 ge tch a r 函 数 没 有 参 数 , 其 一 般 形 式 为 :ge tcha r( )。 2、 putch ar 函 数 putcha r 函 数 的 作 用 是 向 终 端 输 出 一 个 字 符 。 二、练习 (一)选择题 1、 下 面 四 个 选 项 中 , 均 是 不 合 法 的 用 户 标 识 符 的 选 项 是 ____ 。 ( A) A ( C) b -a P _0 goto do in t ( B) float ( D) _123 la0 te mp _a INT

2、 若 x, i, j 和 k 都 是 int 型 变 量 , 则 计 算 下 面 表 达 式 后 , x 的 值 为 ______。 x=(i=4, j=16,k=32) ( A) 4 ( B) 16 ( C) 32 ( D) 52

3、 下 列 四 个 选 项 中 , 均 是 不 合 法 的 整 型 常 量 的 选 项 是 ______ 。 ( A) --0f1 ( B) -0xcdf ( C) -018 ( D) -0 x48eg -0x ffff 017 999 -06 8 0011 12 ,3456 5e2 03 f

4、 下 面 四 个 选 项 中 , 均 是 合 法 浮 点 数 的 选 项 是 ______。 ( A) 1e1 ( B) -.60 ( C) 123e ( D) -e3 5e -9.4 12e -4 1.2e -.4 .8e -4 03e2 -8 e5 2e -1 5.e -0

5、 下 面 四 个 选 项 中 , 均 是 合 法 字 符 的 选 项 是 ______。 ( A) ’\’’ ‘\\’ ‘\xf ’ ( B) ’\’ ‘\017’ ‘\n’

C 语言程序设计详解
( C) ’\018’ ‘\f ’ ‘x ab’( D) ’\0’ ‘\101’ ‘x lf ’

22

6、 以 下 不 正 确 的 叙 述 是 ______。 ( A) 在 C 程 序 中 , 逗 号 运 算 符 的 优 先 级 最 低 。 ( B) 在 C 程 序 中 , AP H 和 aph 是 两 个 不 同 的 变 量 ( C) 若 a 和 b 类 型 相 同 , 在 计 算 机 了 赋 值 表 达 式 a=b 后 , b 的 值 不 变 。 ( D) 当 从 键 盘 输 入 数 据 时 , 对 于 整 型 变 量 只 能 输 入 整 型 数 值 , 对 于 实 型 变 量只能输入实型数据。

第三章 C 程序的流程设计
一、算法 1、 算 法 的 概 念 为解决某一个问题而采取的方法和步骤,就称为算法。 2、 算 法 的 性 质 ①有穷性:一个算法应包含有限的操作步骤 ②一个初始:此动作序列只有一个初始动作 ③确定性:算法中的每一个步骤都应当是确定性的,仅有一个后继动作。 ④ 有 一 个 或 多 个 输 出 :序 列 终 止 表 示 问 题 得 到 解 答 或 问 题 没 有 解 答 ,没 有 输 出的算法是没有意义的。 二、选择型程序设计 1、 if 语 句 的 形 式 ① if( 条 件 表 达 式 ) ② if( 条 件 表 达 式 ) 注意: ① if 语 句 中 的 条 件 表 达 式 一 般 为 逻 辑 表 达 式 或 关 系 表 达 式 , 但 也 可 以 是 任 意 语句 语句 1 e lse 语句 2

C 语言程序设计详解

23

的 数 值 类 型( 包 括 整 型 、实 型 、字 符 型 、指 针 类 型 ) ,例 如 下 列 语 句 也 是 合 法 的 。 if(‘a ’) prin tf(“ %d” ,’a’);

② 在 if 语 句 中 , 分 号 是 语 句 的 结 束 标 志 。 ③ 在 if 和 e lse 后 面 可 以 只 含 一 个 内 嵌 的 操 作 语 句 , 也 可 以 有 多 个 操 作 语 句 , 此时用花括号将几个语句括起来成为一个复合语句。 例 1 : 以 下 不 正 确 的 if 语 句 形 式 是 ( A) if(x> y&&x != y); B) if(x== y) C) if(x!= y) x+= y; scanf(“ %d”,&x ) else scan f(“ %d”, &y); ) 。

D) if(x< y) {x++;y++;}; 答案:C 详 解 : scanf(“%d”, &x)末 尾 应 加 分 号 , 因 为 分 号 是 语 句 不 可 缺 少 的 部 分 。 例 2 : 已 知 int x=10, y= 20,z=30;以 下 语 句 执 行 后 x, y,z 的 值 是 ( if(x> y) z=x;x= y;y=z ; 答 案 : x, y,z 的 值 分 别 是 : 20 30 30 ) 。

详 解 : 在 此 语 句 中 , 条 件 x> y 为 假 , 所 以 只 执 行 x= y;y=z ;两 条 语 句 。 例 3、 以 下 不 正 确 的 语 句 是 ( A) if(x> y); B) if(x= y)&&(x !=0) x+= y; )

C) if(x!= y) scan f(“ %d ”,&x); D) if(x< y){x++;y++}; 答案:D 详 解 : 分 号 是 语 句 结 束 的 标 志 , y++的 末 尾 无 分 号 , 所 以 y++不 是 合 法 的 语 句。 2、 if 的 嵌 套 if( 条 件 1 ) if( 条 件 2) 语句 1 e lse 语句 2

C 语言程序设计详解
e lse if( 条 件 3) 语句 3 e lse 语句 4 )

24

例 4: 以 下 程 序 的 输 出 结 果 是 (

main ( ) { int a=100,x=10, y=20,o k1=5,ok2=0; if(x< y) if(y!=10) if (!ok1 ) a=1; else if(ok2 ) a=10; p rin tf(“%d\n” ,a); } 答 案 : 100 详 解 : 把 10、 20、 5、 0 分 别 给 变 量 x、 y、 o k1、 ok2 赋 值 , 执 行 条 件 语 句 后 a 值 没 有 改 变 , 所 以 a 值 仍 是 原 值 1 00。 3、 switch 结 构 switc h 语 句 是 多 分 支 选 择 语 句 , 其 形 式 如 下 : switch (表 达 式 ) { case 常 量 表 达 式 1 : 语 句 1 case 常 量 表 达 式 2 : 语 句 2 ………… defau lt:语 句 n+1 } 注意: 1、 switch 后 面 括 弧 内 的 “ 表 达 式 ” 可 以 是 整 型 表 达 式 或 字 符 型 表 达 式 , 也 , 可以枚举型数据。 2、当 表 达 式 的 值 与 某 一 个 case 后 面 的 常 量 表 达 式 的 值 相 等 时 ,就 执 行 此 case 后 面 的 语 句 , 若 所 有 的 case 中 的 常 量 表 达 式 的 值 都 没 有 与 表 达 式 的 值 匹 配 的 , 就 执 行 defa ult 后 面 的 语 句 。 3、 每 一 个 ca se 的 常 量 表 达 式 的 值 必 须 互 不 相 同 , 否 则 就 会 出 现 互 相 矛 盾 的 现象。 4、 执 行 完 一 个 c ase 后 面 的 语 句 后 , 流 程 控 制 转 移 到 下 一 个 c ase 继 续 执 行 ,

C 语言程序设计详解
直 到 遇 到 bre ak 语 句 或 执 行 完 为 止 。 5、 defau lt 可 以 放 在 ca se 语 句 的 后 面 , 也 可 以 放 在 case 语 句 的 前 面 。

25

例 5: 运 输 公 司 对 用 户 计 算 运 费 , 距 离 越 远 , 每 公 里 运 费 越 低 。 设 每 公 里 每 吨 货 物 的 基 本 运 费 为 p ,货 物 重 为 w,距 离 为 s ,折 扣 为 d, 则 总 运 费 f 计 算 公 式 为 f=p*w*s(1-d), 编 写 程 序 。 公 里 数 s 与 折 扣 率 d 的 标 准 如 下 : 此 程 序 可 用 ( if… … else 来 完 成 , 也 可 以 用 switch 来 完 成 ) 。 s<250k m 250≤ s<500 500≤ s<1000 1000≤ s<2000 2000≤ s<3000 3000≤ s ma in() { int s; floa t p ,w,d,f; prin tf(“请 输 入 每 公 里 每 吨 货 物 的 基 本 运 费 ”); scanf(“%f”,&p); prin tf(“请 输 入 货 物 重 ” ); scanf(“%f”,&w); prin tf(“请 输 入 公 里 数 ” ); scanf(“%f”,&s); switch ((in t)(s/250 )) { case 0 : d=0 ; break ; ca se 1 : d=0. 05; brea k; ca se 2 : ca se 3 : d=0. 075; b reak ; ca se 4 : ca se 5 : case 6 : ca se 7 : d=0. 1; break ; ca se 8 : ca se 9 : case 10 : ca se 11 : d=0.1 5; break ; de fau lt: d=0.2 ; } d=0 d=0 .05 d=0 .075 d=0 .1 d=0 .15 d= 0.2

C 语言程序设计详解
f=p*w*s (1-d); printf( “ 基 本 运 费 是 : %f” ,f); } 详解: 1、 多 个 case 可 共 用 一 组 执 行 语 句 , 必 须 写 成 如 下 的 形 式 : case 4 : ca se 5 : case 6 : ca se 7 : d=0. 1; break ; case 后 面 只 能 有 一 个 常 量 ,把 上 式 改 写 成 c ase 4,5 ,6,7 : d=0.1; 形式是错误的。

26

break ;的

2、 switc h 后 面 括 弧 内 的 “ 表 达 式 ” 必 须 是 整 型 表 达 式 或 字 符 型 表 达 式 , 也 可 以 是 枚 举 型 数 据 , 对 于 swith 来 说 , 关 键 是 把 原 始 数 据 转 换 为 易 表 达 的 形 式 。 例 6: 请 读 以 程 序 写 出 程 序 的 输 出 结 果 。 #inc lude<std io h> main ( ) { int x=1, y= 0,a=0,b=0; switch(x ) { ca se 1 : switch (y) { case 0 : a++;b reak ; case 1 : b++;b reak ; } ca se 2 : a++;b++;b rea k; } p rintf(“ a=%d,b=%d ”,a,b); } 答 案 : a=2,b=1 详 解 :此 程 序 是 switc h 的 嵌 套 结 构 ,在 此 程 序 中 break 跳 出 内 层 switch 结 构 , 接 着 执 行 外 层 switc h 的 case 2 后 的 语 句 。 例 7: 写 出 下 面 程 序 的 运 行 结 果 是 ( ) main () { int i; for(i=1 ;i<=5;i++) switch (i%5)

C 语言程序设计详解
{ case 0 : ca se 1 : de fau lt: ca se 2 : } } 答 案 : #& & &* prin tf(“ *”); brea k; p rin tf(“#” ); b reak ; prin tf(“ \n” ); p rin tf(“&”);

27

详 解 :default 可 放 在 c ase 语 句 的 前 面 ,也 可 以 放 在 case 语 句 的 后 面 ,当 i%5 不 等 于 0,1,2 时 ,将 执 行 defau lt 后 的 语 句 p rintf(“ \n”);执 行 完 成 后 没 有 break,将 继 续 执 行 case 2 后 的 语 句 printf(“ &” ); 三、循环型程序设计 1、 wh ile 语 句 while 语 句 用 来 实 现 ” 当 型 ”循 环 结 构 , 其 一 般 形 式 如 下 : while (条 件 表 达 式 ) 例 11 : 设 有 程 序 段 : in t k=10; wh ile (k=0) 答案:0 答 案 解 析 : 在 此 程 序 的 while 结 构 中 ,条 件 表 达 式 k=0 的 结 果 永 远 为 0 即 为 假 , 所 以 循 环 执 行 的 次 数 为 0。 例 12 : 下 面 程 序 段 的 运 行 结 果 是 ( ) x= y=0; wh ile (x<15) y++ ,x+=++y; k=k -1; 循 环 体 执 行 ( )次。 循环体语句

p rintf(“ %d,%d” , y,x ); 答 案 : 8, 20 例 13 、 设 有 程 序 段 t=0; while (prin tf(“ *”)) { t++; if(t>3 ) bre ak; } 循环执行( )次

C 语言程序设计详解
答案:4

28

答 案 解 析 : while 结 构 中 的 条 件 表 达 式 prin tf(“ *”)的 值 为 输 出 数 据 的 个 数 , 在 此 例 中 , prin tf(“ *” )的 结 果 为 1, 即 为 真 。 2、 do -while 语 句 do -wh ile 语 句 的 特 点 是 先 执 行 循 环 体 ,然 后 判 断 循 环 条 件 是 否 成 立 ,其 一 般 形式为: do{ 循环体语句 }wh ile (条 件 表 达 式 ); 例 14 、 若 有 如 下 语 句 in t x=3; do {p rin tf(“%d \n” , x -=2);} while (--x); 则上面程序段输出结果是( 答案:1 例 15 、 以 下 程 序 段 循 环 执 行 几 次 。 x=-1 ; do { x=x *x;} 答案:1 例 16 、 下 面 程 序 的 运 行 结 果 是 ( ) main ( ) { int y=1 0; do{y--;} wh ile(--y); prin tf(“%d \n” , y--); } 答案:0 3、 for 语 句 C 语 言 中 的 fo r 语 句 使 用 最 为 灵 活 , 不 仅 可 以 用 于 循 环 次 数 已 经 确 定 的 情 况 , 而且可以用于循环次数不确定而只给出循环结束条件的情况,它完全可以代替 while 语 句 , 其 一 般 形 式 为 : for(表 达 式 1; 表 达 式 2; 表 达 式 2) ) 。

wh ile(!x);

C 语言程序设计详解
语句 说明:

29

① for 语 句 一 般 形 式 中 的“ 表 达 式 1 ”可 以 省 略 ,此 时 应 for 语 句 之 前 给 循 环 变 量赋初值。注意省略表达式 1 时,其后的分号不能省略。 ②如果表达式 2 省略,即不判断循环条件,循环无终止地进行下去。 ③表达式 3 也可以省略,但此时程序设计者应另外设法保证循环正常结束。 ④ 可 以 省 略 表 达 式 1 和 表 达 式 3, 只 有 表 达 式 2, 即 只 给 循 环 条 件 , 在 这 种 情 况 下 , 完 全 等 同 于 wh ile 语 句 。 ⑤ 3 个 表 达 式 都 可 省 略 , 如 : for( ; ; ) 语 句 , 相 当 于 wh ile(1 ) 语 句 , 即 不 设 初 值 ,不 判 断 条 件( 认 为 表 达 式 2 为 真 值 ) ,循 环 变 量 不 增 值 。无 终 止 地 执 行 循 环 体 。 ⑥表达式 1 可以是设置循环变量初值的赋值表达式, 可以是与循环变量无关 也 的 其 他 表 达 式 。 for(su m=0 ;i<=100;i++) su m=su m+i;

⑦ 表 达 式 一 般 是 关 系 表 达 式( 如 i<=100)或 逻 辑 表 达 式( 如 a<b && x< y) ,但 也可以是数值表达式或字符表达式,只要其值为非零,就执行循环体。 例 17 : 若 i 为 整 型 变 量 , 则 以 下 循 环 执 行 次 数 是 ( for( i=2 ;i!=0 ; ) 答案:2 例 18 : 以 下 不 是 无 限 循 环 的 语 句 是 ( A) for(y=0,x=1 ;x>++ y;x=i++) i=x; B) for(;;x++=i) C) while(1){x++;} D) for(i=10;;i--) su m+ =i; 答案:A 例 19 、 执 行 语 句 for( i=1 ; i++<4 ; 答案:4 例 20 、 下 面 程 序 段 的 功 能 是 计 算 1000! 的 末 尾 含 有 多 少 个 零 。 请 填 空 。 for(k=0,i=5 ;i<=1000 ;i+ =5) {m=i; while ( ) {k++;m= m/5;} } ); 后 变 量 i 的 值 是 ( ) ) p rin tf(“%d” ,i--); ) 。

C 语言程序设计详解
答 案 : m%5!=0 4、 break 与 con tinu e

30

在 break 语 句 可 以 使 流 程 跳 出 switch 结 构 , 继 续 执 行 switch 语 句 下 面 的 一 个 语 句 。 实 际 上 , b rea k 语 句 还 可 以 用 来 从 循 环 体 内 跳 出 循 环 体 , 即 提 高 结 束 循 环 , 接 着 执 行 循 环 下 面 的 语 句 。 break 语 句 的 一 般 形 式 为 : b reak ; continue 语 句 只 结 束 本 次 循 环 , 而 不 是 终 止 整 个 循 环 的 执 行 。 con tinue 语 句 的 一 般 形 式 为 : co ntin ue; 例 21 : 下 列 程 序 的 运 行 结 果 是 ( ma in ( ) { in t i, j,x=0; for(i=0 ;i<2;i++) {x++; for(j=0 ;j<=3;j++ ) { if(j%2 ) co ntin ue; x++;} x++; } printf(“x=%d\n ”,x); } 答案: 例 22 、 下 面 程 序 的 运 行 结 果 是 ( main ( ) { in t k=0 ;cha r c=’A’; do {switch (c++) c ase ‘A’:k++;break ; c ase ‘B’:k --; c ase ‘C’:k+=2;brea k; c ase ‘D’:k=k%2;co ntin ue; c ase ‘E’:k=k *10 ;break; d efau lt:k=k /3 ; } k++; }wh ile (c<‘ G’ ); prin tf(“k=%d \n”,k ); 答案: 5、 循 环 的 嵌 套 一 个 循 环 体 中 又 包 含 另 一 个 完 整 的 循 环 结 构 称 为 循 环 的 嵌 套 。内 嵌 的 循 环 中 ) ) 。

C 语言程序设计详解
还可嵌套循环,这就是多层循环。 6、 举 例 : ①求和问题 例 23 : s=1+2+…………..+100 例 24 : s=1!+2!+………… +100! 例 25 : e=1+1/1!+1/2 !+1/3!+…… 例 26 : s=1-1/3 !+1/5 !-1/7!+……. 精 确 到 10 - 6 精 确 到 10 - 6

31

#inc lude “ math .h” main ( ) { long t; double s; for(s=0, t=1, i=0;fabs(1/t)>=1e -6 ;i++) { t=(-1)*t *i; s=s+1/t; } prin tf(“%lf”,s); }(例 26 程 序 设 计 ) 例 27 : 有 一 分 数 序 列 : 2/1, 3 /2, 5 /3, 8 /5 , 13/6, 21 /13, ……. 求 出 这 个 数 列 的 前 20 项 之 和 main () { int s=0, f1=1,f2=2 ; fo r(I=1;I<=20 ;I++) { s=s+f2 /f1 ; f2=f1+f2 ; f1=f2 -f1 ; } prin tf(“%d” ,s); } 例 28 : 打 印 九 九 表 main ( ) {in t i,j; for(i=1 ;i<=9;i++) { for(j=1 ;j<=9;j++) p rin tf(“%2d *%2 d=%2d”,i, j, i*j); p rintf(“ \n” );

C 语言程序设计详解
} } 例 29 : 打 印 出 下 列 图 形 * * * * * main ( ) { int i, j; for(i=1 ;i<=5;i++) { for(j=1 ;j<=5+fab s(i-3 );j++) prin tf(“ ” ); for(j=1 ;j<=5 -2 *fabs(i-3 );j++) prin tf(“* ” ); prin tf(“ \n” ); } } 例 30 、 打 印 出 下 列 图 形 * *** ***** *** * 例 31 、 兔 子 繁 殖 问 题 main ( ) { in t i,f1 ,f2, f3 ; for(i=3;i<=12;i++) { f3=f1+f2 ; f1=f2; f2=f3; } prin tf(“%d ”,f3 ); } * * * *

32

C 语言程序设计详解
例 32 、 求 最 大 公 约 数 、 最 小 公 倍 数 。 main ( ) {in t r,u, v, m,n; scanf(“%d, %d”, &m, &n ); m=u ;n= v; if(u<v) {r=u;u= v;v=r;} while (u!=0) {r=u%v;u=v;v=r;} prin tf(“最 大 公 约 数 是 : %d, 最 小 公 倍 数 是 ” , v, m*n /v); } 例 33 、 s n =a+aa+aaa+a a…a, 从 键 盘 输 入 a 及 n 后 , 求 s n 方法一: main () {in t n,a ; long s; scnaf(“%d %d”,&n ,&a ); for(i=1 ;i<=n;i++) s=s*10+i*a ; prin tf(“%ld”, s); } 方法二: main () {in t n,a ; long s,t=0 ; scnaf(“%d %d”,&n ,&a ); for(i=1 ;i<=n;i++) {t=t*10+a s=s+t; } prin tf(“%ld”, s); }

33

例 34 、 给 出 一 个 不 多 于 5 位 的 正 整 数 , 要 求 ① 求 出 它 是 几 位 数 ② 分 别 打 印 出每一位数③逆序打印此数据。 main ( ) {long a; in t i=0;s=0; prin tf(“它 的 每 一 位 数 : ”); While(a !=0) { i=i+1 ; x=a%10; a=a/10 ; s=s*10+x ;

C 语言程序设计详解
printf(“%d ”, x); } prin tf(“ \n” ); prin tf(“它 是 %d 位 数 \n ”,i); prin tf(“它 的 逆 序 是 %d \n”,s); } 例 35 、 输 出 1—100 之 间 每 位 数 的 乘 积 大 于 每 位 数 的 和 的 数 ma in() { in t n,k=1, s=0, m; for(n=1;n<=100 ;n++) {k=1;s=0 ; m=n ; wh ile (m!=0) { k=k+m%10 ; s=s+ m%10 ; m= m/10 ; } if(k>s) printf(“%d”,n ); } }

34

例 36 、 猴 子 吃 桃 问 题 , 猴 子 第 一 天 摘 下 若 干 桃 子 , 当 即 吃 了 一 半 , 还 不 过 瘾 又 多 吃 了 一 个 ,第 二 天 又 将 剩 下 的 桃 子 吃 掉 一 半 ,又 多 吃 了 一 个 ,以 后 每 天 都 吃 前 一 天 剩 下 的 半 多 一 个 , 到 第 10 天 , 再 吃 桃 时 只 剩 下 一 个 桃 子 , 求 第 一 天 共 摘下多少了桃。 ma in() {in t i,s=1 ; fo r(i=9;i<=1;i--) s=2 *s+1 ; prin tf(“第 一 天 共 摘 下 %d 个 桃 子 ”, s); } 例 37 : 准 备 客 票 : 某 铁 路 线 上 共 有 10 个 车 站 , 问 需 要 准 备 几 种 车 票 。 main () {in t i,j,s=0 ; for(I=1 ;I<=9;I++) fo r(j= I+1 ;j<=10;j++ ) s=s+1 ; printf(“需 要 准 备 %d”, 2 *s); } 例 38 、 有 1020 个 西 瓜 , 第 一 天 卖 一 半 多 两 个 , 以 后 每 天 卖 剩 下 的 一 半 多 两个,问几天以后能卖完。

C 语言程序设计详解
ma in ( ) { in t da y=0, s=102 0; while (s<=0) {s=s/2 -2; da y+ +; } p rin tf(“%d”,da y); }

35

例 39 、 从 三 个 红 球 、 五 个 白 球 、 六 个 黑 球 中 任 意 取 出 八 个 球 , 且 其 中 必 须 有白球,输出所有可能的方案。 main () {in t red,white,b lack ; for(white=1;wh ite<=5;wh ite++) fo r(red=0 ;red<=3;re d++) fo r(b lack=0 ;b lack <=6;black++) if(white+red+black==8) p rin tf(“%d 个 红 球 , %d 个 白 球 , %d 个 黑 球 ”, red, white,b lack); } 例 40 、 二 分 迭 代 法 二 分 迭 代 法 的 思 想 是 : 先 取 f(x)=0 的 两 个 粗 略 解 x1 与 x2。 若 f(x1)与 f(x2 ) 符 号 相 反 , 则 方 程 f(x )=0 在 区 间 ( x1,x 2) 中 至 少 有 一 个 根 。 While(fabs(x1 -x2 )>=1e -6) { x3=(x1+x2)/2 ; if(f(x3 )*f(x2)>0 ) x2=x3 ; else x1=x3 ; } 例 41 、 牛 顿 切 线 法 求 a 的 平 方 根 。 x=√ a x 2 =a 构造函数 f(x )=x 2 -a

x2=x1 -f(x1)/f ’(x1 ) double sq -roo t(doub le a) {double x; x=a; wh ile(fabs(x *x)-a>=1e -6) x=(x+a/x) *0 5 ;

C 语言程序设计详解
re turn (x ); }

36

例 42 、 求 积 分 用 梯 形 法 求 sin(x )*cos(x)的 定 积 分 , 设 上 限 a、 下 限 b 分 别 为 0,1.2。 积 分 区 间 分 割 数 n=100. S=h/2[f(a )+f(b )]+h(f(a +h)+f(a+2h)+………..+ f(b )) main ( )

{ in t i,n=100 ; double h, s,a=0,b=1.2 ; s=0.5 *(sin(a )*cos(a )+sin (b)*c os(b )); for(i=1;i<=n;i++) s=s+sin(a+ i*h)*c os(a+i*h ); printf(“%lf”, s); } 例 44 、 验 证 一 个 数 是 否 为 素 数 ma in( ) {in t n , I, flag=1; scnaf(“%d” ,&n ); for(i=2 ;i<=sq rt(n);i++) if(n%i==0) {flag=0;b reak ;} if(flag==1) prin tf(“%d 是 素 数 。 ”,n); else prin tf(“%d 不 是 素 数 。 ”,n); } 例 45 、 输 入 一 个 数 , 输 出 这 个 数 的 质 因 子 乘 积 的 形 式 。 例 如 输 入 72 后 , 输 出 : 72=2 *2 *2 *3 *3。 ma in () { in t n, i=2,flag=0 ; scan f(“%d”,&n ); p rintf(“ %d=”,n); wh ile (n!=1 ) { if(n%i==0) {if(flag==0) {printf(“ %d”, i);flag=1 ;} e lse

C 语言程序设计详解
{p rintf(“ *%d ”,i);} n=n/i; } else i=i+1 } } 二、练习

37

例 5 : 请 阅 读 以 下 程 序 : 若 运 行 时 输 入 2 .0<回 车 >, 则 上 面 程 序 的 输 出 结 果是( )

#inc lude <std io.h> main ( ) { floa t a,b ; sca nf(“%f”,&a ); if(a<0. 0) b=0.0 ; e lse if((a<0.5) &&(a !=2.0) b=1.0 /(a+2.0 ); e lse if(a<10.0 ) b=1.0/a ; e lse b=10. 0; prin tf(“%f\n” ,b); } 答 案 : 0.500000 例 6: 请 阅 读 下 面 的 程 序 : ma in( ) { in t s, t, a,b; scan f(“%d,%d”, &a, &b); s=1; t=1; if(a>0) s=s+1; if(a>b) t=s+t; e lse if(a==b) t=5; e lse t=2 *s; p rintf(“ %d,%d” ,s, t); } 为了使输出结果 t 为4,输入量 a 和 b 应满足的条件是( 答 案 : b>a>0 编 要 ‘ ‘ 、 、 、 例 10 : 写 程 序 给 出 一 百 制 成 绩 , 求 输 出 成 绩 等 级 A’、 B’ ‘ C’ ‘ D’ ‘ E’ 90 分 以 上 为 A, 80-8 9 分 为 ‘ B’ 70-79 为 ‘ C’ 60 -69 为 ‘ D’ 60 分 以 , , , , 下 为 ‘ E’ 。 ) 。

C 语言程序设计详解
main () {in t score ; scan f(“ %d”, &sco re); switch(score/1 0) {ca se 10 : ca se 9 :prin tf(“等 级 是 A”); brea k; ca se 8 : p rin tf(“等 级 是 B”); bre ak; ca se 7 : p rin tf(“等 级 是 C”); bre ak; ca se 6 : p rin tf(“等 级 是 D”); brea k; defau lt: p rintf(“等 级 是 E”); break ; } }

38

第四章 模块化程序设计

一、函数 1、 C 程 序 结 构 一个简单的函数调用例子。 main () {printstar(); print_ message (); printstar(); } prin tsta r() { printf(“ ************ **************\n” ); } prin t_ message() { printf(“How do you d o!\n” ); } 说明: ① 用 C 语 言 编 写 函 数 至 少 要 编 写 一 个 ma in()函 数 , 行 C 程 序 就 是 执 行 相 应 执 的 main()函 数 ,调 用 其 他 函 数 后 流 程 回 到 ma in 函 数 ,在 ma in 函 数 中 结 束 整 个 程

C 语言程序设计详解
序的运行。

39

②一个 C 程序可由一个主函数和若干个函数组成。由主函数调用其他函数, 其他函数也可以互相调用。同一个函数可以被一个或多个函数调用任意多次。 ③ 所 有 函 数 都 是 平 行 的 ,即 在 定 义 函 数 时 互 相 独 立 的 ,一 个 函 数 并 不 从 属 于 另一个函数,即函数不能嵌套调用 ④从用户使用的角度看,函数有两种:标准函数,用户自定义函数。 ⑤从函数的形式看,函数分两类:无参函数、有参函数。 例 1: 以 下 正 确 的 说 法 是 ( ) 建 立 函 数 的 目 的 之 一 是 : A) 提 高 程 序 的 执 行 效 率 B) 提 高 程 序 的 可 读 性 C) 减 少 程 序 的 篇 幅 D) 减 少 程 序 文 件 所 占 内 存 答案:B 例 2: 以 下 正 确 的 说 法 是 ( ) A) 用 户 若 需 调 用 标 准 库 函 数 , 调 用 前 必 须 重 新 定 义 B) 用 户 可 以 重 新 定 义 标 准 函 数 , 若 如 此 , 该 函 数 将 失 去 原 有 含 义 C) 系 统 根 本 不 允 许 用 户 重 新 定 义 标 准 库 函 数 D) 用 户 若 需 调 用 标 准 库 函 数 , 调 用 前 不 必 使 用 预 编 译 命 令 将 该 函 数 所 在 文 件包括到用户源文件中,系统自动去调。 答案:B 2、 函 数 的 定 义 函数定义就是在程序中设定一个函数模块。 例 3: main ( ) { doub le su m(in t a,do uble b );/*函 数 声 明 */ } double su m(in t a,d ou ble b ) /*函 数 定 义 */ { /*函 数 体 */ } 注意:

C 语言程序设计详解

40

①函数名应符合 C 语言对标识符的规定。以字母或下划线开头,后跟字母、 数字下划线的组合。 ② 形 式 参 数 写 在 函 数 后 面 的 一 对 圆 括 号 内 ,表 示 将 从 主 调 函 数 中 接 收 哪 些 类 型的信息,程序进行编译时,并不为形式参数分配存储空间。只有在被调用时, 形式参数才临时地占有存储空间。 ③ 函 数 返 回 值 类 型 ,如 省 略 返 回 值 类 型 系 统 默 认 为 in t 型 , 对 不 需 要 使 用 函 数 返 回 值 的 函 数 , 应 定 义 为 void 类 型 。 ④ 函 数 的 外 部 性 , 函 数 不 能 嵌 套 ,一 个 函 数 不 能 定 义 在 别 的 函 数 内 部 。 3、 函 数 声 明 在 主 调 函 数 中 ,要 对 在 本 函 数 中 将 要 调 用 的 函 数 事 先 作 一 声 明 。所 谓“ 声 明 ” 是 指 向 编 译 系 统 提 供 必 要 的 信 息 :函 数 名 ,函 数 的 类 型 ,函 数 参 数 的 个 数 ,类 型 及排列次序。 ①函数声明末尾要加; ② 函 数 声 明 可 以 不 写 形 参 名 ,但 必 须 写 类 型 标 识 符 。如 上 例 中 可 以 把 声 明 改 为 : doub le su m(a,b ); 例 4 : 若 调 用 一 个 函 数 , 且 此 函 数 中 没 有 re turn 语 句 , 则 正 确 的 说 法 是 ( ) A) 没 有 返 回 值 B) 返 回 若 干 个 系 统 默 认 值 C) 能 返 回 一 个 用 户 所 希 望 的 函 数 值 D) 返 回 一 个 不 确 定 的 值 答案:D 例 5、 C 语 言 规 定 , 函 数 返 回 值 的 类 型 是 由 ( ) A) retu rn 语 句 中 的 表 达 式 类 型 决 定 B) 调 用 该 函 数 时 的 主 调 函 数 类 型 所 决 定 C) 调 用 该 函 数 时 系 统 临 时 决 定 D) 在 定 义 该 函 数 时 所 指 定 的 函 数 类 型 所 决 定 答案:D 例 6、 下 面 函 数 调 用 语 句 含 有 实 参 个 数 为 ( ) func ((exp1 ,exp2 ),(exp3,exp4, exp5)); su m(in t ,double ); 但 不 能 只 写 形 式 参 名 而 不 写 类 型 如 : doub le

C 语言程序设计详解
答案:2 。 例 7 、 若 输 入 的 值 是 -1 25,以 下 程 序 的 运 行 结 果 是 ( ) # inc lude “ ma th.h ” ma in() { int n; scanf(“%d” ,&n ); n=fabs(n ); fun(n ); } fun(in t n) { int k,r; for(k=2;k<=sqrt(n);k++) { r=n%k; while (r==0) { printf(“%d” ,k); n=n/k ; if(n>1) p rin tf(“ *” ); } } if(n!=1) prin tf(“%d \n”, n); } 答 案 : -125=-5*5*5 。 例 9、 以 下 正 确 的 函 数 定 义 形 式 是 ( ) A) double fun(in t x, in t y) B) double fun(in t x ;int y) C) double fun(in t x, in t y); D) double fun(in t x, y) ; 答案:A 。 例 10 、 以 下 正 确 的 函 数 形 式 是 ( ) A) double fun(in t x, in t y) {z=x+ y;re tu rn z ;} B) fun (int x, y) {in t z ; retu rn z ;} C) fun (int x,int y) {in t x, y;doub le z; z=x+ y;re tu rn z ;} D) doub le fu n(int x ,in t y) {doble z ; z=x+ y;re tu rn z;}

41

C 语言程序设计详解
答案:D 4、 函 数 的 传 值 调 用 参数是函数调用时进行信息交换的载体,关于形参与实参的说明:

42

① 在 定 义 函 数 中 指 定 的 形 参 ,在 未 出 现 函 数 调 用 时 ,它 们 并 不 占 用 内 存 中 的 存 储 单 元 。只 有 在 函 数 调 用 时 ,函 数 中 的 形 参 才 被 分 配 内 存 单 元 ,形 参 与 实 参 各 占一个独立的存储空间,函数返回时,临时存储区被撤销。 ② 在 被 定 义 的 函 数 中 ,必 须 指 定 形 参 的 类 型 ,实 参 可 以 是 常 量 、变 量 或 表 达 式,但要求它们有确切的值。实参与形参的类型应相同或赋值兼容。 ③ C 语 言 规 定 ,实 参 变 量 对 形 参 变 量 的 数 据 传 递 是“ 值 传 递 ” ,即 单 向 传 递 , 只由实参传给形参,而不能由形参传回来给实能。 例 11 、 main ( ) { int a=3,b=5; vo id swap(in t x, in t y); swap (a,b ); prin tf(“%d ,%d”, a,b); } vo id swap (int x ,in t y) {in t te mp ; te mp=x ;x= y;y= te mp ; } 输 出 结 果 : 3, 5 。 例 12 、 以 下 正 确 的 说 法 是 ( ) 在 C 语言中, A) 实 参 与 其 对 应 的 形 参 各 占 用 独 立 的 存 储 单 元 。 B) 实 参 和 与 其 对 应 的 形 参 共 占 用 一 个 存 储 单 元 C) 只 有 当 实 参 和 与 其 对 应 的 形 参 同 名 时 才 共 占 用 存 储 单 元 。 D) 形 参 是 虚 拟 的 , 不 占 用 存 储 单 元 。 答案:A 例 13 、 以 下 不 正 确 的 说 法 是 ( ) 。 C 语言规定 A) 实 参 可 以 是 常 量 、 变 量 或 表 达 式 B) 形 参 可 以 是 常 量 、 变 量 或 表 达 式

C 语言程序设计详解
C) 实 参 可 以 为 任 意 类 型 D) 实 参 类 型 应 与 其 对 应 形 参 的 一 致 答案:B 5、 函 数 的 递 归 调 用

43

在调用一个函数的过程中又出现直接或间接地调用该函数本身, 为函数的 称 递归调用。 例 14 、 用 递 归 方 法 计 算 n!的 函 数 rfa ct( )。 假 设 n 为 正 数 。 求 n!可 以 用 递 推 方 法 , 即 从 1 开 始 , 乘 2 , 再 乘 3……一 直 乘 到 n。 这 种 方 法 容 易 理 解 ,也 容 易 实 现 。递 推 法 的 特 点 是 从 一 个 已 知 的 事 实 出 发 ,按 一 定 规 律 推出下一个事实,再从这个新的已知的事实出发,再向下推出一个新的事实。 floa t rfac1 (int n ) { in t i; floa t t; for(i=1 ;i<=n;i++) t=t*I; retu rn(t); } 求 n!也 可 以 用 递 归 方 法 , 即 5!=5 *4!, 而 4 !=4 *3!,3!=3 *2 !,2!=2 *1 !,1!=1, 可 用下面的递归公式表示。 =1 rfact(n) =rfac t(n -1)*n long rfac t(in t n ) { if( n<=1) retu rn(1); else re tu rn(n *rfa ct(n -1 )); } 分析:递归总是由两部分组成的: ①递归方式 ②递归终止条件 例 15 、 求 1/n! ①递归方式 n> 1 f15 (n)= f15(n -1)*1 /n n>1 n=1

C 语言程序设计详解
②递归终止条件 n=1 f15=1

44

double f15 (in t n ) { if(n==1) return (1); e lse return (f15 (n -1 )*1/n); } 例 16 、 s=1+1/2+1/3+…….+1/n ①递归方式 ②递归终止条件 n> 1 n=1 f16 (n)= f16(n -1)*1 /n f16 (n)=1

double f16 (in t n ) { if(n==1) return (1); e lse return (f16 (n -1 )+1/n); } 例 17 、 s=1-1/2+1 /3 -1 /4+…..1/n ①递归方式 ②递归终止条件 n> 1 n=1 精 确 到 10 - 6

f17 (n)= f17(n -1)±1/n f17 (n)=1

double f17 (in t n, in t fla g) { if(n==1) return (1); e lse return (f17 (n -1 , -flag )+1/n *flag); } main () {in t n, flag; scan f(“ %d”, &n); if (n %2==0) flag== -1 ; else flag==1 ; printf(“%lf”, f17(n ,fla g)); } 例 18 、 以 下 程 序 的 功 能 是 用 递 归 法 计 算 学 生 的 年 龄 , 已 知 第 一 位 学 生 年 龄 最 小 , 为 10 岁 , 其 余 学 生 一 个 比 一 个 大 2 岁 , 求 第 5 位 学 生 的 年 龄 。 ①递归方式 ②递归终止条件 n> 1 n=1 f18 (n)= f18(n -1)+2 f18 (n)=10

C 语言程序设计详解
int f18 (in t n ) { if(n==1) return (10); e lse return (f18 (n -1 )+2); } 例 19 、 求 u,v 两 数 的 最 大 公 约 数 ①递归方式 ②递归终止条件 v!=0 v= =0 f19 (u, v)= f19(v, u%v) f19 (u, v)=u

45

int f19 (in t u ,in t v) { if (v==0) retu rn(u ); e lse re turn (f19(v,u %v)); } 例 20 、 兔 子 繁 殖 问 题 、 牛 群 繁 殖 问 题 ①递归方式 ②递归终止条件 n> 1 n=1 n=2 f20 (n)= f20(n -1)+f20(n -2 ) f20 (n)=1 f20(n )=1

int f20 (in t n ) { if(n==1) return (1); else if(n==2) re turn (1); e lse return (f20 (n -1 )+f20(n -2)); } 例 21 、 写 出 计 算 Ackermann 函 数 ack(m,n) 的 递 归 函 数 。 对 于

m>=0,n>=0,Ack(m,n)定 义 为 : a ck(0, n)=n+1 a ck(m,0)=ac k(m-1, 1) a ck(m,n)=ac k(m-1, ack(m,n -1 )) ①递归方式 ②递归终止条件 n> 1 n=0 ack (m,n )=ack (m-1,ack (m,n -1)) ack (m,n )=ack (m-1,1)

C 语言程序设计详解
m=0 ack (m,n)=n+1

46

d ouble ack (in t m, in t n) { if(m==0) retu rn(n+1 ); else if(n==0) retu rn(a ck(m-1,1 )); else retu rn(a ck(m-1, ack(m,n -1 ))); } 例 22 、分 别 写 出 Hermite 多 项 式 H n (x)的 值 的 递 推 和 递 归 函 数 。H n (x )定 义 如 下: H 0 (x)=1 H 1 (x)=2x H n (x)=2xH n - 1 (x)-2 (n -1)H n - 2 (x) 递推法: doub le h1 (int n,floa t x) { floa t s1=1,s2=2 *x, s3; int i; if(n==0) re turn (1); else if(n==1) re turn (2 *x); else { for(i=2 ;i<=n;i++) {s3=2 *x *s2+2 *(n -1)*s1; s1=s2; s2=s3; } } } 递归法: ①递归方式 ②递归终止条件 n> 1 n=0 n=1 h(n ,x)=2 *x *h (n -1,x)-2 *(n -1)*h (n -2 ,x) h(n ,x)=1 h (n,x )=2 *x

double h 1(int n,floa t x ) { if(n==0) return (1); e lse if(n==1) retu rn(2 *x ); e lse re turn (2 *x *h (n -1,x )-2 *(n -1)*h (n -2 ,x )); }

C 语言程序设计详解
例 23 、 求 a 的 平 方 根 递推法: double sq_root(doub le a) { doub le x ; x=a; wh ile(fabx(x *x )-a)>= 1e -6) x=(x+a /x)*0. 5; re turn (x); } 递归法: ①递归方式 fabx (x *x)-a)>=1e -6

47

sqroo t(x, a)=sq roo t((x+a/x )*0 .5,a) sq root(x,a)=x

② 递 归 终 止 条 件 fabx (x *x )-a )<1e -6 do uble sq root(doub le x,d ouble a) { if(fab s(x *x )-a<1e -6 ) re tu rn(x ); else retu rn(sqroo t((x+a /x )*0.5,a )) }

例 24 、 求 一 个 给 定 数 字 的 所 有 质 因 子 , 如 7 2=2 *2 *2 *3 *3 递推法: vo id yiz i(in t n) {in t i=2,flag=0; while (n!=1) { if(n%i==0) { if(flag==0) e lse n=n /i; } else i=i+1 ; } } 递归法: vo id yiz i(in t n, in t i,in t flag ) {if (n !=1) { if(n%i==0) { if (flag==0) {prin tf(“%d=%d”,n i); flag=1 ;}

{p rin tf(“ %d=%d”,n, i); prin tf(“ *%d”, i);

flag=1; }

C 语言程序设计详解
else prin tf(“ *%d ”,i); yiz i(n/i, i,fla g); } e lse yiz i(n, i+1, fla g); } } 例 24 、 用 递 归 法 将 一 个 整 数 n 转 换 成 字 符 串 vo id con ve r(in t n ) {in t i; if(i=n /10)!=0) c on vert(i); putcha r(n %10+’0’); } 二、变量的存储属性 1、 动 态 变 量

48

动态变量是 C 程序中使用最多的一种变量,在程序执行过程中自动进行建 立 和 撤 销 ,它 们 存 在 于 程 序 的 局 部 ,也 只 在 这 个 局 部 中 可 以 使 用 ,这 种 变 量 称 为 动 态 变 量 , 动 态 变 量 有 两 种 : 自 动 ( au to) 变 量 和 寄 存 器 ( reg iste r) 变 量 。 在一个函数内部定义的变量是局部 例 25 : main () { in t x=1 ; { void prt(vo id ); in t x=3 ; prt( ); printf(“x=%d\n ”,x); } prin tf(“x=%d \n”,x ); } vo id prt(void ) { int x=5; prin tf(“x=%d” ,x); } 注意: 1、系 统 在 程 序 执 行 过 程 中 动 态 建 立 动 态 撤 消 ,在 赋 值 前 它 的 值 是 不 确 定 的 。 2、 局 部 可 用 。

C 语言程序设计详解
3、 外 层 的 变 量 被 内 层 的 同 名 变 量 屏 蔽 。 例 26 : 以 下 正 确 的 说 法 是 ( ) 如果在一个函数中的复合语句中定义了一个变量,则该变量( ) A) 只 在 该 复 合 语 句 中 有 效 B) 在 该 函 数 中 有 效 C) 在 本 程 序 范 围 内 均 有 效 D) 为 非 法 变 量 例 27 : 以 下 正 确 的 说 法 为 ( ) A) 在 不 同 函 数 中 可 以 使 用 相 同 名 字 的 变 量 B) 形 式 参 数 是 局 部 变 量 C) 在 函 数 内 定 义 的 变 量 只 在 本 函 数 范 围 内 有 效 D) 在 函 数 内 的 复 合 语 句 中 定 义 的 变 量 在 本 函 数 范 围 内 有 效 2、 寄 存 器 变 量 reg ister 通常把使用频率较高的变量定义为寄存器变量。 3、 静 态 变 量 注意: ① 在 编 译 时 为 其 分 配 空 间 , 如 不 赋 初 值 , 初 值 为 0。 ②局部可用或全局可用。 ③静态变量具有可继承性。 4、 外 部 变 量 在一个文件中,定义在所有函数之外的变量称为外部变量。 注意: ①在编译时为其分配空间。 ②全局可用。 ③限定本文件的外部变量只在本文件使用 sta tic int a=3; main ( ) { } sta tic

49

④将外部变量的作用域在本文件范围内(或在其它文件)扩充。 exte rn

C 语言程序设计详解
三、编译预处理 注意: ①编译预处理是在编译前对源程序进行的一些预加工。 ② C 语 言 的 预 处 理 命 令 均 以 “ #” 开 头 , 末 尾 不 加 分 号 ③编译预处理命令可以出现在程序中的任何位置 1、 宏 替 换 ①字符串宏替换 ②带参的宏替换 注意: ①宏名与宏体之间应以空格相隔 ②宏名不能用引号 ③ 较 长 的 定 义 在 一 行 写 不 下 时 , 可 在 末 尾 加 \。 ④对带参宏定义时、宏休及其各个形参应用括号括起来。 2、 文 件 包 含 格 式 1: #in clu de“ 文 件 标 识 ” 格 式 2: #in clu de<文 件 名 > 例 28: 以 下 叙 述 中 不 正 确 的 是 ( ) A) 预 处 理 命 令 行 都 必 须 以 #开 头 B) 在 程 序 中 凡 是 以 # 号 开 头 的 语 句 行 都 是 预 处 理 命 令 C) C 程 序 在 执 行 过 程 中 对 预 处 理 命 令 行 进 行 处 理 D) 以 下 是 正 确 的 宏 定 义 #define IBM_P C

50

例 29 : 以 下 叙 述 中 正 确 的 是 ( ) A) 在 程 序 的 一 行 上 可 以 出 现 多 个 有 效 的 预 处 理 命 令 行 B) 使 用 带 参 的 宏 时 , 参 数 的 类 型 应 与 宏 定 义 时 的 一 致 C) 宏 替 换 不 占 用 运 行 时 间 , 只 占 编 译 时 间 D) 在 以 下 定 义 中 C R 是 称 为 “ 宏 名 ” 标 识 符 #define C R 045 例 30 : 设 有 以 下 宏 定 义 : #define W IDTH 80

C 语言程序设计详解
#define LENGTH WIDTH+40

51

则 执 行 赋 值 语 句 : v= LENGTH*20 (v 为 in t 型 变 量 )后 , v 的 值 是 (

) 。

第五章 数组

数组是指一组同类型数据组成的序列,用一个统一的数组名标识这一组数 据 ,用 下 标 来 指 示 数 组 中 元 素 的 序 号 ,同 一 数 组 中 的 所 有 元 素 必 须 属 于 同 一 数 据 类型。 一、一维数组 1、 一 维 数 组 的 定 义 一 维 数 据 的 定 义 方 式 为 :类 型 说 明 符 数 组 名 [常 量 表 达 式 ];例 如 :int a[10 ]; 说明: ①数组名定名规则和变量名相同,遵循标识符定名规则。 ②数组名后是用方括号括起来的常量表达式,不能用圆括号。 ③常量表达式表示元素的个数,即数组长度。 ④常量表达式中可以包括常量或符号常量,不能包含变量。 例 1: 以 下 对 一 维 数 组 a 的 正 确 说 明 是 ( A) int a (10 ); C) int n;scan f(“%d”,&n); int a[n ]; ) 。

B) in t n=10 ,a[n]; D) #define SIZE 10 int a[S IZE ];

C 语言程序设计详解
答案:D 2、 一 维 数 组 的 初 始 化 ① 可 对 全 部 元 素 赋 初 值 : 例 如 : int a[5 ]={1 ,3,5,7,9 }; ② 可 给 部 分 赋 值 : 例 : in t a[5]={1,3 ,5}; ③ 如 果 想 使 全 部 元 素 为 1: 例 in t a [5]={1,1,1,1 ,1 };( 注 : 不 能 省 略 ) ④在对全部元素赋值时,可不指定数组长度。 例 in t a [ ]={1,2,3, 4,5, 6};

52

⑤ 如 对 一 个 静 态 或 外 部 的 数 组 不 进 行 初 始 化 , 隐 含 的 初 值 为 0。 如 不 对 动 态 数组初始化,则其初始值为一些不可预料的数。 例 2: 以 下 能 对 一 维 数 组 a 进 行 正 确 初 始 化 的 语 句 是 ( A) int a [10 ]=(0,0,0 ,0, 0); C) int a[]={0}; 答案:C 例 3: 以 下 不 正 确 的 定 义 语 句 是 ( A) double x [5]={1 .0,2 .0,3.0,4,0 ,5.0}; C) char c1 []={‘1’,’2 ’,’3’,’4 ’,’5’}; 3、 一 维 数 组 元 素 的 引 用 数 组 元 素 的 表 示 形 式 为 : 数 组 名 [下 标 ] 例 4: 数 组 元 素 引 用 实 例 main ( ) {in t I,a[10 ] for(I=0;I<=9;I++) a [i]= I; for(I=0;I<=0;I++) prin tf(“%d” ,a[i]); } 说明: ①下标可以是整型常量、变量或表达式 ②不要越界 ) 。 B) int y[5]={1,2 ,3,4,5 ,6}; D) ch ar c2 []={‘\x1 0’, ’\x a’}; B) int a[10]={}; D) in t a[10]={1 0 *1}; ) 。

C 语言程序设计详解
例 5 : 若 有 说 明 : int a [10];则 对 a 数 组 元 素 的 正 确 引 用 是 ( A) a[10 ] B) a[3.5] C) a (5) D) a[1 0 -1 0]

53
) 。

例 6: 下 面 程 序 中 有 错 误 的 行 是 ( 号 1 2 3 4 5 6 7 } main () { in t a [3]={1 }; int i;

)注:每行程序前面的数字表示行

sc anf(“%d”, &a ); fo r(I= 1;I<3 ;I++) a [0]=a [0]+a [i];

prin tf(“a [0]=%d \n”,a[0 ]);

答案:4 4、 数 组 名 作 为 函 数 参 数 main ( ) {void swap(in t x[2 ]) in t a [2]={3 ,5}; swa p(a ); printf(“%d,%d \n” ,a[0 ],a[1]); } vo id {in t t; t=x [0];x[0 ]=x[1 ];x[1]=t; } 输 出 结 果 : 5, 3 注意: 以数组名作参数时,采取的不是“值传递”方式,而是“地址传送”方式, 即把实参数组起始地址传给形参数组, 样形参数组就和实参数组共占同一段内 这 存单元。 5、 一 维 数 组 的 应 用 举 例 例 7: 对 n 个 数 排 序 ( 由 小 到 大 ) 起 泡 法 swap (in t x [2])

C 语言程序设计详解

54

基 本 思 想 :将 相 邻 两 个 数 a[0 ]与 a[1]比 较 ,按 要 求 将 这 两 个 数 排 好 序 ;再 将 a[1]与 a[2 ]比 较 ,.…. 依 次 处 理 , 直 到 将 最 后 两 个 数 比 较 处 理 完 毕 。 vo id bubb le (int a[],int n) {in t I,j,te mp for(I=1 ;I<=n -1 ;I++) for(j=0 ;j<=n-I-1 ;j++) if(a [j]>a[j+1]) { te mp=a[j]; a[j]=a[j+1]; a[j+1]= te mp; } } 例 8 : 选 择 法 : 从 所 有 元 素 中 选 择 一 个 最 小 元 素 放 在 a[0 ]作 为 第 一 轮 ; 第 二 轮 是 从 a[1 ]开 始 到 最 后 一 个 元 素 选 择 一 个 最 小 的 放 在 a [1]中 以 此 类 推 。 n 个 数 要 比 较 n -1 轮 。 vo id selectsort(in t a [], int n ) {in t I,j,p,te mp ; for(I=0 ;I<n -1;I++ ) {p= I; fo r(j= I+1 ;I<n ;I++) if(a [j]<a[p]) p=j; if(p!= i) {te mp=a[p];a [p]=a [i];a [i]=te mp ;} } } 例 9:插 入 法 : 有 n 个 数 , 已 按 由 小 到 大 顺 序 排 列 好 , 要 求 输 入 一 个 数 据 , 把它插入到原有数列中,而仍然保持有序。 vo id f(int a[ ], in t n, in t x) {in t I,j; wh ile(a [i]<=x && i<n ) i++; If(a[i]>x) {for(j=n -1;j>= I;j--) a[j+1]=a [j]; a [i]=x; } else a [i]=x; } 改写:

C 语言程序设计详解
vo id f(int a[ ], in t n, in t x) {in t I,j; wh ile(a [i]<=x && i<n ) i++; for(j=n -1 ;j>= I;j--) a[j+1]=a [j]; a[i]=x ; } 例 10 : 插 入 法 : 下 面 程 序 的 运 行 结 果 是 ( main () { in t I=0 ,n=3,j,k=3; in t a [5]={1 ,4,5}; wh ile(I<=n&&k>a[I]) I++; for(j=n -1 ;j>= I;j--) a[j+1]=a [j]; a[i]=k ; for(I=0;I<=n;I++) prin tf(“%3d” ,a[i]); } 答案:1 3 4 5 例 11 : 插 入 法 : 若 有 以 下 程 序 段 : ………….. int a[]={4,0,2 ,3,1}, I, j, t; for(I=1;I<5;I++ ) {t=a[i];j= I-1 ; wh ile (j>=0&&t<a [j]) {a [j+1]=a [j];j--;} a [j+1]=t; } for(I=0;I<5;I++ ) prin tf(“%d ”,a [i]); ………… 则该程序段的输出结果是( 答案:0 1 2 3 4 ) 。

55

) 。

例 12 : 下 面 程 序 用 “ 两 路 合 并 法 ” 把 两 个 已 按 升 序 排 列 的 数 组 合 并 成 一 个 升序数组。请填空。 main () { in t a [3]={5 ,9,19 }; in t b [5]={12 ,24,26,3 7 ,48}; in t c [10], I=0, j=0,k=0; wh ile(I<3 &&j<5) if(_______ ___)

C 语言程序设计详解
{c[k ]=b[j];k++;j++;} e lse {c[k ]=a[i];k++;I++;} wh ile(_____ ___) { c[k]=b[j];k++;j+ +;} wh ile(_____ ___) { c[k]=a[i];k++;I+ +;} for(I=0 ;I<k ;I++) p rintf(“ %3d”,c [i]); } 例 13 : 折 半 查 找 法 vo id b ina ry_se arch (int a[], in t n, in t x) {in t mid, top=0,bo t=n -1 , I,find=0 ; do {mid=(top+bot)/2; if(x==a[mid]) {p rin tf(“ found” );find=1;} e lse if(x<a[mid]) bo t= mid -1 ; e lse bo t= mid+1; }wh ile ((top<=bot)&&(find==0)); }

56

例 14 : 下 面 程 序 用 “ 顺 序 查 找 法 ” 查 找 数 组 a 中 是 否 存 在 某 一 关 键 字 。 请 填空。 main () {in t a [8]={25 ,57,48,3 7, 12,92,86,33 }; in t I,x; scan f(“ %d”, &x); for(I=0 ;I<8 ;I++) if(x==a[I]) {prin tf(“ Found ! The index is :%d \n”, --i);__ __________ ;} if(_____ _______ ) p rintf(“Can ’t found !”); } 例 15:要 求 写 一 函 数 , 实 现 对 包 含 任 意 个 数 据 的 数 列 实 现 头 尾 颠 倒 。 vo id f(in t a[ ], int n) {in t I,t; for(I=0 ;I<n /2;I++) { t=a[i];a[i]=a[n -i];a [n -i]=t; } } 例 16 : 下 面 程 序 的 运 行 结 果 是 ( ) 。

C 语言程序设计详解
main () {in t a [10]={1 ,2,2,3, 4,3 ,4,5,1,5 }; in t n=0, I,j,c,k ; for(I=0 ;I<10 -n;I++) {c=a[i]; for(j= I+1;j<10 -n ;j++) if(a [j]==c) {for(k=j;k<10 -n ;k++) a[k ]=a[k+1]; n++; } } for(I=0 ;I<10 -n;I++) p rintf(“ %d”,a [i]); } 答 案 : 12345 例 17 : 当 从 键 盘 输 入 18 并 回 车 后 , 下 面 程 序 的 运 行 结 果 是 ( main () { int x, y, I,a [8], j,u , v; sc anf(“%d” ,&x); y=x ;I=0; do { u= y/2 ; a [i]= y%2 ; I++ ;y=u; }wh ile (y>=1); fo r(j= I-1;j>=0;j--) p rin tf(“%d”,a [j]); } 答 案 : 10010

57

) 。

例 18 : 有 17 个 人 围 成 一 圈 , 编 号 为 0—16, 从 第 0 号 的 人 开 始 从 1 报 数 , 凡 报 到 3 的 倍 数 离 开 圈 子 ,然 后 再 数 下 去 ,直 到 最 后 只 剩 下 一 个 人 为 止 ,问 此 人 原来的位置是多少号。 main () {in t a [17], I, t=0,s=0 ; for(I=0 ;I<17 ;I++) a[i]=1 ; wh ile(t<=16) { for(I=0;I<17;I++) if(a [i]==0) {s=s+ 1; if(s%3==0) {a[i]=0;t=t+1;}

C 语言程序设计详解
} } for(I=0 ;I<17 ;I++) if(a [i]==1) printf(“%d”, i); } 二、二维数组 1、 二 维 数 组 的 定 义 二维数组定义的一般形式为: 类型说明符 注意: 数 组 名 [常 量 表 达 式 ][常 量 表 达 式 ]

58

二 维 数 组 在 内 存 中 是 按 一 维 连 续 顺 序 存 放 的 。 设 有 一 个 m*n 的 二 维 数 组 a, 其 中 第 i 行 第 j 列 元 素 a[i][j]在 数 组 中 的 顺 序 号 计 算 公 式 为 : i*n +j 例 19 : 以 下 对 二 维 数 组 a 的 正 确 说 明 是 ( A) int a [3 ][] 答案:C 2、 二 维 数 组 的 引 用 二 维 数 组 的 元 素 的 表 示 形 式 为 : 数 组 名 [下 标 ][下 标 ] 例 20 : 若 有 说 明 : int a[3][4];则 对 数 组 元 素 的 正 确 引 用 是 ( A) a[2][4 ] 答案:C 3、 二 维 数 组 初 始 化 ①分行给二维数组赋初值 如 : in t a [3][4]={{1,2, 3,4},{5 ,6,7,8 },{9, 10,11 ,12}}; ②可写在一个花括弧内 如 : int a[3 ][4 ]={1,2, 3,4,5,6,7, 8,9,10,11 ,12}; ③可给部分赋值 如 : in t a [3][4]={1 ,2,3 }; 如 : in t a [3][4]={{1}, {2},{3}}; ④可省略一维长度 如 : in t a [ ][4]={1 ,2,3, 4,5,6,7,8, 9,10}; 如 : in t a [ ][4]={{1}, {2},{3}}; B) a[1,3] C) a[1+1][0 ] D) a(2)(1 ) ) 。 B) flo at a (3,4 ) C) do uble a[1][4] ) 。 D) floa t a(3)(4 )

C 语言程序设计详解
。 例 21 : 以 下 不 能 对 二 维 数 组 a 进 行 正 确 初 始 化 的 语 句 是 ( ) A) int a [2 ][3 ]={0}; B) int a[ ][3 ]={{1 ,2},{0}}; C) int a[2 ][3 ]={{1,2 }, {3,4}, {5,6}}; D) int a [ ][3 ]={1,2,3 ,4 ,5,6}; 答案:C

59

例 22 : 若 有 说 明 :int a[ ][3]={1 ,2,3,4 ,5,6,7 };则 a 数 组 第 一 维 的 大 小 是( ) 。 答案:3

4、 函 数 参 数 (p 160) 例 23 : 求 一 个 3 *4 矩 阵 的 所 有 靠 外 侧 的 元 素 之 和 。 设 矩 阵 为 : 3 a= 2 7 8 5 0 9 –3 -1 10 5 4

main () {in t add (int m, int n, int arr[]); in t total,a[3 ][4 ]={3,8, 9,10,2,5, -3,5,7 ,0, -1,4}; to ta l=add(3, 4,a[0]); printf(“to ta l=%f” ,to ta l); } add(int m, int n, int arr[]) {in t I,j,su m=0 ; for(I=0 ;I< m;I= I+ m-1 ) for(j=0 ;j<n;j++) su m=su m+a rr[I*n+ j]; for(j=0 ;j<n ;j= j+n -1 ) fo r(I=1;I< m-1 ;I++) su m= su m+arr[I*n +j]; } 5、 二 维 数 组 举 例 例 24 : 将 一 个 二 维 数 行 、 列 互 换 后 输 出 。 Void f(in t a[ ], in t n, in t m ,int b[ ]) {in t I,j; for(I=0;I<n;I++ ) for(j=0 ;j< m;j++) b[j*n+ i]= a [I*m+ j];

C 语言程序设计详解
for(j=0 ;j< m;j++) { fo r(I=0;I< n;I++) p rin tf(“%4d”,b [j*n+ i]); prin tf(“ \n”); } } 例 25 : 求 矩 阵 对 角 线 元 素 之 和 main () {in t a [3[3 ]={1,3,6 ,7,9, 11,14,15,17},su m=0 , I, j; for(I=0 ;I<3 ;I++) for(j=0 ;j<3;j++) if((I== j)||(I+ j==3)) su m=su m+a[I][j]; }

60

例 26 : 下 面 程 序 的 功 能 是 检 查 一 个 二 维 数 组 是 否 对 称 ( 即 : 对 所 有 I 和 j 都 有 a[I][j]=a[j][I]) 请 填 空 。 。 main () {in t a [4][4]={1 ,2,3,4, 2, 2,5,6,3,5, 3,7,4,6 ,7,4}; in t I,j,found=0 for(I=0 ;I<4 ;I++) for(j=0 ;J<I;J++) if(a[i][j]!=a[j][i] ) {foun d=1;b reak;} if(found) p rin tf(“N o”); } 例 27 : 以 下 程 序 是 求 矩 阵 a,b 的 和 , 结 果 存 入 矩 阵 c 中 并 按 矩 阵 形 式 输 出 。 请填空。 a= 2 -4 3 -1 0 1 b= -7 -8 -9 10

main () {in t a [3][2]={2 , -1, -4,0, 3,1}; in t b [4][3]={7 , -9, -8,1 0}; in t I,j,k,s, c[3 ][2 ]; for(I=0 ;I<3 ;I++) fo r(j=0;j<2;j++) {for(s=0,k=0 ;k<2;k++) s+=a[i][k]*b[k ][j]; c[i][j]=s; } for(I=0 ;I<3 ;I++)

C 语言程序设计详解
{ for(j=0 ;j<2 ;j++) p rin tf(“%6d”,c [I][j]); p rintf(“ \n” ); } } 例 28 : 下 面 程 序 的 运 行 结 果 是 ( main () {in t I,j,ro w,co l, min ; in t a [3][4]={{1,2,3 ,4},{9,8,7, 6},{-1, -2,0,5 }}; min=a[0][0 ]; for(I=0 ;I<3 ;I++) for(j=0 ;j<4;j++) if(a[i][j]< min) {min=a [i][j];row= I;co l=j;} printf(“%d,%d ,%d \n”, min, ro w,co l); } 答案: ) 。

61

例 29 : 找 出 一 个 二 维 数 组 中 的 鞍 点 , 即 该 位 置 上 的 元 素 在 该 行 上 最 大 , 在 该列上最小。也可能没有鞍点。 vo id f31(in t m, in t n, in t arr[] ) {in t I,j,k, max ,ro w,c ol, flag ; for(I=0 ;I< m;I++) {max=a rr[I*n+0]; row= I;col=0 ; fo r(j=1;j<n;j++) if(arr[I*n+j]>max) {max=a rr[I*n +j]; ro w= I;co l=j;} flag=1 ; for(k=0;k< I;k++) if(a rr[k *n+ j]< ma x) flag=0 ; if(flag==1) prin tf(“ 鞍 点 的 位 置 : 第 %d 行 , 第 %d 列 ”, I,j); } } 例 30 : 打 印 出 以 下 的 杨 辉 三 角 形 (包 括 10 行 ) 1 1 1 1 1 1 1 2 3 4 5 1 3 6 1 4 1 5

10 10

C 语言程序设计详解
…....….... . ma in () {in t a[10][10], I, j; for(I=0 ;I<10 ;I++) { a[I][0 ]=1; a[I][I]=1; } for(I=2 ;I<10 ;I++) for(j=1 ;J<I;j++) a [I][j]=a[I-1 ][j]+a[I-1][J -1]; }

62

例 31 : 下 面 是 一 个 5 *5 阶 螺 旋 方 阵 。 试 编 程 打 印 出 此 形 式 的 n *n 的 方 阵 1 16 15 14 13 2 17 24 23 12 3 18 25 22 11 4 19 20 21 10 5 6 7 8 9

main () { in t a [10][10 ], I, j,k=0, m,n; printf(“%d”, &n); if(n%2==0) m=n /2 ; else m=n /2+1; for(I=0 ;I< m;I++) { for(j= I;j<n -I;j++) {k++;a[i][j]=k;} for(j= I+1 ;j<n -I;j++) {k++;a[j][n -I-1 ]=k;} for(j=n -I-2;j>= I;j--) {k++;a[n -I-1][j]=k;} for(j=n -I-2;j>= I+1;j--) {k++;a[j][i]=k;} } for(I=0;I<n;I++ ) {for(j=0;j<n;j++) p rin tf(“%5d”,a [i][j]); p rintf(“ \n” ); } } 三、字符数组 用来存放字符数据的数组是字符数组。字符数组中的一个元素存放一个字

C 语言程序设计详解
符。 1、 字 符 数 组 的 定 义 char a [10]; 2、 字 符 串 的 结 束 标 志

63

为了测定字符串的实际长度,C 语言规定了一个“字符串的结束标志” 以 , 字 符 ‘\0’代 表 。 例 32 : 下 面 程 序 段 的 运 行 结 果 是 ( ) char c [5]={‘a ’,’b ’,’\0 ’, ’c’, ’\0’}; prin tf(“%s”,c ); 答 案 : ab 3、 字 符 数 组 的 初 始 化 ①逐个字符赋值 char c [10]={‘c ’,’o ’, ’m’,’p’, ’u’, ’t’,’e’, ’r ’}; ②对一个字符数组指定一个字符串初值 char c [10]={“co mp ute r”}; 系统允许在初始化一个一维字符数组时,省略字符串常量外面的花括号。 如 : char c[10 ]=”co mp uter” 例 33 : 下 面 是 对 s 的 初 始 化 , 其 中 不 正 确 的 是 ( ) A) char s[5]={“ abc”}; B) char s[5]={‘a ’,’b ’, ’c’}; C) char s[5]=”” D) char s[5]=”ab cdef” 答案:D 例 34 : 对 两 个 数 组 a 和 b 进 行 如 下 初 始 化 char a []=”ABCDEF”; char b []={‘A’, ’B’,’C ’,’D’,’E’, ’F’};则 以 下 叙 述 正 确 的 是 ( A) a 与 b 数 组 完 全 相 同 C) a 和 b 中 都 存 放 字 符 串 答案:D 4、 字 符 数 组 的 输 入 和 输 出 B) a 与 b 长 度 相 同 D) a 数 组 比 b 数 组 长 度 长 ) 。

C 语言程序设计详解
① 逐 个 字 符 输 入 输 出 。 用 格 式 符 “%c ”输 入 或 输 出 一 个 字 符 。 ② 将 整 个 字 符 串 一 次 输 入 和 输 出 。 用 “ %s” 。

64

③ 为 了 解 决 sc anf 函 数 不 能 完 整 地 读 入 带 有 空 格 字 符 的 字 符 串 , C 语 言 提 供 了 一 个 专 门 用 于 读 字 符 串 的 函 数 ge ts, 它 读 入 全 部 字 符 ( 包 括 空 格 ) 直 到 遇 到 , 回 车 符 为 止 , 用 g ets(s)表 示 。 puts(s)的 作 用 是 将 一 个 字 符 串 ( 以 ’\0’结 束 的 字 符 序 列 ) 输 出 到 终 端 , 在 输 出 时 将 字 符 结 束 标 志 ’\0’转 换 成 ’\n ’, 即 输 出 完 字 符 串 后 换 行 。 例 35 : 下 面 程 序 段 的 运 行 结 果 是 ( ) char c [5]={‘a ’,’b ’,’\0 ’, ’c’, ’\0’}; prin tf(“%s”,c ); A) ’a’’b’ 答案:B 例 36 : 有 两 个 字 符 数 组 a、 b, 则 以 下 正 确 的 输 入 语 句 是 ( ) A) gets(a,b); C) scanf(“%s%s”, &a, &b); 答案:B 例 37 : 有 字 符 数 组 a[80]和 b[8 0],则 正 确 的 输 出 语 句 是 ( ) A) puts(a,b) C) putcha r(a ,b) 答案:D 5、 字 符 串 运 算 函 数 ① 字 符 串 拷 贝 函 数 strc p y 如 strcp y(str1 ,”Chin a”) ② 字 符 串 连 接 函 数 strc at 如 strca t(str1,str2) ③ 字 符 串 比 较 函 数 strc mp 如 strc mp(str1, str2) ④ 测 字 符 中 长 度 函 数 strlen 如 strlen(“Co mputer”) 例 38 ; 下 面 程 序 段 的 运 行 结 果 是 ( ) char c [ ]=” \t\v\\\0 will\n”; prin tf(“%d ”,strlen (c)); 答案:3 例 39 : 下 面 程 序 段 的 运 行 结 果 是 ( ) 。 strcp y(str1,str2 ) B) prin tf(“%s,%s” ,a[],b[]); D) puts(a ),pu ts(b) B) sc anf(“%s%s”, a,b); D) ge ts(“a” ),gets(“b” ); B) ab C) ab c D) a b

C 语言程序设计详解
char a [7]=”a bcdef”; strcp y(a,b); prin tf(“%c”,a [5]); 答案:e 例 40 : 判 断 字 符 串 a 和 b 是 否 相 等 , 应 当 使 用 ( ) A) if(a==b) C) if(strc mp(a ,b)) 答案:C 6、 二 维 数 组 B) if(a=b) D) if(strcp y(a ,b)) char b[4 ]=”ABC”;

65

二 维 数 组 可 以 认 为 由 若 干 个 一 维 数 组 所 组 成 的 , 因 此 一 个 n *m 的 二 维 字 符 数组可以存放 n 个字符串。 例 41 : 写 出 程 序 的 输 出 结 果 ( ) main () { char str[3][6]={“Ch in a”,”Japan”,” Korea”}; str[1 ][5]=’ ’; printf(“%s\n”, str[1 ]); } 答 案 : Japan Korea 7、 字 符 串 数 组 举 例 例 42 : 下 面 程 序 段 将 输 出 co mpu te r, 请 填 空 。 char c []=” It’s a co mputer” ; for(I=0;_ ___________ _ ;I++) {___ _________ ;prin tf(“%c” ,c[j]); } 答案: I<=7 J=I+7 例 43 : 下 面 程 序 段 的 运 行 结 果 是 ( char x []=” the teach er” ; I=0 ; while (x[++i]!=’\0’) if(x[I-1 ]==’t’) p rintf(“%c” ,x[i]); ) 。

C 语言程序设计详解
答 案 : he 例 44:删 除 字 符 删除一个字符串中的一个字符 ① void d el(cha r a [ ],char b [ ],int n)

66

{in t I,j=0 ; for(I=0;a[i]!=’\0’;I++) if(I!=n) } ② void { strcp y(&a[n ],&a[n+ 1]); } 删除一个字符串中的某个字符 vo id f(ch ar a [ ],cha r x) {in t I; for(I=0;a[i]!=’\0’;I++) if(a[i]==x) } 下 例 45 : 面 程 序 的 功 能 是 将 已 按 升 序 排 好 序 的 两 个 字 符 串 a 和 b 中 的 字 符 按 升序归并到字符串 c 中,请填空。 # inc lude “stdio.h” ma in() { char a []=”a cegik m” ; char b []=”bd fhjlnpq ”; char c [80], *p; int I=0, j=0,k=0; while (a[i]!=’\0’ && b [j]!=’\0’) {if(a [i]<b[j]) (_____ ________); else (___________ _); k++; } c [k]=’\0’; if(____________ ) p=b+j; strcp y(&a [I],&a[I+1 ]); d el(cha r a [ ],in t n) b[j++]=a[i]

C 语言程序设计详解
e lse p=a+ I; strcat(c,p ); pu ts(c); } 答案: c [k]=a[I++] c [k]=b[j++] a [i]==’\0 ’ 例 46 : 下 面 程 序 的 功 能 是 在 三 个 字 符 串 中 找 出 最 小 的 。 请 填 空 。 ma in() {cha r s[20], str[3][20]; int I; for(I=0;I<3;I++ ) gets(str[i]); strcp y(s,______ __); if(strc mp(str[2 ],s)<0) strcp y(s, str[2 ]); prin tf(“%s\n ”,_______ ___); } 答案: (strc mp(str[0 ], str[1 ]))<0? str[0 ]:str[1] s 例 47 : 下 面 程 序 的 运 行 结 果 是 ( ) #inc lude “ stdio .h” main ( ) {char s[ ]=”ABCCDA”,c; in t k ; for(k=1;(c=s[k ])!=’\0’;k++) {switch (c) {case ‘A’:pu tcha r(‘%’);con tinue ; case ‘B’:++k ;bre ak; defau lt:pu tcha r(‘*’); case ’C’:putc har(‘&’);c ontinue ; } pu tcha r(‘#’); } } 答 案 : #&*&%

67

例 48:输 入 一 行 字 符 , 统 计 其 中 有 多 少 个 单 词 , 规 定 单 词 间 以 一 个 或 多 个 空 格相隔。 #inc lude “ stdio .h” main ( )

C 语言程序设计详解
{ char string [81 ]; int I, s=0,flag=0 ; gets(string ); for(I=0;string[i]!=’\0’;I++) { if((flag==0)&&(a[i]>=’a’&&a[i]<=’z ’)||(a[i]> =’A’&&a [i]<=’Z’)) {flag=1; s=s+1; } if a[i]=’ ’ flag=0 ; } prin tf(“%d ”,s); } 例 49:有 n 个 国 家 名 , 要 求 按 字 母 先 后 顺 序 排 列 , 并 按 序 输 出 。 昌 泡 法 : vo id bubb le (int a [], in t n) {in t I,j,te mp for(I=1 ;I<=n -1 ;I++) for(j=0 ;j<=n-I-1 ;j++) if(a [j]>a[j+1]) { te mp=a[j]; a[j]=a[j+1]; a[j+1]= te mp; } } 选择法: vo id selectsort(in t a [], int n ) {in t I,j,p,te mp ; for(I=0 ;I<n -1;I++ ) {p= I; fo r(j= I+1 ;I<n ;I++) if(a [j]<a[p]) p=j; if(p!= i) {te mp=a[p];a [p]=a [i];a [i]=te mp ;} } }

68

C 语言程序设计详解

69

第六章

指针

一、指针的概念 指 针 即 地 址 ,一 个 变 量 的 指 针 就 是 指 该 变 量 的 地 址 ,存 放 指 针 的 变 量 就 是 指 针变量。 注意:指针变量中只能存放地址。 二、指针变量的定义和引用 1、 指 针 变 量 的 定 义 int *p; 注意: ① *是 指 针 变 量 的 特 征 ②只是分配了一个存储单元,并没有指真正指向,要想使一个指针变量 指向一个整型变量必须赋值。例如: in t *p, I= 3; p=&I; 2、 指 针 变 量 的 引 用 ( 两 个 有 关 指 针 的 运 算 符 ) 此 语 句 定 义 了 一 个 指 针 变 量 p, p 中 可 存 放 一 个 整 型 变 量 的 地 址 。

C 语言程序设计详解
①& ②* 例 3: int *p,a ; p=&a; scanf(“%d” ,p); *p=5 ; / *指 向 变 量 a 的 值 赋 给 p */ 取地址运算符号 指针运算符 *p 表 示 p 所 指 向 的 变 量 值 。

70

/*从 键 盘 输 入 一 个 值 赋 值 给 p 所 指 向 的 变 量 a */ / *把 5 赋 值 给 变 量 p 所 指 向 的 a */

例 4: 使 两 个 指 针 变 量 交 换 指 向 ma in() { int *p1,*p2 , *p,a=10,b= 20; p1=&a,p2=&b ; prin tf(“%d ,%d \n”, *p1 , *p2 ); p=p1;p1=p2;p2=p ; prin tf(“%d ,%d \n”, *p1 , *p2 ); } a 10 &a p1 a 10 &b p1

b

20 (a)

&b

p2

b

20 (b)

&a

p2

例 5: 交 换 两 个 指 针 变 量 所 指 向 的 变 量 的 值 。 ma in () { int *p1,*p2 ,a=10,b=20, t; p1=&a,p2=&b ; prin tf(“%d ,%d \n”, *p1 , *p2 ); t= *p1;*p 1= *p2 ;*p2= t; prin tf(“%d ,%d \n”, *p1 , *p2 ); } a 10 &a p1 a 20 &a p1

b

20 (a)

&b

p2

b

10 (b )

&b

p2

。 例 6: 以 下 程 序 错 误 的 原 因 是 ( ) main ( )

C 语言程序设计详解
{ int *p, *q, a,b ; p=&a;q=&b; scan f(“ %d”, *p ); *p= *q ; } 答案:

71

。 例 7 : 若 有 定 义 int a= 5;下 面 对 ( 1) ,( 2) 两 个 语 句 的 正 确 解 释 是 ( ) 1、 in t *p= &a; 2、 *p=a ;

A) 语 句 1 和 2 中 的 *p 含 义 相 同 。 B) 1 和 2 语 句 的 执 行 结 果 都 是 把 变 量 a 的 地 址 赋 给 指 针 变 量 p C) 1 在 对 p 进 行 说 明 的 同 时 进 行 初 始 化 , 使 p 指 向 a, 2 将 变 量 a 的 值 赋 给 指 针 变 量 p。 D) 1 在 对 p 进 行 说 明 的 同 时 进 行 初 始 化 , p 指 向 a,2 将 变 量 a 的 值 赋 于 *p。 使 答案: 若 ( 。 例 8 : 有 语 句 int *po int,a=4 ;和 po int= &a;下 面 均 代 表 地 址 的 一 组 选 项 是 ) A) C) a, po in t, *&a *&poin t, *p oin t, &a B) &*a ,&a, *p oin t D)&a, &*point, poin t

答案: 三、指针作为函数参数 函 数 的 参 数 不 仅 可 以 是 整 型 、实 型 、字 符 型 等 数 据 ,还 可 以 是 指 针 类 型 ,它 的作用是将一个变量的地址传送到另一个函数中。 例 9:输 入 a 和 b 两 个 整 数 , 按 先 大 后 小 的 顺 序 输 出 a 和 b。 main ( ) { vo id swap (int *p x, int *p y); int x, y; swap (&x, &y); if(x< y) swap (&x ,&y); prin tf(“%d ,%d”,x , y); } void swap (int *px, int *p y) { int t;

C 语言程序设计详解
t= *px; ma in( ) X *px =*p y; *p y= t; } swap(px ,p y) px &a py y &b

72

例 10 : 一 组 数 组 有 10 个 元 素 , 要 求 输 出 最 大 值 和 最 小 值 。 ma in( ) {in t arr[1 0]={-1,2,3, -4, -5 ,7,8,9, 10, -7 }, *p1, *p2, a,b ; p1= &a;p 2=&b; max_ min (arr,p1,p2 ); p rintf(“ %d,%d” ,a,b ); } vo id max min(in t a rr[ ], int *pt1,int *p t2 ) {int I; *p t1= *p t2= arr[0 ]; for(I=1;I<10;I++) {if(*p t1>a rr[i]) *p t1=arr[i]; if( *pt2>a rr[i]) *p t2=arr[i]; } } 四、指针与数组 1、 一 维 数 组 的 指 针 表 示 方 法 ( 1) 数 组 中 各 元 素 的 地 址 。 int a[10 ]={1,2 ,3,4,5, 6, 7,8,9,10}; a 1 2 3 4 5 6 7 8 9 10

① &a[0 ] ②a 注意:

&a [1] a+1

&a[2] 、 、 &a[i]、 、 &a [9 ] 、 、 a+2 、 、 a+ i、 、 、 a+9 、 、、

在 编 译 系 统 计 算 实 际 地 址 时 , a+i 中 的 i 要 乘 上 数 组 元 素 所 占 的 字 节 数 , 即 a+i*(一 个 元 素 所 占 的 字 节 数 )

C 语言程序设计详解
( 2) 数 组 元 素 值 ① a[0] a [1] a[2 ] 、 、 a[i]、 、 a[9 ] 、、 、、 *(a+ 2)、 *(a+i) 、 *(a+9 )

73

② *(a+0) *(a+1) 说明:

引 用 一 个 数 组 元 素 , 可 以 用 下 标 法 : 如 a[i]形 式 ; 也 可 以 用 指 针 法 如 *(a+i) 形式。 例 11 : 若 有 以 下 定 义 , in t a[5], *p=a ;则 对 数 组 元 素 的 正 确 引 用 是 ( ) ( A) *&a[5] 答案: 例 12 : 对 数 组 元 素 地 址 的 正 确 引 用 是 ( ) ( A) p+5 答案: 例 13 : 若 有 定 义 ,则 数 值 不 为 3 的 表 达 式 是 ( int x[10 ]={0,1, 2,3,4,5 , 6,7,8,9}, *p1; A) C) x[3 ] p1=x+2, *(p1++) B) D) p1=x+3, *p1++ p 1=x+2, *++p1 ) : ( B) *a+1 ( C) &a+1 ( D) &a[0 ] ( B ) a+2 ( C) *(p+5) ( D) *(a+2 )

答案: 例 14 : 分 别 用 下 标 法 、 地 址 法 访 问 数 组 元 素 main ( ) {in t a [5]={1, 3,5,7,9 }, I, *p ; for(I=0 ;I<5 ;I++) p rintf(“ %d”,a [i]); for(I=0;I<5;I++ ) p rintf(“ %d”, *(a+i)); for(p=0;p<a+5;p++) prin tf(“%d” , *p); } 注意: ① 指 针 变 量 可 以 实 现 使 本 身 的 值 改 变 , 但 不 要 出 现 a++, 因 为 a 是 数 组 名 , 它是数组首地址是常量,它的值在程序运行期间是固定不变的。

C 语言程序设计详解
②要注意指针变量的当前值。 2、 二 维 数 组 的 指 针 表 示 方 法 例 : in t a [3][4]={1 ,2,3, 4,5,6,7,8, 9,10,11,12 }; 1、 每 行 的 起 始 地 址 a

74

① &a[0 ][0 ] a[0 ] a [0][0] 1 a[1 ] a[1 ][0 ] 1 a[2 ] a[2 ][0 ] 1 ② a[0 ] a

&a[1 ][0 ] a [0][1] 2 3 a[1 ][1] 2 3 a[2 ][1] 2 a[1] 3

&a [2][0] a [0][2] 4 a[1 ][2 ] 4 a[2 ][2 ] 4 a[2 ] a [2][3] a [1][3] a[0 ][3 ]

a[0] a[1] a[2] ③ a+0 ④ *a ⑤ &a[0 ] 1 5 9 ③ *a+1 3、 各 元 素 的 值 ① *(&a [0][0]) ② *(a[0 ]+1) ③ *(*a+1) *( &a[0 ][1 ]) *(a[0 ]+2) *(*(a+1)+1) *(&a[0][2]) *(a [1]+2) *( *(a+2 )+2) 2 6 10 a+1 *(a+1 ) &a[1 ] 3 7 11 4 8 12 a+2 *(a+2) &a[2] 2、 各 元 素 的 地 址 ① &a[0 ][0 ] ② a[0]+1 *(a+2)+2 &a [0][1] a[0 ]+ 2 &a [0][2] a [1]+2

*(a+ 1)+1

C 语言程序设计详解
例 15 : 指 向 数 组 元 素 的 指 针 变 量 main ( ) {in t a [3][4]={1 ,2,3,4, 5, 6,7,8,9,10 ,11,12}; in t *p ; for(p=a[0 ];p<a[0 ]+15;p++) p rintf(“ %d”, *p ); } 例 16 : 指 向 一 维 数 组 的 指 针 变 量 main ( ) {in t a [3][4]={1 ,2,3,4, 5, 6,7,8,9,10 ,11,12}; in t I, j, ( *p) [4]; p=a; for(I=0 ;I<3 ;I++) for(j=0 ;j<5;j++) p rintf(“ %d”, *( *(p+ I)+j)); } 注意: int (*p )[5 ]表 示 p 是 指 针 变 量 , 它 指 向 一 个 包 含 5 个 元 素 的 一 维 数 组 int *p[5 ] 是 指 针 数 组 。

75

例 17 : 若 有 以 下 定 义 和 语 句 in t a [2][3],(*p )[3];p=a;则 对 a 数 组 元 素 地 址 的 正确引用为( ) ( A) *( p+2) ( B) p [2] ( C) p[1 ]+1 ( D) (p+1)+2

则对 a 数组元素的正确引用是() ( A) p+1) [0] ( B) *(*(p+2)+1) ( C ) *(p[1 ]+1) ( 例 18 : 若 有 以 下 定 义 : int x[4 ][3 ]={1,2,3 ,4,5, 6,7,8,9,10 ,11,12}; int (*p )[3 ]=x; 则 能 够 正 确 表 示 数 组 元 素 x[1 ][2 ]的 表 达 式 是 ( ) ( A) *((*p+1)[2]) ( C) *(*(p+5)) 答案: 例 19 :若 有 以 下 定 义 和 赋 值 语 句 ,则 对 b 数 组 的 第 I 行 第 j 列 元 素 的 非 法 引 ( B) (*p+1)+2 ( D) *( *(p+1 )+2) ( D) p[1]+2

C 语言程序设计详解
用为( ) 。

76

Int b[2 ][3 ]={0},(*p )[3 ]; P =b; A) *( *(p+ i)+j) C) (p+i)+j B) D) *(p [i]+j) (*(p+ i))[j]

例 20 : 写 出 下 面 的 输 出 结 果 main ( ) { int *p,a [10]={1 ,2,3,4 ,5 ,6,7,8,9,1 0}; p=a ; scan f(“%d”,&*p ); prin tf(“%d ”, *&a [0 ]); prin tf(“%d ”, *p++); prin tf(“%d ”,(*p )++); prin tf(“%d ”, *++p); prin tf(“%d ”,++ *p ); } 答案: 注 意 : ++、 *、 &同 优 先 级 , 是 向 右 而 左 的 结 合 方 向 。 按 自 右 向 左 方 向 结 合 运 算 , 因 此 先 执 行 *再 执 行 &。 按 自 右 向 左 方 向 结 合 运 算 , 因 此 先 执 行 &再 执 行 *。

3、 数 组 指 针 作 为 函 数 参 数 在数组一章中介绍了数组名作函数参数的情况。数组名代表数组起始地址, 用数组名作参数传递的是地址(将数组起始地址传递组被调用函数的形参) 既 , 然地址可以作为参数传递,那么指向数组的指针变量当然也可以作为函数参数。 例 21 : 求 二 维 数 组 中 全 部 元 素 之 和 main ( ) { in t a [3][4]={1,2,3,4 ,5 ,6,7,8,9,1 0,11,12}; int *p=a[0 ], total; total=add (p,12 ); prin tf(“ to tal=%d \n”, to tal); } in t add (int arr[ ], int n ) { int I, su m=0 ;

C 语言程序设计详解
for(I=0 ;I<n ;I++) su m=su m+a rr[i]; re turn (su m); } 注意:

77

在 用 数 组 名 作 函 数 参 数 时 ,数 组 名 代 表 数 组 首 地 址 ,在 调 用 函 数 时 ,实 际 上 是把数组的首地址传给形参,形参与实参共占用一段内存。 例 22 : 有 3 个 学 生 , 每 人 考 5 门 课 , 求 每 个 学 生 的 平 均 分 和 每 门 课 的 平 均 分数 main ( ) { floa t stu_ a ve(float (*p )[5]); floa t cou r_a ve (floa t *p t); floa t score[3 ][5 ]={{10 0,60,70,80, 67}, {62,71, 98,45,57}, {90,39 ,89,39 ,90}}; int I; for(I=0;I<3;I++ ) prin tf(“%f”,stu_a ve (sco re+i)); for(I=0;I<5;I++ ) prin tf(“%f”,cou r_ ave (sc ore [0]+ i)); } floa t stu_ a ve(float (*p )[5]) { int j; flo at su m; floa t su m=0,a ve ; fo r(j=0;j<5 ;j++) su m= su m + *( *p+j); retu rn(su m/5) } floa t c our_a ve(flo at *p t) {in t I; float su m; for(I=0;I<3;I++ ) {su m= su m+ *p t; pt=p t+5; } retu rn(su m/3); } 五、字符串与指针 字 符 串 ----用 双 引 号 引 起 来 的 0 个 或 多 个 有 效 字 符 序 列 称 为 字 符 串 。 1、 定 义 :

C 语言程序设计详解
char string [10 ]; 2、 初 始 化 char str[12 ]=”ch ina” ; cha r *s=”c hina” ; cha r *s

78

顺 次 赋 值 , 在 末 尾 加 ’\0’作 为 结 束 标 志 。 str c h i n a \0

只 把 chin a 的 首 地 址 赋 给 指 针 变 量 s。 s c h i n a \0

例 23 : 下 面 判 断 正 确 的 是 ( ) ( A) char *a=”ch ina ”;等 价 于 char *a ;*a=”ch ina”; ( B) char str[10 ]={“c hina” };等 价 于 char str[10 ]; str[ ]={“china ”};

( C) char *s= ”china” ; 等 价 于 cha r *s;s=”china”; ( D) char c [4]=”ab c”, d[4]=”abc ”; 等 价 于 c h ar c [4]=d[4 ]=”abc” ; 3、 赋 值 数 组 : cha r str[12 ]; strc p y(str, ” I lo ve Ch ina”); 指 针 : cha r *str2 ; str=” I lo ve Ch ina” ;

str2=” I lo ve China” ; 。 例 24 : 下 面 能 正 确 进 行 字 符 串 赋 值 操 作 的 是 ( ) A) B) C) D) char s[5 ]={“ABCDE”} char s[5 ]={‘A’,’B ’,’C ’,’D’, ’E’}; char *s;s=”ABCDE”; char *s; sc anf(“%s”,s);

答案: 4、 输 入 、 输 出 数 组 : char str[12]; scanf(“%s”,str); prin tf(“%s”,str); ge ts(str); pu ts(str);

C 语言程序设计详解
指 针 : char str1 [20], *str2=str1 ; scan f(“ %s”, str2); p rintf(“ %s”, str2); ge ts(str2); pu ts(str2);

79

例 25 : 下 面 程 序 段 中 , for 循 环 的 执 行 次 数 是 ( ) cha r *s=” \ta\018bc” ; fo r(;*s!=’\0’;s++) 答案: 例 26 : 下 面 程 序 段 的 运 行 结 果 是 ( ) cha r *s=” abcde” ; s+=2;p rintf(“ %d”, s); 答案: 例 27 : 设 有 下 面 的 程 序 段 char s[ ]=”china’;cha r *p ; p=s; 则下列叙述正确的是( ) ( A) s 和 p 完 全 相 同 ( C) *p 与 s[0 ]相 等 ( B) 数 组 s 中 的 内 容 和 指 针 变 量 p 中 的 内 容 相 等 ( D) s 数 组 长 度 和 p 所 指 向 的 字 符 串 长 度 相 等 printf(“ *”);

例 28 : 以 下 正 确 的 程 序 段 是 ( ) ( A) char str[20 ]; scanf(“%s” ,&str);

( B) char *p ; scan f(“ %s”,p ); ( C) char str[20 ]; scanf(“%s” ,&str[2 ]);

( D) char str[20 ], *p=str; scanf(“%s”,p [2]); 答案: 例 29 : 下 面 程 序 段 的 运 行 结 果 是 ( ) cha r str[ ]=”ABC”, *p=str; prin tf(“%d \n”, *(p+3 )); 答案: 例 30 : 若 有 语 句 : char s1 [ ]=” strin g1”,s2 [8], *s3, *s4=” strin g2”; 则 对 库 函 数 strcp y 的 错 误 调 用 是 ( ) 。 ( A) strcp y(s1,”string 2”); ( C) strcp y(s3,” string 1”); ( B) strcp y(s4,” string1”); ( D) strcp y(s1, s2);

C 语言程序设计详解
例 31 : 若 有 说 明 语 句 char a [ ]=” It is mine” ; char *p=” It is mine” ; 则以下不正确的叙述是( ) ( A) a+1 表 示 的 是 字 符 t 的 地 址 ( B) p 指 向 另 外 的 字 符 串 时 , 字 符 串 的 长 度 不 受 限 制 ( C) p 变 量 中 存 放 的 地 址 值 可 以 改 变 ( D) a 中 只 能 存 放 1 0 个 字 符 。 例 32 : 下 面 程 序 段 的 运 行 结 果 是 ( ) char *p=”ab cdefg h”; p+=3 prin tf(“%d \n” ,strlen(strcp y(p,”ABCD”))); A) 8 B) 1 2 C) 4 D) 7 答案:

80

例 33 : 下 面 程 序 的 功 能 是 将 一 个 整 数 字 符 串 转 换 为 一 个 整 数 , 如 ” -1234” 转 换 为 -1234,请 填 空 。 main () {char s[6 ]; in t n ; gets(s); if(*s==’-’) n= -ch nu m(s+1); else n=chnu m(s); printf(“%d\n”,n ); } chnu m(char *p) { in t nu m= 0,k, len, j; len=strlen (p ); for( ;____________ ; p++ ) { k=_____ _________ ; j= --len ; wh ile ( _____ ____ ) {k=k *10 ;} nu m=nu m+k ; } } 答案: *p!=’\0’

C 语言程序设计详解
k=*p -‘\0’ j -- >=0 例 34 : 输 入 一 个 字 符 串 , 内 有 数 字 和 非 数 字 字 符 , q p 如 :a123x4 56 1760? 302ab567

81

将 其 中 连 续 的 数 字 作 为 一 个 整 数 依 次 存 放 到 一 数 组 a 中 ,如 123 存 放 到 a[0 ] 中 , 456 存 放 到 a [1]中 。 main ( ) {char s[80 ], *p , *q; in t a [80], I, t=0,flag=0 ; gets(s);p=s;q=s; for( ; *p!=’\0’ ; p++) { if((*p>=’0’ && *p<=’9 ’)&&(flag= =0)) {flag=1;q =p;} if!((*p<’0 ’||*p> ’9’)&&(flag= =1)) {t=0; for(;q<p;q+ +) s=s*10+ (*q -‘0’); a[j]=s; j= j+1; flag=0; } } } 六、指针与函数 一 个 函 数 包 括 一 系 列 的 指 令 ,在 内 存 中 占 据 一 片 存 储 单 元 ,它 有 一 个 起 始 地 址 ,即 函 数 的 入 口 地 址 ,可 以 通 过 这 个 地 址 找 到 该 函 数 ,这 个 地 址 称 为 函 数 的 指 针。 1、 用 函 数 指 针 调 用 函 数 例 35 : 求 a,b 的 和 。 main ( ) {in t a,b ,c; in t add (int x,int y); scan f(“ %d,%d” ,&a, &b); c=add(a ,b); printf(“%d’,c); } int add(in t x, in t y) {re turn (x+ y);} 2、 指 向 函 数 的 指 针 作 函 数 参 数 ①定义 in t (*p)( ) 指向返回整型值的函数 ②赋值 p=add; 赋值只写函数名 ③调用 c=(*p)(a,b) 调用时根据需要写上实参。

C 语言程序设计详解

82

例 36 : 求 定 积 分 :计 算 [0,1]之 间 函 数 1+x 2 、[0,2]之 间 函 数 1+x+x 2 +x 3 、[0, 3.5]之 间 函 数 x/(1+x 2 )的 定 积 分 。 floa t f1 (floa t x ) {return (1+x *x);} floa t f2(float x) {return (1+x+x *x+x *x *x );} floa t f3 (floa t x ) {return (x/(1+x *x));} floa t integra l(float a, floa t b ,floa t (*fun )( )) { in t n=100, I; floa t s,h=(b -a)/n ; s=((*fun)(a)+ (*fun )(b ))/2; for(I=1;I<n;I++ ) s=s+( *fun )(a+ I*h); retu rn(s*h); } main ( ) { printf(“%f” ,in teg ra l(0 ,1,f1 )); printf(“%f” ,in teg ra l(0 ,2,f2 )); printf(“%f” ,in teg ra l(0 ,3.5,f3 )); } 七、返回指针的函数 一 个 函 数 可 以 带 加 一 个 整 型 值 ,字 符 型 值 、实 型 值 ,也 可 以 带 回 指 针 型 的 数 据,即地址。 例 37 : 编 写 一 个 strch r 函 数 , 它 的 作 用 是 在 一 个 字 符 串 中 找 一 个 指 定 的 字 符,返回该字符的地址。 char *strchr(cha r *str, c har ch ) {wh ile (*str++!=’\0 ’) if(*str==ch) re turn (0); } 八、指针数组和指向指针的指针 1、 指 针 数 组 char *s=”ch ina ” return(str);

char *n a me [5]={“ Li Fu n”,”Zhang li”,” li tian” , ”su fang ”,” wang le ”};

C 语言程序设计详解
例 38 : 有 三 个 字 符 串 , 要 求 按 字 母 顺 序 输 出 。 Char *string [3]={“Da ta Struc ture ”,”Co mpu te r Design”,”C Lan guage” }; Char *p; Int I; If(strc mp(string [0],string[1])>0) { p=sting [0];string [0]=string [1];string [1]=p;} if(strc mp(string[0 ],string[2])>0) {p=string[0 ],string [0]=string [2];string [2]=p;} if(strc mp(string[1 ],string[2])>0) {p=string [1];string [1]=string[2 ];string[2 ]=p;} for(I=0;I<3;I++ ) p rintf(“ %s\n”,strin g[i]); 例 39 : 设 有 以 下 程 序 段 char str[4 ][10 ]={“first” ,”second ”,” third”, ”fou rth”}, *strp [4]; int n; for(n=0;n<4 ;n++) strp[n]=str[n];

83

若 k 为 in t 型 变 量 且 0 <=k<4,则 对 字 符 串 的 不 正 确 引 用 是 A) strp 答案: 例 40 : 以 下 正 确 的 说 明 语 句 是 ( A) int *b [ ]={1,3,5 ,7,9 }; B) int a[5 ], *nu m[5 ]={&a[0 ],&a [1],&a [2],&a [3],&a [4]}; C) int a[ ]={1,3, 5,7,9};in t *n u m[5]={a [0], a[1 ],a[2 ],a [3],a[4 ]}; D) int a [3 ][4 ],(*n u m)[4] nu m[1]=&a[1 ][3 ]; 例 41 : 设 有 以 下 定 义 char *c c[2 ]={“1234” ,” 5678”}; 则正确的叙述是( ) A) cc 数 组 的 两 个 元 素 中 各 自 存 放 了 字 符 串 “ 1234” 和 “ 567 8 ” 的 首 地 址 B)cc 数 组 的 两 个 元 素 分 别 存 放 的 是 含 有 4 个 字 符 的 一 维 字 符 数 组 的 首 地 址 C) cc 是 指 针 变 量 , 它 指 向 含 有 两 个 数 组 元 素 的 字 符 型 一 维 数 组 ) 。 B) str[k] C) strp[k ] D)*strp

C 语言程序设计详解
D) cc 数 组 元 素 的 值 分 别 是 “ 1234” 和 “ 5 678” 答案: 例 42 : 若 有 说 明 : char *langu age[ ]={“ FOR”,”BA”,”PA”,”JA”}; 则 表 达 式 *language [1]> *language [3]比 较 的 是 ( ) langu age[2 ]的 值 是 ( 答案: 例 43 : 若 有 说 明 : char *langu age[ ]={“ FOR”, ”BA”,”PA”,”JA”}; 则以下不正确的叙述是( ) A) Language+2 表 示 字 符 串 “ PA” 的 首 地 址 B) *languag e[2 ]的 值 是 字 母 P )

84

C) language 是 一 个 字 符 型 指 针 数 组 , 它 包 含 5 个 元 素 , 每 个 元 素 都 是 一 个 指向字符串变量的指针 D) language 是 一 个 字 符 型 指 针 数 组 , 它 包 含 5 个 元 素 , 其 初 值 分 别 是 : “ FOR”,”BA”,”PA”,”JA” 2、 指 向 指 针 的 指 针 char **p , *p1,s; 表示指针变量 p 是指向一个字符指针变量。 例 44 : 若 有 以 下 说 明 和 语 句 char *langu age[ ]={“ FOR”,”BA”,”PA”,”JA”}; char **q ;q=language+2 则 语 句 prin tf(“%o”, *q );的 执 行 结 果 是 ( ) 。 答案: 2、 指 针 数 组 作 main 函 数 的 形 参 ( 1) 形 式 main (int a rgc,cha r *a rg v[ ]) 注意: ①第一个形参是整型、第二个形参是指针数组。 ②形参名可以改变,但数据类型不能改。 ( 2) 形 参 来 源 有 一 源 文 件 c file.c ,

C 语言程序设计详解
main (int a rgc,cha r *a rg v[ { ..... ..... } 经 编 译 连 接 后 得 到 一 目 标 文 件 名 为 c file. ex e,从 键 盘 输 入 文 件 名 : cfile co mpu te r cla nguage ])

85

则 arg c 为 3, a rg v[0], a rg v[1], arg v[2 ]分 别 指 向 串 cfile、 co mpu te r、 clanguag e 例 45: ma in(in t a rgc ,c har *a rg v[ {wh ile(a rg c>1) {++arg v; puts(*a rg v); --argc; }} 输 出 结 果 : 例 46: 以 下 正 确 的 叙 述 是 ( ) A) C 语 言 允 许 main 函 数 带 形 参 , 且 形 参 个 数 和 形 参 名 均 由 用 户 指 定 B) C 语 言 允 许 ma in 函 数 带 形 参 , 形 参 名 只 能 是 a rgc 和 a rg v. C)当 ma in 函 数 带 形 参 时 , 传 给 形 参 的 值 只 能 从 命 令 行 中 得 到 。 D) 若 有 说 明 , ma in(int a rgc ,char *a rg v),则 形 参 argc 的 值 必 须 大 于 1。 答案: 例 47: ma in 函 数 的 正 确 形 式 是 ( ) A) main(int a rgc,ch ar *arg v) B) ma in(in t abc, char **abv) C) ma in(in t a rgc, char a rg v) D) main(int c,cha r v[ ]) 答案: ])

C 语言程序设计详解

86

第七章

结构体、共用体和枚举类型数据

一、为什要引入结构体类型 存在着大量要将不同类型的数据组合成一个有机的整体, 些组合在一个整 这 体 中 的 数 据 是 互 相 联 系 的 ,例 如 :一 个 学 生 的 学 号 、姓 名 、分 数 等 。它 们 是 同 一 个 处 理 对 象 ----居 民 的 属 性 , 但 又 不 属 于 同 一 类 型 。 二、结构体类型 1、 定 义 一 个 结 构 体 类 型 的 一 般 形 式 为 : struct person {lon g xh ; char na me[20]; floa t score ; }; 说明: ①一个结构体类型有其专有的标志,它由两个单词组成,第一个关键字

C 语言程序设计详解
struct, 第 二 个 单 词 按 标 识 符 命 名 规 则 指 定

87

② 结 构 体 类 型 由 若 干 个 数 据 项 组 成 ,每 一 个 数 据 项 都 属 于 一 种 已 有 定 义 的 类 型。它们并不是变量,而是一个结构体类型中的成员。 ③结构体类型并非只能有一种,而可以有许多种,这是与基本类型不同的。 ④ 定 义 一 个 结 构 体 类 型 ,并 不 意 味 着 系 统 将 分 配 一 段 内 存 单 元 来 存 放 各 数 据 项成员,只是表示这个类型的结构。 ⑤ 系 统 没 有 预 先 定 义 结 构 体 类 型 ,凡 需 使 用 结 构 体 类 型 数 据 的 ,都 必 须 在 程 序中自己定义 2、 定 义 结 构 体 类 型 变 量 的 方 法 ①在定义了一个结构体类型之后,把变量定义为该类型 struct person {lon g xh ; char na me[20]; floa t score ; }; struct person stud1 , stud2 ;

类型标识符

结构体变量名

②在定义一个结构体类型的同时定义一个或若干个结构体变量。 struct person {lon g xh ; char na me[20]; floa t score ; } stud1 , stud2 ; ③直接定义结构体类型的变量 struct {lon g xh ; char na me[20]; floa t score ; } stud1 , stud2 ;

C 语言程序设计详解
说明: ① 在 定 义 了 变 量 stud 1 和 stud 2 后 , 它 们 就 具 有 了 结 构 体 类 型 的 特 征

88

②在定义一个结构体类型时可以利用已定义了的另一个结构体类型来定义 其成员的类型 例: struc t da te

{in t month; int da y; int yea r; }; struct person {lon g xh ; char na me[20]; floa t score; struct da te b irthda y; }; 例 1: 当 说 明 一 个 结 构 体 变 量 时 系 统 分 配 给 它 的 内 存 是 A)各成员所需内存总量的总和 B)结构中第一个成员所需内存量 C)成员中占内存量最大者所需的容量 D)结构中最后一个成员所需内存量 答案: 例 2: 设 有 以 下 说 明 语 句 struct stu {in t a ; floa t b ; } stutyp e; 则下面叙述不正确的是() A ) struc t 是 结 构 体 类 型 的 关 键 字 B ) struc t stu 是 用 户 定 义 的 结 构 体 类 型

C 语言程序设计详解
C ) stu typ e 是 用 户 定 义 的 结 构 体 类 型 名 D)a 和 b 都是结构体成员名 3、 结 构 体 变 量 的 初 始 化

89

在 初 始 化 时 ,按 照 所 定 义 的 结 构 体 类 型 的 数 据 结 构 ,依 次 写 出 各 初 始 值 ,在 编译时就将它们赋给此变量中各成员。 struct person {lon g xh ; char na me[20]; floa t score ; } stud ={”101 89”,“ wan g”,97.5}; 4、 结 构 体 变 量 的 引 用 ①引用结构体变量中的一个成员 stud.xh ②可以将一个结构体变量作为一个整体赋组另一个具有相同类型的结构体 变量。 struct person {lon g xh ; char na me[20]; floa t score ; }; Main ( ) { struct stud1 ={”1 0189” ,“wang” ,90.5}; struc t stud2 ; stud2=stud1 ; } 5、 结 构 体 变 量 的 输 入 和 输 出 C 语言不允许把一个结构体作为一个整体进行输入或输出操作。 例 如 : printf(“%d”, stu d1) 和 要 sc anf(“%d” , &stud1); 如 输 出 stud 变 量 可 以 用 语 句

C 语言程序设计详解
prin tf(“%ld, %s,%f\n”,stud.xh, stud.na me,stud. score); 如 输 入 stud 变 量 可 以 用 语 句 scanf(“%ld,%s,%f\n ”,&stud. xh,stud.na me, &stu d.score); 三、结构体数组 1、 结 构 体 数 组 的 定 义 方 法 struc t pe rson {lon g xh ; char na me[20]; floa t score ; }; struc t p erson stu[3]; 2、 结 构 体 数 组 的 初 始 化 struct person {lon g xh ; char na me[20]; floa t score ;

90

} struc t pe rson stu [3]={{ 8010, “ wang”,8 9. 5},{ 8011, “li”,65 },{ 8012, “song”,75 }}; 3、 结 构 体 数 组 的 引 用 ①引用某一元素中的一个成员。 Stu [1].n u m ②可将数组中一个元素赋值给另一个元素 struct person stu [1]=s; ③不能把结构体数组元素整体输入、整体输出,只能以单个成员对象进行 输入输出。 注 意 : 在 输 入 过 程 中 为 了 能 不 出 现 过 多 的 麻 烦 , 用 ge ts 来 录 入 相 应 的 串 , 然后用以下函数转化为相应的类型。 Atoi( Atof( ) 将字符串转换为整数 )将 字 符 串 转 换 为 实 数 stu[3 ], s;

C 语言程序设计详解
Atol( )将 字 符 串 转 换 为 长 整 型

91

例 3、 下 面 程 序 的 运 行 结 果 是 ( ) main ( ) { struc t c mplx{int x; in t y; }c[2 ]={1,3,2, 7}; prin tf(“%d ”,c[0]. y/c [0].x *c[1 ].x); } 例 4 、 以 下 scanf 函 数 调 用 语 句 中 对 结 构 体 变 量 成 员 的 不 正 确 引 用 是 ( Stru ct p upil {char na me[20 ]; in t a ge; floa t sc ore; }pup[5 ], *p ; p=pup; A) scanf(“%s”,pup [0]. na me); B) scnaf(“%d” ,&pup [0].ag e); C) scanf(“%f”,&(p -> score )); D) scanf(“%d” ,p ->age ) 答案: 四、结构体变量作为函数参数以及返回结构体类型值的函数 1、 结 构 体 变 量 作 为 函 数 参 数 2、 返 回 结 构 体 类 型 值 的 函 数 五、结构体变量与指针 1、 指 向 结 构 体 变 量 的 指 针 所谓结构体变量的指针就是这个结构体变量所占内存单元段的起始地址。 Struc t P =&stu ; 引 用 成 员 方 式 : *p ) . na me ( p ->na me person *p , stu; ) 。

C 语言程序设计详解

92

->的 优 先 级 别 最 高 , 高 于 自 加 自 减 , 所 以 p ->nu m++相 当 于 (p ->n u m)++ 2、 指 向 结 构 体 数 组 的 指 针 3、 指 向 结 构 体 变 量 的 指 针 作 函 数 参 数 六、共用体类型概念 所谓共用体数据类型是指将不同的数据项存放于同一段内存单元的一种构 造数据类型。 Union exa m {in t a ; flo at b; c har c; } x, y; 七、共用体变量的引用 1、 可 以 引 用 一 个 共 用 体 变 量 中 的 某 个 成 员 项 x.a x.b

2、 不 能 直 接 用 共 作 体 变 量 名 进 行 输 入 输 出 scanf(“%d” ,&x ); prin tf(“%d ”,x); 3、 允 许 在 两 个 同 类 型 的 共 用 体 变 量 之 间 赋 值 。 y=x ; 例 5、 若 有 以 下 说 明 : 则 下 面 不 正 确 的 叙 述 是 ( ) un ion d ata {in t I; char c ; floa t f; }un; A) un 所 占 的 内 存 长 度 等 于 成 员 f 的 长 度 B) un 的 地 址 和 它 的 各 成 员 地 址 都 是 同 一 地 址 C) un 可 以 作 为 函 数 参 数 D) 不 能 对 un 赋 值 , 但 可 以 在 定 义 un 时 对 它 初 始 化 答案:

C 语言程序设计详解
例 6、 以 下 程 序 的 运 行 结 果 是 ( ) main ( ) struct ex {struct e y {in t x ; int y;} in t a ; in t b; }e; e.a=1; e .b=2; e.in.x=e .a *e.b ; e.in. y=e .a+e.b ; 答案: 八、枚举类型数据

93

所 谓“ 枚 举 ”类 型 ,是 指 这 种 类 型 的 变 量 的 值 只 能 是 指 定 的 若 干 个 名 字 之 一 。 定义类型 enu m co lor{red, ye llo w,b lue, wh ite ,black};

定义变量 enu m co lor c ; 引用 c=red; c=g reen ;

九 、 用 TYPEDEF 定 义 类 型 允 许 在 程 序 中 用 typed ef 来 定 义 新 的 类 型 名 来 代 替 已 有 的 类 型 名 , typede f 只 是起了一个新的类型名字,并未建立新的数据类型。 Typede f int in tege r Integ er a,b ; 十 、 动 态 存 储 分 配 ---- 链 表 1、 动 态 存 储 分 配 和 链 表 的 概 念 根 据 需 要 临 时 分 配 内 存 单 元 以 存 放 有 用 的 数 据 ,当 数 据 不 用 时 又 可 以 随 时 释 放存储单元。

C 语言程序设计详解
2、 用 包 含 指 针 项 的 结 构 体 变 量 构 成 结 点 stru ct person {lon g xh ; floa t score ; struct person *n ext; }; struct person stud1, stud2,stud3, *he ad;

94

stud1 .nu m=89101 ;stud 1.score=89; stud1 .nu m=89102 ;stud 1.score=90; stud1 .nu m=89103 ;stud 3.score=98; 例 7、 设 有 以 下 语 句 struct st { in t n ; struc t st *n ext; } struct st a [3]={5, &a [1],7,&a [2],9 ,’\0’}, *p ; p=&a[0]; 则以下表达式中值为 6 的是( ) A) p++-> m C) (* p). n++ B) p ->n++ D) ++p->n

3、 用 于 动 态 存 储 分 配 的 函 数 ① malloc vo id * ma llo c(un sign ed in t size ) 它的作用是在内存开辟指定大小的存储空间, 将此存储空间的起始地址作 并 为 函 数 带 回 。 函 数 值 为 指 针 ( 地 址 ) 这 个 指 针 是 指 向 vo id 类 型 的 , 如 果 想 将 这 个指针赋给其它类型的指针变量,应当进行显式的转换。 ② calloc vo id *c alloc (unsigned int nu m,unsigned in t siz e) 它 有 两 个 形 参 nu m 和 size , 其 作 用 是 分 配 n u m 个 大 小 为 size 字 节 的 空 间 。 ③ free

C 语言程序设计详解
vo id free (vo id *p tr) 其 作 用 是 将 指 针 变 量 p tr 指 向 的 存 储 空 间 释 放 。 ④ rea llo c vo id *reca lloc(vo id *ptr ,unsigne d int size) 用来使已分配的空间改变大小,即重新分配。 4、 链 表 应 用 举 例 P 274

95

7.8 7.9 7.10 : 建 立 一 个 链 表 , 每 个 结 点 包 含 的 成 员 为 : 职 工 号 、 工 资 。 用 malloc 函 数 开 辟 新 结 点 。要 求 链 表 包 含 5 个 结 点 ,从 键 盘 输 入 结 点 中 的 数 据 。然 后 把 这 些 结 点 的 数 据 打 印 出 来 。 要 求 用 函 数 creat 来 建 立 函 数 , 用 list 函 数 来 输 出 数 据 。这 5 个 职 工 的 号 码 为 101,103 ,105, 107,109。用 inse rt 函 数 来 新 增 一 个 职 工 的 数 据 , 这 个 新 结 点 , 按 职 工 号 顺 序 插 入 。 用 de lete 函 数 来 删 除 一 个 结 点 。 Struct wo rk {lon g nu m; floa t gz ; }; 创建 struc t work * Crea te (struc t work { struct wo rk * this, * new; * head )

new=(struct wo rk *) malloc(siz eof(struc t stru)); if (head= =NU LL) h ead =new; else { this=head ; wh ile (this->nex t!= NULL) th is->ne xt=ne w; n ew->ne xt=nu ll scan f(“%ld” ,&ne w->num); this=th is-> next;

C 语言程序设计详解
scan f(“%f”. ,&gz ); } endif retu rn(head); } 浏览 vo id list ( struc t work * h ead) { stru ct wo rk * this, * ne w;

96

if (head==nu ll) prin tf(“no da ta !”); else { this=head ; do{ p rin tf(“%ld, %f\n ”, this->nu m,th is-> gz); th is= this->nex t; }wh ile (this!=NU LL); end if } } 插入 struct wo rk *inse rt( struct work * head ,long x ,flo at y ) { struc t work * th is , *ne w, * fro; n ew=(struc t wo rk *) ma lloc( sizeo f(struct work )); new->nu m=x ; ne w->gz= y; if (he ad= = NULL) head=new; else { this=head ;

C 语言程序设计详解
while ((this!=NU LL) &&(this->nu m>x )) {fro=th is; this=th is->n ext; } if(th is= =hea d) {hea d=new; new->nex t=th is } else {fro ->nex t=new; new->nex t=th is; } endif } 删除 struc work * d el(stru ct work *head, in t x )

97

{struc t work *h ead, * this , *fro; this=head ; wh ile((this!=NU LL) &&(th is->nu m!=x ) {fro= this; th id=th is- nex t; } if (this!=NU LL) If(this= =head) {head=head ->n ext; free (this); } else { fro ->nex t=th is->nex t;

C 语言程序设计详解
free (th is); } endif endif

98


相关文章:
专升本C语言各种程序
专升本C语言各种程序_计算机硬件及网络_IT/计算机_专业资料。1.m 个人的成绩...专升本C语言历年考试题及... 7页 免费 C语言专升本辅导 98页 5下载券 专升本...
专升本C语言程序设计试卷
专升本C语言程序设计试卷_研究生入学考试_高等教育_教育专区。专升本 C 语言程序设计试卷(二) 一、单项选择题(1~30 题每小题 1 分,31~45 题每小题 2 分,...
C语言专升本教案
C语言专升本教案_工学_高等教育_教育专区。第一章 C 语言概述 ? C 程序的组成和形式 C程序是由函数构成的 主函数 其他函数 一个函数由两部分组成 ? 函数的...
经典C语言用于专升本的好资料
10年C语言专升本100题 23页 免费 C语言专升本辅导 82页 2财富值如要投诉违规内容,请到百度文库投诉中心;如要提出功能问题或意见建议,请点击此处进行反馈。 ...
C语言程序设计(专升本)试卷附答案
专升本C语言程序设计试卷j... 9页 免费如要投诉违规内容,请到百度文库投诉中心;如要提出功能问题或意见建议,请点击此处进行反馈。 ...
山东专升本C语言典型案例100题
山东专升本C语言典型案例100题_计算机软件及应用_IT/计算机_专业资料 暂无评价|0人阅读|0次下载|举报文档 山东专升本C语言典型案例100题_计算机软件及应用_IT/...
专升本C语言历年考试题及答案8[1]
专升本 C 语言历年考试题及答案 江西财经大学 2005 年 专升本选拔考试《C 语言程序设计》试卷 (考试时间 120 分钟,总分 100 分) 一、用C语言描述下列命题(共 ...
专升本考试C语言模拟试题及参考答案
专升本考试C语言模拟试题及参考答案_IT认证_资格考试/认证_教育专区。以下程序的输出结果是 【38】 。 # include<stdio.h> # define FUDGE(y) 2.84+y* H& ...
专升本C语言复习题
2004年c语言专升本试题q 暂无评价 5页 2下载券专​升​本​C​语​...专转本 C 语言复习题 一、专转本 C 语言复习题 2 数学表达式 1、编写程序...
专升本C语言模拟题_附答案
C语言专升本辅导 98页 5财富值 C语言专升本辅导 75页 1财富值如要投诉违规内容,请到百度文库投诉中心;如要提出功能问题或意见建议,请点击此处进行反馈。 ...
更多相关标签: