導入
前のレッスンのCALLは、呼び出すだけでデータのやり取りをしていませんでした。実務では「金額を渡して、税込み金額を計算して返してほしい」のように、サブプログラムに引数を渡し、結果を受け取りたいのが普通です。この仕組みが USING 句と LINKAGE SECTION です。
説明
呼び出し側は CALL ... USING ... で、渡したい変数を指定します。
IDENTIFICATION DIVISION.
PROGRAM-ID. MAIN-PROGRAM.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-PRICE PIC 9(6)V99 VALUE 1000.
01 WS-TAX-INCLUDED PIC 9(6)V99.
PROCEDURE DIVISION.
CALL "CALC-TAX" USING WS-PRICE, WS-TAX-INCLUDED.
DISPLAY "税込み価格: " WS-TAX-INCLUDED.
STOP RUN.
呼び出される側は、受け取る引数を LINKAGE SECTION という専用のセクションに宣言し、PROCEDURE DIVISION USING ... でその対応関係を明示します。
IDENTIFICATION DIVISION.
PROGRAM-ID. CALC-TAX.
DATA DIVISION.
LINKAGE SECTION.
01 LS-PRICE PIC 9(6)V99.
01 LS-TAX-INCLUDED PIC 9(6)V99.
PROCEDURE DIVISION USING LS-PRICE, LS-TAX-INCLUDED.
COMPUTE LS-TAX-INCLUDED = LS-PRICE * 1.10.
GOBACK.
LINKAGE SECTION.… WORKING-STORAGE SECTIONとは違い、このプログラム自身のメモリ領域を確保しません。呼び出し元が渡してきた変数のメモリ領域をそのまま指し示す(参照する)だけの、特別なセクションです。PROCEDURE DIVISION USING LS-PRICE, LS-TAX-INCLUDED.… CALL側のUSING WS-PRICE, WS-TAX-INCLUDEDと、個数と並び順が対応します。1番目同士(WS-PRICE⇔LS-PRICE)、2番目同士(WS-TAX-INCLUDED⇔LS-TAX-INCLUDED)が結び付きます。LS-TAX-INCLUDEDにサブプログラム側で計算結果を書き込むと、それは呼び出し元のWS-TAX-INCLUDEDに直接反映されます(LINKAGE SECTIONは呼び出し元と同じ領域を指しているため)。
実行すると次のようになります。
税込み価格: 1100.00
このように、COBOLのサブプログラムの引数はメモリ領域そのものを共有する方式(多くの言語での「参照渡し」に近い)です。値をコピーして渡すのではなく、「同じ領域を指す名前を2つ用意する」というイメージで捉えると理解しやすいでしょう。
引数を受け取らないシンプルなサブプログラム(前のレッスンの CALC-TAX の最初の版)では、LINKAGE SECTION も USING も不要でした。データのやり取りが必要になったときに、この仕組みを使う——という位置づけです。
試すには
「2つの数値を受け取り、その合計を3つ目の引数に返す」サブプログラムを、LINKAGE SECTION と PROCEDURE DIVISION USING を使って書いてみましょう。呼び出し側の CALL ... USING に渡す変数の順番と、サブプログラム側の LINKAGE SECTION の並びが一致しているか、確認してみてください。