CL

149. CLPでポインタを学習する(2)

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で学習するポインタ。理解して頂ければ幸いである。
もうポインタなんて怖くはないはずだ。