4

我现在正在学习 COBOL,真的很喜欢 88 类型的变量,我想知道在其他语言中是否有类似的东西(大多数已知的语言,如 C、Objective-C),甚至使用库。

我唯一能想到的相似之处是使用

#define booleanResult (variableName==95) 

但是不可能设置并boolenResult假设95 作为值。truevariableName

4

4 回答 4

10
05  nicely-named-data             PIC X.
    88  a-meangingful-condition   VALUE "A".
    88  another-meaingingful-condition 
                                  VALUE "A" "B" 
                                     "X" THRU "Z" 
                                      SPACE ZERO.

IF a-meaningful-condition
IF another-meaningful-condition
SET a-meaningful-condition TO TRUE
SET another-meaningful-condition 
                           TO TRUE

IF 测试与 88(条件名称)相关联的数据名称(条件变量)所引用的值,对于单个值或多个值之一,可以包括范围(THRU)和图形常量(零,空间、低价值等)。

SET 是 1985 年标准对 COBOL 的最新补充,它会将data-name 的值更改为88 上指定的第一个值,这样如果您在测试中立即引用 88,则测试将是真实的。

COBOL 在解析为 0 或 1 或其他任何东西的意义上没有布尔值,即为假/真。

任何支持对象的语言都可以用来模仿行为。也许您甚至已经在没有真正意识到的情况下完成了它。

正如 NealB 在评论中指出的那样,可以使用函数(或过程,或将控制权转移到另一个模块),但数据和对它的引用不会在一起,并且不会受到意外伤害。

COBOL 在定义数据结构方面具有很大的灵活性。88 级是维护和理解程序以及首先编写程序的有力帮助。

我不知道另一种语言具有与此等效的直接和自然元素,但是还有很多我不知道的语言。

NealB 在关于使用 THRU/THROUGH 指定值范围的评论中再次提出了重要的一点。

确实需要小心。尽管作者可能认为他们要选择的数据可以用“010”到“090”范围表示,但他们可能没有意识到编译器所做的是通过生成代码来包含该范围内的每个可能值大于或等于“010”且小于或等于“090”。

如果使用 THRU,请确保您的数据不能包含超出预期范围内的任何内容。如果您的意思是“010”“020”“030”...“090”,那很好,只要数据在其入口点得到验证,这样它就永远不会包含任何中间值。

经典示例是大型机上的“A”到“Z”。我们都知道作者的意思,但编译器按字面意思理解。您不能单独使用“A”到“Z”进行验证,因为在 EBCDIC 中,三组字母之间存在“间隙”,使用“A”到“Z”会将这些间隙视为真实的88.

某些 COBOL 编译器中的 88 级别确实下降的地方是缺少的“FALSE”。

从上面的例子中重复使用:

    88  a-meaingingful-condition  VALUE "A".
    88  a-meaingingful-condition-NOT 
                                  VALUE "N".

要测试开关/标志,请使用第一个 88。要关闭 flag.switch,您必须使用第二个。不理想。有关 88 定义的 FALSE 示例,请参阅以下链接之一。

在过去,标志/开关是使用 MOVE 语句设置和重置的。一旦涉及 MOVE,您就会遇到与尝试使用函数时相同的问题。MOVE 与 88 级 VALUE 之间没有绑定关系。

如今,SET 可用于更改字段的值,打开或关闭标志/开关。

    05  FILLER PIC X.
        88  a-meaingingful-condition 
                                  VALUE "A".
        88  a-meaingingful-condition-NOT 
                                  VALUE "N".

被测试的字段甚至不需要名称(它可以是 FILLER 或省略(隐含的 FILLER))。

当然,正如 NealB 在对以下链接之一的评论中指出的那样,有人仍然可以使用 MOVE 对组项目使用引用修改来到达现场。所以...

01  FILLER.
    05  FILLER PIC X.
        88  a-meaingingful-condition 
                                  VALUE "A".
        88  a-meaingingful-condition-NOT 
                                  VALUE "N".

