COBOL简易教程
主要内容 1.COBOL语言的基本概念及程序的结构 • 一个例子
COBOL程序的结构
COBOL源程序的书写格式 2.COBOL数据表示 • 常量
• 层次的概念 • PICTURE语句
• 数据在内存中的各种形式 3.算术运算
变量赋值 (MOVE, MOVE CORR)
算术运算(ADD, SUB, MUL, DIV, COMPUTE 内部函数 4.字符串处理
合并、分离、取子串、替换等 5.程序逻辑控制 • 条件的分类 • IF、EVALUATE PERFORM 6.表处理
定义、赋值、引用、查询 7.读、写多格式记录文件 8.常用语句小结 9.子程序
1/49
等) 1.关于COBOL的初步知识
COBOL是Common Business Oriented Language (通用商业语言,或称管理语言)的缩写 最适用于数据处理
比较接近于自然语言(英语) COBOL的结构严谨,层次性强 COBOL的缺点是比较烦琐。
2/49
1.1 一个例子:
****************************************************************
* * * COBOL TRAINING PROGRAM * * VERSION 2.1.0 COPYRIGHT (C) 2004 * * WISTRON DALIAN SOFTWARE CO., LTD. * * ALL RIGHTS RESERVED. * * * **************************************************************** IDENTIFICATION DIVISION. PROGRAM-ID. EXERCIS6.
AUTHOR. QXLU (WISTRON DALIAN). DATE-WRITTEN. 04-06-23. DATE-COMPILED. 04-06-23.
*----------------------------------------------------------------* * COMMENT : * * * *----------------------------------------------------------------* ENVIRONMENT DIVISION. CONFIGURATION SECTION. SOURCE-COMPUTER. IBM-3084. OBJECT-COMPUTER. IBM-3084. INPUT-OUTPUT SECTION. FILE-CONTROL.
SELECT DDI01 ASSIGN TO \"DDI01\". SELECT DDO01 ASSIGN TO \"DDO01\". *
DATA DIVISION. FILE SECTION. *
FD DDI01 LABEL RECORD IS STANDARD DATA RECORD ARE IN-AREA0, IN-AREA1. 01 IN-AREA0.
05 IN-YEAR-NUM PIC 9(2). 05 IN-PRINCIPAL PIC 9(4)V99. 05 FILLER PIC X(07).
05 RMARK PIC X(01) VALUE X\"0A\". 01 IN-AREA1.
05 IN-INTEREST-RATE OCCURS 5 TIMES PIC V999.
05 RMARK PIC X(01) VALUE X\"0A\". FD DDO01 BLOCK 0 RECORDS LABEL RECORD STANDARD RECORDING F. 01 PRT-REC.
05 FILLER PIC X(79). *
*===============================================================* WORKING-STORAGE SECTION. 01 IN-FILE-DATA.
05 YEAR-NUM PIC 9(2).
3/49
05 PRINCIPAL PIC 9(4)V99. 05 INTEREST-RATE-TABLE.
15 INTEREST-RATE OCCURS 5 TIMES PIC V999. *
01 HEADER0 PIC X(79) VALUE
' TABLE OF SIMPLE INTEREST'. 01 HEADER1 PIC X(79) VALUE
' ************************************'. 01 HEADER2 PIC X(79) VALUE
' PRINCIPAL 4,000.00 FOR 10 PERIODS'. 01 HEADER3 PIC X(79) VALUE SPACE. 01 HEADER4 PIC X(79) VALUE ' PERIOD INTEREST RATE'. 01 HEADER5.
05 OUT-I-R OCCURS 5 TIMES PIC BBBBBBBBB.999. 01 DETAIL0.
05 OUT-PERIOD PIC ZZZ. 05 OUT-P-I-S-ITEM OCCURS 5 TIMES.
10 FOURSPACES PIC X(04) VALUE SPACE. 10 OUT-P-I-SUM PIC 9,999.99. 01 CNT-YEAR-NUM PIC 9(2). 01 I-R-INDEX PIC 9.
01 P-I-SUM PIC 9(6)V99. *
***************************************************************** * P R O C E D U R E D I V I S I O N * ***************************************************************** PROCEDURE DIVISION. *
INPUT-DATA SECTION. OPEN INPUT DDI01. OPEN OUTPUT DDO01. READ DDI01.
MOVE IN-YEAR-NUM TO YEAR-NUM. MOVE IN-PRINCIPAL TO PRINCIPAL. READ DDI01.
MOVE IN-AREA1 TO INTEREST-RATE-TABLE. *
PROCESS-OUTPUT-DATA SECTION. *PRINT HEADER
WRITE PRT-REC FROM HEADER0 BEFORE 1. WRITE PRT-REC FROM HEADER1 BEFORE 1. WRITE PRT-REC FROM HEADER2 BEFORE 1. WRITE PRT-REC FROM HEADER3 BEFORE 1. WRITE PRT-REC FROM HEADER4 BEFORE 1. * PRINT INTEREST RATE
PERFORM TEST BEFORE VARYING I-R-INDEX
FROM 1 BY 1 UNTIL I-R-INDEX > 5 MOVE INTEREST-RATE( I-R-INDEX ) TO OUT-I-R( I-R-INDEX ) END-PERFORM.
WRITE PRT-REC FROM HEADER5 BEFORE 1.
4/49
*PROCESS & PRINT DETAILS PERFORM PRINT-DETAIL
VARYING CNT-YEAR-NUM FROM 1 BY 1 UNTIL CNT-YEAR-NUM > YEAR-NUM. *
CLOSE-FILES SECTION. CLOSE DDI01. CLOSE DDO01. *
STOP RUN. *
*---------------------------------------------------------------* * PRINT-DETAIL * *---------------------------------------------------------------* PRINT-DETAIL SECTION. *
MOVE CNT-YEAR-NUM TO OUT-PERIOD. PERFORM PROCESS-DETAIL
VARYING I-R-INDEX FROM 1 BY 1 UNTIL I-R-INDEX > 5. WRITE PRT-REC FROM DETAIL0 BEFORE 1. *
PRINT-DETAIL-RTN. EXIT. *
*---------------------------------------------------------------* * PROCESS-DETAIL * *---------------------------------------------------------------* PROCESS-DETAIL SECTION. *
COMPUTE P-I-SUM = PRINCIPAL *
( INTEREST-RATE( I-R-INDEX ) * CNT-YEAR-NUM + 1 ). MOVE P-I-SUM TO OUT-P-I-SUM( I-R-INDEX ). *
PROCESS-DETAIL-RTN. EXIT. *
* *** END OF CODING EXERCIS6 ***
1.2 COBOL 程序的结构 (1/p4) 部(Division) 一部可包括若干节
节(Section) 一节可包含若干段
段(Paragraph) 一段可包含若干句子
句子(Sentence) 一个句子可包含若干语句
语句(Statement) 制定计算机完成一定的操作
5/49
子句(Clause) 制定完成某一方面的功能
每个程序应包含四个部
IDENTIFICATION DIVISION (标识部)
主要用来指定源程序名字,也可以写入其他用作备忘的某些信息(如日期、作者等)。
ENVIROMENT DIVISION(环境部)
主要用于指出程序中用到的数据文件名与计算机系统的设备的对应关系,即把某一文件名与一个外部设备联系起来。
DATA DIVISION(数据部〕
程序中所用到的全部数据(包括输入输出的数据和中间数据)都应在数据部中说明它们的类型和所占内存情况。
PROCEDURE DIVISION(过程部〕
用来给出程序要执行的指令,使计算机产生相应的操作,例如进行数学运算。
6/49
1.3 COBOL源程序的书写格式 ( 1/p6) 1 6 7 8 11 * DAT 2000 S 12 72 73 80 A CALCULATION -CALCULATION-SECTION. MOVE ‘2000A’ TO WS-CURR-POS. ADD A TO B. DISPLAY A, B. 1-6 标号区 7 注释区(*) 8~11 A区
部头,节头,段头,层号01,层号77以及文件描述符FD应从A区开写。
12-72 B区,正文 过程部的句子只能从B区开始写,而不能写到A区去。 73-80 注释区 (和C程序一样,编译时注释被舍弃)
1.4 一个最简单的COBOL源程序
IDENTIFICATION DIVISION. PROGRAM-ID. HLLWRLD.
AUTHOR. QXLU (WISTRON DALIAN). DATE-WRITTEN. 04-06-21. DATE-COMPILED. 04-06-21. *
ENVIRONMENT DIVISION. *
DATA DIVISION. *
PROCEDURE DIVISION. DISPLAY 'HELLO WORLD!'. STOP RUN.
2.COBOL数据表示
2.0 常量 (1/p13) • ZERO,ZEROS,ZEROES 表示一个或多个零字符(16进制‘F0’) • SPACE,SPACES 表示一个或多个空格字符(16进制‘40’)
• HIGH-VALUE,HIGH-VALUES 表示一个或多个字符具有最高值(16进制‘FF’, 2进制‘11’)
• LOW-VALUE,LOW-VALUES 表示一个或多个字符具有最小值(16进制‘00’,2进制‘00’)
• QUOTE,QUOTES 表示一个或多个引号字符(16进制‘7F’)
7/49
(MOVE QUOTE TO A)
ALL 常量表示一个或多个该常量组成的字符串 A PIC X(4) A内容 MOVE ALL ‘*’ TO A **** MOVE ALL ‘AB’ TO A ABAB MOVE ALL ‘ABC’ TO A ABCA
2.1 层次的概念 (1p16) 01 WORK-STORAGE.
05 WS-SYS-DATE PIC 9(6).
05 FILLER REDEFINES WS-SYS-DATE.
10 WS-SYS-YY PIC 9(2). 10 WS-SYS-MM PIC 9(2).
10 WS-SYS-DD PIC 9(2). 05 WS-SYS-TIME PIC X(6).
05 FILLER REDEFINES WS-SYS-TIME. 10 WS-SYS-HH PIC 9(2). 10 WS-SYS-MN PIC 9(2).
结构:记录组合项初等项
层次规定如下:从01开始,到49, 外层的层号小,里层的层号大。
66层一般用于重命名
77层一般用于定义无层次的变量 88层一般用于定义条件名
组合项类似于C语言中的结构变量
2.2 PIC子句 ( 1/p83) (1)“9”描述符。
01 X PIC 9999.
01 Y PIC 9(5).
描述 数值 在内存中表示 01 X PIC 9999 1234 1234 01 Y PIC 9(5) 467 00467 01 Z PIC 99 86 86 01 T PIC 9(6) 11011 011011 若 MOVE 1.25 TO Z, Z中的内容为 01,小数点后的舍弃 若 MOVE -1.25 TO Z, Z中的内容为 01,小数点后的舍弃,
负号也舍弃
8/49
(2)“V”描述符。
01 M PIC 999V99.
说明:
1. V隐含小数点的位置,占5个字节,
MOVE 215.63 TO M -> M=215.63 MOVE 1215.637 TO M -> M= 215.63 传送时按小数点对齐,向两边延伸 2. 只能出现一个V
3. 按隐含的小数点位置对准进行运算 A PIC 9(3)V9. A=10.1 B PIC 9(2)V9(2). B=2.02 C PIC 9(2)V9(2). COMPUTE C = A + B => C=12.12 4. 显示时,不显示小数点(用编辑型显示小数点) 描述 数值 在内存中表示 01 A PIC 99V99 7.5 0750 (显示易是0750) 01 T PIC 999V99 498.5 49850 01 W PIC 9(3)V9(2) 781 78100 01 N PIC 9(4) 1245.6 1245 01 H PIC V999 1.234 234
(3)“P”描述符。
1. 01 A PIC 9PPPPPPPPP.
用9999999999来描述,占10个字节。为了节省内存,低位上有若干个0的数,可以用“P”来描述。A在内存中只占1个字节,表示1x109,也可以写成:
01 A PIC 9P(9). 2. 01 A PIC PPPP99.
表示0.000099
3. 描述 内存中数字 等价的算术量 01 AMOUNT PIC 9(4)PPPP 1802 18020000 01 WAP PIC 9(3)P(3) 015 15000 01 WAT PIC P(3)9(2) 11 0.00011 01 WAN PIC PP99 87 0.0087 01 WAN2 PIC VPP99 87 0.0087 P 描述符在COBOL程序中不常用
9/49
(4)“S”描述符。
01 A PIC S99. (S不计数据项长度,表示符号,只能在9最前面)
描述 01 B PIC S9(4)V9(2) 01 C PIC S9(4)V9(2) 01 D PIC S9(4)V99 01 E PIC S9(4)V99 (5)字母型数据的描述”A”
01 T PIC AAAA. 01 T PIC A(4).
MOVE “ABCD” TO T A
要存放包含字母和空格的其他字符,可以用
数值 126.89 -1112.34 -0.2 -727.18 内存中的表示 012689 111234 000020 072718 T B C D X描述
(6)字符型数据的描述”X”
01 A PIC X(2). 描述 送入的数据 内存中的情况 01 R1 PIC X(4) BOOK BOOK 01 R2 PIC X(8) SIN(X) SIN(X)_ _ 01 R3 PIC X(7) COBOL-74 COBOL-7 01 R4 PIC X(12) DATA-NAME DATA-NAME _ _ _
(7)编辑型数据的描述
编辑型数据项仅仅是为了输出的需要,不能用来运算
a. 插入小数点 “.”,用“.”描述符
77 T PIC 99V99 77 N PIC 99.99
若T的原值为12. 56, MOVE T TO N
10/49
T 1 2 5 ^
77 T PIC 999V99 77 N PIC 9.9
若T的原值为112. 56, MOVE T TO N T N 1 2 5 6 2 . ^ 6
1 2 N . 5 6 1 5 b. 插入小数点 “,”, 用“,”描述符
77 A PIC 9(6)V9(2).
77 B PIC 9(3),9(3).9(2).
若A的原值为123456.78, MOVE A TO B A B 1 2 3 4 5 6 7 8 1 2 3 , 4 5 6 . 7 8 ^
c.插入“0”,用“0”描述符
77 R PIC 999
77 T PIC 9990000 (或9(3)0000,或9(3)0(4))
当R的值为678时, MOVE R TO T R T 6 7 8 6 7 8 0 0
d.插入空格用 ”B” 描述符
0 0
77 A PIC 9(3). 77 B PIC B9(3)B.
当A的值为812,MOVE A TO B.
11/49
A 8
e.插入正负号,用”+”或”-”描述符
1 2 B _ 8 1 2 _ 描述符 数值为正 数值为负 + 加”+”号 加”-”号 - 空一格 加”-”号 在如下情况下, MOVE B1 TO B2 B2的描述及结果 B1值 +9999 -9999 9999+ +1268 +1268 _1268 1268+ -1268 -1268 -1268 1268- 0(按+0处理〕 +0000 _0000 0000+
f. 插入”$”
说明 一律加符号 只对负值加负号 9999- 1268_ 1268- 0000 _
77 A PIC 9(3)V99 77 B PIC $999.99
当A的值为186.78,MOVE A TO B A
1 8 6 7 8 $ 1 ^
g.浮动插入正负号和$
8 B 6 . 7 8
浮动插入$,MOVE A TO B 的情况 A的描述 A数值 B的描述 PIC 9(3)V99 21.89 PIC $$99.99 PIC 9(3)V99 12.62 PIC $(3)9.99 PIC 9(3)V99 0.15 PIC $$$9.99 PIC 9(3)V99 0.15 PIC $$$$.$$ PIC 9(3)V99 0.0 PIC $$$$.$$ B内容 _$21.89 _$12.62 _ _$0.15 _ _ _$.15 _ _ _ _._ _ 12/49
PIC 9(3)V99 0.05 PIC $$$$.$$
浮动插入正负号,01 A PIC S9(2)V9(2).
MOVE A TO B.的情况 A数值 B的描述 B内容 -1.3 PIC +++9.9 _ _-1. 3 -1.03 PIC ++++.++ _ _-1.03 0.0 PIC ++++.++ _ _ _ _ _ _ _ -21.86 PIC - -99.99 _-21.86 10.44 PIC - -99.99 _ _ 10. 44 10.44 PIC ++++.++ +10.44 h.取消高位0,用“Z”和“*”描述符
MOVE A TO B A的值 58 85 0.012 0.0 0.0 0.01 1812.43 0.0 2.6 652.32 0.01 2.58 2.58 2.58 2.58 _ _ _$.05 B的描述 PIC Z99 PIC ZZZ.99 PIC ZZZ.ZZZ PIC ZZZ.ZZ PIC $Z(3).ZZ PIC Z(4).ZZ PIC Z,ZZZ,ZZZ.ZZ PIC ***.** PIC **.* PIC *,***.** PIC *(4).** PIC +Z(3).99 PIC -*(3).99 PIC $Z(3).99 PIC $*(3).99 B的内容 _58 _85.00 _ _ _.012 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _.01 _ _ _ _1,812.43 ***.** *2.6 **652.32 ****.01 +_ _2.58 _**2.58 $_ _2.58 $**2.58 i.插入:”DB”和”CR”字符
DB -> 银行业务的借方(Debit) CR -> 银行业务的贷方(Credit)
13/49
Example: MOVE A TO B. A的值 B的描述 512.12 $9(3).99DB -512.12 $9(3).99DB 138.57 $999.99CR -138.57 $999.99CR 只当结果为负时才出现DB或CR
B的内容 $512.12_ _ $512.12DB $138.57_ _ $138.57CR 2.3 数据在内存中的各种形式 (2/p2) 1.单位
bit : 位,二进制的0或1 Byte: 字节,8个二进位 半字: 2个字节,16个二进位
Word: 4个字节,32个二进位 双字: 8个字节,64个二进位
2.数值型数据的存放形式:
(1)外部十进制(扩张十进制)
十进制数字 EBCDIC码 ASCII码 0 1111 0000 0011 0000 1 1111 0001 0011 0001 2 1111 0010 0011 0010 3 1111 0011 0011 0011 4 1111 0100 0011 0100 5 1111 0101 0011 0101 6 1111 0110 0011 0110 7 1111 0111 0011 0111 8 1111 1000 0011 1000 9 1111 1001 0011 1001 + 1111 1100 0011 1100 - 1111 1101 0011 1101 无符号 1111 1111 0011 1111
77 C PIC 9(3) VALUE 486. C 11110100 11111000 11110110 4 8 6
14/49
77 C PIC S9(3) VALUE –486. C 11110100 11111000 11010110 4 8 -6
最后字节前四位,有符号时 “C”(1100) 表示数为正,”D”(1101)表示数为负。
(2)外部浮点数形式:
+1.23876E+59,
77 A PIC +9.99999E+99, 共占12个字节 77 A PIC +9V99999E+99, 共占11个字节
(3)内部十进制(缩合十进制)
(a)-14932在内存中为:0001 0100 1001 0011 0010 1101(3Bytes) 十六进制为:14932D
(b)+43856在内存中为:0100 0011 1000 0101 0110 1100(3Bytes) 十六进制为:43856C
(c)无符号数:3856,在内存中为: 0000 0011 1000 0101 0110 1111(3Bytes,前半个字节补0)
十六进制为:03856F
字节数都为:ROUND((n+1)/2) ROUND表示四舍五入, n表示数字的个数
(4)定点二进制:
不是一个数字对应一个字节或半个字节,而是先把十进制数转化为二进制数。
十进制的10表示如下: 0 0 0 0 0 0 0 0 0 0 0 0 1 0 1 0
根据数据的长度决定所占内存字节 在PIC子句中描述字符9的个数 占内存字节
1~4 2
5~9 4 10~18 8
(5)内部浮点制:
15/49
以内部的指数形式(二进制的指数形式)表示一个数。 短浮点:
4个字节(32位)表示一个数,阶码(指数)为8位,尾数为24位。 长浮点:
8个字节(64位)表示一个数,阶码(指数)为8位,尾数为56位。
数值范围都为:
5.4 * 10 ** (- 79) ~ 7.2 * 10 ** 75
3.PIC的USAGE子句,数值型数据的存放形式的使用:(2/p7)
1. USAGE子句一般格式为:
[USAGE IS] {DISPLAY, COMPUTATIONAL, COMP} USAGE IS DISPLAY 是“显示型用法”,适用于显示、打印。 COMPUTATIONAL(COMP)是“计算型的用法” DISPLAY 标准数据形式,一个字节放一个字符
COMPUTATIONAL
定点二进制形式
COMP
COMPUTATIONAL-1
内部短浮点形式 COMP-1
COMPUTATIONAL-2
内部长浮点形式
COMP-2
COMPUTATIONAL-3 内部十进制形式 COMP-3
2. 01 A PIC 9(4) COMP-3. 或:
01 A PIC 9(4) COMP.
16/49
用DISPLAY显示的结果仍同原样。
3. 01 B PIC 9(6) USAGE IS DISPLAY. 01 B PIC 9(6) DISPLAY. 01 B PIC 9(6).
如不写DISPLAY,则表示隐含。
01 T1 COMP.
03 X PIC S9(3). 03 Y PIC S9(3).
组合项的全部初等项为COMP.
4.符号子句(SIGN子句)
[SIGN IS]{LEADING,TRAILING} [SEPARATE CHARACTER]
02 A PIC 9(3) USAGE DISPLAY
A为012 F0 F1 F2
01 A PIC S9(3) USAGE DISPLAY SIGN IS LEADING.
表示符号在第一个字节的前四位表示。
A为-012 D0 F1 F2
01 A PIC S9(3) USAGE DISPLAY SIGN IS TRAILING(尾部) . 表示符号在最后字节中表示。
A为+012 F0 F1 C2 Sign 语句省略时,相当于 SIGN IS TRAILING(尾部) .
符号单独占一个字节,用SEPARATE
03 A PIC S9(3) USAGE DISPLAY SIGN IS TRAILING SEPARATE
A为+012 F0 F1 F2 4E “+”在EBCDIC码中为4E
01 A PIC S9(3) SIGN IS LEADING SEPARATE
A为-012
17/49
60 F0 F1 F2 “--”在EBCDIC码中为60
5. 重定义子句(REDEFINES子句)(类似于C语言中的联合)
1. 01 A PIC X(5).
01 B REDEFINES A PIC 9(5).
2. 01 A. 03 A1 PIC 9(4).
03 A2 PIC X(6). 03 A3 PIC X(4).
01 B REDEFINES A.
03 B1 PIC X(5). 03 B2 PIC 9(6). 03 B3 PIC 99V9.
A1 A2 A3 B1 B2 B3
层号 数据名1 REDEFINES 数据名2
说明:(a)层号必须相同 (b)必须相邻
(c)可以多次重定义,但必须紧跟出现
(d)不能用于文件节01层,可用于工作单元节01层 (e)不可改变长度
(f)应放在其他子句之前
03 A REDEFINES T PIC X(6) JUST RIGHT . (g)REDEFINES子句不能使用VALUE语句
01 W REDEFINES T PIC X(4) VALUE ‘ABCD’.是错的
6.重命名子句(RENAMES子句)
用REDEFINES子句可以在不改变数据项长度的前提下,重新定义数据 区的名称和数据结构的形式(包括重新定义初等项的类型及长度〕。 用RENAMES子句可以把原来已定义的某些数据项重新组合成一个新项,并以一个新名字来代表它。但用重命名子句不能改变各初等项的长度等属性。
18/49
01 A. 02 B… 03 G… 03 H…
02 C.
03 I… 03 J… 02 D… 02 E… 02 F…
66 K RENAMES G THRU I. 66 M RENAMES B THRU C. 66 N RENAMES E. B G H I C A J D E F
66 数据名1 RENAMES 数据2 [THRU 数据名3] 说明:
(a)层号只能用66,它必须紧跟在01层记录中最后一个数据描述体之后。 (b)数据名2,数据名3可为初等项或组合项,但不能是同一个数据名。
(c)数据名2在记录中的位置在数据名3之前,且数据名3不能包含在数据名2之中。
(d)RENAMES 子句只能用于工作单元节中,不能用于文件节中。
7.遇空置零语句(BLANK子句)
1. 03 A PIC $(5).99 BLANK WHEN ZERO. 当MOVE 0 TO A时,A变为空格
8. 对齐子句(JUSTIFIED子句)
{JUSTIFIED, JUST} RIGHT
77 A PIC X(5).
77 B PIC X(5) JUSTIFIED RIGHT.
MOVE ‘SIN’ TO A, B.
19/49
S I A N
B S I N A
MOVE ‘ABCDEFG’ TO A, B A B C D E
C D B E F G 9. 同步安置语句(SYNCHRONIZED子句)
1紧凑存储节省空间,但在许多定字长的计算机中,一个机器字
(Word)往往指定为四个字节,两个机器字之间为“自然边界”,为了提高效率,从内存读取数据时,通常一次将一个机器字一起取出来。
{SYNCHRONIZED,SYNC} [LEFT,RIGHT]
01 A.
05 A1 PIC 9(3) VALUE 82. 05 A2 PIC X(3) VALUE ‘ABC’. 05 A3 PIC 9 VALUE 7. 05 A4 PIC X(2) VALUE ‘XY’. 05 A5 PIC 9(2) VALUE 12.
A1 A2 A3 A4 A5 0 8 2 A B C 7 X Y 1 2
01 A.
05 A1 PIC 9(3) SYNC LEFT VALUE 82. 05 A2 PIC X(3) SYNC RIGHT VALUE ‘ABC’. 05 A3 PIC 9 SYNC LEFT VALUE 7. 05 A4 PIC X(2) VALUE ‘XY’. 05 A5 PIC 9(2) VALUE 12. 0 8 2 0 _ A B C 9 0 0 0 X Y 1 2 A1 A2 A3 A4 A5 数字补0,字符补空格
10. 多格式数据记录——记录区的重叠(类似于C语言中的联合) FD CARDFILE LABEL RECORD IS STANDARD
20/49
DATA RECORDS ARE CARD-A, CARD-B. 01 CARD-A.
01 RECORD-CODE PIC X. (记录代码,为A, 为CARD-A) 01 FILLER PIC XX.
01 PART-NUMBER PIC 9(5). 01 FILLER XX.
01 QUANTITY PIC 9(6). 01 FILLER PIC XX. 01 PRICE PIC 99V99. 01 FILLER PIC X(58). 01 CARD-B.
01 FILLER PIC X. (记录代码,为A, 为CARD-A) 01 FILLER PIC XX.
01 CUSTOMER-NAME PIC 9(20). 01 FILLER XX.
01 CUSTOMER-NUMBER PIC 9(6). 01 FILLER PIC XX. 01 PART-NUM PIC 9(6). ……..
11.COPY语句(类似于C语言中的宏) (2/ P22)
可以把COBOL程序常用的的数据、程序段 描述共享,而不必每次都重新做。
1. *01 A.
05 A1 PIC 9(4). 05 A2 PIC 9(6)V99. 05 A3 PIC X(10). 05 A4 PIC X(8).
将其文件命名为LIB1, 则: 01 B. COPY LIB1. 编译结果=>01 B.
05 A1 PIC 9(4). …….
2.REPLACING取代原名: 01 B. COPY LIB1
REPLACING A1 BY B1 A2 BY B2 A3 BY B3 A4 BY B4. 一般格式:
COPY 库名 (REPLACING {{标识符1,常量1,字1}BY{标识符1,常量1,字1}}…)
21/49
3.算术运算 (1 /P48) (P 117)
3.1变量赋值(MOVE) (1).同类型数据间的传送规则:
数值型数据之间的传送:传送时按小数点对齐,向两边延伸,如发送项长于接收项,则多余位截去;如短于接收项,接收项的空位补零。
发送项 接收项 0 1 2 3 4 0 0 1 2 3 4 1 2 3 4 5 1 2 3 4 5 2 5 1 3 7 5 1 3 7 2 5 1 3 5 1 3 ^ ^
字符型数据之间的传送:按左端对齐,如发送项长于接收项, 右端多余位截去;如短于接收项,接收项的空位补空格。 发送项 接收项 C H I N A C H I N A C H I N A C H I N C H I N A C H I N A (2).编辑传送
发送项是数值型数据,而接收项是编辑数据型数据,则先将发送项中数据按接收项的描述要求进行编辑,然后再传送。 77 A PIC 9(4)V99 77 B PIC $(6).99 MOVE A TO B 是正确的 MOVE B TO A 是正确的
(3). 组合项的传送(类似于字符型数据之间的传送)
组合项的传送是将发送项的内容不加转换地一个字节一个字节地顺序传送到接收项。
若发送项与接收项长度不同,则:左对齐,右补空格,多余位截去。
结构和描述都相同时 01 A.
05 A1 PIC X(3). 05 A2 PIC 9(4)V99. 05 A3 PIC A(4).
22/49
01 B.
05 05 05
MOVE B1 B2 B3 A
PIC PIC PIC TO
X(3). 9(4)V99 A(4). B.
A B A1 A2 A3 B1 B2 B3 A B C 8 7 5 3 1 2 D E F G A B C 8 7 5 3 1 2 D E F G 如果发送项和接收项长度相同,但结构形式不同,则将发送项的内容原样不变地自左向右传送到接收项 MOVE A TO B. A B A1 A2 A3 A4 A5 B1 B2 B3 B22 B21 8 6 7 T I 3 4 2 Z H A N G C - D 8 6 7 T I 3 4 2 Z H A N G C - D 如果传送时,发送项与接收项长度不同,按:左对齐,右补空格,多余位截去
(4). 对应传送 1)数据名受限和受限名的传送(类似于C语言中结构变量成员的访问)
01 SUM. 01 TOTAL. 04 A1 PIC X(2). 04 A1 PIC X(4). 04 A2 PIC X(3). 04 A3 PIC 9(5). 04 A3 PIC 9(4). 04 B2 PIC 99V99.
MOVE A1 OF SUM TO T1. MOVE A1 OF TOTAL TO T2.
01 SUM. 01 TOTAL. 03 A. 03 A.
04 A1 PIC X(2). 04 A1 PIC X(4). 04 A2 PIC X(3). 04 A3 PIC 9(5). 04 A3 PIC 9(4). 04 A2 PIC 99V99.
MOVE A1 OF A OF SUM TO T1. MOVE A1 OF A OF TOTAL TO T2.
23/49
2)用CORRESPONDING子句的传送----对应传送 (同名传送) (2/P123) MOVE {CORRESPONDING, CORR} 标识符1 TO 标识符2
只传同名的项,对于RENAMES, REDEFINES, OCCURS的数据项不予传送。 01 PAY-RECORD. 01 EDITTED-RECORD.
04 A1 PIC 9(4)V99. 04 B3 PIC ZZZZ.99. 04 A2 PIC 9(4)V99. 04 A2 PIC ZZZ9.99. 04 A3 PIC 9(3)V99. 04 A1 PIC ZZZ9.99. MOVE CORR PAY-RECORD TO EDITTED-RECORD. 相当于: MOVE A1 OF PAY-RECORD TO A1 OF EDITED-RECORD. MOVE A2 OF PAY-RECORD TO A2 OF EDITED-RECORD. 01 A. 01 B. 05 A1 PIC X(3) VALUE ‘111’. 05 A2 PIC X(4) 05 A2 PIC X(4) VALUE ‘2222’. 05 A1 PIC X(3). MOVE A TO B. 与 MOVE CORR A TO B. 不同
3.2 算术运算(ADD, SUB, MUL, DIV, COMPUTE) (1 /P37)
1.ADD
ADD A, B TO C, D. (用C语言可描述为C += (A + B),D += (A + B)) A+B+C=>C, A+B+D=>D
ADD A, B, C GIVING D, E, F.(用C语言可描述为D = E = F = A + B + C) A+B+C=>D, A+B+C=>E, A+B+C=>F 语句 A X Y Z 原10 原15 原25 原30 ADD X TO Y. 10 15 40 30 ADD A, X TO Y. 10 15 50 30 ADD 5, Y GIVING Z. 10 15 25 30 ADD A, Z GIVING X, Y. 10 40 40 30 ADD A, 5, X TO Z. 10 15 25 60 ADD A, X TO Y, Z. 10 15 50 55 ADD 10, 50 TO A. 70 15 25 30 ADD A, Z, Y TO X. 10 80 25 30 2.SUBTRACT
SUBTRACT A, B FROM C. (用C语言可描述为C -= (A + B)) C-A-B=>C
24/49
SUBTRACT A, B FROM C, D.(用C语言可描述为C -= (A + B),D -= (A + B)) C-A-B=>C D-A-B=>D
SUBTRACT A, B, C FROM Z GIVING D, E, F. (用C语言可描述为D = E = F = Z – (A + B + C))
Z-A-B-C=>D , Z-A-B-C=>E ,Z-A-B-C=>F 注意:Z的位置只能有一个变量 语句 X Y Z 原100 原70 原30 SUBTRACT Y FROM Z 100 70 -40 SUBTRACT Z FROM Y 100 40 30 SUBTRACT Y, Z FROM X 0 70 30 SUBTRACT 5, 10 FROM X 85 70 30 SUBTRACT Y, 20 FROM Z 100 70 -60 SUBTRACT Z FROM Y GIVING X 40 70 30 SUBTRACT Y, 15 FROM 100 GIVING Z 100 70 15
3.MULTIPLY
MULTIPLY Y BY B, C, D. (用C语言可描述为B *= Y, C *= Y, D *= Y) Y*B=>B , Y*C=>C , Y*D=>D
MULTIPLY Y BY Z GIVING B, C, D.(用C语言可描述为B = C = D = Y * Z) Y*Z=>B , Y*Z=>C , Y*Z=>D 注意:Y,Z的位置只能有一个变量 语句 A B C 原10 原20 原30 MULTIPLY A BY B 10 200 30 MULTIPLY B BY A 200 20 30 MULTIPLY 0.5 BY A 5 20 30 MULTIPLY A BY B GIVING C 10 20 200 MULTIPLY A BY 0.5 GIVING B, C 10 5 5 MULTIPLY 1.5 BY 5 GIVING A, B, C 7.5 7.5 7.5
4.DIVIDE
DIVIDE Y INTO B, C, D. (用C语言可描述为B /= Y, C /= Y, D /= Y) B/Y=>B , C/Y=>C , D/Y=>D
DIVIDE Y INTO Z GIVING B, C, D.(用C语言可描述为B = C = D = Z / Y) Z/Y=>B , Z/Y=>C , Z/Y=>D
25/49
DIVIDE Y BY Z GIVING C, D.(用C语言可描述为C = D = Y / Z) Y/Z=>C , Y/Z=>D
注意: 有 BY时 ,必须还有GIVING Y,Z的位置只能有一个变量 语句 X Y Z 原40 原20 原10 DIVIDE Z INTO X. 4 20 10 DIVIDE Z INTO 100 GIVING Y. 40 10 10 DIVIDE 2 INTO Z GIVING X. 5 20 10 DIVIDE X BY Z GIVING Y. 40 4 10 DIVIDE 60 BY Y GIVING X. 3 20 10
5.COMPUTE COMPUTE T = (A + B) * C / D. 优先级的顺序: 1.括号 2.正负号 3.乘方 4.乘除 5.加减 - A ** 2 <=> - (A) ** 2 <=> ( - A) ** 2
6.带CORRESPONDING子句的算术运算子句
01 A.
05 A1 PIC 05 A2 PIC 05 A3 PIC
01 B.
05 A1 PIC 05 A3 PIC 05 A2 PIC
ADD CORR A TO B
9(3). 9(2)V99. 9V9.
99V99. 9V9. 99V99.
26/49
相当于: ADD A1 OF A TO A1 OF B. ADD A2 OF A TO A2 OF B. ADD A3 OF A TO A3 OF B. 类似的:
SUBTRACT CORR A FROM B.
7.ROUNDED子句 (1/P127)
ADD A, B TO C ROUNDED 有ROUNDED时,C的值四舍五入, 无ROUNDED时,C的值截断
8.ON SIZE ERROR子句 MULTIPLY A BY B GIVING C ON SIZE ERROR DISPLAY ‘SIZE ERROR‘ STOP RUN. 如果:
77 A PIC 9V9 VALUE 1.2. 77 B PIC 9V9 VALUE 9.0. 77 C PIC 9V9.
9.除法语句中的余数子句(REMAINDER子句)
DIVIDE A INTO B GIVING C [ROUNDED] REMAINDER D DIVIDE 7 INTO 13 GIVING C REMAINDER D D为6
3.3 内部函数 COBOL提供了大量的内部函数供用户使用,主要有如下几类 :
Number Handling Date/Time
Finance(金融学) Mathematics
Statistics(统计学) 下面是一个例子:
IDENTIFICATION DIVISION. PROGRAM-ID. SAMPLE3.
AUTHOR. QXLU (WISTRON DALIAN).
27/49
DATE-WRITTEN. 04-06-21. DATE-COMPILED. 04-06-21. *
ENVIRONMENT DIVISION. *
DATA DIVISION. WORKING-STORAGE SECTION. 01 I PIC 9V9(2). 01 G PIC 9V9(5). 01 I2 PIC 9.9(2). 01 G2 PIC 9.9(5). *
PROCEDURE DIVISION. *
MOVE 1.57 TO I.
COMPUTE G = FUNCTION SIN(I). MOVE I TO I2. MOVE G TO G2.
DISPLAY 'I = ' I2. DISPLAY 'G = ' G2. *
STOP RUN. I = 1.57 G = 1.00000
4.字符串处理
4.1 字符串连接(string语句 ) ( 1/P152)
A,B,C 均为 PIC X(4), D 为PIC X(16),原值为空白。 A=FGH_, B=KLM_, C=XYZ_
1. DELIMITED(定界)
表示连接时源字符在什么位置结束,必须有 DELIMITED定界符
STRING A, B, C DELIMITED BY SIZE INTO D. D=FGH_KLM_XYZ_ _ _ _ _
STRING A, B, C DELIMITED BY SPACE INTO D. D=FGHKLMXYZ_ _ _
STRING A DELIMITED BY ‘H’ B DELIMITED BY ‘M’
C DELIMITED BY ‘Y’ INTO D.
28/49
D=FGKLX_ _ _ _ _ _ _ _ _
STRING A, ’_‘, B, ‘_‘, C DELIMITED BY SIZE INTO D. D=FGH_ _KLM_ _XYZ_
2. POINTER (指定接收项开始接收的位置,类似于C语言中的逻辑指针)
如果不想从接收项的最左端开始接收字符,而是从某一字符位开始向右接收字符,可以用POINTER字句。
MOVE 3 TO T.
STRING A, B, C DELIMITED BY SIZE INTO D WITH POINTER T D=_ _FGH_KLM_XYZ_
3. 如果D的长度不足,使用OVERFLOW溢出短语 若D的长度为8个字节
STRING A, B, C DELIMITED BY SPACE INTO D
ON OVERFLOW DISPLAY 'OVERFLOW'.
IDENTIFICATION DIVISION. PROGRAM-ID. SAMPLE4.
AUTHOR. QXLU (WISTRON DALIAN). DATE-WRITTEN. 04-07-07. DATE-COMPILED. 04-07-07. *
ENVIRONMENT DIVISION. *
DATA DIVISION. WORKING-STORAGE SECTION. 01 A PIC X(4). 01 B PIC X(4). 01 C PIC X(4). 01 D PIC X(8). *
PROCEDURE DIVISION. *
MOVE 'FGH ' TO A. MOVE 'KLM ' TO B. MOVE 'XYZ ' TO C. MOVE SPACE TO D.
29/49
. STRING A, B, C DELIMITED BY SPACE INTO D ON OVERFLOW DISPLAY 'OVERFLOW'. DISPLAY 'A = ' A. DISPLAY 'B = ' B. DISPLAY 'C = ' C. DISPLAY 'D = ' D. *
STOP RUN. 显示如下: OVERFLOW A = FGH B = KLM C = XYZ D = FGHKLMXY
4.2 字符串分解语句(unstring语句 ) ( 1/P154 )
A=DATE_ _PROTECT_QUANTITY_
B PIC X(6), C PIC X(8), D PIC X(9)
1. UNSTRING A INTO B, C, D. B=DATE_ _, C=PROTECT_ D=QUANTITY_
B放满后,放入C,C放满后,放入D
2. DELIMITED(定界)
UNSTRING A DELIMITED BY ‘T’ INTO B, C, D, E. B=DA_ _ _ _, C=E_ _ PRO_ _, D=EC _ _ _ _ _ _ _
3. UNSTRING A DELIMITED BY ALL SPACE OR ‘.’ OR ‘,‘ INTO B, C.
B=DATE_ _ , C=PROTECT_
ALL表示定界符是一个长度不固定的常量
30/49
4. UNSTRING A DELIMITED BY ‘T’ INTO B COUNT IN W. B=DA_ _ _ _, W=2
5. UNSTRING A DELIMITED BY ‘T’ OR ALL ‘ ‘ OR ‘O’
INTO B DELIMITER IN Q
C DELIMITER IN P D DELIMITER IN R. B=DA_ _ _ _, Q=T
C=E_ _ _ _ _ _ , P=_ _ D=PR _ _ _ _ _ _ _ ,R=O 6.MOVE 5 TO U.
UNSTRING A INTO C WITH POINTER U. C=_ _PROTEC
7.TALLYING(接收项记数),实际接收的项数(不是字符数) MOVE 0 TO N.
UNSTRING A INTO B, C, D TALLYING IN N. N=3
MOVE 0 TO N. MOVE 10 TO U.
UNSTRING A INTO B, C, D WITH POINTER U TALLYING IN N. N=2
4.3 检测语句(INSPECT) ( 1/p157) 1.累计一个指定的字符出现的次数
2.用一个指定的字符去替代另一个指定的字符 3.通过指定某些字符来限制上述检查的区间
INSPECT CARD-RECORD TALLYING N FOR ALL ‘ ‘. 检查字符串中的空格个数,放入N
INSPECT CARD-RECORD REPLACING ALL SPACE BY ‘,’ 每找到一个空格,就用逗号替换该空格。
INSPECT一般格式:
INSPECT 标识符1 TALLYING 短语 INSPECT 标识符1 REPLACING 短语
INSPECT 标识符1 TALLYING 短语REPLACING 短语
BEFORE/AFTER短语
INSPECT CARD-RECORD TALLYING N FOR ALL ‘ ‘ BEFORE ‘.’.
INSPECT A REPLACING ALL ZERO BY SPACE
31/49
BEFORE ‘.’. A=000084.301 A=_ _ _ _84.301
TALLYING短语:
INSPECT A TALLYING N FOR CHARACTERS BEFORE ‘.’.
INSPECT A TALLYING N FOR LEADING ‘0’ BEFORE ‘.’. A=0012.34, N=2
A=0001200.34, N=3 A=123.4004, N=0
REPLACING短语
INSPECT A REPLACING
ALL ‘0’ BY SPACE ALL ‘.’ BY ‘,’ ALL ‘A’ BY ‘B’.
A=A000.12B, A=B_ _ _,12B
同时使用TALLYING 和REPLACING
INSPECT A TALLYING N FOR ALL ‘L’
REPLACING LEADING ‘A’ BY ‘E’ AFTER ‘L’. A=SALAMI, N=1, SALEMI
5.程序逻辑控制 (1/p137)
5.1 条件的分类 1) .关系表达式
关系运算符:
大于:IS GREATER THAN 或者 > 小于:IS LESS THAN 或者 < 等于:IS EQUAL TO 或者 =
不大于:IS NOT GREATER THAN 或者 NOT > 不小于:IS NOT LESS THAN 或者 NOT < 不等于:IS NOT EQUAL TO 或者 NOT = 一般常用后面的简写形式 比较规则: A. 数字比较:
按数值的大小。 B. 字母型数据比较
参照编码表,按字典顺序比较。
32/49
在ASCII机器中,A的代码是八进制的101,B的代码是八进制的102,则认为“A”<“B”
在EBCDIC(Extended Binary Coded Decimal Interchange Code)机器中,A的代码是二进制的11000001,B是11000010,也是“A”<“B” 即Z>Y>X ….. >A
Example: “BOY” > “BOT”
“BOOK” < “BOOKS” (“ ”比任何字母都小)
2). 符号条件: IF X IS POSITIVE 相当于 IF X > 0 IF X IS NEGATIVE 相当于IF X < 0 IF X IS ZERO 相当于 IF X = 0 3).类型条件 IF X IS NUMERIC MOVE B TO C.(令X为字符串) 标识符类型 可用的条件类型 肯定型 否定型 数值型 NUMERIC NOT NUMERIC 字母型 ALPHABETIC NOT ALPHABETIC 字符型 NUMERIC NOT NUMERIC ALPHABETIC NOT ALPHABETIC 4).条件名条件(类似于C语言中的switch case结构)
77 X (条件变量) PIC 9(6).
88 X1 VALUE 0 THROUGH (THRU) 99. 88 X2 VALUE 100 THROUGH (THRU) 999.
88 X3 VALUE 1000 THROUGH (THRU) 4999. 88 X4 VALUE 5000 THROUGH 100000 MOVE 98 TO X.
IF X1 MOVE 0.3 TO R. IF X2 MOVE 0.4 TO R. R=0.3
5).复合条件 IF X=Y OR T=W AND C>D AND G IS NOT POSITIVE 优先级顺序 : NOT, AND, OR(同C语言中的!、&&、||)
33/49
5.2 分支语句 ( 2/p195) 1). IF 语句(类似于C语言中的if结构) Format 1. IF 条件
语句 END-IF.
Format 2. IF 条件
语句1
ELSE IF ELSE IF ELSE
语句2
END-IF.
Format: IF条件{语句1,NEXT SENTENCE} (ELSE{语句2, NEXT SENTENCE})
Example:
IF B ** 2 – 4 * A * C NOT < 0 NEXT SENTENCE ELSE
DISPLAY ‘B ** 2 – 4 * A * C < 0’. STOP RUN.
注意:1 NEXT SENTENCE必须是所在层的唯一语句。
2 IF结构中句号”.”的位置
2).EVALUATE语句(类似于C语言中的switch case结构) EVALUATE {标识符1,常量1,条件1}…
{{WHEN{ANY,TRUE,FALSE,[NOT]{{标识符2,常量2}
[{THROUGH,THRU}{标识符3,常量3}]}}…}…语句序列1}… [WHEN OTHER 语句序列2] END-EVALUATE Example 1: EVALUATE A WHEN 3
DISPLAY A WHEN 4
DIVIDE 2 INTO A DISPLAY A END-EVALUATE.
34/49
Example 2:
EVALUATE A ALSO B ALSO C WHEN 1 ALSO 2 ALSO 3 DISPLAY A, B, C END-EVALUATE.
当A=1,B=2,C=3时,显示A,B,C值,只要三者之中有一个不相等,都不执行DISPLAY语句。
注意EVALUATE结构中句号”.”的位置 3).GO TO语句(类似于C语言中的goto)
Format 1. GO TO 过程名(段名/节名)
Format 2. GO TO 过程名1[,过程名2] …过程名n DEPENDING ON 标识符
Format 2, example: GO TO A, B, C, D, E DEPENDING ON I 当I=1时,转到A段,当I=2时,转到B段,…….
<说明>
• 原則上禁止使用。
• 产生异常数据的时候或者需要数据的检验等等的情况下,想跳过(SKIP)后续的
处理的时候使用这个语句
• 使用GOTO语句的时候,要转移到节(SECTION)的出口处(NNNN-EXIT)。 不允许转移到SECTION出口之外的地方。
5.3 循环语句(类似于C语言中的for/while结构)
1).PERFORM执行语句
1.PERFORM 过程名(段名/节名)
A1. MOVE 0.06 TO R. MOVE 1000 TO P. PERFORM C.
A2. MOVE 0.04 TO R. MOVE 100 TO P. PERFORM C. . .
C. ADD 1 TO R. MULTIPLY P BY R GIVING P1. MOVE P1 TO PRINTOUT WRITE PRINTOUT AFTER 2.
过程被执行一次后,回到PERFORM的下一条语句
35/49
2.PERFORM 过程名1 [{THROUGH,THRU} 过程名2]
PERFORM A1 THRU A2
从A1位置,一直执行到A2段的最后一句。
3.PERFORM 过程名1 [{THROUGH,THRU} 过程名2]{整数,标识符}TIMES
PERFORM A1 THRU A2 10 TIMES 执行A1段到A2段 10次。
4. PERFORM 过程名1 [{THROUGH,THRU} 过程名2]UNTIL条件
5. PERFORM 过程名1 [{THROUGH,THRU} 过程名2]VARYING 标识符1 FROM {常数1,标识符2}BY}常数2,标识符3} UNTIL条件 PERFORM T1 THRU T2 VARYING X FROM 1 BY 1 UNTIL X > 5.
X->循环变量,A->初值,B->步长,X > 5条件 PERFORM执行语句——多重循环
1.PERFORM A VARYING I FROM 1 BY 1 UNTIL I > 9
AFTER J FROM 1 BY 1 UNTIL J > 9.
A. COMPUTE P = I * J
DISPLAY I, '*', J, '=', P.
2.PERFORM 过程名1 [{THROUGH,THRU}过程名2]
[VARYING 参数1 FROM 初值1 BY 步长1 UNTIL 条件1] [AFTER 参数2 FROM 初值2 BY 步长2 UNTIL 条件2] [AFTER 参数3 FROM 初值3 BY 步长3 UNTIL 条件3] PERFORM T VARYING I FROM 1 BY 1 UNTIL I > 9 AFTER J FROM 1 BY 1 UNTIL J > 9 AFTER K FROM 1 BY 1 UNTIL K > 9.
5.4 EXIT(出口语句)(注意与C语言中的exit不同,只是一个空操作,类似于C语言中的最小C函数) PERFORM A THRU B. A. IF X > Y GO TO B. MOVE X TO T. …. B. EXIT.
EXIT语句本身并不使计算机产生任何动作,它用来提供一个出口点。
36/49
编码时一般要求EXIT独占一段。
6 表处理 ( 2/p43)
6.1 表的建立 1. 表类似于C语言中的数组
注意表元素是从1开始计数的,而C语言中的数组元素是从0开始计数的
2. 01 STUDENT-RECORD. 05 NAME PIC X(20).
05 COURSE OCCURS 5 TIMES PIC 9(3). 表元素为初等项
3. 01 PRODUCT-RECORD. (一维表)
05 PRODUCT OCCURS 20 TIMES. 表元素为组合项 10 QUANTITY-OF-PRODUCTION PIC 9(6). 10 QUANTITY-OF-SALES PIC 9(6). 10 QUANTITY-OF-HAND PIC 9(6).
4. 01 PRODUCT-RECORD. (二维表) 05 PRODUCT OCCURS 20 TIMES.
10 QUANTITY OCCURS 3 TIMES PIC 9(6).
5. 01 PRODUCT-RECORD.
05 FACTORY OCCURS 10. (一维表) 10 PRODUCT OCCURS 20. (二维表)
15 QUANTITY OCCURS 3 TIMES PIC 9(6). (三维表) 共占3600 Bytes
6. OCCURS 整数 [TIMES] 说明:
(A)OCCURS子句不能用于77层和01层。 01 PRODUCT.
05 UNIT-PRICE OCCURS 5 TIMES PIC 9(3)V99.是错的 (b)PIC不能用于描述组合项。 01 A.
05 B OCCURS 5 TIMES PIC X(30). 10 C PIC X(20).
10 D PIC 9(10). 是错的
37/49
6.2 可变长度的表
1. OCCURS 整数1 TO 整数2 [TIMES] DEPENDING ON 数据名1
2. 01 STUDENT-SCORE-RECORD.
03 NAME PIC X(10).
03 QTY-OF-COURSE PIC 9(2). 03 SCORE OCCURS 1 TO 15 TIMES
DEPENDING ON QTY-OF-COURSE PIC 9(3). 注意:数据名1不能是表元素
01 STUDENT-SCORE-RECORD.
03 SCORE OCCURS 1 TO 15 TIMES DEPENDING ON QTY-OF-COURSE. 04 QTY-OF-COURSE PIC 9(2).
04 SCORE-OF-COURSE PIC 9(3). 是错的
6.3 给表赋初值 1. (a) 在OCCURS上一层赋初值 01 A VALUE IS ZERO.
05 A1 OCCURS 5 PIC X(3). 01 B VALUE 'ABCDEFHIJK'.
05 B1 OCCURS 5 TIMES PIC X(3).
(b) 在OCCURS层赋初值 01 C.
05 C1 OCCURS 5 TIMES PIC 9(3)V99 VALUE 500. 可实现对5个元素初始化为500
(c) 在OCCURS下一层赋初值 01 D.
05 D1 OCCURS 5 TIMES.
15 D11 PIC 9(3) VALUE 100. 15 D12 PIC 9(2) VALUE 10. 可实现对5个元素初始化为10010
2. 使用REDEFINES语句 01 UNIT-PRICE-TABLE.
05 FILLER PIC X(10) VALUE ‘0010000100’. 05 FILLER PIC X(10) VALUE ‘0010000500’. 05 FILLER PIC X(10) VALUE ‘0030000300’. 05 FILLER PIC X(10) VALUE ‘0040001500’.
38/49
05 FILLER PIC X(10) VALUE ‘0050005000’.
01 UNIT-PRICE-TABLE-R REDEFINES UNIT-PRICE-TABLE. 05 RECORD-PRICE OCCURS 5. 15 PROD-CODE PIC 9(4). 15 UNIT-PRICE PIC 9(6).
3. 使用PERFORM语句
PERFORM VARYING J FROM 1 BY 1 UNTIL J > 8
MOVE SPACE TO A1(J) END-PERFORM.
4. 使用INITIALIZE INITIALIZE B.
字符型的为空格,数字型的为0, 5. MOVE LOW-VALUES TO C.
6.4 引用表元素 1)
01 TABLE.
05 B OCCURS 8.
10 C1 PIC X(8). 10 C2 PIC X(2). TABLE B(1) B(2) B(3) B(4) B(5) B(6) B(7) B(8) C1 C2 C1 C2 C1 C2 C1 C2 C1 C2 C1 C2 C1 C2 C1 C2 X(8) X(2) X(8) X(2) X(8) X(2) X(8) X(2) X(8) X(2) X(8) X(2) X(8) X(2) X(8) X(2) C1 (2)
C1 OF B(2)
C1(2) OF B(2)是错误的。
下标只能是B(I), B(2),
B(I+1),A(8)不合法,不能是表达式。
2).用INDEX(位标)访问表元素(位标类似于C语言中的逻辑指针) 01 A.
03 X OCCURS 5 PIC X(2) INDEXED BY I. (I不用定义)
相对地址:(表元素的序号-1)* 元素长度 第二个元素的相对地址:(2-1)* 2 = 2
39/49
如表的起始位置为10010,则其绝对位置为:10010+2=10012 可指定若干个位标名,但只能在该维内使用。
01 A.
05 B OCCURS 5 INDEXED BY IB1, IB2. 10 C OCCURS 4 INDEXED BY IC1, IC2.
15 D PIC 9(2) OCCURS 8 INDEXED BY ID1, ID2, ID3.
如:B(IB1),B(IB2),C(IB1,IC1),C(IB2,IC1),D(IB2,IC2,ID3),D(IB1,IC2,ID2)
位标不能参与运算,只能用SET设置其值
3. SET(设置)语句(用于移动位标) (a)SET I TO 10.
表示将I置位到第10个元素的第一个字节的相对地址上。
(b)SET {标识符1 [,标识符2]…, 位标1 [,位标2]…} TO {标识符3, 位标3, 整数}
(c)SET 位标1 [,位标2]…{UP BY, DOWN BY} {标识符,整数} SET I UP BY 2. (如果I为10,则加2) SET I, J DOWN BY 2. (I,J都减2)
4. 位标数据项,用来存放位标值,但不能做位标:
K USAGE INDEX. 但A(K)错误。
应该:SET A1 TO K.
MOVE A(A1) TO OUT-REC.
SET I TO J.
I 和J都是位标名,将I置位为J
SET J TO 5. 将J置位为5
SET I TO D. 将I置位为D
D为一般数据项,I为位标。
SET K TO I
假如K以被定义为:77 K INDEX
则SET语句将位标I的值存到位标数据项K中。
40/49
6.5 表的检索和SEARCH语句(类似于SQL中的SELECT) 检索出第一条符合条件的记录后,就停止检索
1. 用于顺序检索的SEARCH语句
(a) 01 WORKER-REC REDEFINES WORKER-INFOTB.
05 WORKER-TABLE OCCURS 10 TIMES INDEXED BY N. 10 NUMB PIC X(4). 10 NAME PIC X(10). 10 AGE PIC 9(2).
10 PAY PIC 9(4).
SET N TO 1. (N必须为位标) SEARCH WORKER-TABLE
AT END DISPLAY ‘CANNOT FIND NAME’ WHEN NAME(N) = ‘CHANG SAN’ DISPLAY NAME(N), PAY(N).
(b)SEARCH 表名 [VARYING {位标名1,标识符2}] AT END 强制语句1] WHEN 条件1 {强制语句2,NEXT SENTENCE}
[WHEN 条件2 {强制语句3,NEXT SENTENCE}].. 没有VARYING时,表示用本表第一个位标 若VARYING的位标是所SEARCH的表的,则按该位标SEARCH本表,
若VARYING的位标是另一个表中的位标,则表示仍用本表第一个位标,
本表的位标增值时,VARYING的位标也等量增值。这样可以将两个表关联起来。 如:
01 PRODUCT-TABLE REDEFINES PRODUCT-INFOTB.
05 SHOP-PRODUCTION OCCURS 10 INDEXED BY I11, I12. 10 NUM PIC 9(6). 10 QTY PIC 9(3). 10 GRADE PIC X.
01 PAY-TABLE REDEFINES PRODUCT-INFOTB.
05 SHOP-PAY OCCURS 10 INDEXED I21, I22. 10 NUMB PIC 9(3). 10 PAY PIC 9(5). 10 FILLER PIC X(2). SEARCH SHOP-PRODUCTION VARYING I21 AT END GO TO FINISH WHEN QTY(I11) > 500 DISPLAY PAY(I21)
41/49
MULTIPLY 0.8 BY PAY(I21) DISPLAY PAY(I21) GO TO STOPRUN.
2. 用于已排好序的表的SEARCH语句
01 BOOK-SET REDEFINES BOOK-INFOTB. 05 BOOKTB OCCURS 10
ASCENDING KEY IS NAME(升序) INDEXED BY N. 10 NAME PIC X(5). 10 CLSS PIC X(5). 10 COD PIC X(5). 10 NUM PIC 9(5). 也可以有几个排序项:
01 BOOK-SET REDEFINES BOOK-INFOTB. 05 BOOKTB OCCURS 10
ASCENDING KEY IS NAME DESCENDING KEY IS CLSS DESCENDING KEY IS COD INDEXED BY N. 10 NAME PIC X(5). 10 CLSS PIC X(5). 10 COD PIC X(5). 10 NUM PIC 9(5).
SEARCH ALL BOOKTB AT END DISPLAY 'NOT FOUND' WHEN NAME(N) = 'B2222' AND CLSS(N) = 'B2222' DISPLAY NAME(N), CLSS(N), COD(N), NUM(N).
条件中只许用等号,条件中必须有KEY变量。 AND条件的次序和KEY的次序相同
推测:
(1)
SEARCH ALL时首先把符合WHEN中条件的记录都选出来放到一个集合S1中,然后按设定的键对S1排序,生成一个新的集合S2,最后选出S2的第一条记录(此记录即为最终符合条件的记录)
SEARCH时首先把符合WHEN中条件的记录都选出来放到一个集合S1中,最后选出S1的第一条记录(此记录即为最终符合条件的记录)
(2)
42/49
7.读、写多格式记录文件
DATA DIVISION.
FILE SECTION. *
FD DDI01 LABEL RECORD IS STANDARD DATA RECORD ARE IN-AREA0, IN-AREA1. 01 IN-AREA0.
05 IN-YEAR-NUM PIC 9(2). 05 IN-PRINCIPAL PIC 9(4)V99. 05 FILLER PIC X(07).
05 RMARK PIC X(01) VALUE X\"0A\". 01 IN-AREA1.
05 IN-INTEREST-RATE OCCURS 5 TIMES PIC V999.
05 RMARK PIC X(01) VALUE X\"0A\".
FD DDO01 BLOCK 0 RECORDS LABEL RECORD STANDARD RECORDING F. 01 PRT-REC.
05 FILLER PIC X(79). *
*===============================================================*
WORKING-STORAGE SECTION.
//MD045TA JOB (WISTRON,SD2),'LU QIXUX',CLASS=A, // MSGCLASS=H,MSGLEVEL=(1,1),NOTIFY=&SYSUID //*
//STEP1 EXEC PGM=EXERCIS6
//STEPLIB DD DISP=SHR,DSN=MD045T.TEACHING.PGMLIB //SYSPRINT DD SYSOUT=* //SYSOUT DD SYSOUT=* //SYSIN DD DUMMY
//DDI01 DD DSN=MD045T.TEACHING.DATEXER6,DISP=SHR
//DDO01 DD DSN=MD045T.TEACHING.LSTEXER6,DISP=(NEW,CATLG,DELETE), // SPACE=(TRK,(9,9),RLSE),DCB=(RECFM=FB,LRECL=80) //*
注意:
1 length(IN-AREA0) == length(IN-AREA1) == DDI01中记录的长度(含换行符1Byte) 2 length(PRT-REC) + 1Byte == DDO01中记录的长度(含换行符1Byte), 换行符可能是WRITE语句加的
43/49
DDI01
DDO01
44/49
8.常用语句小结(ACCEPT、DISPLAY、READ、WRITE、OPEN、CLOSE)
(1) ACCEPT语句
ACCEPT 标识符 [FROM助忆名]
如不写FROM部分,如ACCEPT A,则从系统隐含指定的设备上读入一个数据给A。如控制台,读卡机或键盘输入机等。 IDENTIFICATION DIVISION. PROGRAM-ID. SAMPLE1.
AUTHOR. QXLU (WISTRON DALIAN). DATE-WRITTEN. 04-06-21. DATE-COMPILED. 04-06-21. *
ENVIRONMENT DIVISION. CONFIGURATION SECTION. SOURCE-COMPUTER. IBM-3084. OBJECT-COMPUTER. IBM-3084.
SPECIAL-NAMES. CONSOLE IS ABC. *
DATA DIVISION. WORKING-STORAGE SECTION. 01 SYSTEM-DATE-AREA. 05 SYSTEM-DATE.
45/49
10 SYSTEM-YY1 PIC X(02). 10 SYSTEM-YYMMDD.
15 SYSTEM-YY2 PIC X(02). 15 SYSTEM-MM PIC X(02). 15 SYSTEM-DD PIC X(02). 05 SYSTEM-TIME PIC X(06). 01 CONSOLE-AREA PIC X(20). 01 INPUT-AREA PIC X(20). *
PROCEDURE DIVISION. *
ACCEPT SYSTEM-TIME FROM TIME. *
ACCEPT SYSTEM-DATE FROM DATE. *
ACCEPT CONSOLE-AREA FROM ABC. *
ACCEPT INPUT-AREA. *
STOP RUN.
(2) DISPLAY 语句
DISPLAY {标识符1,or 常量1}(标识符2,or 常量2) ...[UPON助忆名]
Example: DISPLAY “MY NAME IS ZHENG” UPON ABC
(3) READ语句
READ 文件 RECORD [INTO 标识符][;AT END 强制语句] Example: READ CARD-FILE
AT END GO TO A1 (4) WRITE语句
WRITE 记录名 [FROM 标识符1]
({BEFORE,AFTER} ADVANCING {{标识符2,整数}(LINE,LINES),{助忆名,PAGE}})
Example1: WRITE T AFTER ADVANCING 2 LINES MOVE T1 TO T
WRITE T AFTER ADVANCING 2 LINES (空行) (空行) xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (T的内容) (空行) xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (…) (空行) xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (…) 46/49
Example2: WRITE T BEFORE ADVANCING 2 LINES MOVE T1 TO T
WRITE T BEFORE ADVANCING 2 LINES xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (T的内容) (空行) xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (…) (空行) xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx (…) (空行) ADVANCING & LINES 可省略 Example3: WRITE T FROM T1 AFTER 3. 等价于 MOVE T1 TO T. WRITE T AFTER 3. (5) OPEN 语句
OPEN {INPUT 文件名1[,文件名2]…}…. OPEN {OUTPUT 文件名1[,文件名2]…}…. OPEN {I-O 文件名1[,文件名2]…}….
(6) CLOSE 语句
CLOSE文件名1[,文件名2]…
9.子程序
(1) PROCEDURE DIVISION [USING 数据名1 [,数据名2]…]
…
GOBACK …
EXIT PROGRAM 子程序名.(子程序出口) (2) 调用程序:
CALL 子程序名 [USING 数据名1 [,数据名2]…] 被调用程序:
PROCEDURE DIVISION [USING 数据名1 [,数据名2]…]
注意:(a)参数必须对应,且依照顺序 (b)也可以不带参数
(3) Sample
计算斐波那契(Fibonacci)数列第n项的函数FIB
主程序
IDENTIFICATION DIVISION. PROGRAM-ID. FIBCALL.
ENVIRONMENT DIVISION.
DATA DIVISION.
47/49
WORKING-STORAGE SECTION. 01 NUM PIC 9(4) VALUE 5. 01 NUMFIB PIC 9(8) VALUE 0.
PROCEDURE DIVISION.
CALL 'FIB' USING NUM, NUMFIB. DISPLAY 'NUM = ', NUM.
DISPLAY 'NUMFIB = ', NUMFIB. STOP RUN.
子程
IDENTIFICATION DIVISION. PROGRAM-ID. FIB RECURSIVE.
ENVIRONMENT DIVISION.
DATA DIVISION.
LOCAL-STORAGE SECTION. 01 NUMTEMP PIC 9(4).
01 NUMFIB1 PIC 9(8) VALUE 0. 01 NUMFIB2 PIC 9(8) VALUE 0. LINKAGE SECTION. 01 NUM PIC 9(4). 01 NUMFIB PIC 9(8).
PROCEDURE DIVISION USING NUM, NUMFIB. EVALUATE NUM WHEN 0 THRU 1
MOVE NUM TO NUMFIB GOBACK WHEN OTHER
MOVE NUM TO NUMTEMP SUBTRACT 1 FROM NUMTEMP
CALL 'FIB' USING NUMTEMP, NUMFIB1 SUBTRACT 1 FROM NUMTEMP
CALL 'FIB' USING NUMTEMP, NUMFIB2 ADD NUMFIB1, NUMFIB2 GIVING NUMFIB GOBACK
END-EVALUATE. END PROGRAM FIB.
COMPUTE TEMP-NUMBER01 = FUNCTION NUMVAL-C(BA0301I)
48/49
TEMP-NUMBER01是数字型 BA0301I 是字符型
这个函数的作用能把字符型转换成数字型
文件定义:
SELECT MCL-FIL ASSIGN MCLMSD ORGANIZATION INDEXED ACCESS DYNAMIC LOCK MODE
IS AUTOMATIC RECORD MCL-KEY STATUS FS.
操作文件:
START MCL-FIL KEY = INVALID SENTENCE.
KEY 值’ 49/49
‘
因篇幅问题不能全部显示,请点此查看更多更全内容