为什么COBOL同时拥有SECTION
和PARAGRAPH
?
有人可以解释为什么COBOL的设计师同时创建SECTION
和PARAGRAPH
s?自从COBOL最初发布以来,这些已经存在,所以我怀疑它们存在的真正原因早已消失(类似于NEXT SENTENCE
之类的东西,它们仍然在语言规范中以便向后兼容但不再需要,因为引入显式范围终止符)。
我的猜测是,可能已引入SECTION
来支持程序覆盖。 SECTION
具有与之关联的可选PRIORITY编号,用于标识其所属的程序覆盖。但是,大多数COBOL的现代实现都忽略或删除了PRIORITY数字(和覆盖)。
目前,我发现在SECTION
的{{1}}部分仍然需要DECLARATIVE
,但是没有理由这样做。我发现除PROCEDURE DIVISION
以外SECTION
和PARAGRAPH
之间的语义差异从属于PARAGRAPH
。
一些COBOL商店禁止使用SECTION
支持SECTION
(在北美似乎很常见)。其他人禁止PARAGRAPH
支持PARAGRAPH
(在欧洲似乎很常见)。还有一些人有关于何时适当的指导方针。所有这一切对我来说都是非常随意的 - 这就引出了一个问题:为什么他们首先会被纳入语言规范?而且,它们今天有任何相关性吗?
如果你回答这个问题,如果你也可以指出一个支持你的答案的参考文件,那将会很棒。
由于
答案 0 :(得分:6)
我在1978年左右在ICL 2903上学习了COBOL。我有一个模糊的内存,可以为SECTION标题分配一个数字范围,这意味着当程序太多时,那些SECTION标题可以换入和换出内存。很大的记忆。
答案 1 :(得分:6)
没有关于此的参考,因为我听说它从我店里的一位老定时器传递给我但是......
在旧的COBOL编译器中,至少对于IBM和Unisys,部分能够一次一个地加载到内存中。回到过去的时候,当内存不足时,一个太大而无法一次性加载到内存中的程序能够使用部分模块化内存使用。有两个部分和段落允许程序员决定哪些代码部分一起加载到内存中,如果它们不能同时加载 - 你需要将相同执行循环的两个部分加载到一起以提高效率。如今它或多或少没有实际意义。
我的商店仅使用段落,禁止GOTO并要求退出段落,所以我们所有的PERFORMS都是PERFORM 100-PARAGRAPH THRU 100-EXIT或类似的东西 - 这似乎使段落更像我的部分。但我不认为现在真的有太大差异。
答案 2 :(得分:5)
我知道这是一个老问题,但OP要求提供关于在COBOL中使用SECTION和PARAGRAPH的原始理由的文档。
你不能获得比CODASYL Journal文档更多的“原创”。
在期刊的语言规范的第8部分,
“COBOL细分是一种提供手段的工具 用户可以与编译器通信以指定对象程序 覆盖要求“
(第331页,第8.1节“分段 - 一般说明”)
“虽然它不是强制性的,但是来源的程序部门 程序通常写成连续的一组部分,每个部分 它由一系列密切相关的操作组成 旨在共同执行特定功能。但是什么时候 使用分段,整个程序部门必须在 部分。此外,每个部分必须归类为归属 无论是固定部分还是其中一个独立部分 对象程序。分割决不会影响对它的需求 程序名称的限定以确保唯一性。“
(第331页,第8.1.2.1节“程序段”)
在她关于比较编程语言的书中(“编程语言:历史与基础”,1969年)Jean Sammet(代表Sylvania Electric的CODASYL委员会成员)表示:
“..存储分配由编译器自动处理。 分配可执行代码的主要单位是一组部分 称为段。程序员组合部分指定一个 每个部分名称的优先级编号。 ...编译器是必需的 看到提供了适当的控制转移以便控制 在没有同时存储的段之间可以发生。 ......“
(p 369 - 371 V.3 COBOL)
答案 3 :(得分:2)
嗯,最简单的原因是SECTION为您提供“模块化” - 就像C中的功能一样 - 是“结构化”程序中的必需品。您会注意到使用SECTION编写的代码看起来比段落中编写的代码更具可读性,因为每个部分都必须有一个“EXIT” - 一个唯一且非常明确的退出点来自SECTION(paragrpah的退出点远更加模糊和隐含,即直到找到新的段落声明)。考虑这个例子,您可能想在代码中使用部分:
*==================
MAINLINE SECTION.
*==================
PERFORM SEC-A
PERFORM SEC-B
PERFORM SEC-C
GOBACK.
*==================
MAINLINE-EXIT.
*==================
EXIT.
*==================
SEC-A SECTION.
*==================
.....
.....
.....
.....
IF <cond>
go to A-EXIT
end-if
.....
.....
.....
.....
.
*==================
A-EXIT.
*==================
EXIT.
在段落中编写代码时,不要以为你会有这种特权。您可能不得不编写一个巨大的ELSE语句来掩盖在达到某个条件时您不想执行的语句(考虑一组语句将跨2-3页运行...另一组IF / ELSE会让你缩进缩进)。当然,你必须使用“GO TO”来达到这个目的,但是你总是可以指导你的专业人士不要使用GO TO,除非是退出,这是一个公平的交易,我认为。
所以,虽然我也同意任何可以使用SECTION编写的东西也可以使用段落编写(很少或没有调整),我个人的选择是去实现可以让我的开发人员的工作将来会更容易!
答案 4 :(得分:1)
首先,段落名称必须是唯一的,除非它们在单独的部分中,因此部分允许段落的“命名空间”。
如果我没记错的话,必须使用SECTION
的唯一原因是DECLARATIVES
。除此之外,它们是可选的,主要用于分段段落。我认为,只有当PERFORM
段落在同一部分时才需要{{1}}这是常见的(相对而言)。
答案 5 :(得分:1)
一个部分可以有几个段落。当您执行某个部分时,它会执行所有部分中的段落。在该部分中,您可以使用PERFORM或GOTO分支到该部分中的段落。
答案 6 :(得分:1)
Cobol是在50年代中期开发的。正如全名所暗示的那样,它是为商业编程而开发的,因为它是一种与商业目的相关的语言,而不是现有的“科学”或“技术”语言(无论如何都有很少的“语言”)和“机器代码”(具体而言)当然,对于一个特定的建筑(我几乎说“特定芯片”,在考虑真空管之前))可能必须通过某些机器上的物理开关/拨盘设置)如果幸运的话有“装配工”。为了它的目的,Cobol当时非常先进。
目的是使用Cobol编写的程序更像英语而不仅仅是一组“代码”,这些代码对于发起者来说意味着什么。
如果你看一些与语言有关的命名法 - 段落,句子,动词,条款 - 它是故意遵循归因于英语的模式。
在您将事物与正式商业文件联系起来之前,SECTION不太适合这一点。
SECTION和段落也出现在PROCEDURE DIVISION之外。与书面英语一样,段落可以单独存在,也可以是SECTION的一部分。
SECTION可能具有与“细分功能”相关的优先级编号。这通常包括“覆盖”SECTION以提供原始级别的内存管理。这是一个“计算功能”,而不是英语语言:-)“分段功能”确实有一些影响,但我从未见过它实际使用过。
如果没有DECLARATIVES(我没有使用,并且刚刚注意到手册不清楚),那么对于PERFORM是否使用SECTION或段落是“选择”。
如果使用GO TO,理性地,可以用PERFORM ...... TRHU实现“等价”......如果没有,并且没有无偿使用PERFORM ...... THRU ......,则存在等价性已经
与“结构化”代码和现代语言的比较是“向后阅读历史”或仅概述特定的“实践”。从“意大利面条代码”获得的声誉和ALTER ...继续......很可能20年来,除非你需要“内存管理”,否则对PERFORM不做太多“常见”,但我没有任何参考或知识来支持这一点。
SECTION允许重复的段落名称,否则段落名称必须是唯一的。
我无法一直把一个特定的手指放在另一个上面。
如果使用GO TO,我会使用SECTION。如果没有,段落。有了DECLARATIVES,我会使用SECTION。如果使用SECTION,我会使用SECTION启动PROCEDURE DIVISION以避免诊断消息。
地方标准可能要求,但不一定是在“现代”(甚至“理性”)的基础上。根据我的经验,很多是“已知”但实际上误解了SECTION和段落。
对于性能(正在处理大量数据,我的意思是质量),那么一个SECTION的PERFORM而不是多个单独的段落将会看到改进。效果与PERFORM ...... THRU相同......但我不想推荐它。 转到PERFORM范围之外是1)坏2)可能会失去“优化”。不应该是一个问题*除了“当GO TO异常/异常并且不期望任何逻辑返回。如果感觉必须”立即“使用它,那么尽管”反直觉“,最好用PERFORM完成“方面(所以记录下来)。
答案 7 :(得分:0)
我将尽我所能回答这个问题。如果您唯一的编码问题是x86或ARM,那么您将遇到很大的困难。是的,这些芯片卖很多,但这并不意味着它们很好,只是便宜的人不介意将它们扔掉。
许多此类信息可以在“ The Minimum You Need to Know to Be an OpenVMS Application Developer”中找到。您会发现它是Dr. Dobb's recommended reading list for all developers上为数不多的标题之一。是的,我写的。这也是HP OpenVMS工程小组为希望学习该平台的开发人员推荐的书。
我在该平台上使用的COBOL主要发生在1980年代,当时是VAX / VMS。然后它变成了OpenVMS; Alpha / OpenVMS;安腾/ OpenVMS;不久将成为x86 / OpenVMS。在具有真实操作系统的真实计算机上,部分具有含义。每个部分都创建了一个PSECT。在链接程序术语中,它是Program SECtion的简称。根据该部分的内容,设置了各种载荷属性。每个PSECT将被加载到一个或多个512字节内存页中。内存页的设计大小与磁盘块完全相同。 VMS代表虚拟内存系统。 IBM拥有一些自己的操作系统,这些操作系统在本质上是不同的,但它们也都是真正的虚拟内存系统。这不是“重叠链接”。这是一个x86术语,是由于严重的体系结构缺陷而产生的。请从286天开始阅读紧凑型,小型,中型和大型“内存模型”。另请阅读EMS和XMS内存分页。 Oiy真有趣!
这是那本书中发现的众多程序之一。
IDENTIFICATION DIVISION.
PROGRAM-ID。 COB_ZILL_DUE_REPORT_SUB。 作者。罗兰·休斯(Roland Hughes)。 书面日期。 2005-02-08。 日期已完成。今天。
环境部门。
输入-输出部分。
文件控制。
SELECT DRAW-STATS
ASSIGN TO 'DRAWING_STATS'
ORGANIZATION IS INDEXED
ACCESS MODE IS SEQUENTIAL
RECORD KEY IS ELM_NO IN DSTATS-REC
LOCK MODE IS AUTOMATIC
FILE STATUS IS D-STAT.
SELECT MEGA-STATS
ASSIGN TO 'MEGA_STATS'
ORGANIZATION IS INDEXED
ACCESS MODE IS SEQUENTIAL
RECORD KEY IS ELM_NO IN MSTATS-REC
LOCK MODE IS AUTOMATIC
FILE STATUS IS M-STAT.
SELECT SORT-FILE ASSIGN TO 'TMP.SRT'.
SELECT SORTED-FILE ASSIGN TO DISK.
SELECT RPT-FILE ASSIGN TO 'ZILL_DUE.RPT'.
数据部门。
文件部分。
FD DRAW-STATS 是全球的 标签记录是标准的。
COPY 'CDD_RECORDS.ZILLIONARE_STATS_RECORD' FROM DICTIONARY
REPLACING ZILLIONARE_STATS_RECORD BY DSTATS-REC.
FD MEGA-STATS 是全球的 标签记录是标准的。
COPY 'CDD_RECORDS.ZILLIONARE_STATS_RECORD' FROM DICTIONARY
REPLACING ZILLIONARE_STATS_RECORD BY MSTATS-REC.
FD RPT文件 标签记录被省略。
01 RPT-DTL PIC X(80).
SD分类文件。
COPY 'CDD_RECORDS.ZILLIONARE_STATS_RECORD' FROM DICTIONARY
REPLACING ZILLIONARE_STATS_RECORD BY SORT-REC.
FD分类文件 ID的值是存储的文件名。
COPY 'CDD_RECORDS.ZILLIONARE_STATS_RECORD' FROM DICTIONARY
REPLACING ZILLIONARE_STATS_RECORD BY SORTED-REC.
工作存储部分。 01常数。 05 SORT-FILE-NAME PIC X(7)值'TMP.SRT'。 05 SORTED-FILE-NAME PIC X(8)VALUE'STAT.SRT'。
01 STATUS-VARIABLES.
05 M-STAT PIC X(2).
05 D-STAT PIC X(2).
05 EOF-FLAG PIC X.
88 IT-IS-END-OF-FILE VALUE 'Y'.
01 STUFF.
05 TODAYS-DATE.
10 TODAY_YYYY PIC X(4).
10 TODAY_MM PIC X(2).
10 TODAY_DD PIC X(2).
05 TODAYS-DATE-FORMATTED.
10 FMT_MM PIC Z9.
10 FILLER PIC X VALUE '/'.
10 FMT_DD PIC 99.
10 FILLER PIC X VALUE '/'.
10 FMT_YYYY PIC 9(4).
05 FLT-1 COMP-2.
05 WORK-STR PIC X(65).
01 REPORT-DETAIL.
05 ELM-NO-DTL PIC Z9.
05 FILLER PIC X(3).
05 HIT-COUNT-DTL PIC ZZZ9.
05 FILLER PIC X(3).
05 SINCE-LAST-DTL PIC ZZZ9.
05 FILLER PIC X(5).
05 PCT-HITS-DTL PIC Z9.999.
05 FILLER PIC X(4).
05 AVE-BTWN-DTL PIC ZZ9.999.
01 REPORT-HDR1.
05 THE-DATE PIC X(12).
05 FILLER PIC X(20).
05 PAGE-TITLE PIC X(17).
01 REPORT-HDR2.
05 FILLER PIC X(33).
05 GROUP-TITLE PIC X(20).
01 REPORT-HDR3.
05 HDR3-TXT PIC X(40) VALUE
'No Hits Since Pct_hits Ave_btwn'.
01 REPORT-HDR4.
05 HDR4-TXT PIC X(40) VALUE
'-- ---- ----- -------- --------'.
程序部门。
A000-MAIN。
PERFORM B000-HSK.
SORT SORT-FILE
ON DESCENDING KEY SINCE_LAST IN SORT-REC
INPUT PROCEDURE IS S000-DSTAT-INPUT
GIVING SORTED-FILE.
PERFORM B010-REPORT-DRAWING-NUMBERS.
STRING SORT-FILE-NAME, ';*' DELIMITED BY SIZE INTO WORK-STR.
CALL 'LIB$DELETE_FILE' USING BY DESCRIPTOR WORK-STR.
STRING SORTED-FILE-NAME, ';*' DELIMITED BY SIZE INTO WORK-STR.
CALL 'LIB$DELETE_FILE' USING BY DESCRIPTOR WORK-STR.
* *设置报告的第二部分 * 将空间移至RPT-DTL。 在高级页面之前写RPT-DTL。
MOVE SPACES TO EOF-FLAG.
MOVE ' Mega Drawing Numbers' TO GROUP-TITLE.
SORT SORT-FILE
ON DESCENDING KEY SINCE_LAST IN SORT-REC
INPUT PROCEDURE IS S001-MSTAT-INPUT
GIVING SORTED-FILE.
PERFORM B010-REPORT-DRAWING-NUMBERS.
STRING SORT-FILE-NAME, ';*' DELIMITED BY SIZE INTO WORK-STR.
CALL 'LIB$DELETE_FILE' USING BY DESCRIPTOR WORK-STR.
STRING SORTED-FILE-NAME, ';*' DELIMITED BY SIZE INTO WORK-STR.
CALL 'LIB$DELETE_FILE' USING BY DESCRIPTOR WORK-STR.
CLOSE RPT-FILE.
CALL 'LIB$SPAWN' USING BY DESCRIPTOR 'EDIT/READ ZILL_DUE.RPT'.
EXIT PROGRAM.
B000-HSK。 致电“ COB_FILL_IN_LOGICALS”。
MOVE SPACES TO STATUS-VARIABLES.
ACCEPT TODAYS-DATE FROM DATE YYYYMMDD.
MOVE TODAY_YYYY TO FMT_YYYY.
MOVE TODAY_DD TO FMT_DD.
MOVE TODAY_MM TO FMT_MM.
OPEN OUTPUT RPT-FILE.
MOVE SPACES TO REPORT-HDR1.
MOVE TODAYS-DATE-FORMATTED TO THE-DATE.
MOVE 'Due Number Report' to PAGE-TITLE.
MOVE SPACES TO REPORT-HDR2.
MOVE 'Drawing Numbers' TO GROUP-TITLE.
B010-报告-图纸编号。
MOVE SPACES TO EOF-FLAG.
OPEN INPUT SORTED-FILE.
READ SORTED-FILE
AT END SET IT-IS-END-OF-FILE TO TRUE.
PERFORM C010-DRAWING-HEADINGS.
PERFORM UNTIL IT-IS-END-OF-FILE
MOVE SPACES TO REPORT-DETAIL
MOVE ELM_NO IN SORTED-REC TO ELM-NO-DTL
MOVE HIT_COUNT IN SORTED-REC TO HIT-COUNT-DTL
MOVE SINCE_LAST IN SORTED-REC TO SINCE-LAST-DTL
MOVE PCT_HITS IN SORTED-REC TO PCT-HITS-DTL
MOVE AVE_BTWN IN SORTED-REC TO AVE-BTWN-DTL
MOVE REPORT-DETAIL TO RPT-DTL
WRITE RPT-DTL BEFORE ADVANCING 1 LINE
READ SORTED-FILE
AT END SET IT-IS-END-OF-FILE TO TRUE
END-READ
END-PERFORM.
CLOSE SORTED-FILE.
C010-DRAWING-HEADINGS。
MOVE SPACES TO RPT-DTL.
MOVE REPORT-HDR1 TO RPT-DTL.
WRITE RPT-DTL BEFORE ADVANCING 2 LINES.
MOVE SPACES TO RPT-DTL.
MOVE REPORT-HDR2 TO RPT-DTL.
WRITE RPT-DTL BEFORE ADVANCING 1 LINE.
MOVE SPACES TO RPT-DTL.
MOVE REPORT-HDR3 TO RPT-DTL.
WRITE RPT-DTL BEFORE ADVANCING 1 LINE.
MOVE SPACES TO RPT-DTL.
MOVE REPORT-HDR4 TO RPT-DTL.
WRITE RPT-DTL BEFORE ADVANCING 1 LINE.
S000-DSTAT-INPUT。
OPEN INPUT DRAW-STATS.
READ DRAW-STATS NEXT
AT END SET IT-IS-END-OF-FILE TO TRUE.
PERFORM UNTIL IT-IS-END-OF-FILE
MOVE SINCE_LAST IN DSTATS-REC TO FLT-1
IF FLT-1 >= AVE_BTWN IN DSTATS-REC
MOVE DSTATS-REC TO SORT-REC
RELEASE SORT-REC
END-IF
READ DRAW-STATS
AT END SET IT-IS-END-OF-FILE TO TRUE
END-READ
END-PERFORM.
CLOSE DRAW-STATS.
S001-MSTAT-INPUT。
OPEN INPUT MEGA-STATS.
READ MEGA-STATS NEXT
AT END SET IT-IS-END-OF-FILE TO TRUE.
PERFORM UNTIL IT-IS-END-OF-FILE
MOVE SINCE_LAST IN MSTATS-REC TO FLT-1
IF FLT-1 >= AVE_BTWN IN MSTATS-REC
MOVE MSTATS-REC TO SORT-REC
RELEASE SORT-REC
END-IF
READ MEGA-STATS
AT END SET IT-IS-END-OF-FILE TO TRUE
END-READ
END-PERFORM.
CLOSE MEGA-STATS.
END PROGRAM COB_ZILL_DUE_REPORT_SUB。
对不起,“代码”功能在此编辑器中的工作方式。
某些部分已经存在。如果没有INPUT-OUTPUT部分,您的程序将无法执行I-O。在此将名称映射到物理存储。
如果您有INPUT-OUTPUT SECTION,则必须有FILE SECTION。在这里定义每个命名文件的记录布局。处理磁盘数据文件时,标签记录始终为标准;写报告文本文件时,标签记录始终为“忽略”。我不记得其他一些条款。请注意所有这些FD语句中包含的SD。 FD是文件定义,SD是排序定义。
如果要使用任何局部变量,则必须具有工作存储部分。您不能动态声明变量,所有变量都必须在此处声明。该PSECT除其他外还获得DATA段属性。如果您调用某项服务或某项服务且其地址不正确,则尝试在此PSECT中执行代码时,操作系统会将您的应用程序从鞍座中射出。
在PROCEDURE DIVISION之后创建的所有PSECT都标记为EXEC,受写保护。如果您在执行期间尝试覆盖此处的任何内容,则操作系统会将您的程序从鞍座中射出。尝试在此处编写的任何其他程序也将被淘汰。
向下扫描到A000-MAIN中的SORT SORT-FILE。 COBOL排序例程非常了不起。请注意,我提供了一个INPUT PROCEDURE,它是一个段落。过去,在运行ROSCOE的IBM大型机上,这必须是一个INPUT SECTION。他们在PSECT上需要不同的属性,以便系统排序例程可以读取/写入。
这是该书中另一个程序的摘录。
*
* FMS定义 * 复制“ MEGA_TEXT_LIB”的“ COBFDVDEF”。
链接部分。
01 FMS-STUFF.
05 FMSSTATUS PIC S9(9) COMP.
05 RMSSTATUS PIC S9(9) COMP.
05 TCA PIC X(12).
05 WORKSPACE PIC X(12).
使用FMS-STUFF进行程序划分。
链接部分创建可共享内存的PSECT。当您调用返回值的外部例程时,它们必须在此处。还必须在链接部分中授予PROCEDURE DIVISION访问其所需的各种内容。
稍后您将在代码段中看到
B010-USER-INPUT.
PERFORM C000-FORWARD-LOAD
CALL 'FDV$PUTAL' USING BY DESCRIPTOR SCREEN-REC.
MOVE SPACES TO WORK-STR.
CALL 'FDV$GETAL' USING BY DESCRIPTOR WORK-STR
BY REFERENCE TERMINATOR.
EVALUATE TERMINATOR
WHEN FDV$K_FK_E6 SET LOAD-FORWARD TO TRUE
WHEN FDV$K_FK_E5 SET LOAD-REVERSE TO TRUE
WHEN FDV$K_FK_F10 SET WE-ARE-DONE TO TRUE
END-EVALUATE.
您可以传递希望的任何局部变量,只要正确传递即可。这是需要特殊PSECT属性的文字。
太晚了,我很累,但我似乎记得您可以在PROCEDURE DIVISION中的SECTION声明中使用USING子句。可用于COBOL的在线文档,至少是GOOGLE索引的文档,实际上是毫无价值的。如果您想了解更多详细信息,请搜索大约1980年代的COBOL教科书。它不会包含任何新内容,但会回答很多问题。
答案 8 :(得分:-1)
我们在所有37K MVS批量COBOL程序中使用COBOL SECTION 编码。我们使用这种技术来获得更快的运行时间并显着降低CPU开销。这种COBOL编码技术与高性能批量汇编程序非常相似。
称之为高性能功能结构化COBOL 编程
一旦定义了SECTION,所有PERFORM xxxxx将在下一个编码SECTION返回,而不是SECTION中的下一段。如果段落在第一个SECTION之前编码,那么它们可以正常执行。 (但我们不允许这样做)
使用SECTION的开销高于使用和 PERFORM 仅使用段落 - 除非 - 您使用 GOTO 绕过应该有条件执行的代码的逻辑。我们的规则是 GOTO 只能在同一个SECTION中指向标记行。 (段落) SECTION中的所有段落必须是SECTION函数的子函数。 EXIT 指令是汇编程序NOP指令。它允许在下一个SECTION之前放置 Tag-Line - 快速退出/返回。
执行 PERFORM xxxx THRU yyyy比没有 GOTO 的SECTION执行更多的CPU开销。
警告:在SECTION中执行PERFORM xxxx 标记行将通过SECTION中的所有代码,直到遇到下一个SECTION。当前SECTION之外的 GOTO 标记行将通过新着陆SECTION中的所有代码落入,直到遇到下一个SECTION。 (但我们不允许这样做)