Microsoft BASICからのFull BASIC入門


初級編


BASICの生い立ち

ケメニーとカーツ

 BASICは,1964年ころにダートマス大学のJ.G.ケメニーとT.E.カーツによって開発された教育用プログラミング言語です。
当時,主流だったFORTRANを手本として,FORTRANの使いにくいところを初学者向きに改めて作成された言語です。
 ケメニーとカーツのBASICは,現在,True BASICと呼ばれ,Windows,Mac,UNIXなどに対応したバージョンがあります。

マイコン用BASIC

 NECのN88-BASICや富士通のF-BASIC,マイクロソフト社のVisual BASICなど多くの人がBASICだと思って使っている言語は,見かけはよく似ていますが,根幹となる部分で本来のBASICと相違する点があります。
 これらの言語は,マイコン用に改変された文法を継承しています。初期のマイクロコンピュータはメモリを十分に使うことができず,限られた容量のROMのなかにBASIC処理系を詰め込むことにエネルギーが注がれました。そのために採用された手法の1つがインタプリタですが,小さく作るために採用された手法はそれだけではありません。 それによって多くの人が低廉にBASICの使えるコンピュータを入手できるようになったのですが,初学者向き言語として生まれたBASICの本質は損なわれてしまいました。

BASIC言語の標準化

BASICの標準化のための作業は1974年に始まり,4年後の1978年に米国および欧州でMinimal BASIC(最小BASIC)として規格化されました。1982年には国際標準化機構(ISO)原案が作成され,1984年にはMinimal BASICの国際規格が制定されました。日本では,ISO規格案に基づいて,1982年に「基本BASIC」という名称でMinimal BASICが規格化されました。
 Minimal BASICの規格化に引き続いて,BASICの完全バージョン(Full BASIC)の規格化作業が開始されたのですが,その作業はかなり難航したようです。1982年に原案が作成され,1986年に欧州,1987年に米国で規格として成立しました。国際標準化機構(ISO)は,1991年に欧州規格と米国規格を包含する形でFull BASICのISO規格を制定しました。日本では,ISO準拠の形で1993年にFull BASICのJISが制定されました。
 1989年,米国でモジュールおよび単文字入力に関する追加の規定が規格化されました。これは,JISでは参考として収録されています。


Microsoft BASICとの違い

問題解決指向

  マイコン用のBASICはシステム開発用の言語として広く用いられてきました。Visual BASICでは,フォームを作成し,フォーム上に実行を開始するためのボタンと結果を表示するためのウインドウを作成するところから始めないと何もできません。Visual BASICは,プログラムを書く人自身の問題を解決するためではなく,他者が使うためのプログラムを書くための言語です。
 しかし,本来のBASICは,問題解決指向です。プログラムは,プログラムを作成する人自身の問題を解決するために書かれます。
 Full BASICはコンピュータの専門家でない人が自分自身で問題を解決するために使うことを目的に設計されています。コンピュータの世界の常識を知らない人にも確実に使えるような工夫があります。

あいまいさを許さない文法

 Full BASICの特徴を端的にいえば,文法の厳格さです。意味があいまいになる可能性のあるところを文法的に禁止して,プログラムを書いた人の意図が機械に誤って伝わってしまうことがないようにしています。
 N88-BASICのようなインタプリタ型のBASICでは,文法上の誤りは実行時に検出されます。しかし,Full BASICでは文法上の誤りはプログラムの実行開始前に検出されることになっています。つまり,Full BASICでは,文法の誤りを見つけるのは人間の仕事ではなく,機械の仕事です。

予約語は18語のみ

 (部分集合規格でない)Full BASICの予約語は次の18語です。

NOT,ELSE,PRINT,REM,PI,RND,MAXNUM,TIME,DATE,EXTYPE,EXLINE,ZER,CON,IDN,TRANSFORM, DATE$, TIME$, NUL$

 マイクロソフト系BASICでは,苦労して作成したプログラムが変数名が予約語とぶつかってしまって動かないことがよくありましたが,Full BASICでは予約語は全部で18個しかないので予約語を避けてプログラムを書くのに苦労することはありません。予約語を独自に拡張することは許されていないので,他社のBASICに移植しようとしたり,同じ会社のBASICであってもバージョンアップすると変数名が予約語とぶつかってしまって動かないなどいう問題は起こりません。
 なお,Full BASICには,部分集合中核と呼ばれる規格があって,その場合は,予約語の数が増えます。ただし,その場合でも,処理系が独自に予約語を増やすことは許されていません。

省略語が少ない

 Microsoft BASICの機能語には,CDBL,CINT,PSET,CLSなど,複数の語をまとめて簡略化した略語がたくさん出てきます。また,LINE文やCIRCLE文のようにパラメータをいくつも並べて多機能化した文があります。
 標準BASICでも,初期に確立した文法では,SIN, COS, TAN, LOG, EXP, ATN,RND, MODなど数値組込関数名を中心に3文字略語が多く用いられますが,比較的新しい時代に追加された文法では,
