IDENTIFICATION DIVISION.
PROGRAM-ID DYNAMIC-MAIN.
AUTHER XXX.
*
ENVIRONMENT DIVISION.
*
DATA DIVISION.
WORKING STORAGE SECTION.
01 IDENTIF PIC X(10).
77 TEST-NUM PIC 99.
*
PROCEDURE DIVISION.
PERFORM INIT-TEST-NUM.
MOVE ‘DYNAMIC-SUB’ TO IDENTIF.
CALL IDENTIF USING TEST-NUM.
DISPLAY ‘TEST-NUM AFTER THE FIRST CALL: ’ TEST-NUM.
PERFORM INIT-TEST-NUM.
CANCEL IDENTIF. /*此处将第一次调用后的子程序从内存中移除*/
MOVE ‘DYNAMIC-ENTRY’ TO IDENTIF.
CALL IDENTIF USING TEST-NUM.
DISPLAY ‘TEST-NUM AFTER THE SECOND CALL: ’ TEST-NUM.
STOP RUN.
INIT-TEST-NUM.
MOVE 10 TO TEST-NUM.
令该主程序中调用的子程序DYNAMIC-SUB的代码如下。
IDENTIFICATION DIVISION.
PROGRAM-ID DYNAMIC-SUB.
AUTHER XXX.
*
ENVIRONMENT DIVISION.
*
DATA DIVISION.
WORKING STORAGE SECTION.
01 PLUS-NUM PIC 99 VALUE 15.
LINKAGE SECTION.
77 MAIN-NUM PIC 99.
*
PROCEDURE DIVISION USING MAIN-NUM.
ADD MAIN-NUM TO PLUS-NUM.
MOVE PLUS-NUM TO MAIN-NUM.
GOBACK.
ENTRY ‘DYNAMIC-ENTRY’ USING MAIN-NUM.
ADD MAIN-NUM TO PLUS-NUM.
MOVE PLUS-NUM TO MAIN-NUM.
GOBACK.
以上程序执行后,将产生如下输出结果。
TEST-NUM AFTER THE FIRST CALL: 25
TEST-NUM AFTER THE SECOND CALL: 25
可以看到,以上这两段程序实际上和静态调用中的两段示例程序是类似的。不过,此处子程序中虽然没有手工进行初始化,但每次调用时仍为最初始的状态。原因是在主程序中,第一次调用该子程序后使用了CANCEL语句将其从内存中移除掉了。这样,在第二次调用时,该子程序将被重新读入内存,其状态和第一次调用时是一样的。
最后,对本节所讲的动态调用与其所对应的静态调用总结如下。
q 在COBOL程序中,静态调用通常使用CALL literal语句实现。CALL literal语句实际上就是将所调用的程序名,或选择性入口地址名作为直接数进行调用。静态调用的子程序每次被调用时的状态,为其上一次调用之后的状态。
q 动态调用通常使用CALL identifier语句实现。CALL identifier语句实际上就是将所调用的程序名,或选择性入口地址名MOVE到变量中调用。并且,凡是使用CALL identifier语句进行的调用都为动态调用。在动态调用中,可以通过CANCEL identifier语句,将调用后的子程序从内存中移除掉。这样,便可使得下一次调用时该子程序为最初始的状态。