投稿
bigslope bigslope
文字列リテラル(""で囲まれた文字列)に添字をつけられる仕様を応用して、文字変数を数値を入れる為の配列変数の代わりとして使用する方法のまとめ。要素数を増やしたい(減らしたい)場合、先頭に挿入/最後尾に追加する事しか出来ない通常の配列に比べ、こちらは任意の位置に数値データを挿入したり、削除して詰めたりするという事が可能になる。ただ、ポインタの知識が必要になるので、初心者は使わない方が良いだろう。
10そうだね
プレイ済み
返信[1]
親投稿
bigslope bigslope
・原理 文字列リテラルに、配列変数のように添字を付けると、文字列の中の1文字(1要素)だけを取り出す事が出来る。 ?"ABCDE"[0] A ←先頭から0番目にある文字、"A"が表示される(5以上の添字を指定するとエラーとなる) 文字を入れてある変数に対しても同じ事が出来る。 A$="ABCDE" OK ?A$[4] E ←A$の中の先頭から4番目にある文字、"E"が表示される
0そうだね
プレイ済み
返信[2]
親投稿
bigslope bigslope
逆に、文字変数に添字を付けて、そこに別の文字を代入した場合、添字の位置にある文字だけを書き換える事が出来る。 A$="ABCDE" OK A$[2]="1" OK ?A$ AB1DE ←先頭から2番目の文字が、"C"から"1"に書き換えられる
0そうだね
プレイ済み
返信[3]
親投稿
bigslope bigslope
代入する文字が2文字以上の場合、上記に加えて、2文字目以降の文字が挿入される。 A$="ABCDE" OK A$[2]="12345" OK ?A$ AB12345DE ←"C"が"1"に書き換えられ、"D"との間に"2345"が挿入される
0そうだね
プレイ済み
返信[4]
親投稿
bigslope bigslope
文字を書き換えず、完全な形で挿入したい場合は、『挿入したい文字列+元の文字』の形式で代入する。 A$="ABCDE" OK A$[2]="12345"+A$[2] OK ?A$ AB12345CDE ←"12345"+"C"が挿入されるので、元の文字が上書きされない
0そうだね
プレイ済み
返信[5]
親投稿
bigslope bigslope
空の文字("")を代入すると、添字の位置にある文字が削除され、その後ろの文字が詰められる。 A$="ABCDE" OK A$[2]="" OK ?A$ ABDE ←先頭から2番目の文字"C"が削除され、"D"から後ろが詰められる このように、文字変数ならばどの位置でも自由に挿入/削除が出来るという原理を応用して、指定した位置の値を挿入/削除する事が出来る、数値配列として使ってみようというコンセプト。
1そうだね
プレイ済み
返信[6]
親投稿
bigslope bigslope
・配列変数の定義と初期値の設定 通常の配列変数では、DIM 変数名[要素数]で定義するが、文字変数を配列として使う場合は、要素の数だけ文字を並べてセットする事で定義を行う。 '通常の数値配列はこのように定義するのに対し… DIM A[5] OK '文字を5個並べて入れる事で、要素数5(初期値は0)の配列として定義する A$=CHR$(0)*5 OK
0そうだね
プレイ済み
返信[7]
親投稿
bigslope bigslope
・数値を入れる、数値を取り出す 数値配列として使う場合は、CHR$で文字に変換したものをセットし、取り出す時はASCで数値に戻す。 使用できる数値の範囲は、CHR$を使う関係上、0~65535に限定される。符号と小数点は使用出来ない。 (C言語でいう所の、unsigned short intに相当する)
0そうだね
プレイ済み
返信[8]
親投稿
bigslope bigslope
A$=CHR$(0)*5 OK '数値の範囲は0~65535 A$[0]=CHR$(65535) OK ?ASC(A$[0]) 65535 OK '65536以上は、65536で割った余りが入る A$[1]=CHR$(65537) OK ?ASC(A$[1]) 1 OK
0そうだね
プレイ済み
返信[9]
親投稿
bigslope bigslope
・配列の途中に数値を挿入 文字の挿入は『挿入したい文字列+元の文字』の形式で出来るので、数値を文字に変換し、それに(数値を変換した)元の文字を連結したものを代入する。
0そうだね
プレイ済み
返信[10]
親投稿
bigslope bigslope
A$=CHR$(0)*5 OK A$[0]=CHR$(1) OK FOR I=0 TO LEN(A$)-1:?ASC(A$[I]):NEXT I 1 ←この場合は要素0の内容が 0  書き換えられるだけ 0 0 0 OK
0そうだね
プレイ済み
返信[11]
親投稿
bigslope bigslope
A$[0]=CHR$(2)+A$[0] OK FOR I=0 TO LEN(A$)-1:?ASC(A$[I]):NEXT I 2 ←これが挿入される 1 ←以降、1つずつずれる 0 0 0 0 OK
0そうだね
プレイ済み
返信[12]
親投稿
bigslope bigslope
・配列の途中の数値を削除 指定した要素を、空の文字("")で書き換えれば削除され、その後ろが詰められる。
0そうだね
プレイ済み
返信[13]
親投稿
bigslope bigslope
A$=CHR$(0)*5 OK A$[1]=CHR$(1) OK FOR I=0 TO LEN(A$)-1:?ASC(A$[I]):NEXT I 0 ←次はこれを削除 1 0 0 0 OK
0そうだね
プレイ済み
返信[14]
親投稿
bigslope bigslope
A$[0]="" OK FOR I=0 TO LEN(A$)-1:?ASC(A$[I]):NEXT I 1 0 0 0 OK
0そうだね
プレイ済み
返信[15]
親投稿
bigslope bigslope
・添字に関する注意点(1) CHR$を使って、要素の一番最後を書き換えようとするとエラーになるので、事実上、一番最後の要素にアクセス出来ない。 この場合、ダミー文字を最後に入れる事で、これを回避する事が出来る。
0そうだね
プレイ済み
返信[16]
親投稿
bigslope bigslope
'要素数5の配列として定義し、初期値として0をセット A$=CHR$(0)*5 OK '要素の一番最後にCHR$でセットしようとするとエラー A$[4]=CHR$(65) Subscript out of range OK '別の文字変数の値をセットしようとしてもエラー B$=CHR$(65):A$[4]=B$ Subscript out of range OK '文字列リテラルならばセットする事は可能だが、入れられる値が限られる A$[4]="A" OK
0そうだね
プレイ済み
返信[17]
親投稿
bigslope bigslope
'要素数5+ダミー文字の配列として定義し、初期値として0をセット A$=CHR$(0)*5+CHR$(0) OK '要素の一番最後でなければCHR$も使える A$[4]=CHR$(65) OK
0そうだね
プレイ済み
返信[18]
親投稿
bigslope bigslope
・添字に関する注意点(2) ダミー文字の1つ手前から文字を追加する(元の文字+挿入したい文字列)事は出来るが、ダミー文字の位置に文字を挿入する(挿入したい文字+元の文字)という形式ではエラーになる。 この為、要素の一番最後の場合と、そうでない場合で処理を分ける必要があり、プログラムが煩雑になってしまうが、ダミー文字をもう1つ追加する事でエラーを回避でき、『挿入したい文字+元の文字』で統一出来る。 配列の最大数は、文字変数なのでLEN関数で求められるが、最後の2文字はダミー扱いなので、LEN(文字変数)-1から更に2を引いた数(-3)にする。
0そうだね
プレイ済み
返信[19]
親投稿
bigslope bigslope
'要素数5+ダミー文字の配列として定義し、初期値として0をセット A$=CHR$(0)*5+CHR$(0) OK '一番最後に文字を挿入する事は出来ない A$[5]=CHR$(1)+A$[5] Subscript out of range OK 'その1つ手前から追加する事は出来るが、出来れば処理を↑で統一したい A$[4]=A$[4]+CHR$(1) OK
0そうだね
プレイ済み
返信[20]
親投稿
bigslope bigslope
'要素数5+ダミー2文字の配列として定義し、初期値として0をセット A$=CHR$(0)*5+CHR$(0)*2 OK 'これなら一番最後にも文字を挿入出来る A$[5]=CHR$(1)+A$[5] OK FOR I=0 TO LEN(A$)-3:?ASC(A$[I]):NEXT I 0 0 0 0 0   これが挿入される 1 ←(後ろにダミー2文字あるが無視) OK
0そうだね
プレイ済み
返信[21]
親投稿
bigslope bigslope
・ポインタの挙動に関する注意点 文字変数は、実態としては文字列リテラルを指し示すポインタとして扱われるので、文字変数を代入によってコピーした後で、これまでのように文字列の一部を書き換えると、コピーした文字変数にも影響が及んでしまう。 この為、文字変数をコピーする際は、そのまま代入するのではなく、配列をコピーするCOPY命令を使うこと。
0そうだね
プレイ済み
返信[22]
親投稿
bigslope bigslope
A$="12345" OK '代入によって文字列をコピー B$=A$ OK A$[2]="A" OK ?A$ 12A45 OK 'A$を書き換えると、B$にも影響が及ぶ ?B$ 12A45 OK
0そうだね
プレイ済み
返信[23]
親投稿
bigslope bigslope
'COPY命令によって文字列をコピー COPY B$,A$ OK A$[2]="B" OK ?A$ 12B45 OK 'この場合はB$に影響は及ばない ?B$ 12A45 OK 'ちなみに、この方法でも良い B$=A$+"" OK
0そうだね
プレイ済み
返信[24]
親投稿
ゆうたん yu-tan-sama
なんかおもしろそうなことやってるなぁ COPYとPOPで配列の任意の要素を削るのはすでにやってたけど 追加に関してはPUSHを使うだけだったから ここまで柔軟な使い方をする例は目からうろこ状態 気になる点があるとしたら… プチコンのバグ、文字列を扱ったときのメモリリークかなぁ
0そうだね
プレイ済み
返信[25]
親投稿
bigslope bigslope
・数値配列と文字変数の比較 数値配列の途中に数値を挿入する場合は、通常はPUSHで増やす、FOR~NEXTを使って配列を1つずつずらす、値を挿入するという手順を踏まなければならないが、文字変数を使う事により、一発で数値の挿入が出来る。 このリストでは、100万の配列の50万番目に数値を挿入しているが、数値配列では約7.5秒かかるのに対し、文字変数を使うと、たった0.15秒で完了してしまう(ノーマル3DSで計測)。 このように、配列の数が非常に多くなるような用途では、劇的な速度の向上が期待できる。
2そうだね
プレイ済み
返信[26]
親投稿
 これ、研究しよう。うまくいけばデータベース作れるかも。
