本文へスキップ

平成23年度 特別試験 ITパスポート試験 問93

この問題の解説と、これまでの解答の記録です。

問93
頻出度★★☆

Q社のRさんは,チケット販売システムの開発で使用する関数のプログラミングとテストを実施しようとしている。この関数は,大人と子供のチケットの購入希望枚数を基に,合計金額の計算を行う。大人のチケットは3,000円,子供のチケットは1,000円である。一度に購入できる大人と子供のチケットの最高枚数は,それぞれ20枚までであり,関数はこの購入条件を満たしているかどうかをチェックする。また,合計で20枚以上購入する場合,割引処理を行う。関数の仕様と処理内容は次のとおりである。 〔関数の仕様〕 関数に渡される引数  J:大人のチケットの購入希望枚数,K:子供のチケットの購入希望枚数  (J,Kは0以上の整数) 関数の戻り値  L:合計金額 (Lは整数) 〔処理内容〕 (1) 購入希望枚数を基に,購入条件を満たしているかどうかを判定する。購入条件を満たしていない場合,合計金額に−1を代入する。 (2) 購入条件を満たしている場合,引数を基に次のとおりに合計金額の計算を行う。   合計金額 = 大人のチケットの購入希望枚数×3,000+子供のチケットの購入希望枚数×1,000 (3) チケットを合計で20枚以上購入した場合は,合計金額から1割を割り引く。 関数の処理の流れを図1に示す。図1のaに入れる適切な条件式はどれか。 図1 関数の処理の流れ図 - 開始 - 判定 [ a ] : No の場合 → L=−1 → 終了 - 判定 [ a ] : Yes の場合 ↓ - 判定 [ J+K≧20 ] : No の場合 → L=3,000×J+1,000×K → 終了 - 判定 [ J+K≧20 ] : Yes の場合 → L=0.9×(3,000×J+1,000×K) → 終了

出典 平成23年度 特別試験 ITパスポート試験 問93
解説

問 93

  • ア

    正解 正解はア。まず流れ図全体の意図を読み取る。この関数は J と K という二つの値から金額 L を求めるもので、判定 a が No のときだけ L に −1 を代入して終了する。金額として −1 はあり得ない値なので、これは「計算できません」を呼び出し元に知らせるエラー値である。つまり判定 a は、渡された J と K が計算してよい正しい範囲に収まっているかを調べる入力チェック (妥当性検査) であり、Yes なら正常値として金額計算に進み、No なら異常値としてエラーで抜ける、という役割を担っている。入力チェックである以上、J と K の両方がそろって範囲内でなければ計算に進んではならない。アの「0≦J≦20 and 0≦K≦20」は、J についての 0 以上 20 以下という条件と、K についての 0 以上 20 以下という条件を and (論理積) で結んだ式なので、両方を同時に満たすときだけ Yes となり、どちらか一方でも負の数や 20 を超える値であれば No、すなわち L=−1 となる。これは入力チェックとして正しい形である。さらに、この条件が後続の処理と矛盾しないことも確認できる。ア を通過した J と K は 0≦J≦20 かつ 0≦K≦20 なので、和 J+K は 0 から 40 までの値を取り得る。したがって次の判定 J+K≧20 は Yes にも No にもなり得て、割引を適用する L=0.9×(3,000×J+1,000×K) の枝と、割引なしの L=3,000×J+1,000×K の枝の両方が実際に実行される。流れ図に書かれたすべての処理が到達可能で、かつ範囲外の入力は確実にはじかれる。この二つを同時に満たす選択肢はアだけであり、よって a に入れる適切な条件式はアである。

  • 不正解イ

    「0≦J≦20 or 0≦K≦20」は、or (論理和) なので J と K のどちらか一方でも 0 以上 20 以下であれば Yes となり、金額計算へ進んでしまう。例えば J=5、K=100 のときは J の条件だけで Yes となり、範囲外の K=100 を使って金額が計算される。J=−30、K=10 のように片方が負の数でも同様に通過してしまう。これでは範囲外の値をはじくという入力チェックの目的を果たせず、エラー値 L=−1 を返す枝がほとんど機能しない。and と or を取り違えた典型的な誤りである。

  • 不正解ウ

    「0≦J+K≦20」は和だけを縛る条件式で、購入条件「大人と子供それぞれ 20 枚まで」と一致しない。J,K は 0 以上の整数なので和が 20 以下なら各値も 20 以下になるが、逆に条件を満たす正当な注文まで拒んでしまう。例えば J=15、K=10 はそれぞれ 20 枚以内で購入できるのに、和が 25 なので No となり L=−1 が返される。加えて後続の判定との整合も崩れる。この条件を満たして進んだ場合 J+K≦20 が保証されるため、次の判定 J+K≧20 が Yes になるのは J+K=20 のちょうど一点だけとなり、割引を適用する L=0.9×(3,000×J+1,000×K) の枝がほぼ意味を失う。入力チェックとしても不十分で、流れ図の分岐設計としても不自然である。

  • 不正解エ

    「J>20 and K>20」は、正常とみなす範囲を取り違えており、条件の向きが逆になっている。この式では J=1、K=1 のような普通の値がすべて No となって L=−1 のエラーになり、J と K がともに 20 を超えたときだけ金額計算に進むことになる。さらに Yes で進んだ場合は J>20 かつ K>20 なので J+K は必ず 40 を超え、次の判定 J+K≧20 は常に Yes となる。その結果、割引なしの L=3,000×J+1,000×K の枝は決して実行されない到達不能な処理となってしまい、流れ図の記述と矛盾する。

ここがポイント
  • 流れ図 (フローチャート) の読み解き方 — ひし形の判定記号は条件を評価して Yes / No のいずれか一方へ分岐する。空欄の条件式を選ぶ問題では、(1) その分岐の先で何をしているかから条件の役割を推定し、(2) どの選択肢を入れても流れ図中のすべての処理が到達可能かを検証する。金額を求める関数で −1 のようなあり得ない値を返す枝は、入力チェック (妥当性検査) の失敗を表すエラー処理と読むのが定石である。
  • and (論理積) と or (論理和) の使い分け — and は結んだ条件をすべて満たすときだけ真、or はどれか一つでも満たせば真になる。複数の変数それぞれに有効範囲を設ける入力チェックでは、各変数の範囲条件を and で結ぶ。ここで or を使うと片方が範囲外でも通過し、チェックとして機能しない。
用語

解答の記録