一步步Cobol 400 上手自学入门教程03 - 数据部

时间:2021-05-29 09:28:14

数据部的作用

程序中涉及到的全部数据(输入、输出、中间)都要在此定义,对它们的属性进行说明。主要描述以下属性:

    • 数据类型(数值/字符)和存储形式(长度)
    • 数据项之间的关系(层次和层号)
    • 文件与记录的关系

数据部可以分为:

  • 文件节(file section):用来描述程序中用到的输入输出文件及记录中各数据项的属性
  • 工作单元节(working-storage section): 用来描述程序中用到的中间数据
  • 联接节(linkage section):用来描述与调用程序间发生数据传递的数据项(即参数)

数据部提供程序变量的存放位置,对不同的数据类型分成不同的节:文件数据(File Section)、静态数据(Working-Storage Section)、参数(Linkage Section)、通信(Communication Section)、报表(Report Section)。
     文件节(18~21行),每个文件描述中包含文件所含纪录的定义,文件节中的数据或从文件读取,
         或由写文件的程序产生。
     第22行表示工作存储节,这节包含程序所需的临时结果和初始化静态数据的数据。
     参数(Linkage Section)包含调用程序传递的数据(其他语言中称为参数)。
     通信(Communication Section),处理COBOL程序和通信设备之间的消息。
     报表(Report Section),报表节实现COBOL报告编写工具系统所需的数据。
     第20,21行的PIC是PICTURE的缩写,表示定义数据格式。
          X(12)表示12个字符的字符串,9(09)表示9位的整数。
     可以将基本项目组成层次结构,称为组数据项或组。
COBOL程序中的数据项的定义从层号开始,01层是最高层,49层是最低层。
     77层项目用于某个组的数据项,如程序中的临时变量。
          66层是为特殊描述符项目保留的,可以更名现有的数据项或组,或以原定义未允许的方式组合。
          88层是对特殊数据项目条件名保留的
          如:
          03 STATE PIC XX.
          88 NEW-ENGLAND VALUES ARE "1","2","3","4","5".
          IF NEW-ENGLAND ... then do something

数据部的结构图

一步步Cobol 400 上手自学入门教程03 - 数据部

文件节(file section)

程序中的每个输入、输出文件的数据格式都要在此描述,包括:

  • 文件名称和属性
  • 文件中包括的记录的名字
  • 每个记录中数据的层次关系
  • 记录中各数据项的格式和占内存的大小

文件的描述一般格式

FD 文件名(内部文件名)

01 记录名

05 数据项1 PIC 。。。。。。

05 数据项2 PIC 。。。。。。

FD语句是文件描述体,用来描述文件与记录的属性,如记录名称、格式、长度。

FD语句下所有的数据组和和数据项组成了该文件的一条记录。

记录描述:记录描述体由01层号开始,后跟记录名。用于定义记录的数据格式,即各下层的数据项的数据类型和长度。如果记录本身就是一个初等项,则在记录名后描述记录型和长度。

记录的层次图

一步步Cobol 400 上手自学入门教程03 - 数据部

数据描述项

数据层次Level-Numbers

数据层次以整数1-49表示,表明了从属关系,见上图。

另外还有特殊的数字:66、77、88

BLANK WHEN ZERO Clause

遇零置空子句(BLANK子句)
  作用:当数据项的值为零时,使它的内容改变为空白(空格)。这个子句只能用于数值型或编辑型的初等项。另外不能用于66、88层次。

JUSTIFIED Clause

对齐子句(JUSTIFIED子句)
    作用:字符或字母型数据传送的时候是按标准的对齐方式,即“左对齐”,若想改为“右对齐”,可以用JUSTIFIED子句。
    格式:JUSTIFIED/JUST  RIGHT

举例,如果是5个字符,对齐效果如下:

一步步Cobol 400 上手自学入门教程03 - 数据部

LIKE Clause

这个还没研究

待补充......

OCCURS Clause

可以把它看成一个重复表(或数组),可以有一维或多维。下面是一个3维表的例子

01 TABLE-THREE.
   05 ELEMENT-ONE OCCURS 3 TIMES.
      10 ELEMENT-TWO OCCURS 3 TIMES.
         15 ELEMENT-THREE OCCURS 2 TIMES
                 PICTURE X(8).

对应的3维表:

一步步Cobol 400 上手自学入门教程03 - 数据部

另外还有更复杂的表达式,比如排序,这个是员工考勤表(一年有52个工作周)

理解上面的三维表后,下面的表就很好理解了

一步步Cobol 400 上手自学入门教程03 - 数据部

如果做成表格,应该是

张三(员工1姓名)