0そうだね
プレイ済み
返信[27]
親投稿
べー mmmggg
プチコンの配列は2次元以上になるとLEN,PUSH,POP等が途端に使えなくなるから文字列配列を2次元として使うと利便性は高くなりそう
0そうだね
プレイ済み
返信[28]
親投稿
bigslope bigslope
文字の1つ1つを数字に変換して数値配列に格納…なんて事をやっていたんで、この文字変数の仕様を知った瞬間、「どうしてもっと早く教えてくれなかったんだよ!」って叫んでしまいました。 数値配列から文字に戻す必要も無く、そのままPRINT A$とやれば、一発で文字列を取り出せるのも強みです。 現状ではunsigned short intですが、2要素1組として扱えばlong intとして扱えますし、符号や小数点の情報を付け加えるといった応用も出来るでしょう。 複数要素の挿入や削除も簡単なので、データベースにも使えそうですね。 ただ、仕様外の使い方なので、更新で消されるんじゃないかという心配が…。
0そうだね
プレイ済み
返信[29]
親投稿
けい kei0baisoku
取りあえず仕様か否かははっきり知っておきたいところですね……… 誰か一人くらいは質問してそうな気が。
0そうだね
プレイ済み
返信[30]
親投稿
myu314 myu314
メモリも節約できるし,データ形式上手くするとINSTRで連想配列っぽいことでもできますし便利便利ですよね ただTXTで保存するとCHR$(13)がCHR$(10)に変換されてしまう仕様なので バイナリデータかつ保存する目的では使いにくいです. あとこれは次のバージョンで修正されるそうですが,A$[LEN(A$)-1]=B$ がエラーになります. 30分ほど悩まされました:)
1そうだね
プレイ済み
返信[31]
親投稿
なかなか面白そうで便利ですよね。 ただ正攻法でないのが気になるところですね。まあ僕も参照ぐらいなら問題なと思ってるんですが、書き換えとかになってくるとメモリリークとか将来的な廃止などが気になるところです…。
0そうだね
プレイ済み
返信[32]
親投稿
ASA fusuian
配列の挿入、削除が欲しいなーと思ってましたが、こんな手があったんですね! 今度使おう!
0そうだね
プレイ済み
返信[33]
親投稿
Godot orz_127
色々検証してあるし、説明も具体的な例があって解り易いです。 途中を "" で削除したり、2文字以上でも挿入できるとは… B$=A$+"" が COPY B$,A$ 代わりになるとはちょっと思いつきませんでした。 参考にさせて頂きます。
0そうだね
プレイ済み
返信[34]
親投稿
bigslope bigslope
myu314さん> 文字形式でのセーブにはそんな制約があったんですね(改行ってCHR$(13)+CHR$(10)だと思っていたんですが)。そうなると、ここだけは数値配列に入れ直してセーブするしか無いか…。 A$[LEN(A$)-1]は、要素の最後を書き換えようとしている為ですね。とりあえず、ダミー文字を置いて、要素の最後ならないようにするという対処方法をやってみましたが、修正されるのであれば、いずれ不要になりそうですね。
0そうだね
プレイ済み
返信[35]
親投稿
Godot orz_127
myu314さんのCHR$(13)がCHR$(10)になるとの情報、自分でも確認してみました。 もしかしたら他にも勝手に変更される文字とかあるのでは?と。 FOR I=0 TO &HFFFF INC A$,CHR$(I) NEXT で作った文字列をTXTでSAVEした後に読んで確認したところ13だけが10に。 他の文字は変化しませんでした。
0そうだね
プレイ済み
返信[36]
親投稿
Godot orz_127
長くなったので一旦切りましたが ここから本題。 テストで書き込んだTXTのファイルサイズが 194432バイトでした。 1文字は2バイト。 65536文字なので単純に2倍すると 131072バイトの筈。 最初の1バイトで収まる文字は1バイトとしてSAVEされるようなので2倍より少ないと予想していたのに 結構隔たりが…。 新たな謎がw とりあえずご報告。
0そうだね
プレイ済み
返信[37]
親投稿
Oskar oskar_liebig
>Gogetさん UTF-8で保存されているからです。ヘルプ・命令表のSAVE (TXT:) を参照。 &H0000 - &H007F → 1バイト &H0080 - &H07FF → 2バイト &H0800 - &HFFFF → 3バイト 計算すると、ちょうど194432バイトになります。 PRINT (&H7F-&H0+1)*1+(&H7FF-&H80+1)*2+(&HFFFF-&H800+1)*3 194432 余談: 本当のUTF-8では &HD800 - &HDFFF の一部の組み合わせ(サロゲートペア)は4バイトにする約束のようですが、3号ではたぶんそうなっていないのでしょう。
0そうだね
プレイ済み