zoukankan      html  css  js  c++  java
  • 一步步Cobol 400上手自学入门教程06

    子程序的命名通常和普通程序的命名方式相同。但是需要注意的是,对于子程序而言,不可将其前缀命名为以下这几个名字。

    AFB           AFH           CBC          CEE          EDC

    IBM            IFY             IGY            IGZ            ILB

    实际上,以上名字都属于IBM相关产品的名字。如果将子程序的前缀命名为以上名字,则在主程序中将不能对其进行调用。当在主程序中试图调用该子程序时,系统将会从IBM的库,或者编译器例程中寻求解决方案。

    静态调用

    下面通过具体的程序示例,以便更好地说明静态调用的特点及用法。首先,假设在静态调用中,某一主程序代码如下。

    IDENTIFICATION   DIVISION.
    
    
    PROGRAM-ID      STATIC-MAIN.
    
    
    AUTHER           XXX.
    
    
    *
    
    
    ENVIRONMENT   DIVISION.
    
    
    *
    
    
    DATA  DIVISION.
    
    
    WORKING STORAGE SECTION.
    
    
    77   TEST-NUM     PIC  99.
    
    
    *
    
    
    PROCEDURE   DIVISION.
    
    
    PERFORM  INIT-TEST-NUM.
    
    
    CALL   ‘STATIC-SUB’   USING    TEST-NUM.
    
    
    DISPLAY ‘TEST-NUM AFTER THE FIRST CALL: ’  TEST-NUM.
    
    
    PERFORM  INIT-TEST-NUM.
    
    
    CALL   ‘STATIC-ENTRY’   USING  TEST-NUM.
    
    
    DISPLAY ‘TEST-NUM AFTER THE SECOND CALL: ’  TEST-NUM.
    
    
    STOP RUN.
    
    
    INIT-TEST-NUM.
    
    
    MOVE  10  TO  TEST-NUM.
    
    
    令该程序的子程序,即与之所对应的被调用程序STATIC-SUB的代码如下。
    
    
    IDENTIFICATION   DIVISION.
    
    
    PROGRAM-ID      STATIC-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  ‘STATIC-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: 35
    View Code

    这是因为,在第一次调用前,子程序中的变量PLUS-NUM通过VALUE语句初始化为15。将该变量中的15和主程序中所传递的参数TEST-NUM中的10相加后,结果将为25。并且,此时子程序中的变量PLUS-NUM在相加运算结束后已由15变成了25。

    当进行第二次调用时,子程序为第一次调用结束后的状态。此时,子程序中的变量PLUS-NUM为25,而并非如第一次调用前的15。虽然第二次实际上仍然是对于子程序STATIC-SUB的调用,但此时该程序中的数据已不同了。第二次调用是将PLUS-NUM中的25和TEST-NUM中的10相加,因此最终结果为35。

    若要希望两次调用时子程序的状态都一致,则需要在子程序中进行相应的初始化。此处所说的初始化通常是指在该程序中的每一个入口地址后,对工作存储节中的本地数据进行初始化。进行初始化后的子程序如下。

    IDENTIFICATION   DIVISION.
    
    
    PROGRAM-ID      STATIC-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.
    
    
    PERFORM  INIT-PLUS-NUM.
    
    
    ADD   MAIN-NUM  TO  PLUS-NUM.
    
    
    MOVE  PLUS-NUM  TO  MAIN-NUM.
    
    
    GOBACK.
    
    
        ENTRY  ‘STATIC-ENTRY’   USING  MAIN-NUM.
    
    
    PERFORM  INIT-PLUS-NUM.
    
    
    ADD   MAIN-NUM  TO  PLUS-NUM.
    
    
    MOVE  PLUS-NUM  TO  MAIN-NUM.
    
    
    GOBACK.
    
    
    INIT-PLUS-NUM.
    
    
    MOVE  15  TO  PLUS-NUM.
    View Code

    仍然采用前面的主程序对以上子程序进行调用,则运行后的结果将如下。

    TEST-NUM AFTER THE FIRST CALL: 25

    TEST-NUM AFTER THE SECOND CALL: 25

    总之,静态调用的程序每次调用前都为其上一次调用后的状态。这一点是关于静态调用最需注意的地方,一定要牢记。

    动态调用

    下面通过具体的程序示例,以便更好地说明动态调用的特点及用法。首先,假设在动态调用中,某一主程序代码如下。

    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.
    View Code

    以上程序执行后,将产生如下输出结果。

    TEST-NUM AFTER THE FIRST CALL: 25

    TEST-NUM AFTER THE SECOND CALL: 25

    可以看到,以上这两段程序实际上和静态调用中的两段示例程序是类似的。不过,此处子程序中虽然没有手工进行初始化,但每次调用时仍为最初始的状态。原因是在主程序中,第一次调用该子程序后使用了CANCEL语句将其从内存中移除掉了。这样,在第二次调用时,该子程序将被重新读入内存,其状态和第一次调用时是一样的。

    最后,对本节所讲的动态调用与其所对应的静态调用总结如下。

          在COBOL程序中,静态调用通常使用CALL literal语句实现。CALL literal语句实际上就是将所调用的程序名,或选择性入口地址名作为直接数进行调用。静态调用的子程序每次被调用时的状态,为其上一次调用之后的状态。

          动态调用通常使用CALL identifier语句实现。CALL identifier语句实际上就是将所调用的程序名,或选择性入口地址名MOVE到变量中调用。并且,凡是使用CALL identifier语句进行的调用都为动态调用。在动态调用中,可以通过CANCEL identifier语句,将调用后的子程序从内存中移除掉。这样,便可使得下一次调用时该子程序为最初始的状态。

  • 相关阅读:
    腾讯云通信服务端返回签名
    synchronized同步语句块
    synchronized同步方法
    springjdbc的批量操作
    yield方法
    暂停线程
    【jdk源码学习】HashMap
    diamond types are not supported at this language level
    【java基础系列】一、常用命令行
    Socket通信综合示例
  • 原文地址:https://www.cnblogs.com/starcrm/p/5780090.html
Copyright © 2011-2022 走看看