AND 和 OR (COBOL) 的问题

发布于 2024-10-05 23:11:02 字数 307 浏览 9 评论 0原文

我似乎无法把这一部分做好。我得到了一个包含一堆名称的输入文件,其中一些我需要跳过,每个名称都有额外的信息。我尝试使用 AND 和 OR 来跳过我不需要的名称,然后我想出了这个。

IF DL-CLASS-STANDING = 'First Yr' OR 'Second Yr' AND
GRAD-STAT-IN = ' ' OR 'X'

它摆脱了除了一个人之外的所有人,但是当我尝试添加另一组 AND 和 OR 时,程序开始表现得像规定一样,甚至不存在。

我是否让它对编译器来说太复杂了?有没有更简单的方法来跳过事情?

I can't seem to get this one part right. I was given a input file with a bunch of names, some of which I need to skip, with extra information on each one. I was trying use ANDs and ORs to skip over the names I did not need and I came up with this.

IF DL-CLASS-STANDING = 'First Yr' OR 'Second Yr' AND
GRAD-STAT-IN = ' ' OR 'X'

It got rid of all but one person, but when I tried to add another set of ANDs and ORs the program started acting like the stipulations where not even there.

Did I make it too complex for the compiler? Is there an easier way to skip over things?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

和影子一齐双人舞 2024-10-12 23:11:02

尝试添加一些括号来对事物进行逻辑分组:

IF (DL-CLASS-STANDING = 'First Yr' OR 'Second Yr') AND
(GRAD-STAT-IN = ' ' 或 'X')

Try adding some parentheses to group things logically:

IF (DL-CLASS-STANDING = 'First Yr' OR 'Second Yr') AND
(GRAD-STAT-IN = ' ' OR 'X')

原来是傀儡 2024-10-12 23:11:02

可能想要研究完全扩展该缩写表达式,因为当有很多子句时,扩展可能不是您所想的 - 通常最好是明确的。


然而,要做的是使用 88 级别变量来使其更具可读性 - 这些是特殊级别,允许直接在数据划分中指定条件,而不是使用代码中明确的条件。

换句话说,在数据部门中放入这样的内容:

03  DL-CLASS-STANDING  PIC X(20).
    88 FIRST-YEAR          VALUE 'First Yr'.
    88 SECOND-YEAR         VALUE 'Second Yr'.
03  GRAD-STAT-IN       PIC X.
    88 GS-UNKNOWN          VALUE ' '.
    88 GS-NO               VALUE 'X'.

然后您可以在表达式中使用 88 级别变量:

IF (FIRST-YEAR OR SECOND-YEAR) AND (GS-UNKNOWN OR GS-NO) ...

在我看来,这是更具可读性的,也是 COBOL 的全部要点毕竟, 看起来像可读的英语。

You may want to look into fully expanding that abbreviated expression since the expansion may not be what you think when there's a lot of clauses - it's often far better to be explicit.


However, what I would do is use the 88 level variables to make this more readable - these were special levels to allow conditions to be specified in the data division directly rather than using explicit conditions in the code.

In other words, put something like this in your data division:

03  DL-CLASS-STANDING  PIC X(20).
    88 FIRST-YEAR          VALUE 'First Yr'.
    88 SECOND-YEAR         VALUE 'Second Yr'.
03  GRAD-STAT-IN       PIC X.
    88 GS-UNKNOWN          VALUE ' '.
    88 GS-NO               VALUE 'X'.

Then you can use the 88 level variables in your expressions:

IF (FIRST-YEAR OR SECOND-YEAR) AND (GS-UNKNOWN OR GS-NO) ...

This is, in my opinion, more readable and the whole point of COBOL was to look like readable English, after all.

冰雪梦之恋 2024-10-12 23:11:02

首先要注意的是,显示的代码是正在运行的代码,并且未显示未给出所需结果的修改后的代码。作为补充,如果只剩下一个人,为什么还需要更多的选择呢?总而言之,除了“我不知道如何在 COBOL 中使用 OR。我不知道如何在 COBOL 中使用 AND”之外,实际问题还不清楚。

除此之外,还有两个实际问题:

  1. 我是否让它对于编译器来说太复杂了?

  2. 是否有更简单的方法来跳过事物[是否有更清晰的方式来编写条件]?

对于第一个问题,答案是否定的。对于编译器来说这并不困难。编译器确切地知道如何处理 OR、AND(以及 NOT,我们稍后会介绍)的任意组合。问题是,人类编写者/读者能否成功地编写一个条件,以便编译器知道他们想要什么,而不是仅仅给出编译器遵循其规则的结果(不考虑对一行的多种可能的人类解释)代码)?

因此,第二个问题变成:

如何编写一个复杂的条件,使编译器能够以与我作为作者的意图相同的方式理解,并且对于具有一定 COBOL 经验的代码读者以相同的方式理解?

