◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇
◆ F−BASIC386ミニガイド ◆
◇ 1995年7月21日(金) (C) 渡辺 良一 ◇
◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆
この文章は、J−TYPEの目次表示を意識して作られています。
●まえがき
この文章は、フリコレのBASICで作られたプログラムを見ていて、気づいた
ことを書いてあります。ここに書いてあることはどれも個人的な意見です。内容的
には、BASICをやっている人には役に立つ内容かと思います(特に初心者)。
中には、BASICに関するテクニックもあります。これなどは、上級者にも役に
立つのではないかと思います(もう知っているという可能性もあるが……)。
長い文ですが、興味の沸く所だけでもぜひ読んでください。
F−BASIC386 V2.1対応で書かれていますが、V1.1でもほとん
どの事が通用します。また、この文章は違う名前でフリコレ10に発表したときのも
のに追加・修正(見直し含む)をしたものです。同じ項目のところは、内容的には
変わっていないので、前回読んで下さった方は再度読む必要もないと思います。
♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪初級編♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪
まず最初は初級編として、初心者がよくひっかかる重要なことを書いておきます。
ここに書いてあることは「知らないと損!」という感じです。「マニュアルではちょ
と説明不足」と思い自分なりに書いてみました。
▽プログラムは見やすく
プログラムは見やすくしましょう。処理の様子を秘密に(分かりにくく)したい
場合以外は、段下げなどを行って見やすくしましょう。そうすれば、あとで手を加
えたい場合(改版)や、他人がプログラムを解読してプログラミングの勉強をした
い場合に分かりやすくなります。
また、分かりづらいところは注釈を入れましょう。注釈を入れる場合
「cls :'画面クリア」とする人がいますが、「:」は不要で、「cls '画面クリア」
とすることが出来ます。
★ラベル
プログラムで分岐するとき、分岐先を行番号で指定するプログラムがあります
が、はっきり言います。今すぐやめましょう。
ショートプログラムならまだしも、ある程度大きなプログラムになってくると、
行番号では、分岐先の役割が分かりにくくなりますし、もしかしたら今後のF−
BASIC386のバージョンアップで実現するかもしれない、行番号なしのプ
ログラム編集に対応できません。
処理のまとまりごとに、コメント文をおいて隙間を開けるのもプログラムを見
やすくする秘訣です。
また、F−BASIC独自の機能として日本語でラベル名を記述することが可
能です。日本語ラベルを使えば、ラベルの後にサブルーチンの説明をコメントと
して書く必要がなくなり、分岐元でもどんな処理のために分岐しているのかが分
かるので日本語ラベルを積極的に使用しましょう。
とは言っても、ラベル名が長くなるという欠点もありますので、多用するルー
チンにやたら長いラベル名は控えた方がいいでしょう。
また、ラベル名の後ろを『:』で区切って命令を記述することも可能です。覚え
ておくといいでしょう。
★変数
プログラム全体で使用する変数に、半角1文字の変数を使用するのは出来るだ
け避けた方がいいでしょう(プログラム全体で使用しているからこそ、逆に短い
名前の変数を付ける場合もあります。例えば X,Y)。また、変数名は変数の役割
の略称や頭文字にするのがいいでしょう。例えば色を指定する変数は「col」に
するなど。そして、変数表を付けておくと、プログラムを解析を能率良く行った
り、手直しを容易に行うことが出来ます。
ちなみに、日本語変数や前述の日本語ラベルは他機種との互換性の問題から使
用しない人もいます。でも、TOWNS専用命令(スプライトなど)をプログラ
ム中でふんだんに使ってしまえば、何をいまさらと思いますが………。
▽初期化
プログラムを書くとき、一番最初に初期化という作業をします。初期化とは、そ
のプログラムを動作させるための環境をしっかりと整えておくことです。例えば、
メモリ初期化、画面初期化、変数初期化(宣言)、音色初期化……………などなど
プログラムをスタートさせる前に様々なことを初期化しなくてはなりません。フリ
コレの中のプログラムを見ていると、これがしっかり出来ていないものがあります。
コンパイルしたものなら大抵はコンパイラが初期化の部分を付け足してくれます
が、インタプリタではそうはいきません。
前のプログラムを実行した環境が残っていることがあるので、うまく動作しない
場合があります。また、プログラムを終了するときには画面を初期化をするように
心がけましょう。
★メモリ初期化
・使用命令
clear,,スタック,配列変数,プロシジャ,DLL
メモリをしっかり初期化しないと、メモリ不足でプログラムが動作しなかった
り、予想したと通りに動作しなかったりします。
よく「clear」だけや「clear,,,200000」とか「clear,,,,1024」となっていた
りしますが、値を省略した部分は前の設定と変わらないので、その前に実行した
プログラムが動画ファイル再生プログラムだったりすると、400KBぐらいの
DLL領域が、そのまま残ってしまいます。使わない領域はしっかりと0を指定する
ことが大切です。
clear,,1024,,0,0
また配列変数領域はDIMで宣言する配列変数のための領域ですから、そのプ
ログラムで使用する大きさは大体わかります。その大体の領域を指定します。正
確に〜バイトまで調べてもいいのですが、そうすると計算ミスが起こったり予想
外の部分で足りなくなったりします。
配列変数領域で使われなかった領域は、単純変数領域に使われます。
領域の使用目的は次のとおりです。
単純変数領域 …………… 文字変数すべてと配列変数でない数値変数
配列変数領域 …………… 配列文字変数の管理用と配列数値変数とその管理用
★変数型宣言
変数型宣言を説明する前に数値変数の型について説明しておきます。
変数には必要に応じていろいろな種類のものがあります。それを変数の型と言
います。
変数の型は始めは意味が分からず読み飛ばしてしまうのですが(自分がそうで
した)、実はとても重要な事なのです。変数には使用する目的によって、型が分
けられています。
◇整数型
−32768〜32767の範囲の整数です。
変数をこの型にするには、変数名の後ろに「%」を付けます。
大抵の変数はこの型を使用します。これより大きな数を代入する場合は次に
あげるロング整数系を用います。
◇ロング整数型
−2147483648〜2147483647の範囲の整数です。
変数をこの型にするには、変数名の後ろに「&」を付けます。
整数型で間に合わない大きさの数値を代入するのに用いる。
◇単精度実数型
少数を代入するときに使用します。有効桁数が7桁までです。
変数をこの型にするには、変数名の後ろに「!」を付けます。
◇倍精度実数型
少数を代入するときに使用します。有効桁数が16桁までです。
変数をこの型にするには、変数名の後ろに「#」を付けます。
少数演算で精度を必要とするときはこの型がいいでしょう。
このように数値変数はいろいろな種類が別れています。では、なぜいろいろな
種類に別れているのでしょうか? なぜ必要に応じて使い分けなければならない
のでしょうか? みんな倍精度整数変数じゃいけないのでしょうか?
この答えには、それぞれの型に必要なメモリが係わってきます。
| 1つに必要なメモリ
整数型 ………………… 2バイト
ロング整数型 ………………… 4バイト
単精度実数型 ………………… 4バイト
倍精度実数型 ………………… 8バイト
たいして違わないと思わないでください。確かにただの変数ならたいした違い
にはなりませんが、配列変数を考えてみてください。せいぜい20000位まで
の整数しか保存しない1000の要素を持った配列変数に、整数型と倍精度実数
型を使った場合どうなるのか?
整数型を使用すると必要なメモリは 2バイト×1000=2000バイト
倍精度実数変数を使用すると必要なメモリは 8バイト×1000=8000バイト
───────────────
差 6000バイト
6000バイトといえば大きな差です。
ついでに説明しておきますがプログラムには変数のほかに定数というものもあ
ります。定数とはプログラム中に直接記述してある数値のことで「A=10*B」なら
ばこのときの「10」が定数です。定数も定数の後ろに「% & ! # $」を付けること
で定数の型を宣言することが出来ます。
ちなみに、BASICでは定数を宣言することは出来ないので「A=10」として、
その後一切変数Aに数値を代入しなくても「A」は変数として扱われます。
さて、ここで出てくるのが変数型宣言です。変数型宣言とは何なのでしょうか?
変数には、型の指定されていない変数(変数名の後ろに何の記号もない変数)
があります。これは、標準では単精度実数型と見なされます。型の指定されてい
ない変数の型を決めるのが変数型宣言です。これを宣言する命令は次のようなも
のがあります。
defint ………………… 整数変数
deflng ………………… ロング整数
defsng ………………… 単精度実数変数
defdbl ………………… 倍精度実数変数
(defstr ………………… 文字変数)
使用例として、「defint a-z」とすると変数名の最初がA〜Zまでの文字で始
まる、型の指定されていない変数が整数変数と見なされます。「時間」という日
本語変数も宣言したい場合は「defint a-z,時」とします。こうすれば「時間」と
いう日本語変数も整数変数として見なされます。
以前、フリコレのプログラムを見ていて『要RAM4M』とあるプログラムを
実行してみました。自分のパソコンはRAM2Mなのでメモリが足りないとエラ
ーが出ました。次に行の最初の方に「defint a-z」を追加し、clear 命令で変数
の領域の調整したらすんなり動いてしまいました。
こんなこともあるのです。しっかり変数の型は使い分けましょう。
ここで注意してほしいのですが、整数型で変数を宣言してしまい、ついうっか
り整数型の範囲を超えるような数値が代入されプログラムが中断することがある
ことです。
このようなことが起こらないように、そのような変数は最後に「&」を付けてロ
ング整数にします。TIME関数(0時0分0秒からのトータル秒数を返す関数)
を代入する変数やゲームで得点をカウントする変数などがそうです。特に得点な
どのように常に増えていくようなものは、変数の範囲を超えてしまうとその場で
エラーが出てプログラムが止まってしまいます。
また変数の範囲を超えなくても、表示の対応していない範囲までに数値が大き
くなると表示が変になってしまいます。例えば、「print using"####";SS」とし
ているのに、SSに9999より大きい数(-999より小さな数)を与えるだけで表示が
バグってしまいます。この場合は「if SS>9999 then SS=9999」とするなどしま
しょう。
これらをしっかりしておかないと、思わぬところでエラーが出てプログラムが
中断したり、予定どおり表示されなかったりします。ロング整数型でも「まず無
いことだから」とか言わないで、しっかり許容範囲を超えないようにしましょう。
前にフリコレ7のBASICで作られた某大作RPGをやっていたら、最後の
面の1つ手前の面をやっていたときに突然エラーが出てゲームが終了してしまい
ました。エラー番号から原因を調べたところ、それまでの面を完璧にやっていた
ために得点が増えすぎて、その結果エラーが出て終了したことが分かりました。
このRPGはとてもBASICで作られたとは思えないほど、素晴らしいでき
のゲームなのですが、このようなバグがあるためにエンディングが見られなかっ
た人、他にもいるのではないでしょうか?
このように、せっかくのゲームがだいなしに近い状態になってしまうこともあ
ります。使用する変数の型には注意しましょう。
結局そのRPGその後どうしたこというと、セーブデータを解析し、得点を減
らして無事エンディングを見ました。結構セーブデータの解析は好きで、ゲーム
に詰まるとすぐに解析するという力技で対処しています。もう、3つのフリーソ
フトのゲームのセーブデータを解析しました。そのうち1つは、プロテクトが掛
かっていたのでBASICでデータ作成ツールなるものまで作ってしまいました。
(みなさんごぞんじのセーブデータが44バイトのパズルゲームですよ☆)
▽ディレクトリについて
ファイルを指定するときに、『A:』や『\』 など固定で読み込んでいる場合があ
ります。これをすると、フリコレに応募したときや、ハードディスクの任意のディ
レクトリにインストールした場合は、AドライブならAドライブに、ルートディレ
クトリならルートディレクトリにコピーしないと動かず、「試しに起動してみよう」
とかしてもらえなとなっちゃいますよ。(固定で読み込んでいる人に限って、「ど
こどこににコピーして使用してください」って書いてないんだよなー)
だからといって一つのディレクトリに全てのファイルを置くのは、ちょとどうか
なと思います。
では、ファイル指定の例をあげます。
・ルートディレクトリの『game.cfg』
\game.cfg
・現在のカレントディレクトリ中の『data』というディレクトリの下の
『name.txt』というファイル
data\name.txt
・『\program\demo\data』がカレントディレクトリのとき、
『\program\demo\graphics\river.tif』というファイル
..\graphics\river.tif
※『..\』はひとつ上のディレクトリを示します。
TownsMENUのマニュアルにはファイル・ディレクトリに関する詳しい説
明がありません。(ぼくのはV2.1L20なので他は知りませんが………)
とくに、ディレクトリ構造は、難しいのに少しも触れていません。
自分は、これを買う前に使っていた学校のFMR50で、MS−DOS Ver3.1を
使用していて、DOSの基礎的なことはマニュアルを読んでほぼ理解していたので
TOWNSを買ったとき、たいした苦労をしなくてすみました。
でも、TownsMENUのマニュアルよりは丁寧に書いてある、MS−DOS
のマニュアルですら、ディレクトリ構造の説明になったら、てんで分からなくなっ
た覚えがあります。結局、ファイル管理ツールなどを使ううちに、分かりましたが。
だから、分からない人はファイル管理ツールでも手に入れて実際に使ってみるか、
持ってない人は、TownsMENUのファイル表示でいろいろしてみるといいで
しょう。『
』となっているのがディレクトリです。
アプリケーションや、GUIの説明もいいですが、基本的知識や、CUI(コマ
ンドモード)がせっかくあるのに、説明がなくてはまさに宝の持ち腐れです。バッ
チファイルを使えば、いろいろな事ができるのに、それについても全く説明があり
ません。
始めて触れて買ったパソコンがTOWNSだという人はこのマニュアルを読んで
どういう感想を持ったのでしょうか? Towns付属のマニュアルニ限らず、そ
の他多くのマニュアルは、初心者がその意味を理解するには難しい、つまり説明不
足だと思います。やはり、分かっている人が書いているから説明に落ち度があるの
だと思います。熟練者には当たり前のことでも、初心者にとっては難しい事であっ
たりしますから。
出来上がったマニュアルは、一度初心者に見せて意見を聞くというのはどうだろ
うか?(ね、富○通サン)
▽セーブ形式について
セーブ形式はアスキー式にしましょう。バイナリファイルだと読み込み保存のス
ピードが速くなるという利点がありますが、他に決定的な欠点がいくつがあります。
先ず、そのままではコンパイルすることができません。バージョンが違うと読み
込めなくなります。テキスト形式(アスキー形式)ではないので、BASICでし
か内容を見たり、編集したりできなくなります。その他、BASICのチェクサム、
変数検索、ラベル検索プログラム等がそのままでは使用できません。また、マニュ
アルによるとファイルサイズが小さくなるそうですが、ときにファイルサイズが大
きくなることがあります(コメントが多いとそうなるようです)。
このような理由から、バイナリ形式での保存は控えた方がいいでょしう。しかし、
そうはいっても、読み込み保存のスピードが速くなるというのは大きな魅力です。
プログラムの開発では何度もセーブ・ロードを繰り返すので、開発中のプログラム
のセーブ形式としてはバイナリ形式もいいと思います。しかし、フリコレなどで発
表する場合はアスキー形式で保存したものにするか、アスキー形式保存のプログラ
ムを付属しておくといいかと思います。
▽STOP OFF
この命令はくせもので、かけるべきかどうか悩むとこでしょう。もし、完成した
プログラムとして発表するならば掛けた方がいいのですが、まだ思わぬバグ(はま
り)があるかもしれないのならば掛けない方がいいでしょう。
フリコレのプログラムを実行していたら、エラーがメッセージが出て「Bドライ
ブにディスクを正しくセットしてください」みたいなことが表示されました。その
ときは、CDから起動していたのでBREAKで中断しようとしたら、STOP
OFFが掛けてあるのです。そのときはしょうがなくリセットしました。
このプログラムの作者は、エラー処理も出来ているしいいだろうと思ってSTOP
OFFが掛けてあったのだと思いますが、必ずしも対処しえないような対処方法を
要求するプログラムはやめたほうがいいかと思います。終了するか、もう一度読み
込むのかを選択するようになっていれば良かったと思います。
ミニ知識になりますが、STOP OFFを掛けると、処理速度がコンマ数%向
上します。
▽コンパイルは行番号なしで
これはコンパイラを持っていない人には関係のない話なのですが、コンパイル時
に行番号ありでコンパイルするとファイルサイズが大きくなってしまうのは知って
ますよね。どうも、プログラム中で『GOTO 2000』とかしているから行番号なしの
コンパイルは出来ないと思っている人がいるようです。でも、実際はそんな事はな
くて、たとえプログラム中で『GOTO 2000』とか『GOSUB 5600』とか記述していて
も行番号なしのコンパイルは出来ます。
コンパイラで行番号ありにする利点と言えば、デバッグ(バグなどがないか調べ
ること)用に利用するかエラー発生行を調べるぐらいです。エラー発生を行番号で
原因を調べるよりも、エラーが起こるような所はファイルアクセスなどのいくつか
に限られるわけですから、「ER=1:LOAD@"DATA.DAT",DAT:ER=0」みたいにしておけ
ば、わざわざ行番号を調べる必要もないと思います。
コンパイラで行番号ありを指定しても、ファイルサイズを大きくしてディスクや
メモリが圧迫されるぐらいです。すぐにでもやめた方がいいでしょう。しかし、ま
だバグの潜んでいる可能性のあるプログラムを発表する場合、もしバグが発生した
ときに行番号も報告してもらえばその原因を追求しやすいという理由から行番号あ
りでコンパイルする人もいます。その場合はいたしかたないと思います。
▽音色ファイル
これはフリコレに限定されるのですが、プログラムでシステムソフト付属の音色
ファイルを読み込むときに「Q:\FJ2\EUP\*.FMB」や「Q:\FJ2\EUP\*.PMB」として読
み込んでいるのがありますが、フリコレのCDには「\FJ2\EUP」というディレクト
リは存在しません。でも、音色ファイルがないわけではありません。音色ファイル
は「Q:\FJ2\TONE」というディレクトリの中にあります。ですから音色の読み込みの
際はこのディレクトリから読み込むことにしましょう。
また、「Q:\FJ2\TONE」以下の音色ファイルははマニュアルにもあるとおりプログ
ラムや音楽演奏への使用が認められているので、フリコレ応募時に一緒にディスク
に入れた方がいいでしょう。
ちなみに、TONE以下の音色ファイルを編集して出来た音色ファイルはミュージカ
ルプランの二次的な著作物となるそうです。でも、そのファイルは元のデータ同様
自由プログラムに組み込んだり配付していいそうです。
♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪操作性編♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪
ここは、プログラムの方法がどうだこうだと言うのではなく、完成したプログラム
の機能がどれだけ使いやすいか? ということです。つまり、ここにあるような事を
気をつけると、プログラムが使う側に親切になる。操作しやすくなる。
う〜ん、うまく説明できない。プログラムを作るときは使う側にたって、操作しや
すいプログラムを作る。この一言に尽きる…………………かな?
▽プログラム終了手段
フリコレを見ていると、プログラムによっては終了手段がなくドキュメントに
「PAUSEキーを押してください」となっているものを見かけますが、PAUSE
はあくまで強制的にプログラムの実行を中断させる手段なので、これを終了方法と
するのはあまり好ましいとはいえません。
だから、しっかり終了手段を用意するべきでしょう。分かりやすい方法、そして
前にもあったようにプログラム終了時に画面を初期化した方がいいでしょう。
また、特定の場面からしかプログラムを終了できないのも不便です。終了できる
場面にいつでもすぐに戻れるようにしておくか、PFキー割り込みか何かで、いつ
でも終了できるようにしておくといいかと思います。
▽CDをBGMに
BASICプログラムに問わず、CD演奏をBGMに使用するプログラムが多く
あります。別にそれ事態は悪いことではないのですが、BASICで作られたプロ
グラムで音楽トラックのあるCDがないとプログラムが動作しないプログラムがあ
ります。そのようなプログラムはフリコレなどでCDから起動するとき大変不便で
すし、ぼくみたいに音楽CDを1枚も持っていない人にとって大変不便です。です
から、音楽CDがなくても無事動作するように作った方がいいでしょう。
♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪おねがい編♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪
BASICプログラマへの個人的なお願いです。
(あっ、コラ、そこ、飛ばし読みすんじゃない!)
▽ソースを公開して
コンパイラを持っていない人には関係のない話なのですが、ソースファイル(コ
ンパイルなどをしてできたファイルの元となっているファイル。BASICの場合
『.EXP』に対する『.BAS』がソースファイルにあたる)を公開してください。
これは、どちらかといえば上級者へのお願いないのですが、最近はコンパイラで
作成されたプログラムはソースファイルを付けないのが常識みたいになっています。
しかし、ソースファイルがないと、このプログラムはどのようにこの処理を実現し
ているのだろうと思ってもそれを調べることができません。
確かに秘密の保持も分かりますが、コンパイルしたものが完全に秘密が守ってい
るかと言うとそうではありません。文字列はプログラム中(この場合 *.EXPのこと)
にまとまって文字列として存在しています。従ってJ−TYPEなどのツールで、
『*.EXP』を直接見てしまえばゲームならばメッセージが分かってしまいます。たい
した秘密の保持にはなっていません。あと、.BASファイルを公開するとプログラム
の変数をいじくってRPGならばLVを20まで上げたり、出てきた敵のHPを0
にしたりとかいじられる危険性がありますが、それがどうしてもいやならば、『デ
ータSAVE』の部分を取った物を公開するとかすれば済むことだと思うのですが…
ソースファイルを公開すれば、きっと皆さんがすばらいしプログラムで恩返しを
してくれます。もしかしたら、プログラム中のミスを指摘してくれるかもしれませ
ん。けちけちしてないで、みんなでソースファイルを公開しましょうね。
♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪テクニック編♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪
その名のとおり、BASICプログラミングテクニックです。ここにあることはマ
ニュアルには一言も書いてありませんが、知っておくとあとあと役に立ちます。でも、
もうすでに知っているという人もおられるかと思われます。
▽動作モードについて
最近のマシンはますます高速化が進み、スプライトを使用するゲームやごく簡単
なグラフィックをデモンストレーションするプログラムでは目にとまらぬ速さになっ
てしまいます。そのため高速マシンには、互換モードと高速モードがあることはも
ちろん知っていますよね。(えっ知らない!? マニュアルを見てね)
| 386機で開発している人は、普通に動作すると思って発表しているようですが、
上のようなプログラムの場合まず早すぎて使いものになりません。そのためこのよ
うなプログラムでは、プログラム中でタイミングを取るか互換モードに切り換えて
から実行しなくてはなりません。タイミングを取る方が確実なのですが、今のBA
SICではなかなか難しいことです。そこで、簡単にできる互換モードに切り換え
る方を取りましょう。えっ、動作モードを切り換える命令なんかないじゃないかっ
て。そのとおり、動作モードを切り換える命令はありません。あったとしても公表
されていません。しかし、OUT命令を使用することで簡単に動作モードを切り換
えることができます。
ノーマル(互換)モードに切り換える …………… out &h5ec,0
ファースト(高速)モードに切り換える …………… out &h5ec,1
この命令を使用して、動作モードを起動時に互換モードに切り換えましょう。高
速モードがない機種では実行しても何も意味はありません。害もありません。
しかし、これだけでは不親切なプログラムです。起動したら互換モードになった
のはいいけど、プログラムを終了しても互換モードのままだ。かといって、プログ
ラム終了時に必ず高速モードに切り換えると、互換モードをわけあって使用してい
た人には迷惑です。(そんな人いないと思いますが……………)
やはり、プログラム終了時には起動時の動作モードに戻してやるべきです。その
ためには次のようにプログラムを組みます。
MODE=inp(&h5ec,1) 現在の動作モードを変数に記録する
out &h5ec,0 動作モードを互換モードに設定する
・
・
・ プログラム本体
・
・
out &h5ec,MODE 起動時の動作モードに戻す
OUT/INP関数の説明はここでは特にしませんが、このとおり使用すればま
ず問題はないと思います。ただし、out のところをむやみやたらにいじくると、大
変危険ですのでやめましょう。いじくって大切なデータが破壊されても責任はとり
ませんからね。
どうしも知りたい人は、Oh!fmTOWNS95年1月号の166ページからの
記事を読みましょう。持ってない人は、手に入れましょう。手に入らない人は、あ
きらめましょう。(なんと薄情な………………)
▽FOR〜NEXTループ脱出術 & スタック領域について
FOR〜NEXTループが、大変便利なのは言うまでもないことのですが、この
『FOR〜NEXTループ』は一つだけ欠点があります。それは、一度ループに入っ
たら、『FOR』で定義されたことを終えるまでループから脱出出来ないという事
です。絶対に不可能ではないのですが、仮に下ようにした場合
| 1000 for I=0 to 10000
| 1010 if ○=□ then 1030
| 1020 next
| 1030 cls
・
・
・
| 2000 goto 1000
すぐに、「スタック領域が足りません」というエラーが発生します。スタック領
域というのはBASICの場合、FOR〜NEXT、WHILE〜WEND、
GOSUB〜RETURN命令などで主に使われるメモリの特定の領域のことです。
「使う」といっても、どのように使われるのか? マニュアルには詳しい説明はあ
りません。例えば、GOSUB〜RETURN命令では、サブルーチンを呼び出す
ときGOSUB命令を使い、そのサブルーチンからGOSUBで呼び出した場所に
戻るのにRETURN命令を使うのでしたよね。そのRETURN命令で戻るべき
場所をどのように知ればいいのでしょうか? 「呼び出した場所を記憶しておけば
いい。」ふつうならそう考えますよね。もう分かりましたね。その呼び出した場所
を記憶しておくメモリ上の領域こそスタック領域そのものなのです。
原理的には、GOSUB命令でこのGOSUBのある場所をスタック領域に記録
しておき、サブルーチン内でRETURN命令が出てきたらスタック領域に記録さ
れているデータを元に、正しいGOSUBの位置に戻ります。FOR〜NEXTや
WHILE〜WENDの場合は原理がちょっと違います。FORやWHILEに処
理がさしかかるとすぐにそれと呼応するNEXT・WENDをプログラム中から捜
し出します。そして、その二つの位置(もしかすると一つかもしれません)をスタッ
ク領域に記録し、ループ内の処理を実行します。だから、FORとNEXT・WH
−ILEとWENDは必ず一対になっている必要があるわけです。そして、NEXT
やWENDの位置に来るたびにFORやWHILEの定義の内容と照らし合わせて
チェックします。そして、定義を満たしていたら、ループを脱出します。
また、RETURNでサブルーチンから戻ったり、NEXTやWENDでループ
を脱出するとき、それと同時にGOSUBやFORやWHILEでスタック領域に
記録した情報を消去します。そしてFORならNEXT、WHILEならWEND、
GOSUBならRETURNでなければこの情報を取り除くことはできません。こ
れはとても重要な処理で、これを行わないと、どんどんスタック領域に情報がたまっ
ていき、すぐに一杯になってしまいます。
話は戻りますが、上のプログラムの場合、FOR〜NEXTループから、GOTO
命令でループ外に脱出しているため、前述の通りスタック領域に記録された情報が
消去されません。そして再びFOR〜NEXTループに処理が戻ると、またスタッ
ク領域が使用されます。こうして、どんどんスタック領域に情報がたまっていき、
「スタック領域が足りません」というエラーが発生するわけです。スタック領域を
使いきることはあまりないことですから、このエラーが発生した場合はプログラム
に欠陥があると考えた方が無難でしょう。スタック領域をいくら増やしても、プロ
グラムに欠陥がある場合は、いつか必ず「スタック領域が足りません」とエラーが
発生します。
さて、前ブリがとても長かったですが、このスタックを使用するFOR〜NEXT
ループをどのように脱出するか? ただ単にGOTOで脱出することは出来ない、
ということは分かったと思います。では、どうすればいいのでしょうか? 正解は
とても簡単。定義を満たして脱出するように、制御変数に値を代入してあげればい
いのです。
| 1000 for I=0 to 1000
・
・
| 1100 if A=B then I=1000
| 1110 next
| 1120 print A
前ブリの長さの割りに簡単な内容で申し訳ないのですが、制御変数に終値を代入
する。これが、答えです。もし、脱出したい行とNEXT命令の行に間があるのな
らば、
| 1000 for I=0 to 1000
・
| 1100 if A=B then I=1000:goto *NEXT
・
・
| 1200 *NEXT:next
| 1210 print A
とすればいいいわけです。この二つは、しっかりNEXT命令でスタックの内容
を消去しているので、「スタック領域が足りません」のようなエラーが発生するこ
とはないわけです。
▽BEEP音で効果音を作る
F−BASIC386には隠し命令で、BEEP音に音の高さ、長さを指定する
ことができます。
BEEP 363523,<音の長さ>,<音の高さ>
これを利用して、小刻みに音程を変えながら発音することで、BEEP音で効果
音を作ります。
BEEP 363523,3,1200:wait 3
BEEP 363523,3,1150:wait 3
BEEP 363523,3,1300
などとして効果音を作ります。これを参考に音の長さ、音の高さを適当に変更す
ると色々な効果音を作ることが出来ます。BEEPを9回ぐらい連続で実行しても
いいです。
昔、今のように音源など積んでいることが常識ではないころは、みんなこうやっ
てBEEP音を使い効果音を作っていました。中には、BASICで音の長さを変
えられないので、FOR-NEXTとBEEP 0/1を使用して小刻みにBEEP音の発音、非発
音を切り換えて効果音を作ったりしていました。
(パソコンと本格的にやり出して2・3年なのに、なぜこんなことを知ってる。)
♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪♪
●あとがき
フリコレのBASICプログラムを見ていて気づいたことや、プログラムを組ん
でて発見したこと、自分の知っているプログラミングテクニックを書いてみました。
これらの多くは、BASICに限らずプログラミングするときに役に立つかとと思
います。途中、雑談に近い内容の体験談もありましたが、どうでしたでしょうか。
また、これを参考にしてプログラムを作成、そしてそのプログラムを発表した場
合は、ぜひドキュメント参考文献の欄にこれを書いておいて下さい。もちろん強制
はしませんが、それを発見したときぼくにとって、喜びそして励みになります。
この文章の著作権は筆者にあります。営利目的に使用しなければ、転載・配付な
どは自由です。ただし、ここに書いてあることについて一切の責任を筆者は負わな
いこととします。
この中にもしかするとうそが書いてあるかもしれませんあ・し・か・ら・ず。
うそがあったとしても、前にあるとおり責任はとりませんので、謝って訂正する程
度しかできません。
ここに書いてあることに対する、反論、異議、文句等を持った方がおられるかと
思います。そのような方は、遠慮なくこちらへ、
〒370−12 群馬県高崎市根小屋町554−3 渡辺 良一
うその指摘は感謝し致します。それ以外の感想等でも、お気軽にどうぞ。
『反論の手紙』と『手紙なし』。どっちがイヤと言えばもちろん『手紙なし』。
◎参考文献
F−BASIC386V2.1リファレンス
改訂第3版 FMTOWNSテクニカルデータブック 千葉憲昭 氏著