LoginSignup
8
7

More than 5 years have passed since last update.

1人COBOL再研修〜基本構文編〜

Last updated at Posted at 2019-06-15

これの続き。今回は基本文法編ということで、前回も使った文法も含めて総ざらい。

※ 横ルーラの記載方法が変わっていますが、見方は前回と同様です。プログラムにコメントとして埋め込みたかったので変えています。

画面出力・入力

画面出力

記法
DISPLAY   <出力したいもの>.

任意の文字やデータ項目を出力することができる。Cのprintf()のようなもの。文字リテラルと変数を一緒に出したいときは+をつけて文字列連結したくなると思うが、COBOLでは何もつけずに後ろに一緒に出したいデータ項目や文字リテラルを書く。

サンプル
      *---1---------2---------3---------4---------5
       IDENTIFICATION         DIVISION.
       PROGRAM-ID.            SAMPLE.
      *
       ENVIRONMENT            DIVISION.
      *
       DATA                   DIVISION.
       WORKING-STORAGE        SECTION.
       01  STR                PIC X(5)
                                VALUE 'WORLD'.
      *
       PROCEDURE              DIVISION.
       MAIN                   SECTION.
       MAIN-S.
         DISPLAY              "HELLO " STR.
       MAIN-E.
         STOP RUN.

実行結果

HELLO WORLD

入力

記法
ACCEPT   <入力先>  [FROM  <入力ソース>].

画面入力を行う。Cでいうscanf()のようなもの。入力先には入力データの格納先のデータ項目を記載する。入力ソースはいくつかある。以下は自分が使ったことがあるもの。

記載方法 入力ソース
CONSOLE コンソール
DATE YYMMDD形式のシステム日付
TIME HHMMSSTT形式のシステム時刻

小言を言うとこの勉強でHHMMSSの次はTTだって知った。

ちなみに、FROM <入力ソース>を記載しないとコンソールからデータを取ってくる。

サンプル
      *---1---------2---------3---------4---------5
       IDENTIFICATION         DIVISION.
       PROGRAM-ID.            SAMPLE.
      *
       ENVIRONMENT            DIVISION.
      *
       DATA                   DIVISION.
       WORKING-STORAGE        SECTION.
       01  IN-CONSOLE         PIC X(05).
       01  IN-NOTLISTED       PIC X(05).
       01  IN-DATE            PIC 9(06).
       01  IN-TIME            PIC 9(08).
      *
       PROCEDURE              DIVISION.
       MAIN                   SECTION.
       MAIN-S.
      *--コンソールニュウリョク
         ACCEPT               IN-CONSOLE  FROM  CONSOLE.
         ACCEPT               IN-NOTLISTED.
      *--システムジコク
         ACCEPT               IN-DATE     FROM  DATE.
      *--システムジコク
         ACCEPT               IN-TIME     FROM  TIME.

      *--シュツリョク
         DISPLAY              IN-CONSOLE.
         DISPLAY              IN-NOTLISTED.
         DISPLAY              IN-DATE.
         DISPLAY              IN-TIME.
       MAIN-E.
         STOP RUN.

実行結果(最初2行は自分で入力したものなので出力しているのは3行目から)

HELLO
WORLD
HELLO
WORLD
190615
14291199

システム日付やシステム時刻はシステムから勝手に取ってきてくれるので自分で何か入力とかは不要。

データ操作

リテラルやデータ項目を他のデータ項目に代入

記法
MOVE   <リテラルor元データ項目>  TO  <格納先データ項目>.

他の言語でいう格納先 = 格納元データと同じ。COBOLではこれをMOVE文でやる。

サンプル
      *---1---------2---------3---------4---------5
       IDENTIFICATION         DIVISION.
       PROGRAM-ID.            SAMPLE.
      *
       ENVIRONMENT            DIVISION.
      *
       DATA                   DIVISION.
       WORKING-STORAGE        SECTION.
       01  IN-STR1            PIC X(05).
       01  IN-STR2            PIC X(05).
       01  CNST               PIC X(05)
                                VALUE 'WORLD'.
      *
       PROCEDURE              DIVISION.
       MAIN                   SECTION.
       MAIN-S.
      *--リテラルカラ
         MOVE                 'HELLO' TO IN-STR1.
      *--データコウモクカラ
         MOVE                 CNST    TO IN-STR2.
      *--シュツリョク
         DISPLAY              IN-STR1.
         DISPLAY              IN-STR2.
       MAIN-E.
         STOP RUN.

実行結果

HELLO
WORLD

となると、1+1の結果(2)を入れるなら

MOVE  1 + 1  TO  RESULT.

