3号プログラミング覚え書き(3) 文字列編
・特定の文字を取りたい時は、MID$だけでなく、A$[0]のような記法でも使える
仕様上は規定されていないため、非推奨の技法。
文字を更新する時は使えない。
・文字列が入った変数から別の変数へ代入しても、新たにメモリは確保されない
例えば文字列リテラルを変数に代入すると、変数には文字列リテラルの位置への参照が格納される。したがって、さらにその変数から別の変数への代入をおこなっても、文字列のために使うメモリは増えない。
Cなどと同様に以下の手順で文字列のメモリが確保されると思われる。
まず、ソース中の文字リテラルがメモリに確保される。
それを変数に代入すると、文字リテラルの位置への参照が、変数に格納される。
・1文字でも文字を変えると別の文字列としてメモリ上に確保される。
実質上は同じ文字列であっても、なんらかの操作をすると、別の文字列とみなされる。(同一の文字列であるかどうかのチェックはなされていない模様)
ローカルスコープの変数は、自作関数/命令の中から別の自作関数/命令を呼び出すとスタックに保存されるため、
「長大な文字列を引数として受け取り、一部変更して再帰呼び出しする」
というような処理をすると、すぐに「Stack overflow」エラーになってしまう。
上記のような処理を64Kバイトの文字列に対して行うと、概ね60回程度で「Stack overflow」エラーとなる。(このことからスタックのサイズは概ね4Mバイト程度と考えられる)
・文字列の処理は全般に遅い
文字列の処理は全般に遅く、特に新たな文字列が生成されるような処理はできるだけ少なくするべき。
・ASC関数は先頭の文字に効く
ASC関数は先頭の文字を変換するので、ASC(LEFT$(S$,1))のようなことをせず、ASC(S$)の方が簡潔かつ速い。
・ASC関数に空文字列("")を渡すとIlleagal function callエラーになる。
文字列変数を操作している時にASCのところでエラーになる場合はケースが多い。
文字列変数の中身が1文字以上であることが保証されいない時は、ASCを実行する前に必ず空文字列("")かどうかのチェックをしておく。
・更新時に、文字列変数A$に対してA$[0]="X"のような書き方ができるかは調査中
最初の項目のとおり、文字列変数A$に対してA$[0]で0文字目を参照することができる。
読み取り時は問題ないが、更新時に A$[0]="X" のようにすることは、以前のバージョン(Ver3.0当時)では問題があった。
現在のバージョン(Ver3.2)で問題がないかどうかは調査中。
ちなみに、この書き方は、 A$=SUBST$(A$,0,1,"X") と等価ではない。
A$[0]="X" は、A$が指すメモリをそのまま書き換えてしまうからだ。