首先,快速重新排列问题中的(工作)代码:

IF DL-CLASS-STANDING = 'First Yr' OR 'Second Yr'
AND GRAD-STAT-IN = ' ' OR 'X'

以及答案之一中建议的代码:

IF (DL-CLASS-STANDING = 'First Yr' OR 'Second Yr')
AND (GRAD-STAT-IN = ' ' OR 'X')

第二个版本更清晰,但是(或和)它与第一个版本相同。它并没有使该代码工作,而是允许该代码继续工作。

答案是解决复杂性增加的条件问题的解决方案:括号/圆括号(简单地简化复杂性是另一种可能性,但如果没有非工作示例,很难提出建议)。

原始代码可以工作,但是当它需要更复杂时,轮子就开始脱落。

建议的代码可以工作,但是它没有(完全)解决扩展条件复杂性的问题,因为在较小程度上,它在括号内重复了扩展条件复杂性的问题健康)状况。

怎么会这样呢?

一个简单的条件:

IF A EQUAL TO "B"

一个稍微复杂的条件:

IF A EQUAL TO "B" OR "C"

稍微但不完整的简化:

IF (A EQUAL TO "B" OR "C")

如果条件必须变得更复杂,使用 AND,对于人类来说可以很简单(编译器不关心,它不能被愚弄了):

IF (A EQUAL TO "B" OR "C")
AND (E EQUAL TO "F")

但是这又如何呢?

IF (A EQUAL TO "B" OR "C" AND E EQUAL TO "F")

将 AND 放在括号内可以复制人类的原始问题。这是什么意思,它是如何工作的?

一个答案是这样的:

IF (A EQUAL TO ("B" OR "C") AND E EQUAL TO "F")

也许更清楚,但不是对每个人来说,而且最初的问题仍然存在,只是较小的。

所以:

IF A EQUAL TO "B"
OR A EQUAL TO "C"

对于第一部分进行了简化,但问题仍然是次要的(只需添加 AND ...),因此:

IF (A EQUAL TO "B")
OR (A EQUAL TO "C")

导致:

IF ((A EQUAL TO "B")
OR (A EQUAL TO "C"))

And:

IF ((A EQUAL TO "B")
 OR (A EQUAL TO C))

现在,如果有人想用 AND 进行扩充,那就很容易且清晰了。如果在与条件部分之一相同的级别上完成,则它仅附加到该条件部分。如果在最外层完成,它会附加到两者(全部)。

IF (((A EQUAL TO "B")
  AND (E EQUAL TO "F"))
 OR (A EQUAL TO "C"))

或者

IF (((A EQUAL TO "B")
 OR (A EQUAL TO "C"))
AND (E EQUAL TO "F"))

如果有人想在括号内插入 AND 该怎么办?嗯,因为括号内的内容很简单,而且人们不倾向于这样做。如果括号内的内容已经很复杂,那么往往会添加它。似乎一些因单独存在而变得简单的东西往往不会变得复杂,而一些已经很复杂的东西(不止一件事,而不是单独的东西)往往会在没有太多进一步思考的情况下变得更加复杂。

COBOL 是一种古老的语言。许多用 COBOL 编写的旧程序仍在运行。许多 COBOL 程序必须经过修改,或者只是阅读才能理解某些内容,并且在其多年的生命周期中需要多次修改。

当更改代码时,通过向条件添加某些内容,最好不需要“干扰”条件的原始部分。如果复杂性留在括号内,则更有可能需要对代码进行干扰,这会增加理解(更复杂)和更改(需要更多小心,需要更多测试,因为代码被干扰)的时间。

许多旧程序都是不良实践的例子。除了小心对待他们之外,没有什么可做的。

没有任何借口去编写新的代码,这些代码在未来需要比绝对必要的更多的维护和保养。

现在,上面的例子可能被认为是冗长的。这是COBOL,对吧?打字很多?但 COBOL 在数据定义方面提供了巨大的灵活性。作为其中的一部分,COBOL 具有级别 88(条件名称)。

以下是上述部分内容的数据定义:

01  A PIC X.
    88  PARCEL-IS-OUTSIZED VALUE "B" "C".
01  F PIC X.
    88  POSTAGE-IS-SUFFICIENT VALUE "F".

条件变为:

IF PARCEL-IS-OUTSIZED
AND POSTAGE-IS-SUFFICIENT

所有相关的文字值现在都有一个名称,而不仅仅是文字值,以便编码器可以指示它们的实际含义,以及携带该名称的实际值意义。如果需要向 PARCEL-IS-OUTSIZED 添加更多类别,则扩展 88 级别的 VALUE 子句。

如果要组合另一个条件,那就简单多了。

这一切都是真的吗?嗯,是的。这么看吧。

COBOL 对编码条件的结果进行运算。

If condition

