LIST
そこに注意して例 5 を書きなおすと、
(X11-BASIC) ' 例 5'
Input "n ? "; n a = 5
If n > 1 Then
For k = 2 To n a = 3 * a + 2 Next k
Endif Print a Stop End
(Result)
holy@mint ~ $ xbasic testx.bas n ? 3
53
> run n ? 2 17
> run n ? 1 5
>
のように、If 文で n=1 の場合は、For...Next を実行しない
ように回避する必要があります。
Step 文
For...Next 構文で繰り返しのたびごとに制御変数に加算 される数値を 1 以外の数値にすることができます。次のプ ログラムでは、x の値を 0 から 1 まで 0.1 ずつ加算しながら x2 を計算して出力します。
(X11-BASIC) ' 例6
For x = 0 To 1 Step 0.1 Print x, x ^ 2
Next x Stop End
(Result)
holy@mint ~ $ xbasic testx.bas 0 0
0.1 0.01 0.2 0.04 0.3 0.09 0.4 0.16 0.5 0.25 0.6 0.36 0.7 0.49 0.8 0.64 0.9 0.81 1 1
>
また、数値を大きい値から小さい値へ変化させる目的で この構文を用いることができます。
(X11-BASIC) ' 例7
For k = 10 To 1 Step -1 Print k
Next k Stop End
(Result)
holy@mint ~ $ xbasic testx.bas 10
9 8 7 6 5 4 3 2 1
>
While...Wend
While の後に書かれた式の条件が成立する間、繰り返しを
実行する構文です。
(X11-BASIC) a = 1
While a <= 10
Print " No."; a a = a + 1
Wend End
(Result)
holy@mint ~ $ xbasic testx.bas No.1
No.2 No.3 No.4 No.5 No.6 No.7 No.8 No.9 No.10
>
ループからの脱出
エスケープシーケンスというんでしょうが、それよりも
脱出(ジェイルブレーク)と言ったほうがかっこいいので、まあ「脱出」としておきました。まあ、ちょっと言ってみ
たかっただけです。どうでもいんですが。
Break
Break 文の実行によって、すぐに現在回ってるループから
外に抜け出します。(X11-BASIC) For X = 1 To 10 If X = 5 Then Break Endif Print X Next X
Print " - Break Loop@"; X End
(Result)
holy@mint ~ $ xbasic testx.bas 1
2 3 4
- Break Loop@5
>
Exit If [式]
[式]が真(TRUE)の場合、ループから外に抜け出します。
(X11-BASIC) For X = 1 To 10 Exit If X = 5 Print X
Next X
Print " - End@ "; X End
(Result) 1
2 3 4
- End@ 5
>
他の言語では、ループの途中からループの先頭へ戻る命 令に Continue という名前の命令を用意してるのもあります。
けれど X11-BASIC には、そういう用法の Continue はありま せん。
X11-BASIC にある Continue は、Stop で一時中断したプロ
グラムを再開する場合と、Select...Case...EndSelect の選
択肢中で使う場合の 2 通りについてです。(X11-BASIC で数値計算をさせていて、ある条件になったら ループから抜け出す BREAK を仕掛けたんですけど、どうし ても BREAK されず、代わりに Exit If で回避したことがあ りました。かなりこなれた X11-BASIC でもそういうことが あるので言語処理系を信用しすぎないことも必要だと思い ます)
他のループ命令
X11-BASIC には他にもループ命令が用意されています。も ともと BASIC には、こんなに似たような命令いらないだろ というのが多いです。おそらくそれは、他の言語を使って きた人への配慮なんだと思うんです。使い慣れた言葉がな いとイラッとしますよね。そういうストレスを感じさせな いための。
Do...Loop
繰り返しを実行する構文です。エスケープする条件を途
中に儲けないと無限ループするので注意が必要です。(X11-BASIC) Do
Input a$
Exit If a$=""
Loop End
(Result)
holy@mint ~ $ xbasic testx.bas
? r
? e
?
>
Repeat...Until
Until の後に書かれた式の条件が成立する間、繰り返しを
実行する構文です。For や While がループの頭で判定してるのに対して、ループの末尾で判定してるのが特徴です。
(X11-BASIC) a = 1
Repeat
Print " No."; a a = a + 1
Until a > 10 End
(Result)
holy@mint ~ $ xbasic testx.bas No.1
No.2 No.3 No.4 No.5 No.6
No.7 No.8 No.9 No.10
>
文字列
制御構文や数値処理のあとに残った計算機でやることと 言ったら九割方は文字列操作と言えます。
そもそも現代的な計算機の出自からして戦争中敵軍の暗
号を解読する作戦から始まったことですし、数字も含めて 記号一般を取り扱う機械だと考えてよいでしょう。社会において人とのコミュニケーション以外の仕事と いったら、結局は記号の操作(移し替え)に終始していると 思いませんか?
そういう訳で、まずは文字列変数について説明します。
一般にプログラミング文法の説明するとき、文字列は
「String」と呼びます。X11-BASIC は動的型付けでして、変
数を扱うのにプログラムの先頭で変数の宣言をしなくても思いのままに作って代入できます。しかも特にローカルだ と宣言しない限り、全てグローバル変数となります。それ が気持ちいいか悪いかは、作成してるプログラムの性質や
目的によると思います。X11-BASIC ではそうなってるということです。
そして、X11-BASIC で文字列変数は、「変数名$」と表現 されます。これが文字列の配列とすると「変数名$()」と なります。
文字列変数への代入は、
A$ = "はじめまして"
のようにします。ダブルクォーツで囲んでるのをわかって ください。
Print A$
とすれば
はじめまして
と表示されます。
次に変数の変換について説明します。
命令:Val
書式:Expression = Val ( String )
String の内容にしたがって文字列を、数値に変換します。
日付や時間、小数点、論理値などで試してみましょう。
(X11-BASIC)
Print Val("09/06/72 01:00") Print Val("3.1415")
Print Val("-25") Print Val("True") Print Val("False") End
(Result) 9
3.1415
-25 0 0
文字列から数値に変換できない場合は「0」を返します。
最初の「日付 時間」は最初の区分「09」だけ数値に変換 されたようです。True/False
みたいな文字列を論理値に変えることはできないようですね。
今度は逆に数値を文字列に変換してみます。そうしたい
時は、Str$(Number)を使います。(X11-BASIC) A = 3.0E-3 B$ = Str(A) Print A Print B$
End
(Result)
holy@holy-901:~$ xbasic testx.bas 0.003
0.003
>
文字列連結
X11-BASIC での文字列連結演算子は「+」です。
Microsoft BASIC では"2"+"3"で"23"になりますが、Full
BASIC では同じことを"2"&"3"と書きます。GAMBAS で
は"2"&"3"です。X11-BASIC の場合は"2"+"3"という話です。
(X11-BASIC) A$ = "おはよう"
B$ = "こんにちは"
C$ = A$ + "、" + B$
Print C$
(Result)
おはよう、こんにちは
Print 文による文の出力は、";"で続けることができます。
これは改行しないで続けて、という意味になります。また、
","でつなげると間にタブが挿入されます。
(X11-BASIC) A$ = "おはよう"
B$ = "こんにちは"
Print A$; "、"; B$
Print A$, "、", B$
C$ = A$; "、"; B$
Print C$
(Result)
holy@holy-901:~$ xbasic testx.bas おはよう、こんにちは
おはよう 、 こんにちは
>
となります。C$の内容が出力されないのは、文字列どうし の接続を"+"ではなく、";"にしてしまってるからです。
ここは、
C$ = A$ + "、" + B$
とするのが正解です。
文字列の分割
命令:Split
書式:Split t$, d$, mode, a$, b$
説明:t$という文字列を d$で分けて、a$という部分と b$と いう部分にします。つまり、t$=a$+d$+b$という関係になり ます。
mode は、
0:デフォルト
1:do not search in parts of t$ which are in
brackets. Quoted parts of the string are not split up.
例
> Split "Hello, this is a string.", " ", 0, a$, b$
> print a$
Hello,
> print b$
this is a string.
関数:Word$()
書式:a$ = Word$(b$, n[, delimiter$])
説明:文字列 b$の n
番目の文字を返します。文字をスペース、または delimiter$で与えられる文字で分割します。
例
> a$ = Word$("Hello, this is a string.", 3)
> Print a$
this
> b$ = Word$("Hello, this is a string.", 2, ",")
> Print b$
this is a string.
関数:Trim$
書式:b$ = Trim$(a$) b$ = Xtrim$(a$)
説明:a$で与えられる文字列を整形して返します。X のつい てる方は、大文字になります。
1.タブをスペースにします。
2.二重スペースを一つのスペースにします。
3.文字列の後ろに続いてるスペースを取り除きます。
4.ダブルクォーツで囲まれた部分は変えません。
例
> Print Trim$(" a b c d") a b c d
部分文字列の取り出し
文字列から任意の部分を取り出すには、Right$, Left$, Mid$などの関数を使います。
Left$は、任意の長さを指定されれば与えられた文字列の
左側から数えた文字までを返します。Right$は、任意の長さを指定されれば与えられた文字列の右側から数えた文字 までを返します。
ここでは、Mid$の例を下記に示します。
関数:Mid$
書式:m$ = Mid$(t$, s[, l])
説明:t$で与えられた文字列から、整数 s から開始して、
長さ(整数)l までの文字列を m$に返します。もし l が与え
られなければ、開始位置の文字を返します。また l に負の
整数を与えるとエラーにはなりませんが何も返されません。例
> Print Mid$("X11-BASIC", 3, 2)
1-> Print Mid$("X11-BASIC", 4)
-> Print Mid$("X11-BASIC", 2, -1)
>
また、文字列の右側や左側をピックアップしたいのなら、
t$ = Right$(a$ [, n]) 文字列a$の右側(終わり)から n 文字ぶんの文字列を t$に返します。
t$ = Left$(a$ [, n]) 文字列a$の左側(頭)から n 文字ぶんの文字列を t$に 返します。
を使う手もあります。
Len は、文字列の長さを数えるときに使う関数です。
Left$, Right$, Mid$では、どこからどこまでと指定する ときに文字列の長さを指定します。これを指定したりする ときに便利なので覚えとくといいと思います。
関数:Len
書式:l = Len(t$)
説明:引数として与えられた文字列の数を返します。これ は ASCII 文字で何文字ぶんになるかを返します。
X11-BASIC には Python や Ruby
みたいに文字エンコードの 宣言はありません。公式では ANSI 標準の ASCII コードに対応とだけ言ってます。アルファベット+α 以外の文字につ いては、X11-BASIC を動かしてる環境しだいのように、利用
者に任せてるって感じです。Tips というか、運用上のノウハウなんですが例えば Linux で UTF-8 コードによる日本語を使ってるならば、
(X11-BASIC)
A$ = "うーん、この"
Length = Len(A$)
Print A$; ":"; Length Quit
End
Result
うーん、この:18
それぞれの文字は、UTF-8 の文字コードでは
「う」の UTF-8 コード : E3 81 86
「ん」の UTF-8 コード : E3 82 93
「こ」の UTF-8 コード : E3 81 93
「の」の UTF-8 コード : E3 81 AE
に対応してまして、ひらがな・カタカナ・漢字は 2
バイト、ASCII コードにすると
3文字ぶんに相当するので、Len()で
得られる文字数は 3x6 文字=18 とカウントされてるわけです。Windows で SHIFT-JIS コードでソースを書いて、コマンド プロンプトで実行させるなら ASCII コードにすると 2 文字
ぶんとなります。部分文字列の置換 関数:Replace$
書式:t$ = Replace$(a$, s$, r$)
説明:Replace 関数は、文字列 a$の中にあるパターン s$に
相当する文字列を r$に置き換えます。a$が空なら、空の文 字列が返されます。また s$が空なら文字列
a$がそのまま返 されます。
(例)
> Print Replace$("x11-basic is a cool basic", "bas","BAS") x11-BASic is a cool BASic
> Print Replace$("x11-basic is a cool basic", "a", "") x11-bsic is cool bsic
> Print Replace$("x11-basic is a cool basic", " ", "--") x11-basic--is--a--cool--basic
他にめぼしいのは
t$ = Reverse$(a$) 文字列a$の並び順を逆転します t$ = Space$(i) i個の連続したスペースを返します。
のような文字列関数があります。
(例)
> Print Reverse$("abcdef") fedcba
> Print "abc" + space$(2) + "def"
abc def
文字列の検索
X11-BASIC には、文字列内の部分文字列の検索用に、
Instr 関数が用意されています。
a=Instr(s1$, s2$ [,n]) s2$のあたまから何文字目に s1$があるか調べる a=Rinstr(s1$, s2$ [,n]) s2$の後ろから数えて何文字目に s1$があるか調べ る
この関数は、文字列変数 s2$内に文字列 s1$と一致する部
分があるかを調べます。関数の戻り値としては、文字列内で最初に現れる位置を整数で返します。該当する文字列が ない場合は「0」が返されます。
また、該当する部分文字列が何カ所もあるような場合は、
何文字目から検索を始めるかをオプション指定できます。
このオプションは、整数 n で与えます。
(例)
> Print Instr("x11-basic is basic", "bas") 5
> Print Instr("x11-basic is basic", "bas", 6) 14
> Print Instr("x11-basic is basic", "not") 0
他に、あるパタンに文字列が合致してるか調べる関数と しては、Glob()があります。
f = Glog(a$, b$ [,flags])