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


HSPTV!掲示板


未解決 解決 停止 削除要請

2010
0903
黒伊耶那岐ループ内サブルーチンジャンプでbreakできない6解決


黒伊耶那岐

リンク

2010/9/3(Fri) 21:51:52|NO.34824


repeat 30 mes cnt gosub *sub_test loop stop *sub_test if cnt = 15 : break return
「repeat外でbreakした。」と言われ、エラーが出るんですが、私としてはこれはあくまでrepeat内でbreakしているつもりなのですが、なぜrepeat外なのでしょうか?
また、こういうことがしたいときにはどうすればよいのでしょうか?



この記事に返信する


SYAM

リンク

2010/9/3(Fri) 22:03:14|NO.34825

>こういうことがしたいとき

こうですかねえ…


done=0 repeat 30 mes cnt gosub *sub_test if done : break loop stop *sub_test if cnt = 15 : done=1 return



ext

リンク

2010/9/3(Fri) 22:06:19|NO.34826

確かにそのスクリプトでは、repeatの中でbreakが行われていると言えます。

しかしgosubが行われた時点で、サブルーチンのネストレベルは加算されているため、
もし、そのような方法でのコンパイルと実行が可能であったとしても、
その処理が連続することで、ネストレベルが加算され続けてしまい、
結果的にエラーが発生する恐れがあります。

その対処方法としては以下のように、breakを行いたくなった場合に、
フラグとなる変数に値を代入し、
repeat〜loopの間でそのフラグの値をチェックした上で、
breakでループを抜け出すといった処理が有効かと思います。


repeat 30 mes cnt gosub *sub_test if Flag = 1 : break loop stop *sub_test if cnt = 15 : Flag = 1 return



黒伊耶那岐

リンク

2010/9/3(Fri) 22:49:29|NO.34827

SYAMさま、extさまご回答ありがとうございます。

>gosubが行われた時点で、サブルーチンのネストレベルは加算されているため
???
returnする前にbreakしてるからネストがおかしなことになるってことですか?
私の書いたソースが仮に抜けれた場合、breeak後もネストレベルが1のままになってやばいって理解であってます?

なるほど!フラグ立てればいいだけの話ですよね…こんな簡単なことに気づかないとは迂闊でした。
…ただ、欲を言わせてもらうと

上のソースは簡潔に問題を表すため、ループを1つにしましたが、実際のソースは、

foreach A gosub *sub_test loop foreach B gosub *sub_test loop foreach C gosub *sub_test loop …
と多数の配列に同じ処理を行うものでして…
やっぱり1個1個のループにフラグチェッカーつけないと駄目ですか?
(breakが必要ない!やっぱり要る!とかなったりとか、デバグのため一時コメントアウトしたいとなったりという事態を考えると、できれば一箇所で済ませたい
と思うのは無い物ねだりでしょうか?)



SYAM

リンク

2010/9/3(Fri) 23:00:32|NO.34832

どうしてもというなら、フラグのチェック部分を #define で書いておけば記述は一箇所になりますね。



黒伊耶那岐

リンク

2010/9/3(Fri) 23:19:29|NO.34833

>SYAMさま
やっぱりそれくらいしかないですよね。
1つ1つのループに書き足すことにします。

皆様ご回答ありがとうございました。



KA

リンク

2010/9/4(Sat) 17:49:07|NO.34838

解決しているけど・・・

X=A
gosub *fo

*fo
foreach X
gosub *sub_test
loop
return

こんな感じにはできない?



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