现在他们甚至不能使用引用修改,因为没有要命名的字段。该字段的值只能来自定义上的 VALUE 子句,或来自将 88 之一设置为 TRUE 的 SET 语句。

在这个阶段,标志/开关的值,它的实际值,变得无关紧要。

01  FILLER.
    05  FILLER PIC X(7).
        88  a-meaingingful-condition 
                                  VALUE "APPLE".
        88  a-meaingingful-condition-NOT 
                                  VALUE "BICYCLE".

因为没有任何东西可以用来测试文字/数据名称,并且该字段不能成为除 SET 之外的任何动词的目标,因此您不再需要检查所有表示它们包含 N、Y 或 0 的字段,或1,这样做,它们不是错误的情况,并且没有其他值被放置在这些字段中。

我不是建议使用 APPLE 和 BICYCLE,只是用它们来说明这一点。

88 也可以具有以十六进制表示法表示的值,就像任何字母数字字段一样:

    88  a-meaingingful-condition  VALUE X"25".

也可以在组项上指定 88,通常使用比喻常数作为值:

01  a-group-item.
    88  no-more-data-for-matching VALUE HIGH-VALUES.
    05  major-key                 PIC X(10).
    05  minor-key                 PIC X(5).

在文件匹配过程中,可以在文件末尾将密钥设置为高值,并且使用密钥仍然会导致其他文件被正确处理(低于该文件的密钥) .

以下是来自 SO 的一些问题的链接,这些问题与 88 级直接相关或与重要方面相关。

COBOL 88 级数据类型

cobol中的组变量

在 Cobol 中,为了测试“null 或 empty”,我们使用“NOT = SPACE [ AND/OR ] LOW-VALUE”?它是哪一个?

“NO”前缀在 COBOL 变量中是否有任何特殊含义?

大写字母的COBOL数据验证?

于 2014-01-24T17:28:18.407 回答
2

我的第一个编程语言是 Cobol,现在我使用的是 c#,这是我对 Cobol 88 级别的解决方案:

在 Cobol 中:

01  ws-valid-countries pic xx.
    88  valid-country 'US', 'UK' 'HK'.

move ws-country  to ws-valid-countries

if  valid-country
    perform...

在 C# 中

string[] ValidCountries = {"US","UK","HK"} ;

if ( ValidCountries.Contains(newCountry.Trim().ToUpper())  )
{
   // do something
于 2015-04-29T14:07:06.877 回答
1

将其视为一个布尔 getter(基本上就像在您的宏中一样)和一个 setter(强制变量成为相应的值)。谁说 COBOL 在 1965 年不现代?

于 2014-01-24T17:09:38.483 回答
-1

正如其他人所说,只是一些对象编程。哪个更强大,但远没有那么优雅。喜欢 :

01  MY-DATASET.
    05  MY-DEPARTEMENT PIC 9(2).
        88  ILE-DE-FRANCE VALUES 75, 77, 78, 91 THRU 95.

可以在名为 MyDataset 的类中粗略地翻译成旧 VBA :

Public MyDepartement As Integer
Property Get IleDeFrance() As Boolean
    Dim MyArray() As Variant
    MyArray = Array(75, 77, 78, 91, 92, 93, 94, 95)
    IleDeFrance = UBound(Filter(MyArray, MyDepartement, True)) > -1
End Property

(刚刚测试,它适用于 VBA-excel2013)而且我使 VBA 尽可能简单,部门编号没有干净的 getter 或 setter,只是一个公共数据。由于类是一个数据仓库以及针对它们的编码操作,因此您可以在内部做比简单的 88 级更多的事情(这可能就是为什么此功能没有构成更现代的语言的原因)。但是以复杂性和可读性为代价。

不太优雅,因为必须专门定义数组,并且还必须指定其中的测试存在。虽然它是美妙的88级所固有的。

于 2015-12-08T15:29:59.803 回答