HSP3 プログラミングの基礎U | |
(4) ユーザ定義
◎ ユーザ定義命令
メッセージを表示するmes命令のような命令(コマンド)をプログラマ自身が定義(作成)することができる。これを「ユーザ定義命令」という。
コマンドの名前は、自由につけることができる。ただし、重複しないこと。
#deffunc コマンドの名前 パラメータ
コマンドのためのプログラム
return
コマンドを使う前に定義する必要がある。
パラメータは省略できる。指定するパラメータのタイプには以下のものがある。
int 整数値 var 変数(配列なし) double 実数値 label ラベル str 文字列 local ローカル変数 array 変数(配列あり)
「new command」と表示するコマンド cmd1 を定義する。
goto *start #deffunc cmd1 ;コマンド定義 mes "new command" return *start cmd1 ;コマンド使用 stop
「new command」と表示される。
プログラムは上から順番にという原則により、下から2行目でユーザ定義命令cmd1を使用しているので、それより前の位置で定義をしている。ちなみに、次の例はエラーになる。
;このサンプルはエラーになる。
*start
cmd1
stop
#deffunc cmd1
mes "new command"
return
次のように、サブルーチンでも同じように書くことができるが、gosub命令を使って gosub *cmd1 のように書かなくてはならない。
goto *start *cmd1 ;サブルーチン mes "new command" return *start gosub *cmd1 ;サブルーチン使用 stop
▼パラメータの指定
パラメータで指定した整数値の2倍を表示するコマンド bai を定義する。
goto *start
#deffunc bai int para ;コマンド定義
nn = para * 2
mes "Ans=" + nn
return
*start
bai 5
stop
「Ans=10」と表示される。
ユーザ定義命令baiに続けてパラメータを指定する。パラメータはコマンド定義のパラメータ用の変数paraで受け取られる。
パラメータparaが受け取る値は整数なので、データの型としてintを指定している(int para)。ほかに、データの型には実数値を表すdouble、文字列を表すstrなどがある。
ユーザ定義命令baiで、2.5の2倍を計算する。
変更部分のみ(サンプルの下から2行目)
bai 2.5 ;変更部分 5 -> 2.5
「Ans=4」と表示される。 変数paraは整数型なので整数部分の2を値として受け取るためである。
実数が処理できるようにユーザ定義命令baiを変更する。
goto *start
#deffunc bai double para ;int -> double
nn = para * 2
mes "Ans=" + nn
return
*start
bai 2.5
stop
「Ans=5.000000」と表示される。
ユーザ定義命令のパラメータが数値の時、doubleで指定しておけば整数でも実数でも正しい答えが求められる。しかし、「処理の効率化を図る」ため、整数だけでよいときはintで指定する。(整数よりも実数を処理(計算)する方が時間がかかる。)
▼パラメータと変数について
ユーザ定義命令のパラメータparaや中で使われている変数nnの値を調べる。
goto *start #deffunc bai int para nn = para * 2 mes "Ans=" + nn return *start bai 5 mes nn ;← mes para ;← stop
「Ans=10」と「10」の2行表示された後、エラーになる。
このサンプルでわかることは、次の2点である。
・ユーザ定義命令のパラメータで使用した名前paraは、定義部分以外では使えない。
・変数nnは場所に関係なく、プログラム全体で共通して使うことができる。
定義部分の最後でパラメータparaを0にする。
goto *start
#deffunc bai int para
nn = para * 2
mes "Ans=" + nn
para = 0 ;←
return
*start
bai 5
mes nn
mes para
stop
「Ans=10」と表示された後、エラーになる。
このサンプルでわかることは、次の点である。
・パラメータには値を格納することができない。
1〜5の2倍を表示する。 変数nnがプログラム全体で共通なことによる不都合な例である。
goto *start #deffunc bai int para nn = para * 2 mes "Ans=" + nn return *start nn = 1 *loop1 bai nn nn = nn + 1 if nn < 5 : goto *loop1 stop
「Ans=2」、「Ans=6」と2行だけ表示される。
「Ans=2」、「Ans=4」、「Ans=6」、「Ans=8」、「Ans=10」と5行表示されることを期待したが、実行結果は違った。次に、トレースの結果を示す。変数nnがプログラム全体で共通であることが原因である。
変数 nn のトレース goto *start 1 ピンク色の列が実行順序。
ピンク色の列の右が変数 nn の値。#deffunc bai int para 6 14 nn = para * 2 7 2 6 15 6 mes "Ans=" + nn 8 16 return 9 17 *start 2 nn = 1 3 1 *loop1 4 12 bai nn 5 13 nn = nn + 1 10 3 18 7 if nn < 5 : goto *loop 11 19 stop 20
定義部分の変数nnか、メインプログラム部分(ラベル*staret以降)の変数nnか、どちらかの変数を別のものに変えると正しい結果が得られる。
◎ モジュール定義
変数名やラベル名を独立して扱えるプログラムの単位を定義する。
#module
プログラム
#global
1〜5の2倍を表示する。 モジュールにすることで変数nnの不都合を解決した例である。
#module #deffunc bai int para nn = para * 2 mes "Ans=" + nn return #global *start nn = 1 *loop1 bai nn nn = nn + 1 if nn < 5 : goto *loop1 stop
「Ans=2」、「Ans=4」、「Ans=6」、「Ans=8」、「Ans=10」と5行表示される。
プログラムは#module 〜 #globalをとばして、メインのプログラム(ラベル*start)から実行される。ラベル*startはなくてもかまわない。
次の2つのプログラムの違いを確認してみよう。
#module #deffunc bai int para nn = para * 2 mes "Ans1=" + nn return #deffunc bai2 int para nn = para bai para mes "Ans2=" + nn return #global *start nn = 1 *loop1 bai2 nn nn = nn + 1 if nn <= 5 : goto *loop1 stop |
#module #deffunc bai int para nn = para * 2 mes "Ans1=" + nn return #global #module #deffunc bai2 int para nn = para bai para mes "Ans2=" + nn return #global *start nn = 1 *loop1 bai2 nn nn = nn + 1 if nn <= 5 : goto *loop1 stop |
||
メインのプログラムとひとつのモジュールで構成されている。 モジュール内のコマンドbaiとbai2で使われている変数nnが共通になる。 |
メインのプログラムと二つのモジュールで構成されている。 |
変数をプログラム全体で共通に利用できるようにしておくか、モジュール(#module 〜 #global)にして変数名やラベル名を独立したものにしておくか、どちらにするかはケースバイケースである。
2006 © Hiroshi Masuda |