OPTION ARITHMETIC DECIMAL
OPTION ANGLE DEGREES
SET POINT COLOR
SET LINE STYLE
のように長い綴りであっても略語にせずに記述するのが普通になっています。また,1命令でまとめてたくさんのパラメータを指定してしまうような文法はありません。そのため,プログラムの文字数が多くなり,タイプ入力の手間は増大しますが,初心者でも意味を想起しやすいものになっています。


数値

十進演算

 Full BASICでは,数値は浮動小数点10進数です。単精度,倍精度の区別や,整数型というのはありません。
 10進小数を2進小数で近似するために発生する誤差がありませんから,0.1を10回加算すれば正確に1になります。たとえば,次のプログラムでは,11回繰り返しを実行し,最後の結果は正確に0になります。

10 FOR x=-1 TO 0 STEP 0.1
20   PRINT x
30 NEXT x
40 END

演算結果の正確さ

Full BASICには数値演算の実行結果の正確さに関する規定があります。この規定は四則演算ばかりでなく,べき乗演算やSQR関数などの組込み関数にも適用されます。その規定のおかげで,べき乗演算やSQR関数の予期せぬ誤差を心配する必要がなくなります。
次のプログラムは100以下のピタゴラス数をすべて求めるものですが,Full BASICでは正しいプログラムです。しかし,規格外のBASICでは正しい結果が得られることを保証することができません。実際,昔のN88-BASICでは正しくない結果が得られます。

10 FOR x=1 TO 100
20    FOR y=x TO 100
30       LET z=SQR(x^2+y^2)
40       IF INT(z)=z THEN PRINT x,y,z
50    NEXT y
60 NEXT x
70 END

数値式の文法

 加減乗除の四則演算とべき乗演算は2項演算ですが,例外があります。「-2*a+3」のように数値式の先頭に負号を書くとき,この負号は2項演算ではありません。Full BASICでは,数値式の先頭にある正号,負号も,2項演算の正号,負号と同等に扱う約束になっています。しかし,コンパイラやインタプリタを作る立場からすると,こういう例外はやっかいです。
 基本BASIC, Full BASIC以外の多くの言語では,符号を反転する負号を優先順位の高い単項演算として扱う文法を採用して,このやっかいさを解消しています。マイクロソフトのBASICもそういう文法を採用しています。

 基本BASICやFull BASICの文法で書かれた数値式はマイクロソフトの文法でも正しく処理できます。しかし,逆は成立しません。この事実だけで判断するとマイクロソフトのやり方のほうが優れているように思うかも知れませんが,実際はそうではありません。
 インタプリタとかコンパイラを自分で作ってみようと考える人以外は,数値式の文法まで深く考えることはないのが普通だと思います。文法の許容範囲が広いということは,機械と人間との間で意味の解釈に食い違いが生じる可能性が大きくなるということです。

 BASICでは,同順位の演算を続けて書いたときには左から順に実行されることになっています。たとえば,2^3^4は(2^3)^4を意味しますから,4096になります。これは,マイクロソフトのBASICでも同じです。
 マイクロソフトのBASICでは,単項演算の符号反転は,べき乗演算子の右側ではべき乗演算よりも優先する約束になっています。ですから,2^(-3)のことを2^-3と書くことができます。しかし,2^-3^2と2^(-3)^2とは同じ意味にはなりません。マイクロソフトBASICでは,2^-3^2は2^(-3^2)を意味するものと解釈されます。

真偽値

 Full BASICでは,大小比較やAND, OR, NOTの論理演算は数値演算とは別のカテゴリーに属するものとして扱われます。しかし,マイクロソフトのBASICでは,論理演算は数値演算の一部です。大小比較は,真のとき-1,偽のとき0の2項演算です。大小比較の優先順位は加減算より低く設定されていますから,たとえば,1+2<4は(1+2)<4の意味になって,基本BASICやFull BASICの文法で書かれた大小比較はマイクロソフトのBASICでも正しく処理できます。

 マイクロソフトのBASICでは,大小比較や論理演算は数値演算の一部ですから,数値式の中に混ぜて書くことができます。たとえば,
10 PRINT 2+(1<3)
を実行すると,答えは1になります。同様に
10 PRINT 2<1<3
も実行可能で,答えは-1になります。マイクロソフトの解釈では 2<1<3 = (2<1)<3 = 0<3 = -1 となるわけです。
しかし,2<1<3は偽なのだから0になるはずだという人もいるでしょう。そういう人がマイクロソフトのBASICを使うのは危険です。

 マイクロソフトの文法では,IF文など,Full BASICの文法では論理式を書くことになっているところには数値式を書くことになっています。そして,その数値が0でないとき条件が真であると判断されます。ですから,マイクロソフトBASICで
10 IF 2<1<3 THEN PRINT "Y" ELSE PRINT "N"
を実行すると結果は「Y」になります。一方,Full BASICでは,この文は文法誤りとなって実行できません。

数値型指定

Microsoft BASICは数値定数や数値変数の末尾に!や%,#などの記号を付加して数値の型の別を指定しますが,Full BASICには数値の型の別がありません。
Full BASICは!を行末注釈を書くために用います。!より右は注釈です。そのため,次のようなプログラムはFull BASICでは異なる意味に解釈されます。たとえば,

