执行THRU变化:确切的行为?

hsi*_*sim 4 cobol

我试图理解COBOL程序的行为,我绊倒了以下几行:

PERFORM  525-NUMERIC    THRU  525-EXIT                       
    VARYING K FROM 1  BY 1   UNTIL  K > CAR-L.         
Run Code Online (Sandbox Code Playgroud)

我理解全球概念,它是基于价值的某种循环K,但我不明白这些THRU 525-EXIT词的影响?

Bil*_*ger 12

PERFORM可以连续执行一系列段落或SECTIONS.这是通过使用THRU/THROUGH命名系列的最后一段/ SECTION来完成的,PERFORM已经命名了起点.

一段简单的PERFORM:

       PERFORM                      10-OPEN-INPUT-FILES
Run Code Online (Sandbox Code Playgroud)

这为PERFORM建立了一个"范围",从10-OPEN-INPUT-FILES开始,到该段的最后一个语句结束.

多个段落的表演,一个接一个:

       PERFORM                      10-OPEN-INPUT-FILES
         THRU                       10-OPEN-INPUT-FILES-EXIT
Run Code Online (Sandbox Code Playgroud)

这为PERFORM建立了更广泛的范围,从10-OPEN-INPUT-FILES开始,到10-OPEN-INPUT-FILES-EXIT的最后声明结束.

这不是一个好的或有用的东西,但它以特定的方式被大量使用,这也许就是你所拥有的.这是与每个段落相关联的"退出段落".一个原始段落,后跟一个唯一的退出段落(由第二段的位置,没有别的)与原始段落相关联.

这是绝对必要的,没有它们,程序可以正常工作.但是,由于存在"退出段落",当然现在有一个标签可以成为GO TO的目标.编写一些愚蠢的东西,或者遇到已经编码过的东西,并且只是为了让你(但也许不是下一个人)摆脱困境而堵塞了GO.这不是一件好事,虽然它经常被视为"权宜之计".下一次在相同的代码中,将采取权宜的路线,下一次,然后应该总是简单的事情变得......复杂.

令人惊讶的是(我认为,对于许多人来说这是正常做法),不止一些网站在其本地标准中有每个PERFORMed段落必须包含一个退出段落,并且PERFORM ... THRU ...必须编码.

除了通过邀请使用GO TO来解决问题之外,另一个问题是代码的物理位置现在是相关的.如果在exit-paragraph之前放置一个新段落,那么它将成为PERFORM范围的一部分,无论是否有意.有些人甚至打算将几个段落编写在PERFORM的范围内,并且使用随便的GO TO作为他们的"摆脱困境"工具.

另一个问题是,当您遇到PERFORM ...与THRU ...时,您不知道PERFORM中包含多少段(或SECTIONS)而不查看段落(或SECTIONS)本身.

你也可以执行一个部分.这是一个过程标签,后跟单词SECTION,并以句号/句号终止.

SECTION可以包含段落.当您执行一个部分时,SECTION中的所有段落都在PERFORM范围内,直到SECTION的最后一个声明.它就像一个PERFORM ...... THRU ......没有THRU ...位.它有与PERFORM ... THRU相同的问题......另外还有一个问题,即如果使用唯一段落作为GO TO的目标,如果复制SECTION以制作新的SECTION,则必须非常小心.从一个SECTION(或段落)中走出来是完全合法的,但这通常是无意的并且可能导致混乱,因为程序控制在其他地方徘徊.如果在SECTION中使用GO TO到退出段落,最好的办法是对exit-paragraph 使用相同的名称.在SECTION中的任何GO TO将由编译器自动"限定"到该SECTION中的段落(如果在SECTION中引用了非唯一段落名称,但在SECTION本身中没有该名称的段落,编译器将发现错误).

使用您的代码,找到正在进行的段落,并按顺序搜索THRU上指定的段落.它可能只是一个愚蠢的退出(只有一个EXIT语句和一个句号/句号的段落).如果你非常不走运,那两者之间可能还有其他段落.任何此类段落都包含在PERFOR的范围内,而不是在PERFORM声明中明确说明.该

值得注意的是,EXIT语句本身什么都不做.这是"无操作"或NOP(或NOOP).在执行段落的末尾,将生成许多指令以执行退出处理,这是自动的,并且(并且从未)依赖于EXIT语句的存在.

过去,在1985年标准之前,EXIT必须在一个段落中自行编码.这已不再是这种情况.您可以使用EXIT语句(例如20)填充段落,然后使用DISPLAY完成段落.执行该段落,您将看到DISPLAY输出.

在没有THRU的情况下执行的段落不应包含GO TO.如果它不是一个编译错误确实包含GO TO.这是一个等待发生的事故.

感觉需要使用GO TO的人必须使用PERFORM ... THRU ...或使用部分的PERFORM.不幸的是,即使原始编码器不使用GO TO,使用PERFORM ... THRU ......或部分执行确实可以让将来的人轻松使用GO TO.如果GO TO有某个地方可以去,那么GO TO更有可能出现在某个时刻.如果GO TO没有现有目标,那么下一个编码器将不再需要进行其他更改而不再使用GO TO.