なのか?と思うかもしれないが、そんなことをするともれなく怒られる(コンパイルエラー)。どうするかは下へ。

四則演算を行う

記法
COMPUTE  <計算結果格納先> = <計算式>.

ただただ四則計算して結果を入れる。それだけ。

サンプル
      *---1---------2---------3---------4---------5
       IDENTIFICATION         DIVISION.
       PROGRAM-ID.            SAMPLE.
      *
       ENVIRONMENT            DIVISION.
      *
       DATA                   DIVISION.
       WORKING-STORAGE        SECTION.
       01  RESULT             PIC 9(02).
       01  IN-NUM             PIC 9(01)
                                VALUE 9.
      *
       PROCEDURE              DIVISION.
       MAIN                   SECTION.
       MAIN-S.
      *--ケイサン
         COMPUTE              RESULT = IN-NUM + 1.
      *--シュツリョク
         DISPLAY              RESULT.
       MAIN-E.
         STOP RUN.

実行結果

10

制御

条件分岐

記法
IF  <条件式>  THEN
  <TRUE>のときの制御
ELSE
  <FALSE>のときの制御
END-IF.

これは他の言語とも似てるからとっつきやすい。普通に条件によって処理を分岐させているだけ。ただ注意したいのは、等価演算子の使い方がちょっと違う。

よく使われるやつ COBOLだとこうなる 意味
A == B A = B ABが同じ
A != B A NOT= B ABが違う

ほかは同じ。

サンプル
      *---1---------2---------3---------4---------5
       IDENTIFICATION         DIVISION.
       PROGRAM-ID.            SAMPLE.
      *
       ENVIRONMENT            DIVISION.
      *
       DATA                   DIVISION.
       WORKING-STORAGE        SECTION.
       01  CNST               PIC 9(02)
                                VALUE 1.
      *
       PROCEDURE              DIVISION.
       MAIN                   SECTION.
       MAIN-S.
         IF     CNST = 1      THEN
           DISPLAY            'TRUE'
         ELSE
           DISPLAY            'FALSE'
         END-IF.
       MAIN-E.
         STOP RUN.

実行結果

TRUE

気をつけなければならないのは.(ピリオド)。IF〜END-IFが1つの命令になるので、IFの中の制御にピリオドを付けてはいけない。これになれるまで苦労したし数週間たった今でもつけてしまう時がある。

ついでにいうと、IFが入れ子になったときも同じで、

      *---1---------2---------3---------4---------5
         IF     <条件式1>      THEN
           IF   <条件式2>      THEN
             <条件式1・2がTRUE>
           END-IF
         ELSE
           <条件1がFALSE>
         END-IF.

こうなる。

ケース分けがある条件分岐

記法
EVALUATE  <検査対象>
  WHEN    <定数1>
    <検査対象が定数1のときの制御>
  WHEN    <定数2>
    <検査対象が定数2のときの制御>
  WHEN    OTHER
    <検査対象が上のどれでもないときの制御>
END-EVALUATE.

他言語でいうswitch-case文になる。結果が複数通り考えられていて、IFで書くと複雑になるときにこっちを使えばいい。

サンプル
      *---1---------2---------3---------4---------5
       IDENTIFICATION         DIVISION.
       PROGRAM-ID.            SAMPLE.
      *
       ENVIRONMENT            DIVISION.
      *
       DATA                   DIVISION.
       WORKING-STORAGE        SECTION.
       01  CNST               PIC 9(01)
                                VALUE 1.
      *
       PROCEDURE              DIVISION.
       MAIN                   SECTION.
       MAIN-S.
         EVALUATE  CNST
           WHEN    1
             DISPLAY          'HOGE'
           WHEN    2
             DISPLAY          'FOO'
           WHEN    OTHER
             DISPLAY          'BAR'
         END-EVALUATE.
       MAIN-E.
         STOP RUN.

実行結果

HOGE

終了条件があるループ

その前に

他のセクションのプログラムの呼び出し

記法
PERFORM  <呼び出しセクション名>.

COBOLではプログラムはセクション(他言語でいう関数)で分けることができて、これを呼び出すときに使う。

サンプル
      *---1---------2---------3---------4---------5
       IDENTIFICATION         DIVISION.
       PROGRAM-ID.            SAMPLE.
      *
       ENVIRONMENT            DIVISION.
      *
       DATA                   DIVISION.
       WORKING-STORAGE        SECTION.
      *
       PROCEDURE              DIVISION.
      *--メインセクション
       MAIN                   SECTION.
       MAIN-S.
         PERFORM              SUB.
       MAIN-E.
         STOP RUN.
      *--サブセクション
       SUB                    SECTION.
       SUB-S.
         DISPLAY              'HELLO WORLD'.
       SUB-E.
         EXIT.

