第7回:1バイトたりとも無駄にはしない

今回は基本に戻ってBASICでプログラムを作る時の話になります。
ポケコンでゲームを作っている時にどうしても悩まされるのが”メモリ不足”だと思います。

G801をはじめとするRAMが8KB(FRE=5859バイト)のユーザーは、
あまりのメモリの少なさに「大作が作れないよぅ」と嘆いているでしょうし、
RAMが32KB(FRE=30435バイト)のユーザーも、
G801とかでも遊べる様にする為に出来るだけプログラムサイズを小さくしないといけない場合もあります。

そこで今回は、BASICプログラムにおけるメモリの節約法を書いていこうと思います。
わずか数バイトのみみっちい話でも、塵も積もれば山となるのです。


●マルチステートメントにする●

マルチステートメントって何?という人もいるかもしれませんが、
簡単に説明すると『複数のBASIC命令を”:”(コロン)でつないで1つの行に収める事』を指します。

例えば、
リスト 1
 10:A=10
 20:B=20
 30:C=30
 40:D=40
 50:E=50
 60:F=A+B+C+D+E 
 70:PRINT F
 80:END
というプログラムをマルチステートメント化すると

リスト 2
 10:A=10:B=20:C=30:D=40:E=50:F=A+B+C+D+E:PRINT F:END 
のように1行になりました。

この時、リスト1に比べてリスト2の方が14バイトの節約になります。
なぜ同じ内容なのにメモリの節約になるかというと、
BASICリストでは1つの行を作る為には行番号用の2バイトと、
その行のエンドマーク用の1バイトで合計3バイトのメモリを使ってしまいます。

それなら、8行のリストが1行になったんだから(3バイト*7行分=21バイト)の節約になりそうですが、
プログラム中のコロンの数が増えた分の7バイト引いて結果的に14バイトの節約になります。


●16進数は10進数に直す●

BASICプログラムで16進数を使うのは、
CHR$とかマシン語にアクセスする命令(POKE,PEEK,CALL)などの時がありますが、
これを10進数に直すと数バイトの節約になります。

例:CALL &H100 → CALL 256
  (とすると、なんと2バイトの節約!)

あまり意味がないように見えるかもしれませんが、16進数を10進数に直す最大のメリットは、
メモリの節約よりも「処理速度が速くなる」という事です。
少なくとも、アクションゲームの様なスピードが要求されるプログラムでは、
全ての16進数を10進数に直しておいた方がいいと思います。


●まずは1文字変数を使いきる●

1文字変数(固定変数)とはアルファベットのA($)〜Z($)までの26個の変数の事です。
ポケコンにはあらかじめ「固定変数エリア」というエリアがあって、
1文字変数に数値や文字列データを代入しても、この「固定変数エリア」にデータが確保されるので、
変数使用料(←勝手に命名)としてポケコンに数バイト払う必要はないのです。

ところが、2文字変数(アルファベット2文字 OR アルファベット+数字)を使用した時には、
変数使用料として15バイトも取られてしまいます。(数値変数の場合です)

さすがに15バイトもとられるのはもったいないので、
1文字変数を全て使い切るまでは2文字変数は使わない様にするとよいでしょう。
もちろん2文字変数を使ってプログラムを書くと、1文字変数の時よりメモリを余計に使いますしね。

例:S=S+200 → SC=SC+200
  (とすると、なんと2バイトの損!!)

ましてや、文字変数に2文字変数なんかを使った日には、
変数使用料として23バイトも取られてしまいます。余りにももったいないでしょ?

しかし、2文字の文字変数は悪い事ばかりではありません。
A$〜Z$までの1文字の文字変数は、最大で7文字までしか文字データを入れる事が出来ないのに対して、
2文字文字変数は最大16文字までの文字データを入れる事が出来るので
DIM命令を使いたくない時には有効です。まあ、そのへんは臨機応変に・・・・


●THENは全然使わない●

THENというのはIF文の後ろについてくる命令で、THENだけを単独で使う事はありません。
E200/G800シリーズのBASICではTHENを省略することが出来ます。

具体的に説明していくと、
リスト 3
 10:IF B=1 THEN PRINT ”OK” 
             ↓
 10:IF B=1 PRINT ”OK” 
リスト 4
 10:IF A=1 THEN B=1 
         ↓
 10:IF A=1 LET B=1 

まず、リスト3の方ですが、THENが省略されて「B=1」の後に直接PRINT文がきています。
なぜこの場合THENが省略できるかというとPRINTという命令が、単独で使える基本命令だからです。

E200/G800シリーズのBASICの場合は、THENの後が基本命令の時はTHENを省略する事が出来ます。
「PRINT」以外の基本命令には、

 CALL CLS END FOR〜NEXT 
 GOTO GOSUB IF INPUT LET 
 LOCATE ON〜GOTO ON〜GOSUB 
 POKE READ STOP USING WAIT 

等があります。THENを省略すると1回につき2バイトの節約となるのです。

次にリスト4ですが、この場合はTHENの部分をLETに置き換えています。
「LET」という命令は、変数にある数値やデータを代入する時に頭につける
命令ですが、省略するのが一般的なので普段はあまり見かけない命令です。
「A=3」という代入文も、本来なら「LET A=3」とするのが正式な記述なのです。

リスト4の場合は、THENを省略して基本命令のLETをもってきてる訳です。
しかし、LETという命令自体が普段省略されている命令なのだから、

10:IF A=1 B=1 (LETを省略している)

という記述でもいい様な気がしますが、さすがにエラーになってしまいます。
LETという命令は、THENの後に代入文が来た時の為だけに存在するといっても過言ではない命令なのです。

さて、リスト4ではTHENをLETに変えたので見た目には1バイトの節約になっていそうですが、
実際にはメモリの節約にはなっていません。
なぜなら、THENもLETもポケコンのRAMの中では「中間コード」という2バイトの記号として収まってるからです。

「それなら意味ないじゃん!」と言われそうですが、
確かにTHENの後が代入文の時に限ってはそうかもしれません。(速度的にも殆ど変わりませんし)
結局これは好みの問題であって、
私の場合は「THEN」と入力するよりも「LET」と入力した方が楽なのでLETを使っています。

とりあえず『ポケコンのIF文にはTHENを使わなくてもいい』という事さえ頭にいれておけば、
ネット上や雑誌などに載っているプログラムを手入力する時に
掲載されているプログラムを一字一句同じ様に入力しなくても自分で省略出来るので楽になりますよ。

ただしG815やG850ではIF文にELSEを使う事ができ、
ELSEを使う場合はTHENを省略する事は出来ないのでドンドン使っていきましょう。



もっと知りたいINDEX第1回第2回第3回第4回第5回第6回第7回第8回

TOPページに戻る
 
  inserted by FC2 system