くりかえし命令と配列変数
この章では、FOR~NEXT文について学びます。
FOR~NEXT文は、それがあるだけでプログラムリストを読むのがぐっと難しくなるというおそろしい命令です。
プログラムした人は意味があって使っているしその意味もわかっているのですが、そのリストを読むほうはたまったものじゃありません。
それでも使うのはなぜかといえば、とてもベンリだからです。
これがあるだけでプログラムの手間はものすごく少なくなります。
あんがい悪くないですね。プラマイでいえばプラスじゃないでしょうか。
さらにこの章では、DIM命令、いわゆる配列変数についても学びます。
配列変数というものはパッと頭で理解するのがなかなかむずかしく、プログラムをおぼえはじめた人はみんなひっかかるポイントです。
正直わたしも何度か「こんなものなけりゃいいのに」と思いました。
「なんの役にたつんだ?」とも思いました。
「なくていいじゃん」とも思いました。
でも、そういうものが意外とけっこう役にたつということは、ここまでこの講座を読んできた人なら知っているはずです。
くやしいことにこれが本当に役にたつのです。
この章では、できるだけじっくりと配列変数のことをおぼえていきます。
あんまりじっくりすぎて途中でめんどくさくなるかもしれませんが、カベをのりこえるためだと思ってじっくり読んでみてください。
「くりかえし命令」と言ってどんな命令を想像するかな?
GOTOで作る無限ループなんか、「くりかえし」になるんじゃねえか?
0001#. @MUGEN
0002#. PRINT”クリカエシ”
0003#. GOTO @MUGEN
たしかに何度もくりかえしているね。じゃあ、無限ループじゃなく10回くり返したら途中でループをやめる、とするとどうすればいいかな?
ムリじゃねえの?
ず、ずいぶんアキラメが早いね。ええと、変数を使って、ループのたびに変数の中身を変えて、IF~THEN文で変数によって別のラベルまで……
ウォオー! 話を聞いてるだけでめんどクセエうえに、言ってるイミもよくわかんねえぜ!
なかなか難しいよね。そこで役に立つのがFOR~NEXT命令なんだ。
まずこのプログラムを見てごらん。
0001#. FOR A=1 TO 10
0002#. PRINT”クリカエシ”
0003#. NEXT
ほとんどゼンブとっかえてるじゃねえか! とりあえずRUNしてみるか。
ちゃんとクリカエシを10回書いたところで終わったね。
3行のプログラムにしちゃナカナカやるじゃねえか。どうやらクワシク話をきかなきゃならねェようだな!
英語で「FOR」は「~から」、「TO」は「~まで」という意味になるね。
FOR A=1 TO 10は「A=1から10まで」と読んでもいいだろう。
そして「NEXT」は「次にいく」というところかな。「次のくりかえしを始める」って考えればこれはわかるよね。
NEXTの方はだいたいワカッたぜ。しかしFORの方、「A=1から10まで」ってのはイミわからねェな。フツウ「1から10まで」じゃねえのか?
あれ? たしかBASICでイコール記号を使うのは変数のときだけだから……?
よくおぼえていたね。そう、このAは変数なんだ。
なんでココで変数が出てくんだ……?
話が見えてこねェぞ! ワカるようにセツメイしやがれ!
ジッサイにプログラムで見てもらうのが早いかな? ちょっと書きかえてみよう。
0001#. FOR A=1 TO 10
0002#. PRINT”クリカエシ”;A
0003#. NEXT
これをRUNするとこうなるね。
1から10まで、くりかえすたびに変数Aがふえている、のかな?
そう考えてマチガイじゃないね。これがFOR~TOのむずかしいトコロなんだけど、「A=1から始めて、変数Aが10になるまで、変数Aを1ふやしながらくりかえす」というのがFOR A=1 TO 10の正しいイミなんだ。
ズイブンいろいろなコトがはぶいて書いてあんだな、FOR~TO文にはよォ! わかりづれェ!
そのまま書いても長い命令になって、打ちづらいだろうしね。これくらいがちょうどいいんじゃないかな。
おっと待てよ、オレのギモンがカイケツしてないままだったぜ! なんで変数がかならず出てくんだ? はじめの方で使ったこのプログラムだけは、変数いらねえじゃねえか!
0001#. FOR A=1 TO 10
0002#. PRINT”クリカエシ”
0003#. NEXT
それはもっともかもしれないね。FOR~NEXT文では変数を使うことの方がずっと多いから……としか言えないかな。じっさい、変数を使わないループなら変数のことはムシすればいいんだし、別にモンダイはないだろう?
ウムム……タシカに。
うっかり別のところで変数Aを使ってると、FOR命令で変数のナカミが変わっちゃうから、それだけは気をつけないとね。
なんだかマルメこまれた気がしねェでもないが……
次はこのFOR~NEXT文と相性のいい、DIM命令について説明するよ!
まずサイショに、「配列変数」について知っておこうか。
イヤなヨカンだな……。漢字が4コ以上つづいたコトバはムズカシいモンと決まってるぜ!
まあまあ。いままでにおぼえた変数とたいした違いはないんだよ。
ホントに?
使いかたがトクシュだからとまどうかもしれないけど、変数と同じように使うものだってコトさえ忘れなければ、けっこうカンタンなはずさ。
まず、いつもの変数を考えてみようか。
0001#. APPLE=56
0002#. PRINT”リンコ゛”;APPLE;”コ”
おぼえてるかな? サンプルプログラム1でこんな使いかたをしたよね。
オボエてなくたって、リストを読めばイミはわかるぜ。えーと、"RUN"!
リンコ゛56コ
OK
そうそう、変数
APPLEのナカミ、
56を
PRINTするんだゼ!
(もうわすれてたのか……)
これを配列変数に変えてみよう。
0001#. CLEAR:DIM APPLE(1)
0002#. APPLE(0)=56
0003#. PRINT”リンコ゛”;APPLE(0);”コ”
1行目からさっそく新しい命令が2つ……
ああ、そこは今は気にしないでいいトコロだから、2行目から読むようにしてね。
ン? じゃあ変わったのは、変数のウシロに(0)がついただけってコトか? それともAPPLE(0)てのをPRINTすると56とはチガってくんのか?
いいや、APPLE(0)のナカミは56でマチガイないよ。
リンコ゛56コ
OK
じゃあナマエ以外ゼンブ同じじゃねェかよ!
変数と同じだって言ったじゃないか。こういうものなんだよ。
うーん……これはワンパク君じゃなくても、フツウの変数でいいじゃないかって思うな。
よし、その気持ちをわすれずに、配列変数の使い方その2にいってみよう!
0001#. CLEAR:DIM APPLE(2)
0002#. APPLE(0)=56
0003#. APPLE(1)=32
0004#. PRINT”リンコ゛”;APPLE(0);”コ”
0005#. PRINT”リンコ゛”;APPLE(1);”コ”
やっぱり1行目はムシして読んでね!
テメー……まさか、ソレもこのフツウの変数と同じだって言うんじゃねェだろうな……
0001#. APPLE0=56
0002#. APPLE1=32
0003#. PRINT”リンコ゛”;APPLE0;”コ”
0004#. PRINT”リンコ゛”;APPLE1;”コ”
合ってるよワンパク君! ちゃんとわかってるじゃないか。
ウオォー! ガキあつかいもタイガイにしやがれー! 変数のナマエが違うだけじゃねえか!!
そうそう、名前くらいのちがいだって思えばいいんだよ。教えやすくてたすかるなあ。
チッ、ここまではテメーのオモワクどおりってワケか。だが、そろそろ配列変数だけができるワザを言わねえと、オレもダマっちゃいないぜ!
配列変数ならではって言うと……こういうのはどうかな?
0001#. CLEAR:DIM APPLE(32)
0002#. APPLE(1)=56
0003#. APPLE(2)=32
0004#. APPLE(3)=71
#####. :
0032#. APPLE(31)=45
0033#. PRINT”1ニチメ リンコ゛”;APPLE(1);”コ”
0034#. PRINT”2ニチメ リンコ゛”;APPLE(2);”コ”
0035#. PRINT”3ニチメ リンコ゛”;APPLE(3);”コ”
#####. :
0063#. PRINT”31ニチメ リンコ゛”;APPLE(31);”コ”
あんまり長いから途中ははぶいたけど、31日分のリンゴを数えるプログラムなのはわかるよね。
つまり……カッコの中の数字があるからわかりやすいって感じ……?
フザケんじゃねエー! だからソレ、こう書いても同じじゃねえか!
0001#. APPLE1=56
0002#. APPLE2=32
0003#. APPLE3=71
#####. :
0031#. APPLE31=45
0032#. PRINT”1ニチメ リンコ゛”;APPLE1;”コ”
0033#. PRINT”2ニチメ リンコ゛”;APPLE2;”コ”
0034#. PRINT”3ニチメ リンコ゛”;APPLE3;”コ”
#####. :
0062#. PRINT”31ニチメ リンコ゛”;APPLE31;”コ”
そうだよワンパク君! よくここまでガマンしたね! ここまでは本当に変数といっしょなんだ。これから、配列変数だけの使い方に変えていくよ。
お、おう……? ガマンしたオボエはあんまりねェが、とにかくのぞむトコロだぜ!
0001#. CLEAR:DIM APPLE(32)
0002#. APPLE(1)=56
0003#. APPLE(2)=32
0004#. APPLE(3)=71
#####. :
0032#. APPLE(31)=45
0033#. FOR DAY=1 TO 31
0034#. PRINT DAY;”ニチメ リンコ゛”;APPLE(DAY);”コ”
0035#. NEXT
!!
わかってきたかな。33行目からはおぼえたばかりのFOR~NEXTを使っているね。
変数DAYを1から順にふやしながら、31までくりかえすんだよね。
DAYが1のトキは、1ニチメ リンコ゛”;APPLE(1);”コ”ってコトになる……そしてくりかえしてDAYが2になったら、2ニチメ リンコ゛”;APPLE(2);”コ”に……!
これが31まで自動でくりかえされるってワケか!
これは配列変数じゃないとできないだろう。こういう使い方もできるね。
0033#. INPUT”ナンニチメヲ シラヘ゛マスカ”;DAY
0034#. PRINT DAY;”ニチメ リンコ゛”;APPLE(DAY);”コ”
INPUTで数字を変数DAYに入れて、34行目で配列変数APPLE(DAY)をPRINTするわけだね。
うーん、これを普通の変数でやろうとすると、変数名を入力させて……いやいやそれもダメか……
みんなもわかったみたいだね。つまり配列変数は「変数名に変数を使える」ベンリな変数なんだ。
ヘンスウメイをヘンスウにツカえるヘンスウ……
ごめんごめん、「変数」というコトバばっかりでわかりづらかったね。こういうふうに、口で説明するのがムズカシいのが配列変数なんだ。だから今回はできるだけジッセン的に説明したよ。
ヘッ、なかなかヤルじゃねえかクソッタレー!
それ、ほめてるの?
配列変数についてわかってきたところで、DIM命令もおぼえておこう。
配列変数を使うときはいつも1行目に書いてあったね。
0001#. CLEAR:DIM APPLE(32)
DIM APPLE(32)というのは、これから配列変数をAPPLE(0)~APPLE(31)まで用意する、という命令だよ。
いちいち前もって数を決めておかないといけないの?
そう。このことを「配列宣言」と言うんだけど、かならず配列宣言するのはちょっとめんどうではあるね。
メンドウなコトなんざやってられるか! イキナリ書けばいいじゃねえか!
0001#. APPLE(31)=1
Subscript out of range (1)
OK
というエラーが出るんだよね。
のヤロー! こうすりゃいいんだろ! 負けたキブンだぜ!
0001#. DIM APPLE(32)
0002#. APPLE(31)=1
OK
使うのはAPPLE(31)までなのに、DIM APPLE(32)と書かなきゃいけないのがフシギなんだけど……。
そのDIMだと、用意されるのはAPPLE(0)~APPLE(31)だからね。数を数えてみるとわかるよ。
……タシカに、32コあるな。しかし言われねえとピンとこねえハナシだぜ!
LOCATE命令でもそうだったけど、ゼロから数えるから、頭で考える数より1つズレちゃうんだね。これは気をつけないといけないかな。
いっそありえないくらい大きく宣言したら?
ところが配列のこの数字は、「合計で」32768個までと決まってるんだ。たとえばDIM APPLE(32768)と宣言したあとだと、DIM ORANGE(1)くらいでもエラーになってしまうんだよ。
ヤッカイだな、まったく! まあホドホドに使うくらいならダイジョウブなんだろ?
0001#. DIM APPLE(300)
0002#. APPLE(31)=1
RUN
Duplicate definition (1, DIM)
OK
!? な、ナンだ? 300個テイドでエラーは出ねェハズだぞ!
そう感じるのもモットモだね。でもこれは配列変数の「二重定義」になっちゃうんだ。
???
たとえば、こう書くのはよくないって、なんとなく思うんじゃないかな?
0001#. DIM APPLE(32)
0002#. APPLE(31)=1
0003#. DIM APPLE(300)
まあ……いちどナカミを1に決めたAPPLE(31)が3行目でどうなっちゃうのか、不安になるね。
だから、プチコンでは同じ配列変数の名前で2度DIMするとエラーになるようになってるんだ。
そこでさっきのワンパク君だけど……
オレは最初に……
0001#. DIM APPLE(32)
って書いて
RUNして、次に
0001#. DIM APPLE(300)
にして
RUNしたが……、まさか、ソレか?
プログラムが終わっても変数の情報は消えないから、それでもエラーになっちゃうんだ。
そんなコト言われてもどうすりゃいいってんだ! これハマリじゃねえか!
だいじょうぶ。変数の情報が残ってるのがモンダイなんだから、これをリセットすればいいんだ。
0001#. CLEAR
0002#. DIM APPLE(300)
インテリ君がかならず1行目に書いていた、CLEAR命令だね!
日本語では「かたづける」と言えばいいかな。こう書くだけで、変数はぜんぶリセットされるんだ。
めんどクセェことをはぶくとだ、プログラムにDIM命令を書くトキは、かならず前にCLEARを書いときゃいいってことだな?
ワンパク君のまとめ方はランボウだけど、今回はボクもサンセイかな。
そうそう、CLEARを使うならプログラムのはじめの方がオススメだってことも言っておかないとね。あんまり途中で使うと、ダイジな変数もいっしょにクリアされちゃうかもしれないよ。
チッ、なにかとメンドウだぜ!
しかしまあワリと今回はジュウジツしたな。デカいヤマを乗りこえたって感じだゼ!
あ、でもその前にもう1つ、おぼえておきたいコトが……
マジでか。
配列変数の説明に使ったこのプログラムだけど……
0001#. CLEAR:DIM APPLE(32)
0002#. APPLE(1)=56
0003#. APPLE(2)=32
0004#. APPLE(3)=71
#####. :
0032#. APPLE(31)=45
0033#. FOR DAY=1 TO 31
0034#. PRINT DAY;”ニチメ リンコ゛”;APPLE(DAY);”コ”
0035#. NEXT
いま見直しても、2~32行目がずいぶん長いって思うよね。
でもコロンで2行や3行をまとめても、まだけっこう長いしなあ。
こういうデータをまとめたいときに役にたつのが
DATAと
READのコンビなのさ。
まずは
DATAの使い方を先に見てみよう!
0002#. DATA 56,32,71,40,64,73,61,10,45,80
0003#. DATA 25,71,63,54,98,23,14,66,58,47
0004#. DATA 94,36,31,26,45,71,24,76,66,58,46
ホントにデータって感じだね。
やってるコトは「,」で区切りながらリンゴの数を順に並べてるだけ……みたいだな。
リンゴの数の種類は全部で31。4行目だけ1つ飛び出してるけど、これはいいの?
DATA文はかなり自由だから、1行に何個データがあってもいいんだ。2行目では10個、3行目も10個、4行目では11個。プログラムしていて見やすければそれが一番だと思うよ。
だがイマんとこ、ただ数をズラッと書いてるだけじゃねえか! DATAの使いミチにはほど遠いゼ!
そこがポイントだね。DATA命令はそのままだと何のイミもないんだ。そこでREAD命令の出番になるよ。
READ、日本語で言えば「読む」だね。
いちばんカンタンな
READ命令の使いかたはこうかな。
0005#. READ APPLE
さっきの
DATA文の後にこう書くと、最初のデータ
56が変数
APPLEに入るよ!
31コあるデータなのに、入る数字は最初の1つだけかよ。どういうこった!
いくつもデータを読み込むなら、
READのあとに変数を並べて書くね。今回使うのは配列変数だから……
0005#. READ APPLE(1),APPLE(2),APPLE(3)
0006#. READ APPLE(4),APPLE(5),APPLE(6)
#####. :
こんなふうに10行ほど続けると全部のデータが読み込めるよ。
ゼンゼン長ったらしいゼ、まだまだ使えたもんじゃねェな!
あれ、待ってよ。配列変数っていうことは……?
そう、気がついたようだね。今の
READ文を短くまとめると、こうなるんだ。
0005#. FOR DAY=1 TO 31
0006#. READ APPLE(DAY)
0007#. NEXT
ココでもまたFOR~NEXTか……。オボエたての命令だが、ずいぶんアチコチで使うんだな。
特に配列変数やREADにはベンリな命令だからね。31行あった文が6行におさまったのはFOR~NEXT文のおかげだね。
いままでのプログラムリストを全部書いてみると、こうなるね。
0001#. CLEAR:DIM APPLE(32)
0002#. DATA 56,32,71,40,64,73,61,10,45,80
0003#. DATA 25,71,63,54,98,23,14,66,58,47
0004#. DATA 94,36,31,26,45,71,24,76,66,58,46
0005#. FOR DAY=1 TO 31
0006#. READ APPLE(DAY)
0007#. NEXT
0008#. FOR DAY=1 TO 31
0009#. PRINT DAY;”ニチメ リンコ゛”;APPLE(DAY);”コ”
0010#. NEXT
ウオォ、いつのまにか10行まで短くなってたのか!
5~10行目はかぶってるところがあるから、まとめちゃおう。
0001#. CLEAR:DIM APPLE(32)
0002#. FOR DAY=1 TO 31
0003#. READ APPLE(DAY)
0004#. PRINT DAY;”ニチメ リンコ゛”;APPLE(DAY);”コ”
0005#. NEXT
0006#. DATA 56,32,71,40,64,73,61,10,45,80
0007#. DATA 25,71,63,54,98,23,14,66,58,47
0008#. DATA 94,36,31,26,45,71,24,76,66,58,46
こんなふうに
DATAはプログラムリストのどこに置いてもいいんだよ。
READすると自動的にリストの最初にあるデータをさがして順番に読みこむからね。
オイオイ、8行におさまっちまったぞ!
やっていることは同じでも、はじめのころの63行あったプログラムとくらべると、かなりコンパクトになったろう。
あんまり短くしすぎると書いてる自分もこんがらがるので考えものじゃが、目で追えるていどならセイリしてまとめるのは良いことじゃな。こういうのもプログラムのひとつのダイゴミじゃ。
あ、ハカセ。いつから……?
ジジイの言うこともワカる気がするゼ。ケッキョク配列変数もFOR~NEXTもナシで書いた方がワカりやすさじゃイチバンなんじゃねえか? とか思ったモンだが……
今までの話をだいなしにしそうなハツゲンだね。
しかし、BASICの命令をクシして、めんどクセェことをゼンブはぶいたのはロックだゼ! オレのパンクスピリットにもウッタエるモノがあったな!
ワカッてくれたようでうれしいのう。そんなパンクキッズのキミのために、次のサンプルプログラムはサウンドをフィーチャーしてみたぞい。
やってやろうじゃねェかコノヤロー! さっさと見せやがれェ!
(なんだろうこのテンカイ……)
- FOR~NEXT命令
- FOR (変数)=(最初の数) TO (終わる数)
NEXT
最初の数から始めて、変数を1ずつふやしながら、終わる数までFOR~NEXTまでをくり返します。
- 配列変数
- A((数字))という形の変数が配列変数です。たとえばA(1)とA(2)はまったく別のものとして、違う数が中に入ります。
- DIM命令
- DIM (変数)((数))
配列変数に使う数を決める「配列宣言」をします。たとえばDIM A(10)ならA(0)~A(9)まで10個の配列変数が用意されます。
- CLEAR命令
- CLEAR
変数をリセットします。DIM命令の「二重定義」をしないために、プログラムのはじめのうちに使っておくのがいいでしょう。
- READ命令・DATA命令
- DATA (データ),(データ),……
変数に入れるデータ(数字など)を「,」でくぎって連続で書くことができます。
READ (変数)
変数にDATA文で書いたデータを読みこみます。データはプログラムの中で先にあるものから順に呼びだされます。