000001(员工1工号)

  第几周(1)

  旷工(0)

  迟到(1)

  ------

  第几周(2)

  旷工(0)

  迟到(0)

  ------

  ......(重复52个子表)

李四(员工2姓名)

000002(员工2工号)

  第几周(1)

  旷工(0)

  迟到(1)

  ------

  第几周(2)

  旷工(0)

  迟到(0)

  ------

  ......

王五(员工100姓名)

000100(员工100工号)

  第几周(1)

  旷工(0)

  迟到(1)

  ------

  第几周(2)

  旷工(0)

  迟到(0)

PICTURE Clause

定义基本项目的具体长度,格式,数据类型。可以简写成PIC.

格式字符串最多30个字符,可以包含下列字符:
    A  字母A-Z,a-z,空格
    B  插入空格
    P  标量字符,代表字段中不显示的小数点位置
    S  代数符号,实际显示取决于项目的USAGE
    V  小数点位置
    X  任何字符
    Z  抑制前头的0并转换成空字符
    0  插入0
    9  数字0~9
    /  插入/
    ,  插入,(逗号不能作为字符串的最后一位,最后时逗号是分隔符)
    .  插入.
    *  抑制前头的0并转换成*
    +  正值插入+,负值插入-
    -  正值插入空格,负值插入-
    $  插入美元号
    CR 正值插入两个空格,负值插入CR
    DB 正值插入两个空格,负值插入DB
例子:
    03 VAR PIC AAAAA.    VAR变量长度为5个字符,不能有数字,等价于03 STATE PIC A(5)。
    输入ASDFG ,显示ASDFG
    03 VAR PIC XXXXX.   VAR变量长度为5个任意字符。等价于03 FILLER PIC X(5)。
    输入123AS , 显示123AS
    03 VAR PIC 99/XXX/9999 长度11,输入05may2004,显示05/may/2004
    03 VAR PIC 0ABXXX/9999 长度11,输入05may2004,显示05 may/2004
    03 VAR PIC 9(3) 长度3,0~999之间。
    03 VAR PIC 9(4)V99 长度6,0.00~9999.99之间。
    03 VAR PIC S9(5)V99 长度7,-99999.99~99999.99之间。
    03 VAR PIC 9(6)PPP 长度6,可以是1000,2000,...,999999000。输入1234,显示1000。
    03 VAR PIC PPP999 长度3,0.000001~0.000999之间。输入123,显示0.000123。
    03 VAR PIC ZZZ.99,输入100.50,显示100.50;输入-51.50,显示51.50;
    输入0,显示.00.
    03 VAR PIC $ZZZ.ZZ-,输入100.50,显示$100.50;输入-51.50,显示$51.50-;
    输入0,显示
    03 VAR PIC $***,***.99CR,输入1000,显示$**1000.00;输入-1000,显示$**1000.00CR;
    输入0,显示$***,***.00;输入51.5,显示$***,*51.50
    03 VAR PIC $$$,$$$.99,输入100.50,显示$100.50;输入-100.50,显示$100.50;
    输入0.777,显示$.77;输入0,显示$.00
    03 VAR PIC $.$$$,输入1.00,显示$.00;输入0.65,显示$.65;
    输入0,显示$.00;
    03 VAR PIC $--,输入17.7,显示$17;输入-17.7,显示$-17;
            输入-5,显示$-5
    03 VAR PIC $999.99+,输入100.50,显示$100.50+;输入-100.50,显示$100.50-;
    03 VAR PIC 9(3)B9(3),输入55,显示000 055;输入1000.78,显示001 000;
    03 FILLER PIC X(44),补上44个空位。

REDEFINES Clause

重新定义数据区的名称和数据结构的形式.

RENAMES Clause

将原来已定义的数据项重新组合成为一个新项,并以一个新名字来代表它.

层号只能用66,它必须紧跟在01层记录中最后一个数据描述体之后,因为它是对记录中有关部分重新组合和命名的.

例子:

一步步Cobol 400 上手自学入门教程03 - 数据部

SIGN Clause

符号字句(SIGN子句)
SIGN子句用来指定数值型数据描述体中运算符号的状态和位置
(一)在没有SIGN子句时,数值的符号是存放在数据项最近最后一个字节
如+012的显示型数据,内存中为 F0  F1  C2
(二)用SIGN子句可以指定符号在数值的前部还是后部
  02 A PIC S9(3) USAGE DISPLAY SIGN IS LEADING.
       C0 F1 F2
 02 A PIC S9(3) USAGE DISPLAY SIGN IS TRAILING.
       F0 F1 C2
02 A PIC S9(3) USAGE DISPLAY
二者相同,缺省符号在后
(三)指定符号单多占一个字节,用SEPARATE
   02 A PIC S9(3) USAGE IS DISPLAY SIGN IS  
                     TRAILING  SEPARATE.(+12)
