繰り返し処理、選択処理では、まだまだお話したいことがたくさんあるのですが、このカテゴリーの目的には1週間~10日ほどでプログラミングをひととおりやってみましょうということもあるので、とりあえず今は先に進みます。
コンピュータのコンピュータらしいところというと、計算が速い、たくさんのデータを記憶できるなどいろいろありますが、もうひとつ「データの保存・再利用ができる」ということがあります。電卓にもメモリーキーがありますが、コンピュータの場合、記憶・保存できるデータが数値だけでなくストリングも可能です。この章からしばらくいろいろなデータの保存・再利用の仕方について勉強します。この章では配列を使ってデータを保存することを覚えましょう。
ここまでテストの平均点を求めるプログラムを例にやってきましたが、これをもう少し改造してみましょう。平均点が出たところで、補習対象者(仮に平均点の2分の1に達しなかった生徒とします・・・厳し過ぎますか?)を抽出して表示するようにします。どうしたらよいでしょう。この場合、まず全受験者の点数の平均を求めてから、それぞれの点数が平均の2分の1以上・未満を判定することになります。そのためには最初に入力した全員の点数を保存しておく必要があります。しかし、しか~し、変数はたしかにデータを記憶できるのですが、それは次に同じ変数に別のデータが入ってくるまでの間です。たとえば、次のようなプログラムでは①で5を入力したとするとこの時点で変数Aには5が入っていますが②で10を入力したとすると、この時点で最初に入力した5は消えてしまいます。
図11-1.変数に新しい値が入ると前の値は追い出される
これでは平均を求めた後、このデータを再利用できません。最初に入っていた値を残しておくにはどうしたらよいでしょう。
[配列]
図11-2.配列の概念
ここにハイツ立山というアパートがあります。1号室は田中さん、2号室は青木さん、3号室は木下さん、4号室は空室、5号室は渡辺さんです。これをTiny BASICっぽく書くと
NAMAE$=TATEYAMA$(1)で変数NAMAE$には"田中"と入ります。同じようにNAMAE$=TATEYAMA$(2)とすると変数NAMAE$は"青木"となります。またTATEYAMA$(4)="高橋"とすると4号室には高橋さんが入居します。配列とはこのようなものです。配列を使うには使用前にDIM(dimension、寸法、次元の意味)で使用宣言をする必要があります。宣言の方法はこうなります。
DIM 配列名(正の整数)
ここで配列名の規則は変数と同じで、半角英数字と _ (アンダーバー)の組み合わせで30文字以内(先頭の1文字は英字)で英字は大文字小文字を区別しません。配列名の後ろに $ を付けるとストリングも扱えますが同じ配列の中に数値とストリングを混在させることはできません。また同じ名前で通常の変数と配列は混在できません。
配列名の後ろの( )内の正の整数は配列のサイズ(いくつ用意するか)で、添え字と呼ばれます。配列の添え字は0から始まります。また
DIM 配列名1(正の整数),配列名2(正の整数),・・・
のように1つのDIMステートメントで複数の配列を使用宣言することもできます。たとえば
DIM BANGO(5),NAMAE$(5),TENSU(5)
とすると、数値が入るBANGO(0)~BANGO(5)、TENSU(0)~TENSU(5)、ストリングが入るNAMAE$(0)~NAMAE$(5)という配列が使えるようになります。このようにして使用宣言された配列は変数と同様に使うことができます。配列名(添え字)のひとつひとつを配列の要素といいます(Tiny BASICでは配列変数と呼んでいます)。たとえば次のプログラムを実行すると図11-3.のようになります。
DIM BANGO(5),NAMAE$(5),TENSU(5)
INPUT "出席番号 ";BANGO(0)
INPUT "氏名 ";NAMAE$(0)
INPUT "点数 ";TENSU(0)
INPUT "出席番号 ";BANGO(1)
INPUT "氏名 ";NAMAE$(1)
INPUT "点数 ";TENSU(1)
図11-3.入力したデータを配列に保存する
これでキーボードから入力したデータは配列に保存されます。ただしこのような使い方では配列を使う意味はほとんどありません。配列を使う大きなメリットは繰り返し処理の中で同じ処理で異なる変数が扱えることです。これを使って前章でやったプログラムを図11-4のように改造してみましょう。このプログラムはテストの平均点を求めた後、それぞれの生徒の得点が平均とどれくらい差があるかを表示するものです。得点-平均点で、平均点より高ければ正、低ければ負となります。入力したデータは配列に保存しておき、平均点を求めた後に再利用します。
1: DIM BANGO$(100),NAMAE$(100),TENSU(100)
2: PRINT "***テストの平均点***"
3: GOKEI=0
4: NINZU=0
5: TOKUTEN=-1
6: I=0
7: NUM$="-1"
8: WHILE NUM$<>"999"
9: INPUT "番号(999=END) ",NUM$
10: IF NUM$<>"999" THEN
11: INPUT "氏名 ",SHIMEI$
12: INPUT "点数 ",TOKUTEN
13: BANGO$(I)=NUM$
14: NAMAE$(I)=SHIMEI$
15: TENSU(I)=TOKUTEN
16: GOKEI=GOKEI+TOKUTEN
17: NINZU=NINZU+1
18: I=I+1
19: END IF
20: WEND
21: HEIKIN=INT(GOKEI/NINZU)
22: PRINT "平均点は";HEIKIN
23: LASTNUM=I-1
24: FOR I=0 TO LASTNUM
25: TENSA=TENSU(I)-HEIKIN
26: PRINT BANGO$(I);" ";NAMAE$(I),TENSU(I),TENSA
27: NEXT I
28: END
図11-4.テストの平均点と受験者各々の点数の差を求めるプログラム
前章のプログラムに追加・変更された部分について説明します。
1行目は配列の宣言です。ここでは番号、氏名、得点を保存しておく配列を0から50で51個ずつ(51人分)用意しています。
6行目で配列の添え字用の変数の初期値を 0 としておきます。
今回は出席番号はストリング型としています。出席番号は普通計算の対象にはならないのと、出席番号に数字以外の文字が含まれる場合(1年A組1番が 1A01 など)にも対応するためです。そして出席番号は手動で入力することにします。出席番号に欠番があったときの対策です。8行目以下のWHILEブロックに入るため7行目では出席番号にあり得ないデータとして -1 を代入しておきます。
9行目で出席番号を入力します。ここで"999"が入力されたらデータ入力終了です。
出席番号が"999"でなければまだデータ入力は続きますから、氏名、点数を入れるのは11~12行目(WHILE~WENDのループ内)になります。
13~15行目は入力したデータを配列に保存しておくところです。このように配列の添え字には変数も使えます(変数の中身は0以上の整数でなくてはなりません)。1回目のループでは添え字用変数 I の値は 0 なので出席番号はBANGO$(0)、氏名はNAMAE$(0)、点数はTENSU(0)に代入(保存)されます。そして18行目で添え字の値を 1 加算して次の生徒のデータは次の配列に入るようにします。
21行目はデータ入力が全部終わって平均を計算するところですが、ここでは INT(GOKEI/NINZU) とINT( )の( )内に点数合計÷人数の計算式が書かれています。このINT( )は関数とよばれるもののひとつです。関数については後で詳しく説明します。INT( )は( )内の数を整数化するものです。( )内は数値である必要があります。( )内の数の小数第一位以下を切り捨てるものなので小数点第一位を四捨五入するのではないことに注意してください。
23行目はデータを保存した配列の最後の添え字を保存しています。このプログラムではデータ入力のループを抜けたところで配列の添え字 I は最後の値+1になっているので I-1の値を別の変数を別の変数に保存しておきます。
そして24~27行目が配列に保存したデータを再利用して平均点との差を計算し、結果をディスプレイに表示する部分です。このプログラムを実行すると図11_3.のようになります。
図11-5.実行画面
【昔はよかったなぁ】
図11-4のプログラムを昔のBASICで書くと図11-6のようになります。
図11-6.図11-4のプログラムを昔のBASICで書くと
行番号10に
OPTION BASE 1
とありますが、これは配列添え字の下限を 0 にするか 1 にするかの指定です。命令というか宣言です。どうして昔のBASICにはこんなものがあったのかというと、この宣言がないとこのプログラム中のすべての配列の添え字は 0 からになります。しかし、プログラム中で使うすべての配列の添え字の最小値が 1 だとした場合、各配列の添え字 0 の要素が主記憶装置上に占める分は無駄になります。OPTION BASE 1とすると、プログラム中の全配列の添え字 0 の要素がなくなるので、それだけ主記憶装置上に占める分の節約になります。昔のBASICが全盛だった頃のパソコンは主記憶装置の容量が8ビットパソコンで64KB、16ビットパソコンで640KBが最大でしたから、実務プログラムを作ろうとすると、このようにして(これ以外の方法でも)メモリ節約との戦いになったものです。
今日のパソコンでは主記憶装置の容量が4GBとか大容量になりましたから、普通の事務処理プログラムやゲームプログラムではメモリ節約なんて考えなくともよくなったので、今のTiny BasicにはOPTION BASEはありません。
行番号にGOTOというのがあります。これは無条件ジャンプといい、指定された行番号(またはラベル)以後の処理にジャンブする命令です。制御ブロックがなかった(構造化プログラミングがほぼ不可能な)昔のBASICにはなくてはならない命令でした。ただGOTO命令の使い過ぎはプログラムがわかりにくくなる原因にもなり、当時からあまり推奨される命令ではありませんでした。今のTiny BasicでもGOTO命令はあるのですが、制御ブロックが使える(構造化プログラミングが可能)ので、よほどの場合でない限り、GOTO命令は出番がなくなりました。
【この章のまとめ】
変数名の後ろに(数字)が付いたものを配列(配列変数)という。
配列を使うとデータの保存、再利用ができる。
配列を使用するには DIMステートメントを使う。書き方は
DIM 配列名(正の整数)
配列名の規則は変数名と同じである。正の整数は配列のサイズ(添え字の最大値)である。添え字の最小値は 0 である。
INT(数値)は( )内の数値を整数化(小数点第1位以下を切り捨てる)する。関数のひとつである。
【演習7】次のプログラム仕様書に基づくプログラムを作りなさい。