COBOLの学習中や、昔ながらのプログラム修正で「GO TO文」っていうのを見かけて、「え、何これ?」「どう使うの?」「使っちゃダメって聞いたけど本当?」なんて思ったこと、ありませんか?
わかります、わかります。なんだかちょっと古めかしい響きもあって、謎めいてますよね。
実はGO TO文、プログラム界の瞬間移動装置みたいなもので、プログラムの実行順序を、びゅーん!と指定した場所にジャンプさせる命令なんです。
便利そうに聞こえるかもしれませんが、使い方を間違えると、コードがあっちこっちに飛びまくって、まるで迷路…いや、スパゲッティみたいに解読不能になっちゃうこともあるんですよ。(経験者は語る…涙)
でも大丈夫!この記事を読めば、GO TO文の正体から上手な付き合い方まで、しっかり理解できます。
読み終わるころには、「ふむふむ、GO TO文ね。完全に理解した(かもしれない!)」ってなってるはず!
さあ、一緒にGO TO文の世界を探検してみましょう!
この記事で学べることリストです!
- GO TO文がどんな命令なのか
- GO TO文の基本的な書き方のルール
- 簡単なサンプルコードでGO TO文の動き
- なぜGO TO文は嫌われがちなのか、その理由
- GO TO文を使わないスマートな書き方(PERFORM文とか)
COBOLの「GO TO文」とは?プログラムの流れを強制的に変える命令
さて、まずは「GO TO文」が一体何者なのか、その正体から探っていきましょう。
簡単に言うと、プログラムの実行の流れを、指定した別の場所(目印となる名前のところ)へ強制的にジャンプさせる命令です。
普通、プログラムは上から下へ順番に実行されていきますよね。
でもGO TO文を使うと、「次はこっちの処理に飛んで!」と、流れを無理やり変えることができるんです。
まさにプログラムの流れをコントロールする、ちょっと強引な司令官みたいなイメージでしょうか。
COBOLには処理の流れを制御するための命令がいくつかありますが、GO TO文はその中でも一番シンプルで直接的な方法の一つと言えますね。
COBOLの「GO TO文」の基本的な書き方(構文)
GO TO文を使うためのルール、つまり「構文」を見ていきましょう。
ルールは意外とシンプルですよ。基本的には2つの要素で成り立っています。
- ジャンプ先の目印を作る(手続き名、ラベルとも言います)
- 「そこへ飛べ!」と命令する(GO TO文を書く)
具体的には、こんな感じで書きます。
* ジャンプ先の目印(手続き名)を定義 手続き名. * ここにジャンプしてきた後の処理を書く ... * どこかの処理の中でGO TO文を使ってジャンプ! GO TO 手続き名.
ジャンプ先の「手続き名」があって、そこに「GO TO 手続き名.」で飛んでいく、という流れです。
次のセクションで、それぞれの書き方をもう少し詳しく見ていきましょう。
手続き名(ラベル)の定義方法
GO TO文で「どこにジャンプするか」を示すためには、まずジャンプ先の目印となる「手続き名(ラベル)」を定義する必要があります。
手続き名は、プログラムの中で「ここだよ!」と示すための名前のことです。PROCEDURE DIVISIONの中に書きます。
書き方は簡単で、好きな名前(手続き名)を付けて、その最後にピリオド「.」を付けるだけ。
例えばこんな感じです。
PROCEDURE DIVISION. 開始手続き. DISPLAY "プログラム開始". GO TO メイン処理. * メイン処理へジャンプ エラー処理. DISPLAY "エラーが発生しました". STOP RUN. メイン処理. * ←これが手続き名の定義 DISPLAY "メイン処理を実行中". IF 条件 = エラー THEN GO TO エラー処理 END-IF. DISPLAY "正常終了". STOP RUN.
上の例だと、「エラー処理」や「メイン処理」が手続き名にあたります。
手続き名の名前は、英数字やハイフン(-)を使って、分かりやすい名前を付けるのがおすすめです。ただし、COBOLが元々持っている特別な意味を持つ言葉(予約語、例えば `MOVE` や `DISPLAY` など)は使えないので注意しましょう。
GO TO文の記述形式
ジャンプ先の目印(手続き名)を作ったら、いよいよGO TO文の出番です。
書き方はとってもシンプルで、「GO TO」と書いて、スペースを空けて、ジャンプしたい手続き名を指定し、最後にピリオド「.」を付けるだけ!
GO TO ジャンプさせたい手続き名.
例えば、さっきの例で言うと、「メイン処理」という手続き名にジャンプさせたいなら、
GO TO メイン処理.
と書きます。
COBOLは大文字と小文字を区別しないことが多いので、`go to メイン処理.` と書いても大丈夫な場合が多いですが、一般的には大文字で書くことが多いですね。
そして、文の終わりには必ずピリオド「.」が必要です。これを忘れるとエラーになっちゃうので、気を付けてくださいね!
COBOLの「GO TO文」の使い方
さあ、理屈が分かったところで、実際にGO TO文を使った簡単なプログラムを見てみましょう。
百聞は一見にしかず、です!
ここでは、入力された数字が「1」だったら特定のメッセージを、「それ以外」だったら別のメッセージを表示して終了する、というシンプルな動きをGO TO文で作ってみます。
GO TO文がどうやってプログラムの流れを変えるのか、その動きに注目してみてください。
サンプルコードの紹介
では、実際のコードを見てみましょう。 コピーして、お手元の環境で動かしてみるのも良い勉強になりますよ。
IDENTIFICATION DIVISION. PROGRAM-ID. GOTO-SAMPLE-REVISED. DATA DIVISION. WORKING-STORAGE SECTION. 01 WS-INPUT-NUM PIC 9(1). PROCEDURE DIVISION. MAIN-PROC. DISPLAY "数字を入力してください (1 または それ以外): " WITH NO ADVANCING. ACCEPT WS-INPUT-NUM. IF WS-INPUT-NUM = 1 THEN PERFORM PROC-ONE ELSE PERFORM PROC-OTHER END-IF. PERFORM END-PROC. *> PERFORM文で終了処理を呼び出す PROC-ONE. *> 数字が1の場合の処理 DISPLAY "入力された数字は1です。". *> ここで終了処理へはジャンプせず、MAIN-PROCへ戻る PROC-OTHER. *> 数字が1以外の場合の処理 DISPLAY "入力された数字は1以外です。". *> ここで終了処理へはジャンプせず、MAIN-PROCへ戻る END-PROC. *> 終了処理 DISPLAY "プログラムを終了します。". STOP RUN.
このコードでは、`ACCEPT` でキーボードから数字を受け取り、`IF` 文でその数字が `1` かどうかを判定しています。
`1` なら `GO TO PROC-ONE.` で `PROC-ONE` という手続き名にジャンプ。
`1` 以外なら `GO TO PROC-OTHER.` で `PROC-OTHER` という手続き名にジャンプします。
それぞれの処理が終わった後、`PROC-ONE` からは `GO TO END-PROC.` で、`PROC-OTHER` はそのまま流れで `END-PROC` に行き着き、プログラムが終了する、という流れですね。
実行結果と解説
このプログラムを実行すると、まず数字の入力を求められます。
例えば「1」を入力した場合、実行結果はこうなります。
数字を入力してください (1 または それ以外): 1 入力された数字は1です。 プログラムを終了します。
どうでしょう? `IF` 文で `GO TO PROC-ONE.` が実行され、`PROC-ONE` の処理(`入力された数字は1です。` の表示)が行われましたね。
その後、`GO TO END-PROC.` で `END-PROC` にジャンプし、最後のメッセージが表示されて終了しました。`PROC-OTHER` の処理は完全にスキップされています。これがGO TO文の力です!
次に、例えば「5」を入力した場合はどうなるでしょうか。
数字を入力してください (1 または それ以外): 5 入力された数字は1以外です。 プログラムを終了します。
今度は `IF` 文の `ELSE` 側が実行され、`GO TO PROC-OTHER.` で `PROC-OTHER` にジャンプしました。
そして、`PROC-OTHER` の処理(`入力された数字は1以外です。` の表示)が実行され、そのまま次の行の `END-PROC` に進み、プログラムが終了しました。`PROC-ONE` の処理はスキップされましたね。
このように、GO TO文を使うと、条件に応じてプログラムの実行順序を自由に変えることができるわけです。
なぜ「GO TO文」は避けるべきと言われるのか?
ここまでGO TO文の使い方を見てきて、「へぇ、便利じゃん!」と思った方もいるかもしれません。
確かに、特定の状況では手っ取り早く処理を分岐させることができます。
しかし!多くのベテランプログラマーたちが口を酸っぱくして「GO TO文はできるだけ使うな!」と言うのには、ちゃんと理由があるんです。
GO TO文を使いすぎると、プログラムがとんでもなく分かりにくくなってしまう危険性が高いからなんですね。
その結果、どういう問題が起こるのか、次のセクションで見ていきましょう。
スパゲッティコードの問題点
GO TO文をあちこちで使いまくると、プログラムの処理の流れが、まるで皿の上でぐちゃぐちゃに絡まったスパゲッティのようになってしまうことがあります。
これを、プログラマーたちは愛情(?)を込めて「スパゲッティコード」と呼びます。
想像してみてください。
ある処理を読んでいたら、突然GO TO文で別の場所に飛ばされる。飛んだ先の処理を読んでいたら、またGO TO文で全然違うところに飛ばされる。
さらにそこから別のGO TO文で、さっき読んでいた場所の近くに戻ってくる…みたいな。
処理A --> GOTO 処理Cへ! ... 処理B --> GOTO 処理Aの途中へ! ... 処理C --> GOTO 処理Bの近くへ! ...
↑こんなイメージです(あくまでイメージですよ!)
こうなると、もう大変!
今プログラムが何をやっているのか、処理がどこから来てどこへ行くのか、追跡するのがめちゃくちゃ難しくなるんです。
プログラム全体の流れを把握できなくなり、読むだけで一苦労、なんてことになりかねません。
プログラムは書く時間より読まれる時間の方がずっと長い、とも言われますから、読みにくいコードは本当に困りものなのです。
デバッグや保守の困難さ
スパゲッティコードのもう一つの大きな問題点は、プログラムの修正(保守)や、バグ探し(デバッグ)が非常に大変になることです。
考えてみてください。処理の流れが複雑に絡み合っていたら…
- プログラムが思った通りに動かない時、どこが原因なのか特定するのがめちゃくちゃ難しい。
- ある部分を修正したら、GO TO文で繋がっている全然関係ないと思っていた別の部分で、予期せぬエラー(バグ)が発生してしまう(デグレードとも言います)。
- 新しい機能を追加しようにも、どこにどう手を入れたらいいのか、影響範囲がどこまで及ぶのか、見当もつかない。
こんな状況、想像しただけでもゾッとしますよね?
保守やデバッグに時間がかかりすぎたり、修正によって新たな問題を生んでしまったり…まさに悪循環です。
だからこそ、プログラムはできるだけシンプルで、処理の流れが追いやすいように書くことが推奨されるのです。保守しやすいコードを書くことは、未来の自分や他の開発者を助けることにも繋がりますからね。
「GO TO文」の代替となる制御構造(PERFORM文など)
「じゃあ、GO TO文を使わずにどうやって処理の流れを制御すればいいの?」
良い質問ですね! COBOLには、GO TO文よりもっとスマートで、プログラムを分かりやすく保つための制御構造が用意されています。
その代表格が「PERFORM文」です。
PERFORM文は、指定した手続き(処理のかたまり)を実行して、終わったら元の場所に戻ってくる、という動きをします。GO TO文のように一方的にジャンプするのではなく、「ちょっとこの処理をお願い!」と頼んで、終わったらちゃんと帰ってくるイメージです。
* メインの処理 ... PERFORM サブルーチンA. * サブルーチンAを実行して戻ってくる ... PERFORM サブルーチンB. * サブルーチンBを実行して戻ってくる ... STOP RUN. * サブルーチンAの定義 サブルーチンA. * ここにサブルーチンAの処理を書く ... EXIT. * PERFORM元に戻る * サブルーチンBの定義 サブルーチンB. * ここにサブルーチンBの処理を書く ... EXIT. * PERFORM元に戻る
PERFORM文を使うと、処理の部品化(モジュール化)が進み、プログラムの構造がとても分かりやすくなります。
どこで何をやっているのか、処理の呼び出し関係が明確になるので、スパゲッティコードになるのを防ぎやすいんですね。
他にも、条件分岐には `IF` 文や `EVALUATE` 文(他の言語でいう `switch` や `case` 文のようなもの)を使うことで、GO TO文に頼らなくても複雑な条件に応じた処理の振り分けが可能です。
これらの構造化された制御命令をうまく使うことが、読みやすく保守しやすいCOBOLプログラムを書くコツと言えるでしょう。
【まとめ】COBOLの「GO TO文」の上手な付き合い方
さて、今回はCOBOLのGO TO文について、基本的な使い方から、なぜ避けられる傾向にあるのか、そして代替手段まで、いろいろと見てきました。
ポイントをまとめると…
- GO TO文は、プログラムの実行を指定した手続き名(ラベル)へジャンプさせる命令である。
- 書き方は `GO TO 手続き名.` とシンプル。
- 便利に見えるが、多用するとスパゲッティコードを招き、プログラムが非常に分かりにくくなる。
- 結果として、デバッグや保守が困難になるリスクが高い。
- 現代的なCOBOLプログラミングでは、PERFORM文やIF文、EVALUATE文などを使った構造化プログラミングが推奨される。
という感じですね!
原則として、これから新しくCOBOLプログラムを書くのであれば、GO TO文の使用は極力避けるべきです。PERFORM文などを活用して、処理の流れが追いやすい、構造化されたプログラムを目指しましょう。
ただ、古いプログラムの保守などで、どうしてもGO TO文が使われているコードに出会うことはあります。そんな時は、この記事で学んだ知識を活かして、「なるほど、ここでジャンプしているんだな」「このGO TO文はこういう役割か」と冷静に読み解き、慎重に扱ってくださいね。
GO TO文を完全に悪者扱いする必要はありませんが、その特性とリスクをしっかり理解した上で、より良いコードを書くための知識として役立ててもらえれば嬉しいです。
これであなたも、GO TO文との適切な距離感を保てるCOBOLプログラマーに一歩近づいたはず!頑張ってくださいね!
【関連記事】
0 件のコメント:
コメントを投稿
注: コメントを投稿できるのは、このブログのメンバーだけです。