10 PRINT 10!+15!

はFull BASICではPRINT 10の意味になります。

MOD演算子とMOD関数

 Full BASICにはMicrosoft BASICにあるMOD演算子がありません。代わりにMOD関数が用意されています。また,Full BASICには整数型というものがないので整数除算を意味する¥演算子がありません。
 Full BASICのMOD関数は,
MOD(x,y)=x-y*INT(x/y)
で定義されています。定義域は実数全体です。たとえば,MOD(9, 2.5)は1.5です。

 Microsoft BASICのMOD演算とFull BASICのMOD関数には注意すべき違いがあります。Full BASICのMOD関数は整数論における剰余の定義と同じで,被除数の符号に関係なく結果は除数と同符号になります。一方,Micorsoft BASICのMOD演算では,結果の符号が被除数の符号と同じになります。通常の応用では除数が定数になる場合が多いので,整数論での定義と一致するMOD関数のほうが便利なことが多いのですが,Microsoft BASICのMOD演算を前提に書かれたプログラムをそのままMOD関数に書き直した場合には正しく動作しないことになります。

 なお,Full BASICでMicrosoft BASICのMOD演算と同様の結果が欲しい場合にはREMAINDER関数を用います。REMAINDER関数は,
REMAINDER(x,y)=x-y*IP(x/y)
で定義されています。ここで,IP関数は,IP(x)=SGN(x)*INT(ABS(x)) で定義される関数です。IP(x/y)は,Microsoft BASICの x\y に相当します。


制御文

代入文

 BASICでは代入文は,
LET 変数 = 数値式
の形に書かれます。マイクロソフトBASICではLETは省略できます。書かずに済むものなら書かないほうが楽でいいと思うかも知れませんが,等号を計算実行の意味に用いる言語は初学者向きではありません。(十進BASICはLETを省くと翻訳時にLETを自動的に補うので,LETを打つのが面倒なら入力しなくてもかまいません)

IF文のネスト

 Aの値が0であるときに

100 IF A<>0 THEN IF A=1 THEN GOTO 200 ELSE GOTO 300

を実行したらどうなるでしょうか。

マイクロソフトの文法では,
IF A<>0 THEN [ IF A=1 THEN GOTO 200 ELSE GOTO 300 ]
のように解釈されるのでA=0のときは何も起こりません。しかし,

 IF A<>0 THEN GOTO 200 ELSE GOTO 300

GOTO 200の部分をIF A=1 THEN GOTO 200に置き換えてもまったく同じ文ができるので,
IF A<>0 THEN [ IF A=1 THEN GOTO 200 ]ELSE GOTO 300
というつもりでこの文を書く人がいるかも知れません。

Full BASICでは,IF文のなかにIF文を書くことを禁止して上述のような問題が起こらないようにしています。

Full BASICでは,次のように書くしかありませんが,この書き方では意図は明確に表現されます。

IF A<>0 THEN
   IF A=1 THEN 200 ELSE 300
END IF

あるいは

IF A<>0 THEN
  IF A=1 THEN 200
ELSE
  GOTO 300
END IF

マルチステートメント

Full BASICにはないマイクロソフトBASICに特有の文法としてマルチステートメントがあります。初心者を相手にするとき,2つの文をコロンでつなげて書いてよいと教えられることが多いのですが,実際にはそうできない場合があります。
10 IF A=1 THEN GOTO 100
20 IF A=2 THEN GOTO 200
の2つの文を結合して
10 IF A=1 THEN GOTO 100 : IF A=2 THEN GOTO 200
としたら意味が変わってしまいます。
 N88-BASICなどの構造化される前のBASICではIF文に複数の文を書くためにマルチステートメントを使う必要がありましたが,現在の構造化されたBASICではマルチステートメントは無用です。

DIM文とDEF文

 Full BASICには,N88-BASICなどのインタプリタ型の言語と異なり,翻訳時に処理され,実行時には制御することのできない種類の文が存在します。
N88-BASICなどのインタプリタ型のBASICではDIM文やDEF文は実行時に処理されますが,Full BASICではDIM文やDEF文は翻訳時に処理されます。ですから,プログラムの実行途中で配列や定義関数を変更するようなことはできません。
 なお,Full BASICではDEF文で定義する関数の名前をFNで始める必要はありません。f(x)のような自然な表現が可能です。

エラー処理

 古いタイプのマイクロソフトBASICでは実行時のエラー処理をON ERROR GOTO文を用いて行いますが,Full BASICには構造化例外処理の構文が用意されています。エラー処理のネスティングができますし,副プログラムや関数などの手続き実行中に発生した例外を呼び出し元に伝達する(処理を任す)こともできます。
Full BASICでは,実行時に発生するエラーを例外(exception)と呼びます。Full BASICでは例外処理にWHEN EXCEPTION IN 〜 USE 〜 END WHENという構造を用います。WHEN行とUSE行の間で例外が発生すると,USE行の次の行に分岐します。
 次のプログラムに例外処理を追加してみます。

