プレイ日記
おちゃめ ochame_nako
プチコン3号には配列変数を初期化する(要素数を0にする)関数や命令がありません。 そこで配列を初期化する命令や関数を作ってみました。書式が異なるものを3種類用意したのでお好みで使って下さい。 また、それを活用して「文字列でも数値でも入る万能変数」が使用可能な関数も作ってみたので良かったら使ってみて下さい。
15そうだね
プレイ済み
返信[1]
親投稿
おちゃめ ochame_nako
これらを使うためには型判別のSUFFIX関数が必要となります。(SUFFIX関数 ver.2.0では文字列は0、整数型は1、実数型は2を返す) 公開キー【 KAEEX3Z4 】、ファイル名「INIT」 公開キーのプログラムにはこれが配列初期化命令ERASE、配列初期化関数INITA、INITS、変数を万能な型で初期化するINIT関数に加えてSUFFIX関数のプログラムも含まれています。 また、これらすべての関数や命令と実行確認ができるサンプルプログラムを含んでいます。 これを実行すれば要素数99999の配列が0になり、メモリが解放されて、数値変数に文字列が入っていることが確認できます。
0そうだね
プレイ済み
返信[2]
親投稿
おちゃめ ochame_nako
使い方の説明とその解説を書いておきます。 ERASE Aとすると配列変数A[]を初期化(要素数を0に)できます。 あえて説明するまでもない方法ですが、POPでデータを1つずつ受け取り要素数が0になるまで繰り返しているだけです。 数値と文字列とを判別することで両方に対応する命令になっています。 数値と文字列の2通りだけなのでSUFFIX関数は使っていません。 A=V>0<3において変数Vに文字列が入っている場合はA=0となり、数値が入っている場合は1となります。
0そうだね
プレイ済み
返信[3]
親投稿
おちゃめ ochame_nako
A=INITA(A)とすると配列変数A[]をA[]の型で初期化できます。 仕組みを説明すると単純で要素数0の配列を代入するだけです。 これによって要素数の多い配列も瞬時に初期化できます。 ただし、ERASE命令とは異なり、実数型と整数型も判別する必要があるためSUFFIX関数を利用しています。 これとVAR関数を組み合わせて引数の型と一致する型に初期化できます。
0そうだね
プレイ済み
返信[4]
親投稿
おちゃめ ochame_nako
A=INITS("#")とすると配列変数A[]を実数型で初期化できます。 INITS("%")ならば整数型、INITS("$")ならば文字列型、INITS("")ならばOPTION DEFINTの有無によって整数型と実数型が決まります。 プチコン3号の配列変数は参照型であり、代入する変数の型によって代入される変数の型も変わってきます。 例えばVAR A[0],B$[0]として、A=B$とすれば配列変数A[]は文字列型として扱われB$=Aとすれば配列変数B$[]は数値型として扱われます。
0そうだね
プレイ済み
返信[5]
親投稿
おちゃめ ochame_nako
この性質を意図的に活用するために作ったのがINIT関数です。 VAR A[0]としておけば、A=INIT("ABC")で配列変数A[0]に"ABC"が代入され文字列変数として活用できます。最初に代入された時点で型が決まります。 グローバル変数ならばあまりメリットはないですが、自作関数内で使えるローカル変数だと「文字列でも数値でも受け付ける便利な関数」を作るのにすごく役に立ちます。 さらに詳しい解説は「プチコン3号入門講座」でネット検索してください。
0そうだね
プレイ済み
返信[6]
親投稿
MIKI ifconfig
順に pop する方法以外だとメモリリークしそう・・・
0そうだね
プレイ済み
返信[7]
親投稿
ツララ LongIceSword
不等式って代入挟まずに一行に連続して書いてもエラーにならないんですね。 計算の優先順位が同じ演算子だと、(V>0)<3みたいな暗黙の括弧がある感じなんでしょうか。
0そうだね
プレイ済み
返信[8]
親投稿
おちゃめ ochame_nako
MIKI★さんへ FREEMEMの値が元に戻る=メモリーリークしていない と確実に言えるものではありませんが、実際の所どうなのかはいろいろ使ってみないと分からないですね。 少なくとも私が使った範囲内では問題ありませんでした。 ツララさんへ 私が試してみたところ不等号の数が2340個の式までは正常に動作しました。 しかし、基本的に比較演算の結果は0と1のみなので複数の不等号を記述して処理する機会はないと思います。 プチコンの場合は現時点(ver.3.1.0以降)で「文字列と数値の比較演算で3を返す」という特殊な仕様(?)になっているためこのような特殊な記述方法が有効になっています。
0そうだね
プレイ済み
返信[9]
親投稿
MIKI ifconfig
メモリリーク、大丈夫そうだとは思ってますが、長期稼動でどうなのかってとこですね。自分はそんな長時間動かさないのであまり気にしてませんけど。 真偽値の大小比較はエッジの立ち上がり(立下り)を検出するのに使ったりしますね。 while 1 stopped = (speed == 0) > (speed_prev == 0) ' 速度!=0から速度==0になった started = (speed > 0) > (speed_prev > 0) ' 速度==0から速度>0になった speed_prev = speed wend 「経験値が閾値を越えたらレベルアップ」のような処理にも使えます。 なお、状態変化を見るだけなら不等号ではなく != を使います。
1そうだね
プレイ済み
返信[10]
親投稿
おちゃめ ochame_nako
◎INIT()関数をさらにもう少しだけ解説 プチコン3号の配列は参照型であり、代入によって代入される側の型も変更されるということとDEFによる自作関数を作る場合は引数に使う変数は代入された段階で型が決まります。 これらはマニュアルに(かなり簡単に)記述しているのを知っている人もいることでしょう。 やはり、一番重要となるのは型の判別です。これ無しではこの関数を作ることはできません。 型判別を行うSUFFIX()関数では私が偶然発見した「数値と文字列の比較で3を返す」というのを活用しています。これによって型判別するのがかなり簡単になりました。 あとは、引数の型に合わせて配列を初期化を3パターン用意するだけです。 そしてPUSHで引数の値を初期値にして完成です。(要素数0では変数としてはすぐに使えないため関数内部で要素数を1以上にする必要がある)
0そうだね
プレイ済み
返信[11]
親投稿
おちゃめ ochame_nako
MIKI★さんへ そのような比較演算の結果の大小比較をする記述は気が付きませんでした。 しかし(プチコン3号の場合は特例を除いて)比較演算の結果は0もしくは1となるためP、Qが比較演算を示しているとすると P>Q が true の時は「Pがtrue、かつ、Qがfalse」に限られるので私だったらこのような記述をしてしまいそうです。(※SPEEDが負数にならない場合) WHILE 1  STOPPED=!SPEED&&SPEED_PREV  STARTED=SPEED&&!SPEED_PREV  SPEED_PREV=SPEED WEND STOPPEDとSTARTEDの結果が1と0ではなく0以外と0で良ければ&&を*に置き換えてさらに1文字短縮可能です。 したがって、比較演算の大小を比較する有効性は私には感じられないのですがP>QではなくP!=Qだったら比較演算の比較は有効に感じます
1そうだね
プレイ済み
返信[12]
親投稿
MIKI ifconfig
x,y (x,yは0か1) を与えると0か1を返す関数 f(x,y) の種類一覧です。 x|y|0123456789abcdef <-- この番号で説明します。 -+-+---------------- 0|0|0000000011111111 0|1|0000111100001111 1|0|0011001100110011 1|1|0101010101010101 0: 0 (x xor y) 1: x and y 2: x > y 3: x 4: x < y 5: y 6: x xor y (x != y) 7: x or y
0そうだね
プレイ済み
返信[13]
親投稿
MIKI ifconfig
8: x nor y (not (x or y)) 9: x == y (not (x xor y)) a: not y b: x >= y c: not x d: x ⇒ y (x ならば y) (x <= y) (x imp y) e: x nand y (not (x and y)) f: 1
0そうだね
プレイ済み
返信[14]
親投稿
MIKI ifconfig
以上、おちゃめさんには自明でしょうけど、なんとなくまとめてみました。
0そうだね
プレイ済み
返信[15]
親投稿
ペンコ penkogoma
いや~実に便利ですね。 今更すごい役に立ちました。感謝!
1そうだね
プレイ済み