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


HSPTV!掲示板


未解決 解決 停止 削除要請

2015
0413
TNK関数の仕様13解決


TNK

リンク

2015/4/13(Mon) 19:51:00|NO.68533

#include "hspext.as";
#module;


#deffunc main;------------------------------------------------------------------
screen 0 , 640 , 480 , 4 , 256 , 256 , 0 , 0; #ウインドウサイズ
title "test"; #タイトル
split_n "aaa\nbbb\nccc";

foreach val; #valが局所化されてねぇーーーー
print "" + val.cnt + ":ok";
loop
return;
end 0;

#deffunc split_n str p1;------------------------------------------------------------------
;文字列を改行に沿って分割して返す
txt = p1;
i = 0; #文字列内位置記憶
dim val; #戻り値(配列)

repeat; #1行づつ取りだす
getstr txt2, txt, i; #改行までを取り出す
if strlen(txt2) < 1 : break; #何もなければループ終了
val.cnt = txt2; #配列に保存
i = i + strsize; #位置情報を修正
loop;
return val;
end 0;

#global;
main;
stop;
end 1;



この記事に返信する


TNK

リンク

2015/4/13(Mon) 19:53:48|NO.68534

昨日HSPをダウンロードしたばかりで、使い方がよく分かっていません。(適当にいじりながら作ってます)。

そこで二つ質問なのですが、
1:mainでvalが参照されます。これはどうすればいいですか?
2:Val = split_n "aa" 戻り値を受け取るとエラーが発生します。どう記述するのですか?



窓月らら

リンク

2015/4/13(Mon) 20:50:18|NO.68535

おなじmodule内では変数名が共有されます。
これを分けたい場合は別のモジュールで定義します。

returnの戻り値は
> p1に数値を指定した場合には、システム変数statに代入されます。
> p1に文字列を指定した場合には、システム変数refstrに代入されます。
> p1に実数値を指定した場合には、システム変数refdvalに代入されます。
> p1の指定を省略した場合には、システム変数の代入は行なわれません。
とリファレンスにありますのでご参考に。

あと、行末を;で閉じる必要はHSPではありません。
また、split命令が用意されてますので、そちらを使用されたほうが良いと思います。
ヘルプ→HSPキーワード検索 でリファレンスが出ます。



TNK

リンク

2015/4/13(Mon) 21:05:20|NO.68536

ありがとうございます。
一応読んだのですが、細部が理解できてません。(たぶん書いてないように思えた)。

それで、できればで良いのですがリファレンスな値が発生しないようにしたいです。
その上で、(リファレンスではなく)戻り値を受け取れればよいな、と思います。
HSPは左辺値を使用するとエラーになるのでしょうか?



TNK

リンク

2015/4/13(Mon) 21:40:27|NO.68537

今マニュアルを読んでますが、
HSPで用意されてるのは、局所化ではなく、グローバル変数の名前空間の自動設定なのでしょうか?
(これも明示的には書いてない?)

これも出来れば、スタティック、もしくはレキシカルな宣言をしたいのですが、無理でしょうか?
どうもヘルプが正しい用語を使わない傾向にあるようなので、まだうまく検索できないです、すみません。



f(風呂入るか…)

リンク

2015/4/13(Mon) 21:43:15|NO.68538

まず

#deffunc

にカーソルを合わせ、F1を押してみよう。
そしてよく読んでみよう。

はい、「#deffunc」は「新規【関数】を作る物」でなく「新規【命令】を作る物」ですね。
関数じゃないので

2:Val = split_n "aa"

とは書けません。

#defcfunc

とエディタで書いて、そこにカーソルを合わせてF1を押し、
それをよく読みましょう。


他にもんんんな場所はあるけれど、まあとりあえず頑張ってみよう。



f(風呂入るか…)

リンク

2015/4/13(Mon) 21:54:58|NO.68539

・・・なんか今、#defcfuncの項目確認したら、
プログラミングマニュアル(hspprog.htm)のモジュール項目も含めて
なんかすげえ不親切だな。

前からこんなだったっけ?

俺どうやってモジュール関連覚えたんだろう。
この説明で理解できる気がしねえ…。


とりあえず、#defcfuncの時の引数は

Val = split_n("aa")

こうやってかっこで囲むのな。



TNK

リンク

2015/4/13(Mon) 21:57:53|NO.68540

#defcfuncでも戻り値を取るとエラーになるです。
命令がよく分からないのですが、左辺値を書くとエラーになるんですか?
関数でもエラーになりすけど、その辺も書いてないように思えました。