10 DEF f(x)=1/x
20 FOR x=-10 TO 10 
30    PRINT x,f(x)
40 NEXT x
50 END


Full BASICには,手続きにおける例外の伝達という特徴があります。手続き実行中に起きた例外は,その手続き中で処理されなければ,呼び出し元に伝達されます。たとえば,次のプログラムで実際に例外が発生するのは100行ですが,呼び出し元である130行に伝達されて,あたかも130行で例外が起きたかのように動作します。

100 DEF f(x)=1/x
110 FOR x=-10 TO 10 
120    WHEN EXCEPTION IN 
130       PRINT x,f(x)
140    USE
150       PRINT x,"error"
160    END WHEN
170 NEXT x
180 END


次のようにすることもできます。

100 DEF f(x)=1/x
110 WHEN EXCEPTION IN 
120    FOR x=-10 TO 10 
130       PRINT x,f(x)
140    NEXT x
150 USE
160    PRINT x,"error"
170    CONTINUE
180 END WHEN
190 END

CONTINUEは,例外発生行の次の行から実行を再開することを指示する命令で,Microsoft BASICのRESUME NEXTに相当します。なお,Microsoft BASICのRESUME 0 に相当するFull BASICの命令はRETRYです。

[Memo] Visual BASICの新バージョンであるVB.NETでは,構造化例外処理が実現されています。VB.NETの Try 〜 Catch 〜 End Tryは,Full BASICのWHEN EXCEPTION IN 〜 USE 〜 END WHEN に相当します。ただし,VB.NETには,Full BASICのCONTINUEやRETRYに相当する命令はないようです。

END文とSTOP文

 Microsoft BASICとFull BASICとではEND文の意味が異なります。Microsoft BASICではEND文はプログラムの実行を終了するという意味がありますが,Full BASICのEND文は主プログラムの終わりを示すために用いられます。Microsoft BASICでは任意の場所にいくらでもEND文が書けますし,END文をまったく書かないこともできますが,Full BASICではEND文は必ず1つだけ書かれます。
 Microsoft BASICのEND文に相当するFull BASICの文はSTOPです。
(補足 Microsoft BASICのSTOPに相当するFull BASICの命令は,DEBUG ON と BREAK です。)

DATA文

MicrosoftのBASICではDATA文はプログラム全体に広域的ですが,Full BASICではDATA文の有効範囲はプログラム単位になっています。ですから,主プログラムしかないようなプログラムではDATA文はEND行より手前に書かなければなりません。

ラベル

 Full BASICにはGOTO文の分岐先を表すラベルの構文が用意されていません。Full BASICはエラー処理まで含めて構造化されているのでGOTO文が必要になることは滅多にありません。しかし,どうしてもGOTO文を使いたい場合は行番号を使います。Full BASICがラベルの文法を用意していないのは,GOTO文の乱用を抑制する意図があるものと解すべきです。

GOSUB〜RETURN

 構造化プログラミング言語であるFull BASICでGOSUB〜RETURNのサブルーチンは用いるべきではありませんが,互換性のために規格上は残されています。GOSUB文を用いる場合の注意はGOSUB文でEND行を超えて分岐することは許されていないことです。したがって,サブルーチン自体をEND行より手前に書かなければなりません。サブルーチンの手前に書く命令はSTOPです。


入出力

配列

 基本BASICでは配列添字の下限は0でしたが,Full BASICでは配列添字の下限は1に変更されています。OPTION BASE文は有効ですから,OPTION BASE 0 を書けば従来通り添字の下限を0にすることができます。
基本BASICでは配列を宣言せずに用いることができましたが,Full BASICでは配列を宣言せずに用いることはできません。これは,Full BASICで利用者定義関数の機能が追加されたため,宣言がないと関数なのか配列なのか判断できないためです。
 Microsoft BASICでは同じ名前の単純変数と配列を同時に用いることができますが,Full BASICでは1つの名前を単純変数と配列の双方に用いることはできません。
 Full BASICではDIM文を用いて単純変数を配列に変えたり,配列の次元を変えることはできません。配列の次元を文法的な属性として扱い,翻訳時にプログラムを検査します。したがって,実行時に配列次元の誤りのエラーが起こることはありえません。

入出力

 Full BASICは入出力を簡潔に記述できる言語です。配列入出力と行列演算のためのMAT文が用意されています。MATはmatrix(行列)の最初の3文字です。
 MAT READ文を用いるとDATA文から配列の大きさ分のデータを読み込みます。

10 DIM A(4)
20 MAT READ A
30 DATA 12,43,45,21


 2次元または3次元の配列の場合には,後方の添字が先に変化する順に読み込みます。たとえば,
DIM A(2,3)
で宣言された配列Aがあるとき
MAT READ A
を実行すると,A(1,1), A(1,2), A(1,3), A(2,1), A(2,2), A(2,3) の順に読みます。
 ですから,配列Aを2行3列の行列として扱いたいときは,次のようなプログラムで初期値の設定ができます。

