【COBOL 読み3-10-2】INDEXとSETを完全理解への道〜係長興奮!

🧩今日の学び
INDEXは値ではなく「位置情報」であり、MOVEではなくSETで操作する存在である
SEARCH文が正しく動くかどうかは、DATA DIVISION側のINDEX設計でほぼ決まる
・COBOLは「動く処理」よりも「動かない宣言」を読めるようになると一気に楽になる

係長)…よし、ではINDEXSETいくぞ。

なるお)お願いしまーす!

係)まずは、前回のコードはこれだ。

01  ITEM-TABLE.
    05 ITEM-REC OCCURS 5 TIMES
        INDEXED BY IDX.
        10 ITEM-ID     PIC X(3).
        10 ITEM-NAME   PIC X(10).
01  TARGET-ID  PIC X(3) VALUE "003".
SET IDX TO 1
SEARCH ITEM-REC
    AT END
        DISPLAY "見つかりません"
    WHEN ITEM-ID(IDX) = TARGET-ID
        DISPLAY "見つけた: " ITEM-NAME(IDX)
END-SEARCH

係)まずはINDEXって何者かってことからだがSETINDEXはセットで覚えろ。単体で理解しようとするな。

05 ITEM-REC OCCURS 5 TIMES
   INDEXED BY IDX.

このIDXだが、数値変数じゃないぞ。

な)え、でもSET IDX TO 1とか書くじゃないすか。

係)そこが一番の罠なんだよ。

INDEXの正体:数値ではなく「場所」を指す存在

係)INDEXはな

  • 配列の位置を指すための内部ポインタ
  • 人間が触るための数値じゃない
  • コンパイラが管理する“場所指定子”

ということだ。

そのため、PICもないし、VALUEもない。

WORKING-STORAGEの数値とは別物だ。

な)ほえ?

だったら、なんで「1」とか入れちゃってるんです?

係)ここでSETの出番となる。

SET IDX TO 1

いいか、これは、IDX に「数値1」を入れてるんじゃないぞ。

な)…。

係)正確には、IDX を「テーブルの1番目を指す状態に設定している」だ。

な)ふむふむ…

なぜMOVEできないのか:SETが必要になる理由

係)では、もしこう書いたらどうなると思う?

MOVE 1 TO IDX

な)…入りそうですけど、入らないんすよね?

係)コンパイルエラーだな。

  • MOVE:数値を代入する命令
  • IDX:数値じゃない

そして、

INDEXED BY IDX.

この部分でINDEXを使うと宣言しているわけだから、そもそも型が違うということになるぞ。

つまり違いはこうだ。

やりたいこと正しい命令
数値を入れるMOVE / ADD
INDEXの位置を変えるSET

そしてSETは左が目的地」の意味がここで効くんだ。

これ、以前やったな。

           SET CT-IX TO 1
           PERFORM UNTIL CT-IX > 50
              IF CT-COUNTRY(CT-IX) = F-COUNTRY-A(1:2)
                 ADD 1            TO CT-COUNT(CT-IX)
                 ADD N-LINE-GROSS TO CT-SUM-GROSS(CT-IX)
                 EXIT PERFORM
              ELSE
                 IF CT-COUNTRY(CT-IX) = SPACES
                    MOVE F-COUNTRY-A(1:2) TO CT-COUNTRY(CT-IX)
                    ADD 1            TO CT-COUNT(CT-IX)
                    ADD N-LINE-GROSS TO CT-SUM-GROSS(CT-IX)
                    EXIT PERFORM
                 END-IF
              END-IF
              SET CT-IX UP BY 1
           END-PERFORM.

な)あ、覚えてますよ!

係長が嘘言ったやつですよね!
左から右にって言ってたのに、右から左になったやつ!

参考:【COBOL 読み1-19】MOVEやSETの違い~水に釘の人生

係)お!覚えてたか、って嘘なんか言ってねーだろ!

SETは英語で読む命令:数値操作ではない

係)これは英語で読むと、Set CT-IX to 1. となって、CT-IXを「1番目」に設定しろとなる。

SET「状態を変える命令」だから

  • 対象(IDX)
  • TO
  • 値(位置)

の順になる。

MOVEと文の形が違う理由が、ここで来る。

つまり、INDEX操作は英語的でないと破綻するというわけだ。

そして、UP BY / DOWN BYも数値加算じゃないぞ。

これも重要だ。

SET CT-IX UP BY 1

な)これ、CT-IX = CT-IX + 1ってことじゃないんすか?

UP BYは加算ではない:走査という考え方

係)見た目はそう見えるな。

でも実態は、「次の要素を指せ」という 位置移動命令 だ。

  • ADD → 数値計算
  • SET UP BYインデックス移動

意味が違う。

な)なんでCOBOLはこんな面倒なことするんすか?

係)理由は単純だ。

  • INDEX
    • 実メモリアドレスに近い
    • 処理系依存
  • 数値として触らせると
    • 移植できなくなる
    • 最適化できなくなる

だから、INDEXは人間に計算させない設計なんだ。

な)なんかよくわからないすけど…

係)深くは知らなくてもいいが、人間は信用されてないってことだ。

さて、以前のコードをINDEX視点で見たとき、こう読め。

SET CT-IX TO 1
PERFORM UNTIL CT-IX > 50
   ...
   SET CT-IX UP BY 1
END-PERFORM

CT-IXを先頭に置く」
「今指している要素を処理する」
「次の要素へ移動する」

数値ループじゃない。

走査命令の連なりだ。

な)だからPERFORM VARYINGじゃなくて、SETなんすか。

書き方自体が変わっちゃうと…。むーん…でもINDEXの宣言をちゃんと見ていれば、わかるって話でもありますよね。

係)そういうことだな。

最後にまとめるぞ。

  • INDEX数値じゃない
  • INDEX位置
  • INDEXを動かせるのは SETだけ
  • SET
    • 対象 → TO → 値
    • 英語として読む
  • MOVE/ADDの感覚を持ち込むと必ず転ぶ

おむすび

係)よし、ここまで来たら、もう一段深く行けるな!

次はINDEXSUBSCRIPT(添字)の違いだぞ!

ここでCOBOL理解が「分かった気」から「使える」に変わるぞ!

な)いやさっきまでSEARCHって言ってなかったすか…?

係)そんなのどうでもいい!次いくぞ!

な)えぇ!?

係長のワンポイント

INDEXは「数」じゃない、配列の中の場所そのものだ。
だからMOVEADDで触らせないし、SETしか許されていない。
SET UP BYは加算ではなく、次の要素へ進めという命令だ。
この一連は計算じゃなく、「走査」を書いていると思え。
INDEXを数値だと思った瞬間、COBOLは牙をむく。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

コメント

コメントする