你如何在 Cobol 中定义一个二维 MxN 数组,其中 M 和 N 都是可变长度的?
这是我在尝试将变量数组包含在另一个数组中时在 Net Express 中收到的消息:
COBCH0144S OCCURS DEPENDING subsidiary to OCCURS only allowed with ODOSLIDE
你如何在 Cobol 中定义一个二维 MxN 数组,其中 M 和 N 都是可变长度的?
这是我在尝试将变量数组包含在另一个数组中时在 Net Express 中收到的消息:
COBCH0144S OCCURS DEPENDING subsidiary to OCCURS only allowed with ODOSLIDE
您要定义的是“复杂发生取决于”结构(复杂 ODO)。
您可以定义一个复杂的 ODO,其中表是矩形的,如下所示:
01 TABLE-REC.
05 M PIC S9(4) BINARY.
05 N PIC S9(4) BINARY.
05 ROWS OCCURS 10 TIMES DEPENDING ON M.
10 COLUMNS OCCURS 10 TIMES DEPENDING ON N.
20 CELL PIC X(1).
诀窍是 N 的声明不能出现在表的变量部分中。例如,以下声明:
01 TABLE-REC.
05 M PIC S9(4) BINARY.
05 ROWS OCCURS 1 TO 10 TIMES DEPENDING ON M.
10 N PIC S9(4) BINARY
10 COLUMNS OCCURS 1 TO 10 TIMES DEPENDING ON N.
20 CELL PIC X(1).
会给你一个错误,因为声明暗示每一行可能包含不同数量的列(即不是矩形表)。
通常,对于 COBOL 中的 ODO 结构真正“购买”你的东西,存在很多困惑。有一个常见但错误的观点是,它可能被用来节省内存,因为数据结构的大小可以动态调整大小。当 ODO 在 LOCAL 或 WORKING STORAGE 下声明时,这绝对是错误的。COBOL 编译器将分配足够的内存来容纳 M 和 N 的最大值。
它“买”给你的是一种在内存中物理组织数据的机制。查看以下程序及其显示的内容:
IDENTIFICATION DIVISION.
PROGRAM-ID. EXODO.
DATA DIVISION.
WORKING-STORAGE SECTION.
77 I PIC S9(4) BINARY.
77 J PIC S9(4) BINARY.
01 DIMENSIONS.
05 M PIC S9(4) BINARY VALUE 6.
05 N PIC S9(4) BINARY VALUE 7.
01 TABLE-REC-1.
05 ROWS OCCURS 1 TO 10 TIMES DEPENDING ON M.
10 COLUMNS OCCURS 1 TO 10 TIMES DEPENDING ON N.
20 CELL PIC X(1).
01 TABLE-REC-2.
05 ROWS OCCURS 10 TIMES.
10 COLUMNS OCCURS 10 TIMES.
20 CELL PIC X(1).
PROCEDURE DIVISION.
PERFORM VARYING I FROM 1 BY 1 UNTIL I > M
PERFORM VARYING J FROM 1 BY 1 UNTIL J > N
MOVE 'X' TO CELL OF TABLE-REC-1 (I J)
MOVE 'X' TO CELL OF TABLE-REC-2 (I J)
END-PERFORM
END-PERFORM
DISPLAY TABLE-REC-1
DISPLAY TABLE-REC-2
GOBACK
.
显示:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXX XXXXXXX XXXXXXX XXXXXXX XXXXXXX XXXXXXX
请注意,ODO 版本将所有数据很好地组合到 6 X 7 矩阵中,而固定表版本保留了 10 X 10 矩阵,其中有一堆“洞”,以将每一行填充到其最大数量的OCCURS
. 有时这种区别很重要(但大多数情况下并不重要)。
我看到您正在使用我不熟悉的 Net Express,因此您可能不得不摆弄下一部分才能工作。使用 IBM Enterprise COBOL for Z/OS,您可以执行以下操作:
在程序中定义一个 ODO,LINKAGE SECTION
这样就不会分配内存,它只是一个记录布局。然后,您可以为所需的表的实际大小动态分配足够的内存(即 M 乘以 N 个元素)。使用以下方式连接两者:(SET ADDRESS OF ODO-DATA-STRUCTURE TO mem-address
在 CICS 下使用 GETMAIN,在批处理下使用 CEEGSTT 获取内存)。现在您有了一个动态数据结构,它确实使用了最少的空间,并且由于上面说明的布局属性,仍然可以正确索引。
在 COBOL 中还有其他使用(或不使用)ODO 的方法,但这些是我所知道的最常见的方法。
您可以通过定义OCCURS来定义多维可变长度数组。取决于您希望去的每个维度级别。