10 DIM A(2,3)
20 MAT READ A
30 DATA 1,2,3
40 DATA 3,4,5


MAT INPUT文を用いるとキーボードからの入力を簡潔に記述することができます。MAT INPUT文の実行時には配列の各要素をコンマで区切って打ち込みます。
MAT PRINT文を利用すると,配列の全要素を出力できます。MAT PRINT USING文で書式を指定して出力することもできます。

配列の大きさの動的変更

 Full BASICではDIMで宣言する添字の上限は定数で記述します。したがって,N88-BASICなどのようにDIM文で配列の大きさを変えることはできません。それに代わる機能として,配列の添字の上限を実行時に動的に変更する機能が用意されています。ただし,変更後の配列の大きさがDIM文で宣言した大きさを超えるような変更はできません。
次のコードを実行するとAの添字の上限は2および3に変更されます。

10 DIM A(10,10)
20 MAT READ A(2,3)
30 DATA 1,2,3
40 DATA 3,4,5


MAT INPUT文でも同様のことができます。さらに,Aが1次元配列である場合には,
MAT INPUT A(?)
と書くことで,Aの大きさをキーボードから入力するデータの個数に合わせることができます。
 配列の大きさを動的に変更したとき,現在の添字の上限をUBOUND関数を用いて知ることができます。

READ IF MISSING

 READ文にIF MISSING THEN EXIT DO を書くことによってDATA文のデータが尽きてしまったときにDO〜LOOPの繰り返しを抜けることができます。この機能を利用すると,DATAの個数をプログラム中で管理するする必要がなくなります。次の2つのプログラムを比較してみてください。FOR〜NEXTを用いるプログラムでは,プログラムを書く人がデータの個数を知らなくてはならないので変更が面倒です。データの個数が多かったらどうなるか考えてみてください。(データの個数はコンピュータに数えさせたいと思いませんか?)

10 DATA 12,43,54,65
20 FOR i=1 TO 4     
30    READ a
40    PRINT a,SQR(a)
50 NEXT i
60 END
10 DATA 12,43,54,65
20 DO
30    READ IF MISSING THEN EXIT DO: a
40    PRINT a,SQR(a)
50 LOOP
60 END

グラフィックス

描画領域

 N88-BASICでは描画領域の大きさは縦400ドット,横640ドットと決まっていますが,Full BASICでは描画領域の大きさは定められていません。描画領域の画素数が異なっても同じ結果が得られることを目的とした命令体系になっています。
 なお,Full BASICでは,特に指定しない限り描画領域の初期値は正方形になります。

座標

 マイクロソフト系BASICでは画面左上端を原点とする画素を単位とする座標系が基本になっていますが,Full BASICでは画素を単位とするのではなく,描こうとする対象に即してプログラム中で定義した座標系で描画するのが原則です。
 プログラムのなかで仮想的に定義された座標系のことを問題座標といいます。問題座標はN88-BASICのワールド座標によく似た概念ですが,N88-BASICのワールド座標はy座標の正の向きが下向きにしか定義できないのに対し,Full BASICの問題座標はy座標は上向きが標準です。(ただし,下向きに定義することも可能です)
 Full BASICで問題座標を設定する命令は SET WINDOW です。パラメータは,左端x座標,右端x座標,下端y座標,上端y座標の順にコンマで区切って書きます。N88-BASICのWINDOW文とはパラメータを並べる順序が異なります。SET WINDOW文では,まず,x座標の範囲を書いて,次にy座標の範囲を書くことになります。

SET WINDOW -8,8,-12,12
x座標の範囲を-8〜8,y座標の範囲を-12〜12とする。

点を描く

 マイクロソフト系BASICでは点を描く命令はPSETですが,Full BASICではPLOT POINTSを用います。
例 2次関数y=x2のグラフを描く

10 SET WINDOW -4,4,-1,7
20 FOR x=-4 TO 4 STEP 0.1
30    PLOT POINTS:x,x^2
40 NEXT x
50 END

点の形を変える

 上のプログラムでは,描かれる点の形は*です。
15 SET POINT STYLE 1
を追加すると点の形を・に変えることができます。
POINT STYLEは,1が・,2が+,3が*,4が○,5が×です。プログラム実行開始時のPOINT STYLEは3です。

折れ線を描く

 Full BASICで折れ線を描く命令はPLOT LINESです。PLOT LINES: に続けて座標をセミコロンで区切って書くとそれらを順に結ぶ折れ線を描きます。座標は,x座標とy座標をコンマで区切って書きます。 たとえば,PLOT LINES: 1,2 ; 3,4 ; 5,6 を実行すると,点(1,2),(3,4),(5,6)を結ぶ折れ線を描きます。

折れ線でグラフを描く

 PLOT POINTS文の最後をセミコロンで止めておくと,次にPLOT LINES文を実行したとき,はじめのPLOT LINES文で最後に指定した点と次のPLOT LINES文で最初に指定した点との間が線分で結ばれます。
例 2次関数y=x2のグラフを描く

