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         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
実行
Ans1=2
Ans2=2
Ans1=4
Ans2=4
Ans1=6
Ans2=6
Ans1=8
Ans2=8
Ans1=10
Ans2=10
 
 メインのプログラムとひとつのモジュールで構成されている。
 モジュール内のコマンドbaiとbai2で使われている変数nnが共通になる。
実行
Ans1=2
Ans2=1
Ans1=4
Ans2=2
Ans1=6
Ans2=3
Ans1=8
Ans2=4
Ans1=10
Ans2=5
 
 メインのプログラムと二つのモジュールで構成されている。

 

 変数をプログラム全体で共通に利用できるようにしておくか、モジュール(#module 〜 #global)にして変数名やラベル名を独立したものにしておくか、どちらにするかはケースバイケースである。


前へ 目次へ 次へ 
2006  © Hiroshi Masuda 

 

 

inserted by FC2 system