web-dev-qa-db-ja.com

ANDおよびORの問題(COBOL)

明日提出する必要がある宿題がありますが、この一部を正しく行うことができないようです。入力ファイルに名前の束が与えられたのを参照してください。いくつかの名前はスキップする必要があり、それぞれに追加情報があります。私はANDとORを使用して不要な名前をスキップしようとしていたので、これを思いつきました。

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

1人を除いてすべて削除されましたが、別のANDとORのセットを追加しようとすると、プログラムは規定のように機能し始めました。

コンパイラーにとって複雑すぎましたか?物事をスキップする簡単な方法はありますか?

36
Kimmy1235

論理的に物事をグループ化するためにいくつかの括弧を追加してみてください:

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

134
Joel Spolsky

うわー、その構文が有効であるかどうかさえ覚えられないのでとても長いです:-)展開が多くの節があるときあなたが考えるものではないかもしれないので、その短縮表現を完全に展開したいかもしれません。明示する方がはるかに良い。

ただし、88レベル変数を使用して読みやすくします。88sは、コードで明示的な条件を使用するのではなく、データ部で直接条件を指定できる特別なレベルです。

言い換えれば、データ部門にこのようなものを入れてください(これは、私の唯一のCOBOLコンパイラがメインフレーム上にあり、今日は休みだからです)。

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

その後、式で88レベル変数を使用できます。

IF (IS-FIRST-YEAR OR IS-SECOND-YEAR) AND (GRAD-STAT-UNKNOWN OR GRAD-STAT-NO) ...

私の意見では、これはより読みやすく、COBOLの全体的なポイントは、結局、読みやすい英語のように見えることでした。

28
paxdiablo

最初に注意すべきことは、表示されているコードは動作していたコードであり、目的の結果をもたらさない修正されたコードは表示されなかったことです。補遺として、なぜ一人しか残っていないのに、さらに選択が必要なのでしょうか?それを要約すると、実際の質問は「COBOLでORを使用する方法がわからない。COBOLでANDを使用する方法がわからない」と言う以上に不明確です。

さらに、2つの実際の質問がありました。

  1. コンパイラーにとって複雑すぎましたか?

  2. 物事をスキップする簡単な方法はありますか[条件を記述するより明確な方法はありますか]

第一に、答えは「いいえ」です。コンパイラーにとって難しいことではありません。コンパイラーは、OR、AND(およびNOT、後で説明します)の任意の組み合わせを処理する方法を正確に知っています。問題は、人間のライター/リーダーは、コンパイラーがその規則に従って複数の可能な解釈を考慮せずに、コンパイラーから結果を単に与えるのではなく、コンパイラーが望むものを知るような条件をうまくコーディングできるかどうかですコードの))?

したがって、2番目の質問は次のようになります。

コンパイラーが著者としての私の意図と同じ方法で、またCOBOLの経験があるコードの読者のために同じ方法で理解する複雑な条件をどのように書きますか?

まず、質問内の(動作する)コードの簡単な再配置:

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

そして、回答の1つで提案されたコード:

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

2番目のバージョンはより明確ですが、(または)最初のバージョンと同じです。そのコードは機能せず、そのコードが機能し続けることができました。

答えは、複雑さが増した状態の問題の解決策に対処していました:括弧/括弧(単純に単純化することも別の可能性ですが、非実用的な例がなければ提案することは困難です)。

元のコードは機能しますしかしより複雑にする必要がある場合、ホイールは落ち始めます。

提案されたコードは機能しますが、ただし条件の複雑さを拡張する問題を(完全に)解決するわけではありません。調子。

これはどうですか?

単純な条件:

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を配置すると、人間の元の問題を再現できます。それはどういう意味ですか、それはどのように機能しますか?

1つの答えはこれです:

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"))

そして:

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

現在、誰かがANDで拡張したい場合、それは簡単で明確です。条件部分の1つと同じレベルで行われた場合、それだけに関連付けられます。最も外側のレベルで行うと、両方(すべて)にアタッチされます。

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を学ぶ人々にとって、物事をシンプルに保つことは、すべての人にとって長期的な利益です。

8
Bill Woodger

原則として、可能な限り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 ...  .
1
Sean Elgin