10 SET WINDOW -4,4,-1,7
20 FOR x=-4 TO 4 STEP 0.1
30    PLOT LINES: x,x^2;
40 NEXT x
50 END

 Microsoft BASICのLINE命令では, LINE -(x,x^2) のように書くと直前に指定した点との間を結ぶことができますが,最初にこの文を実行したときに画面上のどこかの点との間が線分で結ばれ,意図しない余分な線が描かれてしまいます。PLOT LINESでは,最初に指定される点が折れ線の始点になります。

折れ線の接続を断つ


 PLOT LINESを利用して複数の曲線を描くときには折れ線の接続を途中で断たなければなりません。末尾にセミコロンを書かないPLOT LINESを実行すればそうなるのですが,そのとき,座標指定も省略して書くことができます。ちょうど,改行するときに書く空PRINTと同じ要領です。なお,この場合,LINESの次に書くコロンも省きます。
例 n次関数y=xn (n=1,2,3,4,5)のグラフを描く

10 SET WINDOW -4,4,-4,4
20 FOR n=1 TO 5
30    FOR x=-4 TO 4 STEP 0.01
40       PLOT LINES: x,x^n;
50    NEXT x
60    PLOT LINES
70 NEXT n
80 END

関数のグラフなどの曲線を描く

 Full BASICを用いて曲線を描くとき,XYプロッタという装置を頭の中に想起してください。XYプロッタでは,ペンを下ろした状態でペンを動かせば線が描かれます。ペンを上げてペンを動かしても線は描かれません。
 Full BASICではPLOT LINES文でペンの移動とペンの上げ下げに相当する処理が行えます。座標を指定すると,ペンが指定された位置に移動します。座標を区切るセミコロンはペンを下げる働きをします。末尾がセミコロンで終わっていると,ペンは下がったままです。一方,末尾にセミコロンがないと指定座標まで移動してペンを上げます。特に,座標を指定しないPLOT LINES文がペンを上げる目的に使われます。


中級編




制御

ANDとOR

 Microsoft BASICでは,AND, ORは整数型の数値に対して定義された数値演算ですが,Full BASICのAND, ORは制御構造の一部です。 Full BASICでは,論理式 p AND qp が偽であることがわかるとq を評価しません。同様に,論理式 p OR q ではp が真であることがわかるとq を評価しません。ですから,たとえば,配列Aの添字の上限が10であるとき,i<=10 AND A(i)=0 をiの値が11のときに評価しても実行時エラーにはなりません。しかし,Microsoft BASICでは i<=10 の真偽に関係なく A(i)=0 の値を計算しますから,添字が範囲外のエラーになります。

WHILE〜WEND

 Full BASICにはWHILE〜WENDの構文はありません。Full BASICでは,DO WHILE〜LOOPを用います。

SELECT〜END SELECT

Full BASICのSELECT〜END SELECT構文は,文法的にはQuick BASICやVisual BASICのそれとほとんど同じですが,動作が少し異なります。CASE ELSEを省いたとき,実行時に一致するCASE項目がないと,MicrosoftのBASICでは何もせずに次に進みますが,Full BASICでは例外状態になります。

プログラム分割(手続き定義)

手続きの種類

 手続き定義には,関数定義,副プログラム,絵定義,Handlerの4種類があります。副プログラムは,Quick BASIC, Visual BASICのsubプロシージャのことです。絵定義とHandlerはMicrosoft BASICに対応するものがありません。

内部手続きと外部手続き

 関数定義,副プログラム,絵定義には,内部手続きと外部手続きの2種類があります。内部手続きは,主プログラムおよび外部手続きの内部に書かれる手続きで,引数以外は主プログラムまたは外部手続きで広域的です。外部手続きは,主プログラムおよび他の外部手続きと独立した存在で,変数のほか,DATA文のデータ並び,ゼロ番以外の経路番号(Microsoft BASICのファイル番号)も独立です。
 Full BASICでは,主プログラムと外部手続きをプログラム単位と呼びます。

引数の値渡しと参照渡し

 Quick BASICやVisual BASICでは関数プロシージャやSUBプロシージャの引数に変数を書くと参照渡しになりますが,Full BASICでは,関数定義では値渡し,副プログラムと絵定義では参照渡しです。なお,Visual BASICでは ByVal あるいは byRef を書いて引数の渡し方を変更することができますが,Full BASICにはそれに対応する構文はありません。

配列引数

 Full BASICで配列を引数としたいとき,仮引数には括弧とコンマで次元を示します。
A()  1次元
A(,) 2次元
A(,,) 3次元
 実引数に配列を書くときは,配列名のみを書きます。
 関数の引数に配列を書くと値渡しになります。副プログラムと絵定義では参照渡しです。関数の引数に配列を用いるときは,関数呼び出しごとに配列を複製するための余分な時間がかかることに注意してください。

例1 関数定義に配列引数を用いる

100 DATA 23,43,54,61,62,82,90,33,43,15
110 DECLARE EXTERNAL FUNCTION ave
120 DIM a(10)
130 MAT READ a
140 PRINT ave(a)
150 END
160 EXTERNAL FUNCTION ave(a())
170 LET t=0
180 LET n=UBOUND(a)
190 FOR i=1 TO n
200    LET t=t+a(i)
210 NEXT i
220 LET ave=t/n
230 END FUNCTION



