RPG

231. RPGプログラマーのためのポインター講座 (2)

先の章でポインターとはフィールドの開始位置として捉えればよい、ということまでは理解されたと思う。
またポインター自身も 16バイトの変数であることも学習した。

次に具体的にポインターを扱う方法を紹介する。
まず、ポインターのタイプの型であるが、つまり英字フィールドであれば A で
ゾーン10進数であれば S で表すところ、ポインターは * で表す。

【例】 ポインターの定義
	D DSPRCD          S             10A 
	D DSPRCDA         S             11A 
	D DSPRCD_P        S               * 
	D NULL            S              1A   INZ(X'00')
【解説】

この D-仕様書での定義ではレコード名が保存される DSPRCD という名前のフィールドに対して
11 桁の DSPRCDA という名前のフィールドを定義している。
さらにタイプを * で定義されている DSPRCD_P がポインターである。
まず最初の使い方として

	C     DSPRCD        CAT       NULL:0        DSPRCDA    
	C                   EVAL      DSPRCD_P = %ADDR(DSPRCDA)

のように演算する。
DSPRCDA が 11桁として定義されていたのは

	C     DSPRCD        CAT       NULL:0        DSPRCDA

のようにして DSPRCDNULL (ヌル値 X'00') とを結合して DSPRCDA を作るためである。
そうやって DSPRCD の値の最後に NULL を付加した DSPRCDA に対して、初めて

	C                   EVAL      DSPRCD_P = %ADDR(DSPRCDA)

のようにして %ADDR によってポインター DSPRCD_P を算出している。

このように文字列の最後に NULL を付加したものを指すポインターを定義することは、
C言語では一般的でよく使う。
このことを NULL-STOP と呼ぶ。
変数の型としてポインターを扱うとポインターは、先にも解説したように変数の開始位置であるので
開始位置だけでは、その変数はどの位置まで定義されているのか把握することができない。
このため終わりの位置を示すために NULL を付加して終わりを示すのである。

文字列+NULL を示す型は C言語では

	CHAR*

と表現される。( * とはポインターの意味 )
この CHAR* (または char*) は非常に頻繁に使用される型であり i5/OS の API でも char* として
定義されている変数は、ごく普通に見られるので NULL を付加してからポインターを定義する、と
いう方法を良く覚えていて欲しい。

さてこのように NULL-STOP によって変数の長さがわかるように定義するのが char* であるなら
char* は動的な長さを定義するのにもってこいであるし、任意の長さの文字変数を定義できるのでは
ないかと思われた方もいると思うが、まさしくそのとおりである。
char* を受け取る側の API は任意の長さの変数を受け取って処理することができる。
API は汎用的に使用されることを目的としているために char* を受け取りパラメータの変数に
していることが多いのである。
従って RPG 側でもポインターを定義する必要性がある。

NULL-STOP をつけないでポインターだけを API に渡すと API は NULL が見つかるまで
その変数の長さがあるものと誤解して、莫大な長さと解釈してしまう。
場合によってはメモリ・エラーを引き起こしてしまうので必ず NULL-STOP をつけるように注意されたい。

本章で学んだのは

  • ポインターは * として型を定義する
  • %ADDR を使うとポインターを定義することができる
  • ポインターは NULL-STOP を付加してからポインターを定義する