HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2017
0605
UNGAgosub return と goto stop の違いを教えてください。9解決


UNGA

リンク

2017/6/5(Mon) 18:40:58|NO.80123

下のスクリプトについて、
その1のようにgotoで飛んでstopかけるのと、その2のようにgosubで飛んでreturnするのでは
内部的な処理は何が違うのでしょうか?実行時の挙動は同じです。



//その1
button goto "shori1",*aaa

*main
stop
*aaa
dialog "shori1"
stop

//その2
button gosub "shori1",*aaa

*main
stop
*aaa
dialog "shori1"
return

因みに下のようにループを入れた場合は挙動が異なります。


//その1
button goto "shori1",*aaa

*main
repeat
if a!=b {b=a:mes a}
wait 1
loop
stop
*aaa
dialog "shori1"
a++
stop

//その2
button gosub "shori1",*aaa

*main
repeat
if a!=b {b=a:mes a}
wait 1
loop
stop
*aaa
dialog "shori1"
a++
return



この記事に返信する


Unknown

リンク

2017/6/5(Mon) 19:44:32|NO.80124

こちらを参考にしてください。
http://hsp.tv/play/pforum.php?mode=pastwch&num=5340



Cronus

リンク

2017/6/5(Mon) 19:53:02|NO.80125

サンプルスクリプトを作りました。
[例1]gotoとstopの場合

//[例1]gotoとstop命令の場合 repeat redraw 0 color 255,255,255 : boxf color 0,0,0 pos 0,0 mes "" + cnt + "回ループしました。" //とりあえずループ回数を表示 onkey goto *start //キー入力で飛ぶ redraw 1 await 1 loop *start dialog "キーを入力しましたぁぁぁぁ!!" stop //止まってしまう→ループが止まる
[例2]gosubとreturnの場合

repeat redraw 0 color 255,255,255 : boxf color 0,0,0 pos 0,0 mes "" + cnt + "回ループしました。" //とりあえずループ回数を表示 onkey gosub *start //キー入力で飛ぶ redraw 1 await 1 loop *start dialog "キーを入力しましたぁぁぁぁ!!" return //復帰→ループは続く
シューティングゲームとかに使われています。
stop命令だとループも完全に止まってしまいます。
gosub命令を使う時には必ずreturnを入れないとエラーが発生します。
ループを使って*mainを作成し、*startで飛んでgoto *mainを使うとgosubとreturn命令になりますが、
gosubとreturnを使った方が効率がいいです。



沢渡

リンク

2017/6/6(Tue) 14:10:04|NO.80131

まず前者(stopで入力待ちをする)の場合ですが、その例の場合では特段違いはありません。

しかし後者(repeat〜loopで入力待ちをする)のケースでgotoを使うと、
「ループの外に飛び出した後、ループの中に戻ってこられなくなる」という、
非常にまずい状態になってしまいます。
こういうケースの場合は、「gosubでサブルーチンに飛んだ後、
returnでループの中に戻る」というやり方が基本になります。

gotoは、使い方を誤るとあらゆるバグの元凶となる「取り扱い注意」の品ですので、
必要な時にだけ使うことをお勧めします。
個人的には、前者のようなケースであっても『どこのstopで待っているのか
把握できない』というのが気持ち悪いので、やっぱりgosubを使うと思います。



UNGA

リンク

2017/6/7(Wed) 21:28:31|NO.80144

皆様いろいろありがとうございます。

根本的な質問で恐縮ですが、以下の二点について、あらためて教えてください。

1.button gosub や onkey gosub で割り込みがかかった場合、return後にループの中に
  制御が戻ってこれるのはどういう仕組みなのか。

2.stopがかかっているとき、内部ではどのような処理が行われているのか。

特に2のstopについては、私のように昔のBasicのプログラムから入った人間にとっては
わかりにくい部分です。昔のBasicではプログラムを待機状態にするには無限ループを
作るしかなかったので・・・。



沢渡

リンク

2017/6/7(Wed) 22:14:29|NO.80149

まず2.からお答えしますが、stopでプログラムが止まっている間は、
「割り込み」というものを待っている状態になっています。

たとえば、stopの前に「onkey goto *hoge」と宣言しておくと、キー入力があった時に
割り込みが発生し、*hogeというラベルまでジャンプします。
もしジャンプ先にstopがある場合は、またそのstopの部分で割り込み待ちを行います。

これがonkey gotoではなく「onkey gosub *hoge」の場合は、サブルーチンにジャンプした後、
returnでジャンプ元のstopまで戻ります。
stopまで戻るわけですから、returnで戻った後も処理はストップしたままで、
再び割り込み待ちの状態になります。
(だから、UNGAさんの挙げたstopを使った例の場合は、両者に実質的な違いはない)

ここではonkeyを例にとって説明しましたが、onkeyの仲間であるonclickやoncmd、onexitも割り込み宣言ですし、
またbutton命令も、「このボタンを押したら割り込みを発生させるよ」という割り込み宣言です。


次に1.ですが、ループの中にあるwaitやawaitで待っている間も、
stopと同様、割り込み待ちの状態になっています。
ただしstopとは違い、指定した時間だけ待ったら、待つのをやめて次に進みます。
これを、ループを使って何度も繰り返しているわけです。


以上、説明させていただきましたが、これでよろしいでしょうか?



UNGA

リンク

2017/6/10(Sat) 07:50:47|NO.80165

詳しい解説ありがとうございました。

ところで、stopの内部処理は無限ループみたいなものなのでしょうか?
それとも全く違う状態なのでしょうか?「割り込み待ちの状態」という状態がどういう
状態なのか今一つピンときません。しつこくてすみません。



沢渡

リンク

2017/6/10(Sat) 11:35:38|NO.80166

HSP内部のことは知らないので、「無限ループみたい」なのかどうかはわかりません。

「割り込み待ちの状態」でわからないのなら、「キーを押す」「マウスをクリックする」
「画面上のボタンを押す」など、ユーザーが行動を起こすのを待っている状態と言えばいいでしょうか。
stopの場合は「ユーザーが行動を起こすまで何もしない」という意味で、
waitやawaitは「一定時間ユーザーが行動を起こさなかったら次に進む」という意味になります。



沢渡

リンク

2017/6/10(Sat) 11:45:18|NO.80167

一応補足ですが、無限ループ自体には「ボタンを押すなどした時に、ループの外にジャンプする」
という機能はありません。
あくまでも、無限ループの中にあるwaitやawaitが、こういった効果を発揮しています。



UNGA

リンク

2017/6/11(Sun) 05:51:38|NO.80178

解説ありがとうございました。



ONION software Copyright 1997-2023(c) All rights reserved.