logo资料库

CCF中学生计算机程序设计基础篇-小.pdf

第1页 / 共249页
第2页 / 共249页
第3页 / 共249页
第4页 / 共249页
第5页 / 共249页
第6页 / 共249页
第7页 / 共249页
第8页 / 共249页
资料共249页,剩余部分请下载后查看
 CCF 中学生计算机程序设计教材 CCF 中学生计算机程序设计基础篇 中国计算机学会  组编 江  涛   宋新波    朱全民  主编 北  京
第1 章  模块化编程—函数 我 们 处 理 任 何 问 题 都 有 诸 多 环 节 , 比 如 煮 饭 , 先 要 准 备 米 , 将 米 淘 净 后 , 然 后 根 据 米 的 吸 水 特 性 加 水 , 弄 好 后 放 入 电 饭 煲 中 , 按 下 电 饭 煲 的 煮 饭 开 关 , 等 电 饭 煲 灯 熄 灭 , 然 后 饭 就 做 好 了 。 现 在 煮 饭 看 起 来 变 得 十 分 简 单 , 其 关 键 原 因 是 煮 饭 的 技 术 活 都 被 电 饭 煲 干 了 。 电 饭 煲 煮 饭 是 如 何 控 制 火 候 和 时 间 的 , 其 实 我 们 并 不 关 心 , 我 们 所 关 心 的 是 用 电 饭 煲 将 饭 煮 熟 的 结 果 , 这 个 方 法 我 们 叫 封 装 。 在 计 算 机 程 序 设 计 中 , 封 装 是 一 个 非 常 重 要 的 概 念 , 它 是 实 现 程 序 模 块 化 结 构 的 重 要 手 段 。 在 C + + 中 , 我 们 通 常 采 用 函 数 来 进 行 模 块 封 装 , 对 于 函 数 , 我 们 所 关 心 的 是 对 给 定 的 自 变 量 输 入 , 能 否 得 到 我 们 想 要 的 输 出 。 有 些 函 数 系 统 已 经 做 好 了 , 可 直 接 调 用 , 比 如 诸 多 的 数 学 函 数 、 字 符 串 处 理 函 数 等 , 有 些 函 数 则 需 要 根 据 自 己 的 需 求 进 行 个 性 开 发 , 这 章 我 们 就 重 点 讲 授 如 何 创 作 自 己 的 函 数 。 1.1  自定义函数的引入  【 例 1 . 1 】给 出 平 面 上 两 个 点 的 坐 标 , 求 两 点 之 间 的 曼 哈 顿 距 离 。 提 示 : 平 面 上 A 点 (x1,y1) 与 B 点 (x2,y2) 的 曼 哈 顿 距 离 为 :|x1- x2|+|y1- y2|。 分 析 :计 算 曼 哈 顿 距 离 可 以 用 前 面 学 过 的 分 支 结 构 来 解 决 。 程 序 如 下 : 1 //eg1.1_1 2 #include 3 using namespace std; 4 int main() 5 { 6 double x1,y1,x2,y2; 7 double dx,dy; 8 cin>>x1>>y1>>x2>>y2; 9 if(x1>x2) // 计算 |x1-x2| 运 行 结 果 : 输 入 :1.2 1.5 2.5 3.8 输 出 :3.6
10 dx=x1-x2; 11 else 12 dx=x2-x1; 13 if(y1>y2) // 计算 |y1-y2| 14 dy=y1-y2; 15 else 16 dy=y2-y1; 17 cout< 3 using namespace std; 4 double abs(double x) // 计算 x 的绝对值函数 5 { 6 if(x>0) 7 return x; 8 else 9 return -x; 10 } 11 int main() 12 { 13 double x1,y1,x2,y2; 14 double dx,dy,mht; 15 cin>>x1>>y1>>x2>>y2; 16 mht=abs(x1-x2)+abs(y1-y2); 17 cout<
1.2 函数的定义 1.2  函数的定义  前 面 我 们 用 过 了 很 多 C++ 标 准 函 数 , 但 是 这 些 标 准 函 数 并 不 能 满 足 所 有 需 求 。当 我 们 需 要 特 定 的 功 能 函 数 时 ,这 就 需 要 我 们 要 学 会 自 定 义 函 数 , 根 据 需 求 定 制 想 要 的 功 能 。 1 . 2 . 1   函 数 定 义 的 语 法 函 数 体 返 回 类 型 函 数 名 ( 参 数 列 表 ) { } 关 于 函 数 定 义 的 几 点 说 明 : (1 ) 自 定 义 函 数 符 合 “ 根 据 已 知 计 算 未 知 ” 这 一 机 制 , 参 数 列 表 相 当 于 已 知 , 是 自 变 量 , 函 数 名 相 当 于 未 知 , 是 因 变 量 。 如 程 序 eg1.1_2 中 的 abs 函 数 的 功 能 是 根 据 给 定 的 数 x 计 算 x 的 绝 对 值 , 参 数 列 表 中 x 相 当 于 已 知— 自 变 量 ,abs 函 数 的 值 相 当 于 未 知— 因 变 量 。 ( 2 ) 函 数 名 是 标 识 符 , 一 个 程 序 中 除 了 主 函 数 名 必 须 为 main 外 , 其 余 函 数 的 名 字 按 照 标 识 符 的 取 名 规 则 命 名 。 (3 ) 参 数 列 表 可 以 是 空 的 , 即 无 参 函 数 , 也 可 以 有 多 个 参 数 , 参 数 之 间 用 逗 号 隔 开 , 不 管 有 没 有 参 数 , 函 数 名 后 的 括 号 不 能 省 略 。 参 数 列 表 中 的 每 个 参 数 , 由 参 数 类 型 说 明 和 参 数 名 组 成 。 如 程 序 eg1.1_2 中 abs 函 数 的 参 数 列 表 只 有 一 个 参 数 , 参 数 数 据 类 型 是 double, 参 数 名 是 x 。 ( 4 ) 函 数 体 是 实 现 函 数 功 能 的 语 句 , 除 了 返 回 类 型 是 void 的 函 数 , 其 他 函 数 的 函 数 体 中 至 少 有 一 条 语 句 是 “return 表 达 式 ; ” 用 来 返 回 函 数 的 值 。 执 行 函 数 过 程 中 碰 到 return 语 句 , 将 在 执 行 完 return 语 句 后 直 接 退 出 函 数 , 不 去 执 行 后 面 的 语 句 。 ( 5 ) 返 回 值 的 类 型 一 般 是 前 面 介 绍 过 的 int、 double、 char 等 类 型 , 也 可 以 是 数 组 。 有 时 函 数 不 需 要 返 回 任 何 值 , 例 如 函 数 可 以 只 描 述 一 些 过 程 用 printf 向 屏 幕 输 出 一 些 内 容 , 这 时 只 需 定 义 函 数 返 回 类 型 为 void, 并 且 无 须 使 用 return 返 回 函 数 的 值 。 1 . 2 . 2   函 数 定 义 应 用 实 例 根 据 上 述 定 义 , 我 们 知 道 C++ 函 数 形 态 有 以 下 四 类 : 3
(1 ) 返 回 类 型 函 数 名 ( 参 数 列 表 ) 。 (2 ) 返 回 类 型 函 数 名 ( (3 )void 函 数 名 ( 参 数 列 表 )。 (4 )void 函 数 名 ( 下 面 我 们 一 起 来 看 几 个 例 子 : )。 )。 【 例 1 . 2 】给 定 两 个 非 负 整 数 n 和 m , 编 写 函 数 计 算 组 合 数 Cm 分 析 : 首 先 分 析 函 数 的 功 能 , 根 据 给 定 的 n,m 计 算 Cm n 。 n 。n,m 已 知 , 相 当 于 自 变 量 ; Cm n 未 知 , 相 当 于 因 变 量 。 设 计 以 下 函 数 : long long C(int n,int m) 其 中 , 函 数 的 返 回 值 为 Cm n , 返 回 类 型 为 long long, 函 数 名 为 C , 参 数 列 表 中 有 两 个 参 数 n,m, 类 型 都 是 int。 函 数 体 是 实 现 函 数 功 能 的 语 句 , 根 m! ∗ (n − m)! 发 现 需 要 三 次 用 到 “ 计 算 一 个 数 的 阶 乘 ” 这 个 功 能 , 据 Cm n = n! 因 此 把 这 个 功 能 独 立 出 来 设 计 一 个 函 数 来 实 现 : long long f(int n) 该 函 数 的 返 回 值 为 n!, 返 回 类 型 为 long long, 函 数 名 为 f, 需 要 一 个 参 数 n , 类 型 为 int。 综 上 , 该 函 数 的 代 码 如 下 : 1 //eg1.2 2 long long f(int n) 3 { 4 long long ans=1; 5 for(int i=1;i<=n;i++) 6 ans*=i; 7 return ans; 8 } 9 10 long long C(int n,int m) 11 { 12 return f(n)/(f(m)*f(n-m)); 13 } 提 示 : (1 ) 函 数 体 中 的 语 句 可 以 是 对 另 一 个 函 数 的 调 用 。 (2 ) 对 于 较 大 的 n,m 来 说 , 上 述 程 序 可 能 会 产 生 溢 出 。 4 第1章 模块化编程—函数
【 例 1 . 3 】 编 写 函 数 输 出 斐 波 那 契 数 列 的 第 n 项 。 其 中 斐 波 那 契 数 列 f(n) 的 定 义 如 下 : 1.3 函数调用与参数传递 f(1)=0,f(2)=1 f(n)=f(n- 1)+f(n- 2)(n>=2) 分 析 : 因 为 该 函 数 不 需 要 返 回 值 , 只 需 要 输 出 f(n) 即 可 , 所 以 该 函 数 的 返 回 类 型 为 void, 函 数 体 部 分 只 需 计 算 出 f(n) 再 输 出 即 可 。 函 数 代 码 如 下 : 1 //eg1.3 2 void output(int n) 3 { 4 if(n<=2) 5 cout<
两 大 类 : 其 中 一 类 有 返 回 值 , 如 程 序 eg1.1_2 中 的 abs 函 数 、 例 1.2 中 的 f 函 数 和 C 函 数 ; 另 一 类 没 有 返 回 值 , 如 例 1.3 中 的 output 函 数 。 对 于 有 返 回 值 的 函 数 , 调 用 时 必 须 以 值 的 形 式 出 现 在 表 达 式 中 。 比 如 程 序 eg1.1_2 第 16 行 : mht=abs(x1- x2)+abs(y1- y2); 该 语 句 对 abs 函 数 的 调 用 出 现 在 赋 值 语 句 的 右 边 , 程 序 eg1.2 第 12 行 : return f(n)/(f(m)*f(n- m)); 该 语 句 对 f 函 数 的 调 用 出 现 在 return 语 句 中 , 作 为 C 函 数 的 返 回 值 。 对 于 没 有 返 回 值 的 函 数 ,直 接 写“ 函 数 名 ( 参 数 ) ;”即 可 。如 例 1.3 中 , 如 果 需 要 输 出 斐 波 那 契 数 列 的 第 10 项 , 用 “output(10); ” 即 可 实 现 。 程 序 可 以 调 用 任 何 前 面 已 经 定 义 的 函 数 , 如 果 我 们 需 要 调 用 在 后 面 定 义 的 函 数 , 就 要 先 声 明 该 被 调 用 的 函 数 。 声 明 方 法 如 下 : // 声明 sgn 函数 返 回 类 型 函 数 名 ( 参 数 列 表 ) ; 程 序 如 下 : 1 #include 2 using namespace std ; 3 int sgn(int n); 4 int main() 5 { 6 int n; 7 cin>>n; 8 cout<0)?1:-1; 15 } 2 . 形 式 参 数 与 实 际 参 数 函 数 调 用 需 要 理 解 形 式 参 数 与 实 际 参 数 : (1 )函 数 定 义 中 的 参 数 名 称 为 形 式 参 数 ,如 long long C(int n,int m) 中 的 n 和 m 是 形 式 参 数 , 我 们 完 全 可 以 把 n 换 成 a, 把 m 换 成 b , 再 把 函 数 体 中 的 n 换 成 a,m 换 成 b, 函 数 的 功 能 完 全 一 样 。 (2 ) 实 际 参 数 是 指 实 际 调 用 函 数 时 传 递 给 函 数 的 参 数 的 值 。 如 调 用 函 6 第1章 模块化编程—函数
1.3 函数调用与参数传递 数 C(6,3), 这 里 的 6,3 就 是 实 际 参 数 , 其 中 6 传 递 给 形 式 参 数 n ,3 传 递 给 形 式 参 数 m 。 3 . 调 用 函 数 的 执 行 过 程 调 用 函 数 的 执 行 过 程 如 下 : ( 1 ) 计 算 实 际 参 数 的 值 。 如 程 序 eg1.1_2 中 输 入 x1=1.2, y1=1.5, x2=2.5, y2=3.8, 程 序 第 16 行 调 用 函 数 abs(x1- x2) 和 abs(y1- y2), 首 先 计 算 参 数 x1- x2=- 1.3, y1- y2=- 2.3,这 里 的 -1.3 和 -2.3 就 是 实 际 参 数 。 (2 ) 把 实 际 参 数 传 递 给 被 调 用 函 数 的 形 式 参 数 , 程 序 执 行 跳 到 被 调 用 的 函 数 中 。如 程 序 eg1.1_2 中 ,调 用 abs(x1- x2) 时 就 会 把 -1.3 赋 值 给 函 数 定 义 中 的 形 式 参 数 x , 然 后 执 行 abs(- 1.3)。 ( 3 ) 执 行 函 数 体 , 执 行 完 后 如 果 有 返 回 值 , 则 把 返 回 值 返 回 给 调 用 该 函 数 的 地 方 继 续 执 行 。 如 上 面 的 例 子 中 , 就 会 在 执 行 完 abs(- 1.3) 后 返 回 1.3, 再 执 行 abs(- 2.3) 后 返 回 2.3, 接 着 就 可 以 计 算 出 abs(x1- x2)+abs(y1- y2) 的 值 等 于 1.3+2.3=3.6, 再 赋 值 给 左 边 的 变 量 mht。 1 . 3 . 2   参 数 传 递 1 . 传 值 参 数 函 数 通 过 参 数 来 传 递 输 入 数 据 , 参 数 通 过 传 值 机 制 来 实 现 。 前 面 的 程 序 中 的 函 数 都 采 用 了 传 值 参 数 , 采 用 的 传 递 方 式 是 值 传 递 , 函 数 在 被 调 用 时 , 用 克 隆 实 参 的 办 法 得 到 实 参 的 副 本 传 递 给 形 参 , 改 变 函 数 形 参 的 值 并 不 会 影 响 外 部 实 参 的 值 。 【 例 1 . 4 】编 写 程 序 利 用 函 数 交 换 两 个 变 量 的 值 。 1 //eg1.4_1( 错误 ) 2 #include 3 using namespace std; 4 void swap(int a,int b) 5 { 6 int t=a; 7 a=b; 8 b=t; 9 } 10 11 int main() 运 行 结 果 : 输 入 :3 4 输 出 :3 4 7
分享到:
收藏