简单的条件可以通过使用括号进行复合,形成一个条件:

If condition = If (condition) = If ((condition1) operator (condition2))...

依此类推,达到编译器的限制。

人类只需要为了当前的目的而处理他们想要的情况。对于一般逻辑流程,请查看 If 条件。为了进行验证,请查看最低的细节。对于子集,查看与子集相关的条件部分。

使用简单的条件。通过括号/圆括号使条件变得简单。根据需要,通过组合简单条件来创建复杂条件。使用条件名称与文字值进行比较。

OR 和 AND 已经处理完毕。 NOT 通常被视为需要谨慎对待的事情:

IF NOT A EQUAL TO B
IF A NOT EQUAL TO B

IF (NOT (A EQUAL TO B)), remembering that this is just IF condition

因此,如果它变得简单,那么 NOT 并不可怕。

在整个过程中,我一直在编辑空格。因为括号就在那里,所以我喜欢把它们放在你面前。我喜欢构造和缩进条件,以强调我赋予它们的含义。

所以:(

IF ( ( ( condition1 )
    OR ( condition2 ) )
AND
     ( ( condition3 )
    OR ( condition4 ) ) )

而且比这更雕刻)。通过结构化,我希望a)我能少搞砸,b)当/如果我搞砸了,有人更有机会注意到它。

如果条件不简化,那么理解代码就更困难了。更改代码更加困难。对于学习 COBOL 的人来说,保持简单对所有人来说都是长期利益。

The first thing to note is that the code shown is the code which was working, and the amended code which did not give the desired result was never shown. As an addendum, why, if only one person were left, would more selection be necessary? To sum up that, the actual question is unclear beyond saying "I don't know how to use OR in COBOL. I don't know how to use AND in COBOL".

Beyond that, there were two actual questions:

  1. Did I make it too complex for the compiler?

  2. Is there an easier way to skip over things [is there a clearer way to write conditions]?