またこの場合、無効なコンテキストの値はどのように処理されますか?



TNK

リンク

2015/4/13(Mon) 22:03:31|NO.68541

>こうやってかっこで囲むのな。
ありがとうございます。
()で囲み、さらに戻りを代入するとエラーが解消されました。(無効なコンテキストは無条件でエラー?)。
ただ、配列が返ってきてないように思えます。



f(風呂入るか…)

リンク

2015/4/13(Mon) 22:21:11|NO.68542

そりゃ

return val

と書けば

return val(0)

と同義だろうしな。


配列のやり取りするなら、引数でarray使いなよ。

つっても、マニュアルにその辺の説明がまともに見当たらん。
マジで前からこんなだったっけ?


ああもう面倒くさい。

#include "hspext.as" #module #deffunc main screen 0 , 640 , 480 , 4 , 256 , 256 , 0 , 0 sdim result , 64 , 50 count = split_n( result , "aaa\nbbb\nccc" ) repeat count print "" + result(cnt) + ":ok" loop return #defcfunc split_n array work , str p1 ;文字列を改行に沿って分割して返す txt = p1 i = 0 ; #文字列内位置記憶 c = 0 ; #何行あったかのカウンタ repeat ; #1行づつ取りだす getstr txt2, txt, i ; #改行までを取り出す if strlen(txt2) < 1 : break ; #何もなければループ終了 work(cnt) = txt2 ; #配列に保存 i = i + strsize ; #位置情報を修正 c+=1 loop return c #global main stop
こうな。



科学太郎

リンク

2015/4/13(Mon) 22:25:22|NO.68543

TNKさんへ

HSPは昔のN88-BASICを真似て進化してきてます。
だから gosub とラベル名でサブルーチンを記述する方法が基本ですが、
HSP3.0からユーザ定義命令、ユーザ定義関数が記述可能になりました。

この命令と関数の違いは「戻り値」を条件式や数式で使えるかどうかの違いです。
つまり、gosub とラベル名に引数を付けたタイプが「命令」で、
命令に戻り値で呼び出し元にデータを返せるのが「関数」です。

さらに関数にすると必ず変数への代入か、条件式、mes 命令などで受け取る必要があり、
C/C++言語のように関数の戻り値を読み捨てることはできません。→エラーとなる。
よって、関数と定義したら必ず戻り値を受け取りましょう。

また、命令は戻り値を返せませんので「return」命令で値(整数値・実数値・文字列)を返すと
整数値は「stat」
実数値は「refdval」
文字列は「refstr」
というシステム変数で参照可能です。
これは既に「窓月らら」さんがアドバイスしてる通りですね。

あと関数は必ずカッコを付ける必要があるが、
命令はカッコを付けてはいけないし、
配列は基本的に返せません。→JavaScriptとは違う。

#deffunc Sample int _p1,int _p2,\ local a,\ local b,\ local c return
このように記述すると「Sample」命令でしか使えない「a」「b」「c」変数を宣言したことになります。
つまり、C/C++でいう局所変数(ローカル変数)ですね。
しかし、この場合は広域変数(グローバル変数)で既に「a」「b」「c」変数が使われてるとエラーとなります。

マニュアルには上記のように「\」記号で複数行に渡り記述できるとは書いてないが、
プリプロセッサの項目で「\」記号で複数行を表現できると書かれています。

だからユーザ定義命令、ユーザ定義関数で「local」指定は仮引数よりも
後で記述するのが望ましいようなことが書いてありますね。
この意味は上記のことを指してると思います。→たぶん。



TNK

リンク

2015/4/13(Mon) 23:14:40|NO.68544

>f(風呂入るか…)さん
ご丁寧にありがとうございます。
それを見て勉強させてもらいます。
ところで、マニュアルにないものを色々知ってるようですが、どうやって知ったんですか?


>科学太郎さん
ご丁寧にありがとうございます。
おかげでHSPが少し理解できたように思えます。
スタティックやレキシカルな変数は諦める事にします。
(ちなみに教えて頂いたものは、実質グローバル変数のようですね)。



TNK

リンク

2015/4/13(Mon) 23:25:10|NO.68545

仮引数と言う用語だけ分からなかったのですが、プロトタイプのことですか?



TNK

リンク

2015/4/14(Tue) 00:31:42|NO.68546

おかげで、いろいろ理解出来てきたように思えます。
ありがとうございました!



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