実行結果

HELLO WORLD

改めて

終了条件があるループ

記法1
PERFORM  <繰り返すセクション>
  UNTIL  <終了条件>.
記法2
PERFORM
  UNTIL  <終了条件>
    <繰り返したい制御文>
END-PERFORM.

他言語でいうwhile文になる。

記法1は、繰り返したい処理が別セクションにあるときに使う。もし繰り返したい処理がセクション分けするほどのものでもないなら、記法2を使って、直接書いてやればいい。

サンプル
      *---1---------2---------3---------4---------5
       IDENTIFICATION         DIVISION.
       PROGRAM-ID.            SAMPLE.
      *
       ENVIRONMENT            DIVISION.
      *
       DATA                   DIVISION.
       WORKING-STORAGE        SECTION.
       01  CNT                PIC 9(02)
                                VALUE 0.
      *
       PROCEDURE              DIVISION.
      *--メインセクション
       MAIN                   SECTION.
       MAIN-S.
         DISPLAY              CNT.
      *--キホウ1ノループ
         PERFORM              SUB
           UNTIL              CNT = 10.
         DISPLAY              CNT.
      *--キホウ2ノループ
         PERFORM
           UNTIL              CNT = 20
             COMPUTE          CNT = CNT + 1
         END-PERFORM.
         DISPLAY              CNT.
       MAIN-E.
         STOP RUN.
      *--サブセクション
       SUB                    SECTION.
       SUB-S.
         COMPUTE              CNT = CNT + 1.
       SUB-E.
         EXIT.

実行結果

00
10
20

記法1も記法2もやってることは同じなので、好きな方を使ってください。

回数が決まっているループ

記法1
PERFORM    <繰り返すセクション>
  VARYING  <添字>  FROM   <初期値>  BY  <増分>
  UNTIL    <終了条件>.
記法2
PERFORM
  VARYING  <添字>  FROM   <初期値>  BY  <増分>
  UNTIL    <終了条件>
    <繰り返したい制御文>
END-PERFORM.

他言語でいうfor文に当たる。記法が2つあるのは上と同じで、繰り返したい処理が別セクションにあるか直接記述してしまいたいかで使い分けるため。

サンプル
      *---1---------2---------3---------4---------5
       IDENTIFICATION         DIVISION.
       PROGRAM-ID.            SAMPLE.
      *
       ENVIRONMENT            DIVISION.
      *
       DATA                   DIVISION.
       WORKING-STORAGE        SECTION.
       01  CNT                PIC 9(02)
                                VALUE 0.
       01  IDX                PIC 9(02).
      *
       PROCEDURE              DIVISION.
      *--メインセクション
       MAIN                   SECTION.
       MAIN-S.
         DISPLAY              CNT.
      *--キホウ1ノループ
         PERFORM              SUB
           VARYING            IDX  FROM  0  BY  1
           UNTIL              IDX = 10.
         DISPLAY              CNT.
      *--キホウ2ノループ
         PERFORM
           VARYING            IDX  FROM  0  BY  1
           UNTIL              IDX = 10
             COMPUTE          CNT = CNT + 1
         END-PERFORM.
         DISPLAY              CNT.
       MAIN-E.
         STOP RUN.
      *--サブセクション
       SUB                    SECTION.
       SUB-S.
         COMPUTE              CNT = CNT + 1.
       SUB-E.
         EXIT.

実行結果

00
10
20

やってることは上のサンプルと同じ。

おまけ: GO TO

記法
GO TO <パラグラフ名>.

書いている通り、指定したパラグラフ名まで飛んで帰ってこないやつ。他の言語にもあるやつ。

サンプル
      *---1---------2---------3---------4---------5
       IDENTIFICATION         DIVISION.
       PROGRAM-ID.            SAMPLE.
      *
       ENVIRONMENT            DIVISION.
      *
       DATA                   DIVISION.
       WORKING-STORAGE        SECTION.
      *
       PROCEDURE              DIVISION.
       MAIN                   SECTION.
         GO TO                MAIN-E.
         DISPLAY              'HELLO WORLD'.
       MAIN-E.
         STOP RUN.

実行結果

(何もない)

GO TOMAIN-Eまで飛んで終了してるのでDISPLAYは通らない。

注意するのは今までみたいにセクション名ではなくパラグラフ名を指定すること。いざ使うことになると間違えそう…。

今回はここまで

PERFORM VARYINGとか研修の演習で全然使わないから忘れてた。

こうやって勉強して投稿するとかいう目的がないと休みの日に教材見ないからいい勉強になった。

次はデータ項目周りのことをしようかな…→続き(2019/06/29作成)

8
7
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7