CLPのポインタ機能を学習するとポインタの概念が
より具体的でわかりやすく学習することができる。
ここでは実際の具体例に基づいてポインタの使い方について学習してみよう。
[フォントの指定: SETFONT ]
フォント指定 (SETFONT) 選択項目を入力して,実行キーを押してください。 フォント : 種類 . . . . . . . . . . . . > ' MSゴシック ' サイズ . . . . . . . . . . . > 12 4-36, *CALC 終り F3= 終了 F4=プロンプト F5= 最新表示 F12= 取り消し F13= この画面の使用法 F24= キーの続き
[解説]
フォントを指定するテスト用のコマンドである。
[ CMD : SETFONT ]
ソースはこちらから
0001.00 CMD PROMPT(' フォント指定 ') 0002.00 PARM KWD(FONT) TYPE(FONT) SNGVAL((*CONVERT)) + 0003.00 CHOICE(*NONE) + 0004.00 PROMPT(' フォント ') 0005.00 FONT: ELEM TYPE(*CHAR) LEN(14) RSTD(*YES) DFT(*DEFAULT) + 0006.00 VALUES(' MSゴシック ' ' MS明朝 ' + 0007.00 ' HGゴシック ' ' HG明朝 ' *DEFAULT) + 0008.00 EXPR(*YES) PROMPT(' 種類 ') 0009.00 ELEM TYPE(*DEC) LEN(2) DFT(*CALC) RANGE(4 36) + 0010.00 SPCVAL((*CALC 0)) PROMPT(' サイズ ')
[コンパイル]
CRTCMD CMD(MYLIB/SETFONT) PGM(MYLIB/SETFONTCL) SRCFILE(MTSRCLIB/QCMDSRC) AUT(*ALL)
[解説]
フォント・パラメータ(FONT)は14バイトのフォント名 + 2バイトのサイズから成り立っている複合の
パラメータである。
[ CLP : SETFONTCL ]
ソースはこちらから
0001.00 PGM PARM(&FONTINFO) 0002.00 /*-------------------------------------------------------------------*/ 0003.00 /* SETFONTCL : フォントの指定 */ 0004.00 /*-------------------------------------------------------------------*/ 0005.00 DCL VAR(&FONTINFO) TYPE(*CHAR) LEN(18) 0006.00 DCL VAR(&PRMSU) TYPE(*CHAR) LEN(2) /* 2 進数 */ 0007.00 DCL VAR(&FONT) TYPE(*CHAR) LEN(14) 0008.00 DCL VAR(&FLD2) TYPE(*CHAR) LEN(2) 0009.00 DCL VAR(&SIZE_P) TYPE(*PTR) ADDRESS(&FLD2 0) 0010.00 DCL VAR(&SIZE) TYPE(*DEC) STG(*BASED) LEN(2 0) + 0011.00 BASPTR(&SIZE_P) 0012.00 DCL VAR(&SIZEC) TYPE(*CHAR) LEN(2) 0013.00 0014.00 /*( FONTINFO パラメータの取得 )*/ 0015.00 CHGVAR VAR(&PRMSU) VALUE(%SST(&FONTINFO 1 2)) 0016.00 IF COND(%BIN(&PRMSU) *EQ 1) THEN(DO) 0017.00 CHGVAR VAR(&FONT) VALUE(%SST(&FONTINFO 3 14)) 0018.00 ENDDO 0019.00 ELSE CMD(DO) 0020.00 CHGVAR VAR(&FONT) VALUE(%SST(&FONTINFO 3 14)) 0021.00 CHGVAR VAR(&FLD2) VALUE(%SST(&FONTINFO 17 2)) 0022.00 CHGVAR VAR(&SIZEC) VALUE(&SIZE) 0023.00 ENDDO 0024.00 0025.00 SNDPGMMSG MSG('FONT=' *CAT &FONT *CAT ' SIZE=' *CAT + 0026.00 &SIZEC) MSGTYPE(*DIAG) 0027.00 ENDPGM
[コンパイル]
CRTCLPGM PGM(MYLIB/SETFONTCL) SRCFILE(MYSRCLIB/QCLSRC) OPTION(*SRCDBG) AUT(*ALL)
[解説]
フォント・パラメータ: &FONTINFO は
+---------------------------------------------------------+ | パラメータ数 | フォント名 | 長さ | | 2バイト | 14バイト | 2バイト | +---------------------------------------------------------+
として構成させている合計の苦さが 18バイトの変数である。
バラメータ数は
0015.00 CHGVAR VAR(&PRMSU) VALUE(%SST(&FONTINFO 1 2))
によって先頭からの2バイトを読取ればよいが
長さは
0020.00 CHGVAR VAR(&FONT) VALUE(%SST(&FONTINFO 3 14)) 0021.00 CHGVAR VAR(&FLD2) VALUE(%SST(&FONTINFO 17 2))
によって17バイト目から2バイトを読み取って &FLD2に代入する。
ところで &FLD2 は
0008.00 DCL VAR(&FLD2) TYPE(*CHAR) LEN(2) 0009.00 DCL VAR(&SIZE_P) TYPE(*PTR) ADDRESS(&FLD2 0) 0010.00 DCL VAR(&SIZE) TYPE(*DEC) STG(*BASED) LEN(2 0) + 0011.00 BASPTR(&SIZE_P)
として定義されていて &FLD2の先頭をポインタ &SIZE_Pとして定義しており
&SIZE はこのポインタ &SIZE_P を基底としている2バイトのPACK型式の数字として
定義されている。
従って &FLD2 に X’0012F’ の値があれば &SIZE は PACKの12となる。
CHGVAR &SIZE VALUE(%SST(&FONT 17 2))
と直接PACK10進数には代入することはできないので
いったん2バイトの文字として取り出してその2バイトを基底にする
PACK10進数を取り出すといった作業になるのである。
つまりポインタ&SIZE_Pは &FLD2のポインタであると同時に
&SIZE_P のポインタでもあるのである。
このようにポインタはフィールドの場所を示すだけなので
文字列のポインタとして定義していてひけを数字のポインタとして
利用することができるのである。
ここがポインタという柔軟な処理の特徴である。
またポインタはただ場所を示すだけなので長さはいくらでもよいのだ。
長さが不変である変数であってもポインタなら定義することができる。
ところで聡明な読者は気づいたかもしれないが &FLD2 として取り出さなくても
直接に &FONTINFO にポインタを指定してもよい。
ただし受け取りパラメータにポインタを指定することは禁じられているようなので
別の同じ長さのフィールド &FLDINFOCなどに移してからそこで
ポインタを指定してもよい。
次のCLPはそのように変更した例である。
[ CLP : SETFONT2CL ]
ソースはこちらから
0001.00 PGM PARM(&FONTINFO) 0002.00 /*-------------------------------------------------------------------*/ 0003.00 /* SETFONT2CL : フォントの指定 */ 0004.00 /*-------------------------------------------------------------------*/ 0005.00 DCL VAR(&FONTINFO) TYPE(*CHAR) LEN(18) 0006.00 DCL VAR(&FONTINFOC) TYPE(*CHAR) LEN(18) 0007.00 DCL VAR(&PRMSU) TYPE(*CHAR) LEN(2) /* 2 進数 */ 0008.00 DCL VAR(&FONT) TYPE(*CHAR) LEN(14) 0009.00 DCL VAR(&SIZE_P) TYPE(*PTR) ADDRESS(&FONTINFOC 16) 0010.00 DCL VAR(&SIZE) TYPE(*DEC) STG(*BASED) LEN(2 0) + 0011.00 BASPTR(&SIZE_P) 0012.00 DCL VAR(&SIZEC) TYPE(*CHAR) LEN(2) 0013.00 0014.00 /*( FONTINFO パラメータの取得 )*/ 0015.00 CHGVAR VAR(&PRMSU) VALUE(%SST(&FONTINFO 1 2)) 0016.00 IF COND(%BIN(&PRMSU) *EQ 1) THEN(DO) 0017.00 CHGVAR VAR(&FONT) VALUE(%SST(&FONTINFO 3 14)) 0018.00 ENDDO 0019.00 ELSE CMD(DO) 0020.00 CHGVAR VAR(&FONTINFOC) VALUE(&FONTINFO) 0021.00 CHGVAR VAR(&FONT) VALUE(%SST(&FONTINFO 3 14)) 0022.00 CHGVAR VAR(&SIZEC) VALUE(&SIZE) 0023.00 ENDDO 0024.00 0025.00 SNDMMSG MSG('FONT=' *CAT &FONT *CAT ' SIZE=' *CAT + 0026.00 &SIZEC) MSGTYPE(*DIAG) 0027.00 ENDPGM
[コンパイル]
CRTCLPGM PGM(MYLIB/SETFONT2CL) SRCFILE(MYSRCLIB/QCLSRC) OPTION(*SRCDBG) AUT(*ALL)
[解説]
0009.00 DCL VAR(&SIZE_P) TYPE(*PTR) ADDRESS(&FONTINFOC 16)
の部分が変更箇所である。
見てきたようにポインタの使い方とはまとめると
2つの使い方があるのでそれを意識して欲しい。
(1)ある変数に対してポインタを定義する
0009.00 DCL VAR(&SIZE_P) TYPE(*PTR) ADDRESS(&FONTINFOC 16)
(2)ポインタからポインタを基底とする新たな変数を定義する。(具体化)
0010.00 DCL VAR(&SIZE) TYPE(*DEC) STG(*BASED) LEN(2 0) + 0011.00 BASPTR(&SIZE_P)
この2つの使い方が理解できればほぼポインタの使い方が理解できたと言っていい。
ポインタとは変数の開始位置を示す変数である。
ポインタに限らず日常で使っているコンピュータ用語の定義を
明確に言えてこそその用語を初めて理解しているということができるのである。
これはすべてにおいても言えることでもある。
CLPで学習するポインタ。理解して頂ければ幸いである。
もうポインタなんて怖くはないはずだ。