例2 副プログラムに配列を渡す

100 DATA 23,43,54,61,62,82,90,33,43,15
110 DECLARE EXTERNAL SUB mean
120 DIM a(10)
130 MAT READ a
140 CALL mean(a,m)
150 PRINT m
160 END
170 EXTERNAL SUB mean (a(),m)
180 LET t=0
190 LET n=UBOUND(a)
200 FOR i=1 TO n
210    LET t=t+a(i)
220 NEXT i
230 LET m=t/n
240 END SUB

経路引数

 Full BASICではゼロ番以外の経路番号はプログラム単位ごとに独立していますが,経路番号を外部副プログラムの引数とすることができます。仮引数は #1,#2 などのように#と整数を書きます。実引数は#と数値式で指定します。

モジュール

 Full BASICには,複数の外部手続きからなるモジュールを定義することができます。モジュールには,モジュール外からの共用が可能な静的変数を置くことができます。また,モジュール内でのみ共用される静的変数を定義することもできます。モジュールでは,モジュール内で共用される対象として経路番号を宣言することもできます。モジュールには,静的変数を初期化するための初期化コードを含めることができます。

文字列

文字列変数と文字列定数

 文字列の扱い方はMicrosoft BASICとかなり異なりますが,文字列変数名は末尾に$を付加して表すことや,文字列定数は前後を2重引用符でくくって表すことはどちらも同じです。ただし,Visual BASICのように文字列でも数値でも代入できるバリアント型の変数というのはありません。数値データと文字列データは,文法上,明確に区別されています。

文字列連結

 Full BASICでは文字列連結演算子は&です。Microsoft BASICでは"2"+"3"で"23"になりますが,Full BASICでは同じことを"2"&"3"と書きます。Visual BASICでは,文字列連結に&を使うこともできますが,VBでは"2"+3が5になるため文字列としての演算を行わせるために別の演算子が必要になったからです。Full BASICの場合には文法上の問題はありませんが,"2"+"3"が"23"になるのは初心者を惑わす原因になるのでそういう書き方を許しません。

部分文字列の取り出し

 Microsoft BASICでは文字列処理の基本はMID$関数ですが,Full BASICでは文字列変数の部分文字列指定が基本です。文字列変数s$に対してs$(m:n)でs$のm文字目からn文字目までの文字列を表します。
 MID$関数では文字列式を操作対象にすることができますが,Full BASICの部分文字列指定は文字列変数が対象です。そのため,文字列式の計算結果から部分文字列を取り出したいときには,一旦,文字列式の値を文字列変数に代入しておかなければなりません。これがわずらわしいときは,次のようなDEF文を追加すればMicrosoft BASICと同様にMID$関数が使えます。
DEF MID$(s$,m,n)=s$(m:m+n-1)
 なお,(仮称)十進BASICの最新版は,MID$関数を組込関数として用意しています。

部分文字列の置換

 Microsoft BASICではMID$関数を代入文の左辺に書いて文字列の置換ができますが,Full BASICでは部分文字列指定を代入文の左辺に書きます。たとえば,
MID$(s$,4,2)="xy"
に相当するFull BASICの文は
LET s$(4:5)="xy"
です。

 Microsoft BASICのMID$への代入では指定された位置以外の文字は動きませんが,Full BASICの部分文字列指定のある文字列変数への代入では,代入する文字列の長さが指定部分の長さと食い違っている場合,全体の長さが変化します。たとえば,s$="12345"のとき,
MID$(s$,2,2)="a"
を実行するとs$="1a345"になりますが,
LET s$(2:3)="a"
の実行結果はs$="1a45"になります。また,
MID$(s$,2,2)="abcd"
を実行するとs$="1ab45"になりますが,
LET s$(2:3)="abcd"
の実行結果はs$="1abcd45"になります。

 Full BASICでは,この性質を利用して,文字列の一部を削除してつめたり,途中に文字列を挿入したりすることができます。
たとえば,s$="12345"のとき,
LET s$(2:4)=""
を実行するとs$="15"になります。

 部分文字列指定s$(m:n)では,nがmより小さいときはmの直前の空文字列を表す約束になっています。ですから,
LET s$(n:n-1)=t$
を実行すると,n文字目の直前にt$が挿入されます。
たとえば,s$="12345"のとき,
LET s$(3:2)="ab"
を実行するとs$="12ab345"になります。
 つまり,m-1≦nの場合,
LET s$(m:n)=t$

s$ = LEFT$(s$,m-1) + t$ + RIGHT$(s$, LEN(s$)-n)
と同じ意味です。

ファイル

ファイルの種類

 Full BASIC規格は,扱うことのできるファイルの種類によって,中核,内部形式拡充ファイル,固有形式拡充ファイルの3つのレベルがあります。(仮称)十進BASICの現在のバージョンがサポートするファイルは中核です。
