手順による処理の記述

コンピュータが実行する計算をモデル化して、人間にとって分かりやすい計算の記述方法を作る。[教科書5.1.2]

普通の言葉で書くと書きにくいので、手順を書くための特別の書き方を導入する。 ただし、以下では、実際のプログラムほど厳密には書かない。

メモリを抽象化して、変数というものを考える。

ジャンプ命令を抽象化して、条件付き処理を考える。

問題: 今年の八十八夜は何月何日か。ただし今年の立春は2月4日であり、今年は平年である。(とする!)
<残り日数> ← 4+88-1
if <残り日数> >28 (2月の日数)
  then <残り日数> ← <残り日数>-2月の日数
    if <残り日数> >31 (3月の日数)
      then <残り日数> ← <残り日数>-3月の日数
        if <残り日数> >30 (4月の日数)
          then <残り日数> ← <残り日数>-4月の日数
            if <残り日数> >31 (5月の日数)
              then 6月以降の処理
              else "5月" <残り日数> "日" と表示
            endif
          else "4月" <残り日数> "日" と表示
        endif
      else "3月" <残り日数> "日" と表示
    endif
  else "2月" <残り日数> "日" と表示
endif

プログラムのデモ(実演する。自分で動かさなくてよい。)

八十八夜だけでなく、二百十日、二百二十日も計算できるようにしようと考えると、 このような書き方をしているとどんどん長くなってしまう。そこで、 配列と反復処理を導入する。

アドレスでのメモリの指定を抽象化した配列というものを考える。

(前のアドレスに戻るような)ジャンプ命令を抽象化して、反復処理というものを考える。

配列と反復を使うと八十八夜問題は次のように書ける。
<残り日数> ← 4+88-1
m ← 2
while <残り日数> >daymonthm do
  <残り日数> ← <残り日数> - daymonthm
  m ← m+1 
done

プログラムのデモ(実演する。自分で動かさなくてよい。)

プログラムを実行するわけではないので比較的自由に書いてよいが、以下に目安を示す。

練習0: 以下のそれぞれを考えてみよ。

  1. 以下のものを実行した時、(1)において変数iの値はどう変化するか?
    i ← 0
    while i <= 3 do
     i ← i+1
    (1)
    done
    

  2. 以下のものを実行した時、(1)において変数jの値はどう変化するか?
    i ← 0
    j ← 0
    while i <= 3 do
     j ← j+ 2*i + 1
     i ← i+1
    (1)
    done
    

  3. mとnの大きい方を求める。
    if n > m
      then r ← n
      else ここに何を入れたらよいか?
    endif
    ...nとmの大きい方の値がrに入っている。
    

  4. 鶴と亀がいる。頭の合計がh、足の合計がfの時、鶴は何羽で、亀は何匹かを求める。
    t2 ← f - 2*h ... fから足2本分を除くと亀の足2本が残る
    t ← ここに何を入れたらよいか?
    c ← h - t ... 鶴の数
    

  5. nの階乗(n!)を計算せよ。
    以下の(1)〜(4)をどの順序で並べれば良いか?
    ns ← 1
    i ← 1
    done (1)
    i ← i+1 (2)
    while i <= n do (3)
    ns ← ns*i (4)
    
    nsがn!になっているようにする。

  6. 九九の表を出力する。
    i ← 1
    while i <= 9 do
      j ← 1
      while j <= 9 do
        i*jを出力する。
        ここに何を入れたらよいか?
      done
      改行する。
      ここに何を入れたらよいか?
    done
    

  7. y年が閏年か平年かを表示する。
    if yを4で割った余りが0
      then
        if ここに何を入れたらよいか?
          then
            if yを400で割った余りが0
              then
                閏年と表示
              else
                平年と表示
            endif
          else
            閏年と表示
        endif      
      else
        平年と表示
    endif 
    

  8. クラスの学生の身長のデータが配列hに格納されているとする。自分の身長がmの時、クラスで何番目に背が高いかを求める。
    p ← 1
    i ← 1
    while i <= クラスの学生数 do 
      if ここに何を入れたらよいか?
        then p ← p+1
      endif
      i ← i+1
    done
    自分はp番目
    

