解 答 編 第 4 章 条 件 による 分 岐 2 演 習 問 題 4.1 文 法 事 項 1 ) 条 件 分 岐 のために switch case 文 が 使 用 できるのは 条 件 がどのような 形 で 表 される 場 合 か 答 えなさい 分 岐 条 件 が 整 数 の 一 致 条 件 で 表 されている 場 合 に 用 いることができます 2 ) 本 文 中 で 説 明 した switch case 文 を 使 う 場 合 の 注 意 事 項 を 2 つ 答 えなさい switch case 文 は 原 則 として break 文 との 組 み 合 わせで 使 うこと default 文 を 必 ず 付 けること 3 ) マジック ナンバーとは 何 か 答 えなさい また マジック ナンバーがプログラムに 及 ぼす 悪 影 響 とは 何 か 答 えなさい マジック ナンバーとは プログラム 中 に 直 接 書 き 込 まれた 定 数 のことです マジッ ク ナンバーは 見 ただけでは それが 何 であるのか あるいは どんな 役 割 りを 果 たすのかがわかりません このため マジック ナンバーが 書 き 込 まれたプログ ラムは 読 んで 理 解 することが 困 難 になります 4 ) マジック ナンバーをなくすために どのような 方 法 があるか 答 えなさい マジック ナンバーを 無 くすためには #define 命 令 を 用 いた 定 数 定 義 を 用 いる ことができます 例 えば 足 し 算 を 表 すコード 番 号 として 1 を 使 いたい 場 合 #define ADD 1 のように 定 義 することで 直 接 的 な 意 味 が 無 い 1 という 定 数 でなく ADD という 意 味 を 読 み 取 るとこができる 定 数 名 を 使 ってプログラムを 書 くことができ プログ ラムを 読 みやすくすることができます [ 高 度 な 話 題 ] C 言 語 の 新 しい 規 格 では 内 容 を 書 き 換 えることができない const 変 数 が 使 える ようになっています この 変 数 は 名 前 の 通 り 定 数 のために 用 いることができます 例 えば const int ADD = 1; のように const 変 数 ADD を 初 期 化 付 きで 宣 言 すると #define 命 令 と 同 じよう に 用 いることができます #define 命 令 がプリプロセッサの 命 令 であるのと 異 なり const 変 数 は C 言 語 自 体 の 文 法 に 含 まれるため こちらの 方 を 好 んで 用 いるプロ グラマも 多 くいます さらに この 例 のような 定 数 には 本 文 の 第 15 章 の 列 挙 型 を 用 いるのが 最 も 良 い 方 法 です
解 答 編 第 4 章 条 件 による 分 岐 2 演 習 問 題 4.2 整 数 値 を 入 力 すると その 整 数 が 偶 数 か 奇 数 かを 答 えるプログラムを 作 りなさい ただし 1 ) if else 文 を 用 いて 作 ること この 問 題 は 本 当 に 簡 単 です しかし C 言 語 のとんでもない 落 とし 穴 を 含 んでい ます まず 解 答 プログラム 4.1 を 示 しましょう このプログラムは 整 数 を 2 で 割 っ た 余 りが 0 なら 偶 数 という 性 質 を 用 いています ちゃんと 動 きますよ 解 答 プログラム 4.1 偶 数 / 奇 数 判 定 プログラム (if else 版 ) p4_1.c 偶 数 / 奇 数 判 定 プログラム (if else 版 ) int inputnumber; // 入 力 される 整 数 // データの 入 力 printf("input Integer Number > "); scanf("%d", &inputnumber); // 偶 数 / 奇 数 判 定 if(inputnumber % 2 == 0) printf("%d は 偶 数 です \n", inputnumber); else printf("%d は 奇 数 です \n", inputnumber); 2 ) switch case 文 を 用 いて 作 ること 偶 数 / 奇 数 判 定 プログラムを switch case 文 で 作 った 例 を 解 答 プログラム 4.2 に 示 します switch case 文 の 使 用 上 の 注 意 通 り break 文 との 組 み 合 わせで 使 っています さらに 必 要 無 いと 思 われる default 文 も 付 けて エラーメッセー ジを 出 すようにしました しかし 2 で 割 った 余 りは 0 か 1 なので default 文 は 絶 対 に 実 行 されないのではないでしょうか 意 外 なのは 実 行 例 です -1 の 入 力 に 対 して 異 常 です というメッセージが 表 示 されました default 文 が 実 行 された 証 拠 です 実 は 負 の 数 の 割 り 算 で 商 と 余 りを 求 めるのは 意 外 と 問 題 含 みなのです 例 えば 1 を 2 で 割 ると 0.5 です このとき 商 は 1 で 余 りは 1 でしょうか?そ れとも 商 は 0 で 余 りは 1 でしょうか? 要 は -0.5 を 1 に 丸 めるか 0 に 丸 めるかの 問 題 です C 言 語 の 規 格 では この 問 題 は 規 定 されていませんでした つまり コンパイラや マシンによって 結 果 はバラバラだったということです つまり 割 り 算 を 用 いたプ 2
ログラムには 移 植 性 がありません これでは 困 るので C99 の 規 格 では 割 り 算 の 丸 めを 0 の 側 にするように 定 められました つまり 先 ほどの 計 算 結 果 は 商 は 0 で 余 りは 1 です 結 局 解 答 プログラム 4.2 の 実 行 結 果 で default 文 が 実 行 されてしまった 理 由 は 負 の 数 の 入 力 により 剰 余 演 算 の 結 果 として 0 でも 1 でもなく -1 という 値 が 得 ら れたためです 解 答 プログラム 4.2 奇 数 / 偶 数 判 定 プログラム (switch case 版 ) p4_2.c 偶 数 / 奇 数 判 定 プログラム (switch case 版 ) int inputnumber; int remainder; // 入 力 される 整 数 // 2 で 割 った 余 り // データの 入 力 printf("input Integer Number > "); scanf("%d", &inputnumber); // 偶 数 / 奇 数 判 定 remainder = inputnumber % 2; switch(remainder) case 0 : printf("%d は 偶 数 です \n", inputnumber); case 1 : printf("%d は 奇 数 です \n", inputnumber); default: printf(" 異 常 です \n"); [ 実 行 例 ] Input Integer Number > 2 2 は 偶 数 です Input Integer Number > 1 1 は 奇 数 です Input Integer Number > -2-2 は 偶 数 です Input Integer Number > -1 異 常 です % 3
解 答 編 第 4 章 条 件 による 分 岐 2 一 方 で 解 答 プログラム 例 4.1 は 負 の 数 でも 正 しく 動 きます これは if(inputnumber % 2 == 0) という if 文 で 先 に 偶 数 の 場 合 ( いつでも 剰 余 が 0 になる ) を 調 べて それ 以 外 の 場 合 を else 文 で 奇 数 と 判 定 しているためです if(inputnumber % 2 == 1) という if 文 で 先 に 奇 数 を 判 定 するようにプログラムを 書 いていれば プログラ ムは 上 手 く 動 作 しないでしょう もし 先 に 説 明 した 負 の 数 の 割 り 算 の 事 情 を 知 った 上 で プログラム 4.1 を 書 い たとしたら 立 派 ですが このような 事 情 を 知 らずにプログラム 例 4.1 を 書 いたと したら プログラムはたまたま 運 良 く 動 いているにすぎません 誰 にも 考 え 違 いや 知 らないことというのはあるものです 条 件 分 岐 には 自 分 の 想 定 外 の 値 が 得 られた 場 合 を 考 慮 した 例 外 の 分 岐 を 付 けることを 習 慣 付 けておく と 思 わぬ 落 とし 穴 にはまらずに 済 みます 例 えば 解 答 プログラム 4.1 の 場 合 条 件 分 岐 の 部 分 を 次 のように 書 いておくと 良 いでしょう if(inputnumber % 2 == 0) printf("%d は 偶 数 です \n", inputnumber); else if(inputnumber % 2 == 1 inputnumber % 2 == -1) printf("%d は 奇 数 です \n", inputnumber); else printf("error: 演 算 結 果 が 異 常 です \n"); 演 習 問 題 4.3 プログラム 例 4.7を 改 良 して 剰 余 も 求 められるプログラムを 作 りなさい プログラムの 作 例 を 解 答 プログラム 4.3 に 示 します この 解 答 例 での 注 目 点 は 2 点 です 第 一 点 は switch case 文 を 使 ったプロ グラムに 新 たな 分 岐 を 組 み 込 んで 機 能 を 増 やすことがいかに 容 易 かという 点 です 解 答 プログラム 4.3 は 元 になっているプログラム 例 4.7 とほとんど 変 わりません 剰 余 演 算 を 表 すための 定 数 を 定 義 し 剰 余 演 算 を 実 行 するための case 文 を 追 加 し ただけです switch case 文 は その 書 式 上 このような 追 加 が 非 常 に 簡 単 に 読 みやすさを 失 うことなく 実 行 できます その 便 利 さを 噛 み 締 めて 下 さい 第 二 点 目 は 些 細 な 点 ですが printf() 関 数 の 書 式 文 字 列 によって %( パーセ ント ) を 表 示 する 方 法 です 解 答 プログラム 4.3 に 示 す 通 り %% と 2 つ 重 ねる ことによって 一 つの %( パーセント ) を 表 示 することができます 4
解 答 プログラム 4.3 四 則 演 算 を 行 うプログラム p4_3.c 四 則 演 算 を 行 うプログラム ver1.4 1 から 5 の 番 号 入 力 で 演 算 を 選 択 する (switch case 文 ) #define ADD 1 // 足 し 算 #define SUB 2 // 引 き 算 #define MULT 3 // 掛 け 算 #define DIVI 4 // 割 り 算 #define MOD 5 // 剰 余 演 算 int firstnum, secondnum; int operation; int answer; // 入 力 される 2 整 数 // 演 算 の 種 類 // 演 算 の 答 え // データと 演 算 種 別 の 入 力 printf("input Integer Number 1 > "); scanf("%d", &firstnum); printf("input Integer Number 2 > "); scanf("%d", &secondnum); printf("operation 1) +, 2) -, 3) *, 4) / 5) % >> "); scanf("%d", &operation); // 演 算 処 理 switch(operation) case ADD: answer = firstnum + secondnum; printf("%d+%d = %d n", case SUB: answer = firstnum - secondnum; printf("%d-%d = %d n", case MULT: answer = firstnum * secondnum; printf("%d*%d = %d n", case DIVI: answer = firstnum / secondnum; printf("%d/%d = %d n", case MOD: answer = firstnum % secondnum; printf("%d%%%d = %d n", default: printf("error: Operation (1-4) n");
解 答 編 第 4 章 条 件 による 分 岐 2 演 習 問 題 4.4 生 年 月 日 による 次 のような 相 性 占 いがある この 方 法 に 従 って 2 人 の 生 年 月 日 を 入 力 すると 相 性 を 答 えてくれるプログラムを 作 りなさい 1 ) 2 人 のそれぞれの 生 年 月 日 の 各 桁 の 数 を 全 て 足 す この 2 つの 数 の 大 きいほうから 小 さい 方 を 引 く 2 ) 1 ) で 求 めた 数 を 5 で 割 る 割 り 切 れれば 相 性 は 非 常 に 良 い 1 余 れば 相 性 は 良 い 2 余 れば 普 通 3 余 れば 相 性 は 悪 い 4 余 れば 相 性 は 最 悪 プログラムの 作 成 例 を 解 答 プログラム 4.4 に 示 します この 演 習 問 題 は 本 来 は 大 変 面 倒 な 課 題 です 何 故 なら 生 年 月 日 という 形 式 が あり 制 限 がある 入 力 を 処 理 対 象 としているからです 実 用 のプログラムを 作 成 する としたら 入 力 された 日 付 の 妥 当 性 のチェックなどで 大 きな 労 力 を 必 要 とするで しょう しかし ここは 演 習 問 題 ということで 簡 単 のためにチェックを 行 わず ユー ザーの 入 力 を 丸 ごと 信 じることにしましょう 入 力 は 年 月 日 を 別 々に 入 力 することにしました この 他 に 年 月 日 をまとめ て 19980112(1998 年 1 月 12 日 ) のように 大 きな 整 数 として 入 力 してもらう 方 法 もあるでしょう まだ C 言 語 の 勉 強 を 始 めたばかりなので 今 までの 知 識 で できることは 限 られますが 各 自 工 夫 してみて 下 さい 生 年 月 日 の 各 桁 の 足 し 算 は 商 と 余 りの 性 質 を 使 って 計 算 しています プログラム をよく 読 んでみて 下 さい ほとんど 同 じ 文 が 沢 山 並 ぶ 結 果 になってあまりカッコい いプログラムとは 言 えません この 後 繰 り 返 し 構 文 や 関 数 などを 学 ぶと スマー トに 書 き 換 えることができます 解 答 プログラム 4.4 相 性 占 いプログラム p4_4.c 性 格 占 いプログラム int year, month, day; // 成 年 月 日 int aperson, bperson; // 成 年 月 日 の 各 桁 合 計 int result; // 相 性 の 結 果 printf("1 人 目 : 生 まれた 年 ( 西 暦 ) > "); scanf("%d", &year); printf("1 人 目 : 生 まれた 月 > "); scanf("%d", &month); printf("1 人 目 : 生 まれた 日 > "); scanf("%d", &day);
aperson = year / 1000; year = year % 1000; aperson = aperson + year / 100; year = year % 100; aperson = aperson + year / 10 + year % 10; aperson = aperson + month / 10 + month % 10; aperson = aperson + day / 10 + day % 10; printf("2 人 目 : 生 まれた 年 ( 西 暦 ) > "); scanf("%d", &year); printf("2 人 目 : 生 まれた 月 > "); scanf("%d", &month); printf("2 人 目 : 生 まれた 日 > "); scanf("%d", &day); bperson = year / 1000; year = year % 1000; bperson = bperson + year / 100; year = year % 100; bperson = bperson + year / 10 + year % 10; bperson = bperson + month / 10 + month % 10; bperson = bperson + day / 10 + day % 10; if(aperson > bperson) result = aperson - bperson; else result = bperson - aperson; result = result % 5; switch(result) case 0: printf(" 相 性 は 非 常 に 良 い n"); case 1: printf(" 相 性 は 良 い n"); case 2: printf(" 相 性 は 普 通 n"); case 3: printf(" 相 性 は 悪 い n"); case 4: printf(" 相 性 は 非 常 に 悪 い n"); default: printf("error: 異 常 です n"); 7