N88-BASICなどの古いタイプのマイクロソフト系BASICでは1レコードが256バイトのランダムファイルが使えますが,Full BASICではランダムアクセスが可能なファイル形式(相対編成)は拡充ファイルとして定義されています。また,古いタイプのマイクロソフト系BASICではランダムファイルの入出力にFIELD文を用いることができますが,同様の手法による入出力は固有形式拡充ファイルで定義されています。
 (仮称)十進BASICでN88-BASICのランダム・ファイルを操作したい方は こちら をご覧ください。

中核ファイルの概要

 中核で使えるファイルには,表示形式ファイル,順編成内部形式ファイル,流れ編成内部形式ファイルの3種類があります。表示形式ファイルは,通常のテキストファイルです,順編成内部形式ファイルはWRITE文とREAD文を使って読み書きするシーケンシャル・ファイルのことです。流れ編成ファイルというのは,1行に1個のデータが記録されるファイルです。

アクセス・モード

Microsoft BASIC Full BASIC
OPEN "ABC.TXT" FOR INPUT AS #1 OPEN #1: NAME "ABC.TXT" ,ACCESS INPUT
OPEN "ABC.TXT" FOR OUTPUT AS #1OPEN #1: NAME "ABC.TXT"
ERASE #1
OPEN "ABC.TXT" FOR APPEND AS #1OPEN #1: NAME "ABC.TXT" ,ACCESS OUTPUT


 マイクロソフト系BASICには,INPUT,OUTPUT,APPENDの3つのアクセスモードがありますが,Full BASICのアクセス・モードはOUTIN,INPUT,OUTPUTの3つです。Full BASICのINPUTモードとマイクロソフト系BASICのINPUTモードはほぼ同じものです。Full BASICのOUTPUTモードはマイクロソフト系BASICのAPPENDモードに対応します。マイクロソフトBASICのOUTPUTモードに対応する処理を行うときは,アクセスモードOUTINでファイルを開いた後,ERASE文を実行してファイル内容を消去してから書き出しを始めます。
 Full BASICではアクセス・モードの既定値はOUTINです(省略できる)。OUTINで開いたファイルは入力にも使えます。また,ファイル・ポインタを末尾に移動して追記書き出しを行うこともできます。

順次アクセス(読み込み)

 Microsoft BASICではWHILE NOT EOF(n) 〜 WENDのループでファイルにアクセスするのが定石ですが,Full BASICにEOF関数はありません(Microsoft BASICのEOF関数は結果が数値の関数だという点に注意)。Full BASICでは,DATA文からの読み込みと同じ手法を用いてファイルを読みます。

10 OPEN #1: NAME "readme.txt"
20 DO
30    LINE INPUT #1, IF MISSING THEN EXIT DO: s$
40    PRINT s$
50 LOOP 
60 CLOSE #1
70 END

順次アクセス(書き出し)

 書き出しでは,ファイルを開いたらERASE文を実行します。

10 OPEN #1: NAME "A:SQRTABLE.TXT"
20 ERASE #1
30 FOR i=1 TO 10
40    PRINT #1: i,SQR(i)
50 NEXT i
60 CLOSE #1
70 END

20行のERASE文がないと,A:SQRTABLE.TXTがすでに存在するときはファイルの最初から上書きすることになってエラーになります。
 なお,追記書き出しにしたい場合は,20行を
20 SET #1:POINTER END
に変えます。

WRITE文とREAD文(内部形式ファイル)

 Full BASICでは,内部形式ファイルを利用すると,WRITE文で書き込んだデータをREAD文で読み込むことができます。
なお,十進BASICでは,内部形式にCSVを採用しています。したがって,内部形式で書き出すと,Microsoft系BASICのWRITE文による出力とほぼ同じものが得られます。

書き出しプログラム

100 DATA "青木", 56, 74
110 DATA "飯田", 92, 83
120 OPEN #1: NAME "A:sample.CSV",RECTYPE INTERNAL
130 ERASE #1
140 DO
150    READ IF MISSING THEN EXIT DO: s$, x,y
160    WRITE #1: s$,x,y
170 LOOP
180 CLOSE #1
190 END


読み込みプログラム

10 OPEN #1: NAME "A:sample.CSV",RECTYPE INTERNAL
20 DO
30    READ #1,IF MISSING THEN EXIT DO: s$, x,y
40    PRINT s$,x,y
50 LOOP
60 CLOSE #1
70 END


注意 RECTYPEを指定せずにファイルを開くと表示形式で開いたものとみなされます。表示形式で開かれたファイルでは,WRITE文の動作はPRINT文と同じです。

文法の違い

 マイクロソフトBASICではPRINT文,INPUT文,READ文,WRITE文のファイル番号の次に書くのはコンマですが,Full BASICではコロンです。

PRINT #1: x,SQR(x)
INPUT #1: A,B
LINE INPUT #1: s$
PRINT文に書式指定を追加するときは,コロンの手前に,コンマで区切ってUSING節を書く。
PRINT #1,USING "### ##.###": a,b


詳細

Microsoft BASICとの相違の詳細は, BASIC Help の「他のBASICとの相違」を参照してください。


(仮称)十進BASICのホームページへ