これの続き。今回は基本文法編ということで、前回も使った文法も含めて総ざらい。
※ 横ルーラの記載方法が変わっていますが、見方は前回と同様です。プログラムにコメントとして埋め込みたかったので変えています。
画面出力・入力
画面出力
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 |
A とB が同じ |
A != B |
A NOT= B |
A とB が違う |
ほかは同じ。
*---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
改めて
終了条件があるループ
PERFORM <繰り返すセクション>
UNTIL <終了条件>.
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もやってることは同じなので、好きな方を使ってください。
回数が決まっているループ
PERFORM <繰り返すセクション>
VARYING <添字> FROM <初期値> BY <増分>
UNTIL <終了条件>.
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 TO
でMAIN-E
まで飛んで終了してるのでDISPLAY
は通らない。
注意するのは今までみたいに__セクション名ではなくパラグラフ名__を指定すること。いざ使うことになると間違えそう…。
今回はここまで
PERFORM VARYING
とか研修の演習で全然使わないから忘れてた。
こうやって勉強して投稿するとかいう目的がないと休みの日に教材見ないからいい勉強になった。
次はデータ項目周りのことをしようかな…→続き(2019/06/29作成)