在现行标准中,从2014年开始,有一些新版本的EXIT.(EXIT PROGRAMEXIT 的版本已经存在很长时间了,虽然现在受IBM启发GOBACK的更有可能用于返回CALLing程序).

新的可能性包括EXIT PARAGRAPHEXIT SECTION.查看编译器的文档,了解可用的EXIT变体.EXIT的所有变体都会生成可执行代码,EXIT而不是普通代码.

如果你的编译器确实允许EXIT PARAGRAPH和EXIT SECTION,那就意味着你不再需要有一个标签来允许使用(现在是"秘密")GO TO,它不会被称为GO TO,它将被调用EXIT somevariant.请记住,所有这些(除了EXIT PROGRAM)都是伪装的GO TO,并且该代码总是可以重新排列(并且经常简化)以避免GO TO的需要.

它确实需要经验来构建no-GO TO代码,所以现在不要太在意它.如果您的站点使用GO TO(使用THRU暗示),那么了解使用GO TO的后果非常重要,因为现有代码将使用它.

然后以一种小的方式开始,以避免去自己,在你熟悉这样做的技巧时增加你的努力范围.请记住,目的是简化代码,或者至少不会使情况变得更糟,而不仅仅是不通过死记硬背来代码GO TO.如果你的代码很复杂,只是为了避免GO TO,那么使用GO TO直到你知道如何做得更好.

许多,许多,优秀且经验丰富的COBOL程序员使用GO TO编写可理解的程序.不幸的是,大多数程序员并不"很好,经验丰富",所以很乐意用GO TO短路并继续前进.

PERFORM上的VARYING是一种重复执行的方法,具有起点,增量和终止条件.无论是否编码THRU,都是一样的.


可以在此处找到错误的GO TO超出PERFORM范围可能发生的事情的示例:https://codegolf.stackexchange.com/a/20889/16411.用SECTION编码,但同样可以用PERFORM ... TRHU ......


很高兴和布鲁斯·马丁的回答一起阅读这篇文章.


Bru*_*tin 11

继比尔的回答之后,我将尝试添加一个更直观的答案.

         Perform Proc-A thru Proc-D.
         ...

     Proc-A. 
        ....

     Proc-B.
        ....

     Proc-C.
        ....

     Proc-D.
        ....
Run Code Online (Sandbox Code Playgroud)

在上文中,执行Proc-A至Proc-D执行程序的Proc-A,Proc-B,Proc-CProc-D.这是一个简写

     Perform Proc-A
     Perform Proc-B
     Perform Proc-C
     Perform Proc-D
Run Code Online (Sandbox Code Playgroud)

执行直通语法有几个问题:

像上面这样的错误很容易制作但很难发现

它是Cobol功能中的一个,在它被引入时似乎是一个好主意 ; 但应该避免 !!!


小智 5

对比尔和布鲁斯的出色答案进行了阐述.

从Bruce的例子开始.

    Perform B100-Load-From-DB thru B500-Save-To-Db
...
B100-Load-From-DB
...
B200-Adjust-Stock-for-Purchases
...
B300-Adjust-Stock-for-Sales
...
Some-Danged-Ol-Thing
...
B400-Calculate-Markdowns
...
B500-Save-To-Db
Run Code Online (Sandbox Code Playgroud)

这仍然看起来相当简单.每个段落中的代码将按自上而下的顺序处理:B100-Load-From-DB,B200-Adjust-Stock-for-Purchases,B300-Adjust-Stock-for-Sales,Some-Danged-Ol-Thing,B400-计算 - 降价,B500-Save-To-Db

正如比尔指出的那样,将GO TO语句添加到PERFORM ... THRU块将所述代码的作者介绍给第九个地狱圈中的特殊象限.

    Perform B100-Load-From-DB thru B500-Save-To-Db
...
B100-Load-From-DB
...
    GO TO B400-Calculate-Markdowns
...
B200-Adjust-Stock-for-Purchases
...
B300-Adjust-Stock-for-Sales
...
    GO TO B200-Adjust-Stock-for-Purchases
...
Some-Danged-Ol-Thing
...
B400-Calculate-Markdowns
...
B500-Save-To-Db
Run Code Online (Sandbox Code Playgroud)

当有人决定运行PERFORM ... THRU块的一部分时,地狱会更加"聪明地思考".

    Perform B200-Adjust-Stock-for-Purchases thru B300-Adjust-Stock-for-Sales
...
    Perform B100-Load-From-DB thru B200-Adjust-Stock-for-Purchases
...
    Perform B100-Load-From-DB thru Some-Danged-Ol-Thing
Run Code Online (Sandbox Code Playgroud)

有很多机会可以通过镜子继续下去并继续进入几个替代现实.我不只是对理论上的可能性进行辩护.我正在谈论多年来我所拥有的代码的实际经验.

虽然我在成长,呃我的意思是学习用COBOL编码,但是如果我走出去,我几乎被一个带藤条的大男人殴打威胁.因此,我知道如何走在悬崖的边缘,并使用PERFORM ...... THRU与GO穿插在一起,而不是脱离世界的边缘.然而,它使得非常危险的代码可以杀死,所以更重要的是我知道如何去解码这样的代码并将其变成文明的东西.