To the first, the answer is No. It is very far from difficult for the compiler. The compiler knows exactly how to handle any combinations of OR, AND (and NOT, which we will come to later). The problem is, can the human writer/reader code a condition successfully such that the compiler will know what they want, rather than just giving the result from the compiler following its rules (which don't account for multiple possible human interpretations of a line of code)?

The second question therefore becomes:

How do I write a complex condition which the compiler will understand in an identical way to my intention as author and in an identical way for any reader of the code with some experience of COBOL?

Firstly, a quick rearrangement of the (working) code in the question:

IF DL-CLASS-STANDING = 'First Yr' OR 'Second Yr'
AND GRAD-STAT-IN = ' ' OR 'X'

And of the suggested code in one of the answers:

IF (DL-CLASS-STANDING = 'First Yr' OR 'Second Yr')
AND (GRAD-STAT-IN = ' ' OR 'X')

The second version is clearer, but (or and) it is identical to the first. It did not make that code work, it allowed that code to continue to work.

The answer was addressing the resolution of the problem of a condition having its complexity increased: brackets/parenthesis (simply simplifying the complexity is another possibility, but without the non-working example it is difficult to make suggestions on).

The original code works, but when it needs to be more complex, the wheels start to fall off.

The suggested code works, but it does not (fully) resolve the problem of extending the complexity of the condition, because, in minor, it repeats the problem, within the parenthesis, of extending the complexity of the condition.

How is this so?

A simple condition:

IF A EQUAL TO "B"

A slightly more complex condition:

IF A EQUAL TO "B" OR "C"

A slight, but not complete, simplification of that:

IF (A EQUAL TO "B" OR "C")

If the condition has to become more complex, with an AND, it can be simple for the humans (the compiler does not care, it cannot be fooled):

IF (A EQUAL TO "B" OR "C")
AND (E EQUAL TO "F")

But what of this?

IF (A EQUAL TO "B" OR "C" AND E EQUAL TO "F")

Placing the AND inside the brackets has allowed the original problem for humans to be replicated. What does that mean, and how does it work?

One answer is this:

IF (A EQUAL TO ("B" OR "C") AND E EQUAL TO "F")

Perhaps clearer, but not to everyone, and again the original problem still exists, in the minor.

So:

IF A EQUAL TO "B"
OR A EQUAL TO "C"

Simplified, for the first part, but still that problem in the minor (just add AND ...), so:

IF (A EQUAL TO "B")
OR (A EQUAL TO "C")

Leading to:

IF ((A EQUAL TO "B")
OR (A EQUAL TO "C"))

And:

IF ((A EQUAL TO "B")
 OR (A EQUAL TO C))

Now, if someone wants to augment with AND, it is easy and clear. If done at the same level as one of the condition parts, it solely attaches to that. If done at the outermost level, it attaches to both (all).

IF (((A EQUAL TO "B")
  AND (E EQUAL TO "F"))
 OR (A EQUAL TO "C"))

or

IF (((A EQUAL TO "B")
 OR (A EQUAL TO "C"))
AND (E EQUAL TO "F"))

What if someone wants to insert the AND inside the brackets? Well, because inside the brackets it is simple, and people don't tend to do that. If what is inside the brackets is already complicated, it does tend to be added. It seems that something which is simple through being on its own tends not to be made complicated, whereas something which is already complicated (more than one thing, not on its own) tends to be made more complex without too much further thought.

COBOL is an old language. Many old programs written in COBOL are still running. Many COBOL programs have to be amended, or just read to understand something, and that many times over their lifetimes of many years.

When changing code, by adding something to a condition, it is best if the original parts of the condition do not need to be "disturbed". If complexity is left within brackets, it is more likely that code needs to be disturbed, which increases the amount of time in understanding (it is more complex) and changing (more care is needed, more testing necessary, because the code is disturbed).

Many old programs will be examples of bad practice. There is not much to do about that, except to be careful with them.

There isn't any excuse for writing new code which requires more maintenance and care in the future than is absolutely necessary.

Now, the above examples may be considered long-winded. It's COBOL, right? Lots of typing? But COBOL gives immense flexibility in data definitions. COBOL has, as part of that, the Level 88, the Condition Name.

Here are data definitions for part of the above:

01  A PIC X.
    88  PARCEL-IS-OUTSIZED VALUE "B" "C".
01  F PIC X.
    88  POSTAGE-IS-SUFFICIENT VALUE "F".

The condition becomes:

IF PARCEL-IS-OUTSIZED
AND POSTAGE-IS-SUFFICIENT

Instead of just literal values, all the relevant literal values now have a name, so that the coder can indicate what they actually mean, as well as the actual values which carry that meaning. If more categories should be added to PARCEL-IS-OUTSIZED, the VALUE clause on the 88-level is extended.

If another condition is to be combined, it is much more simple to do so.

Is this all true? Well, yes. Look at it this way.

COBOL operates on the results of a condition where coded.

If condition

Simple conditions can be compounded through the use of brackets, to make a condition:

If condition = If (condition) = If ((condition1) operator (condition2))...

And so on, to the limits of the compiler.

The human just has to deal with the condition they want for the purpose at hand. For general logic-flow, look at the If condition. For verification, look at the lowest detail. For a subset, look at the part of the condition relevant to the sub-set.

Use simple conditions. Make conditions simple through brackets/parentheses. Make complex conditions, where needed, by combining simple conditions. Use condition-names for comparisons to literal values.

OR and AND have been treated so far. NOT is often seen as something to treat warily:

IF NOT A EQUAL TO B
IF A NOT EQUAL TO B

IF (NOT (A EQUAL TO B)), remembering that this is just IF condition

So NOT is not scary, if it is made simple.

Throughout, I've been editing out spaces. Because the brackets are there, I like to make them in-your-face. I like to structure and indent conditions, to emphasize the meaning I have given them.

So:

IF ( ( ( condition1 )
    OR ( condition2 ) )
AND
     ( ( condition3 )
    OR ( condition4 ) ) )

(and more sculptured than that as well). By structuring, I hope that a) I mess up less and b) when/if I do mess up, someone has a better chance of noticing it.

If conditions are not simplified, then understanding the code is more difficult. Changing the code is more difficult. For people learning COBOL, keeping things simple is a long-term benefit to all.

为你鎻心 2024-10-12 23:11:02

一般来说,如果可能的话,我会避免使用 AND。嵌套 IF 的工作也一样,更容易阅读,并且通过明智地使用 88 层,不必走得太深。这看起来更容易阅读,至少根据我的经验:

05  DL-CLASS-STANDING            PIC X(20) VALUE SPACE.
    88  DL-CLASS-STANDING-VALID  VALUE 'First Yr' 'Second Yr'.
05  GRAD-STAT-IN                 PIC X     VALUE SPACE.
    88  GRAD-STAT-IN-VALID       VALUE SPACE 'N'.

然后代码就这么简单:

IF DL-CLASS-STANDING-VALID
    IF GRAD-STAT-IN-VALID
        ACTION ...  .

As a rule, I avoid the use of AND if at all possible. Nested IF's work just as well, are easier to read, and with judicious use of 88-levels, do not have to go very deep. This seems so much easier to read, at least in my experience:

05  DL-CLASS-STANDING            PIC X(20) VALUE SPACE.
    88  DL-CLASS-STANDING-VALID  VALUE 'First Yr' 'Second Yr'.
05  GRAD-STAT-IN                 PIC X     VALUE SPACE.
    88  GRAD-STAT-IN-VALID       VALUE SPACE 'N'.

Then the code is as simple as this:

IF DL-CLASS-STANDING-VALID
    IF GRAD-STAT-IN-VALID
        ACTION ...  .
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文