只能用于PIC字符串中含有“S”的数值型描述体中
使用SIGN子句的数据项用法应当是USAGE DIPLAY。而不能用于计算型的数据项

SYNCHRONIZED Clause

同步安置子句(SYNCHRONIZED子句)
    作用:一个机器字一般定为4个字节,从内存中取数据的时候是以机器字为单位的,而数据存放则是按字节连续
    存放的,这里面就存在一个边界对齐的矛盾,会影响目标程序运行时间。用同步安置子句可以指定数据项在内存
    中如何按自然边界来安置。
    格式:SYNCHRONIZED/SYNC  LEFT/RIGHT
    说明:1.用SYNC  LEFT时,左对齐,右边补零或空格。
            2.用SYNC  RIGHT时,右对齐,左边补零或空格

USAGE Clause

这个还没研究

待补充......

VALUE Clause

VALUE字句:用于给变量赋初值
 02      A        PIC       9(3)     VALUE   123.
注意:
(1)只有对工作单元节中的数据项才能赋初值,不能对文件节中输入输出文件中的数据项赋初值。
(2)如果在组合项的描述体中使用VALUE,初值只能是表意常量或非数值型常量。对组合项整体而
言,一律按字符型数据项处理。
       02   A  VALUE  ‘123456’.
         03   A1  PIC  99.                        (12)
         03   A2  PIC  99.                        (34)
         03   A3  PIC  99.                         (56)
       是可以的,并且A1,A2,A3可以进行运算。
       但如果 02   A  VALUE  123456.   则是错误的。
(3)当用一个带符号的数值作初值时,相应的PIC子句中应有‘S’描述符,否则符号无效。
   77  D  PIC  S99  VALUE  -21.

(4)赋初值时应该注意类型的一致性。
   77  D  PIC  X(4)  VALUE  1.22     (错误)

(5)VALUE子句给出的值应适合PIC子句的描述范围,否则会出现截断或产生错误。

2.数值型数据在内存中的存储形式:
 (1)外部十进制(扩张十进制) 按每个数值位表示数值
   77  C  PIC  9(3)  VALUE  486.
  其在内存中占3个字节。则在主机系统内存中的实际内容如下
   11110100  11111000   11110110
     ‘4’       ‘8’        ‘6’
   如果数据项D描述如下(负值)
    77  D  PIC  S9(3)  VALUE -486.
   11110100   11111000   11010110
  主机系统用‘C’(1100)和‘F’(1111)表示正数,‘D’(1101)表示负数

(2)外部浮点数形式:
   77 A PIC +9.99999E+99.
          数符  数值部分  E  阶码符  阶码
   对外部浮点数不能用VALUE子句赋初值,而应该从外部读入或者在程序中用MOVE语句传值

(3)内部十进制
 前四位不起辨识作用,可以只用四位来表示。即每个字放2个十进制数。符号也占半个字。
 所谓内部十进制就是压缩式的外部十进制
 
 (4)定点二进制
 简单的说就是不是一个一一对应的关系,而是把整数直接存储为二进制数。例如
 10存储为1010
 
 (5)内部浮点形式
 短浮点:
     4个字节(32位)表示一个数,阶码(指数)为8位,尾数为24位。
  长浮点:
     8个字节(64位)表示一个数,阶码(指数)为8位,尾数为56位。

数据描述与存储形式的关系
(一)字母型、字符型、编辑型、外部十进制数据和外部浮点形式表示
的数据用标准数据形式存放,即一个字符占一个字节。
(二)数值型数据可以由程序员任意选定存放形式。
(三)数据在计算机内进行运算,都是化成二进制以后再进行运算。

补充:数组(表格操作)

下面是数组的例子:
          01 RECORD-X.
            03 MONTH OCCURS 12 TIMES.
              05 NAME PIC X(12).
              05 DAYS OCCURS 31 TIEMS.
                07 COMMENT PIC X(20).
                07 TEMP-HI PIC S999.
                07 TEMP-LO PIC S999.
          77 CURRENT-DAY PIC 99.
          调用表示如下:
          MONTH(5) : 包含NAME 和 DAYS表格的组项目。
          NAME OF MONTH(5) :基本字母数字项目,长度为12个字符。
          NAME(5) (1:3) 上述第5个项目的前3个字符。
          TEMP-HI(1,31) 基本数字项目,长度为3个字符。前一个参数是在MONTH数组中的位置,后一个参数是在DAYS数组中的位置。相当于MONTH[1].DAYS[31].TEMP-HI。
          COMMENT OF RECORD-X(5,CURRENT-DAY)(11) 基本字母数字项目第五个月的CURRENT-DAY的COMMENT字段的最后10个字符。