以下のプログラムを考えてみよ。(記述できればよく、実行しなくて良い。)

  1. nのm乗を計算する(mは自然数とする)
  2. 1から10までの合計を求める
  3. 配列に格納されているデータの最大値を求める
  4. 配列に格納されているデータの合計を求める
  5. 2つの自然数の最大公約数を求める
  6. 配列に格納されているデータを大きい順に並べる
  7. 年利5%の複利計算の利子が、年利7%の単利計算の利子より初めて多くなるのが何年後か求める
  8. 与えられた金額になる、できるだけ少ない枚数の紙幣とコインの組合せを求める
  9. 与えられた数の約数を求める
  10. 与えられた数が素数か判定する
  11. 5人の採点をオリンピック方式(最大と最小を除いた残りを使う)で集計する
  12. 素数を小さい方から10個求める
  13. ボーリングにおいて、各投球で倒したピンの本数から(ゲームの)得点を計算する
  14. 政党毎の得票数から、ドント方式で政党毎の議席数を求める
いくつできたか?

プログラムを書けるようになるには訓練が必要である。 訓練すればまず間違いなくかなりのものは書けるようになる。 →「情報科学」の招待

以下、範囲外の話題。

報道によると「2005年11月17日に国土交通省が、千葉県にある建築設計事務所の元一級建築士が構造計算書を偽造していたことを発表し、その後の調査で多くのホテルや分譲済みマンションの耐震強度が大幅に不足していたことが明らかとなるという事件があった。」ということである。 この件では「建物の建築確認・検査を実施した行政および民間の指定確認検査機関が見抜けず」とされて、指定確認検査機関が非難を受けたが、(偽造された)紙の構造計算書を検査するのと、(偽造された)電子的な構造計算データを検査するのとどちらが楽か考察してみよ。

2000年問題(西暦を下2桁でしか記録してない(19xxのxxだけ保持しているということ)プログラムは、2000年を1900年と思って誤動作する問題)の時、 高度情報通信社会推進本部決定(平成11年10月29日(金))では、 「中小企業の方へはこれまでも2000年問題に関する危機管理計画の策定をお奨めしてきておりますが、必要なデータのプリントアウト等によるバックアップの確保や社内の緊急体制の整備など危機管理の対応について再度ご確認ください。」 とされていた。(下線は私が挿入した。) 仮に2000年にプログラムが誤動作して全てのデータを消去してしまった場合に、この決定に従って2000年になる前のデータの(紙の)プリントアウトを持っていた場合と同じデータを電子媒体(ただし、記録した後でPCからは外しておく)で持っていた場合の違いを考察せよ。 仮に誤動作せず、バックアップを消去する必要が生じた場合の処理の容易さについても考察せよ。

情報システムを構築する場合は、いきなりプログラムを書くのではなく、まず、どのような動作をするものなのかを決める仕様(スペック,specification)というものを定め、それからその仕様に従ってプログラムを書いていく。 平成17年度の会計検査院法第30条の3の規定に基づく報告書の 「各府省等におけるコンピュータシステムに関する会計検査の結果について」によると、 電子政府構築計画に基づく「業務・システム最適化計画」の仕様書(ここでは機能情報関連図)のなかで、情報の流れの記載に不整合を生じている箇所が47最適化計画のなかの831箇所にあったそうである。 このような不整合があったままプログラムの作成を始めるとどのような問題が生じるのか考察せよ。 また、このように多数の不整合が生じた理由を想像してみよ。

yamaguch@mail.ecc.u-tokyo.ac.jp
Copyright 2011 Kazunori Yamaguchi 山口和紀@東京大学総合文化研究科