03 TEXT PIC XXX OCCURS 1 TO 12 TIMES DEPENDING ON IX.
    定义一个变长的数组。定义的长度是12,实际以IX为准,若IX为10,则TEXT的长度就是30。

索引
  索引名INDEX
    索引名可以用作PERFORM语句的变量,用于SET和SEARCH语句和用作下标。
    03 TEXT PIC XXX OCCURS 7 TIMES INDEXED BY index
      05 A PIC XXX
      05 B PIC XXX
    PERFORM VARYING index FROM 1 BY 1 UNTIL index >7
      DISPLAY A(index),B(index)
    END-PERFORM.
    注意和不用索引名的比较:
    77 index PIC 99
    03 TEXT PIC XXX OCCURS 7 TIMES
      05 A PIC XXX
      05 B PIC XXX
    PERFORM VARYING index FROM 1 BY 1 UNTIL index >7
      DISPLAY A(index),B(index)
    END-PERFORM.

关键字KEY
    关键字有ASCENDING(升序,由低到高)和DESCENDING(降序,由高到低)。
      03 TEXT PIC XXX OCCURS 7 TIMES ASCENDING KEY IS A,B.
      05 A PIC XXX.
      05 B PIC XXX.
    TEXT中的元素按A升序排序,A相同的元素按B升序排序。
    关键字的作用是定义SEARCH语句带ALL短语时表格的排序。

表格初始化,可以一个一个数据项单独初始化,也可以一起初始化。
      03 TEXT PIC XXX OCCURS 7 TIMES VALUES SPACE.
      05 A PIC XXX.
      05 B PIC XXX.                          一起初始化为空格。
      03 TEXT PIC XXX OCCURS 7 TIMES.
      05 A PIC XXX VALUES SPACE.
      05 B PIC XXX VALUES SPACE.            单独初始化。

SET
    保存或恢复索引值。SET A TO B.
    将索引递增或递减一个整数值。SET A UP/DOWN BY N.

SEARCH
    SEARCH A [VARYING B] AT END C {WHEN CONDITION D}...END-SEARCH
    A为带INDEXED BY 短语的表格。每一步都轮流求值CONDITION ,为真时执行D,SEARCH语句终止。    为假时,索引值递增,至最大索引时执行AT END C,SEARCH语句终止。
    若一开始索引值即为最大,则不执行WHEN语句,直接执行AT END 语句。
    VARYING 指定索引B,省略为A中制定的索引。
    下面的例子查找月份表中下一个具有31天的月份。
    01 MONTH-DATA.
      03 MONTH-INFO.
        05 PIC X(10) VALUES "JANUARY".
        05 PIC X(3) VALUES "JAN".
        05 PIC 99 VALUES 31.
        05 PIC X(10) VALUES "FEBRUARY".
        05 PIC X(3) VALUES "FEB".
        05 PIC 99 VALUES 28.
        ...(省略代码)
      03 MONTH REDEFINES MONTH-INFO OCCURS 12 TIMES INDEXED BY MONTH-INDEX.
        05 NAME   PIC X(10).
        05 ABBREV PIC X(3).
        05 DAYS   PIC 99.
    77 CURRENT-MONTH PIC 99.
    77 NEXT-31-DAY-MONTH PIC 99.

SET MONTH-INDEX TO CURRENT-MONTH.
    SET MONTH-INDEX UP BY 1.
    SEARCH MONTH
        AT END MOVE 1 TO MONTH-INDEX
            SEARCH MONTH
                AT END MOVE 0 TO NEXT-31-DAY-MONTH
                WHEN DAYS(MONTH-INDEX) = 31
                    SET NEXT-31-DAY-MONTH TO MONTH-INDEX
            END-SEARCH
        WHEN DAYS(MONTH-INDEX) = 31
            SET NEXT-31-DAY-MONTH TO MONTH-INDEX
    END-SEARCH
    要查找多维表格,要将SEARCH放到PERFORM中。
    01 TABLE-DATA.
      03 DIM-1 OCCURS 10 TIMES INDEXED BY X1.
        05 DIM-2 OCCURS 20 TIMES INDEXED BY X2.
          07 NAME PIC X(20).
          07 STATE PIC XX.
          ...
    PERFORM VARYING X1 FROM 1 BY 1 UNTIL X1 > 20
        SET X2 TO 1
        SEARCH DIM-2
            WHEN STATE(X1,X2) = "AL" ....
            WNEH STATE(X1,X2) = "AZ" ....
        END SEARCH
    END-PERFORM.
    还有一种SEARCH是对有关键字的表格进行查找,和上面的查找差不多,主要是WHEN 条件中要用关键字作为查找条件。比如说关键字为A,则必须有WHEN A = .....