掲示板 > Tiny Basic for Windows

TBasic事始め(2) 構造化プログラミング

(1/2) > >>

sokuhan:
昔々の話になるのだが、
ごく初期のROM-BASICの時代には、行番号を付してのプログラムの記述が原則で、
GOTO文で行番号宛てに処理を跳ばすという技法が当たり前だったのだが、
そうこうしているうちに行番号を使わないプログラミングができるBasic言語が登場して、
それでうまくいけるんだろうかと心配したのだが、
Labelを使えば従前と変わらないということになった。
しかしながら、GOTO文を多用すると、
当初は自分ではその論理プロセスはよく分かっていたはずのものが、
しばらく日を置いてプログラムを見直すと、その論理プロセスが良く辿れないという、
そういう「苛立ち」を味わう羽目に陥る。
いわゆる「スパゲッティ・プログラミング」という、笑い話になったのだった。

GOTO文をできるだけ使わないようにプログラミングを行うために推奨されたのが、
制御構造文を使いこなすということで、
もっとも効果的なことが、
IF ~ THEN ~ ELSE文で処理を分岐させる場合に、
選択された処理ごとにずらずらと処理ルーチンを記述するということは、
一見して分かり易いように見えながら煩瑣な処理になりやすいから、
SELECT CASE文で事例ごとに処理を独立させて記述するということで解決できる。

私にとっての構造化プログラミングへの「入り口」であり「端緒」だったのはここであった。

構造化プログラミングという技法は、
いろいろな技法が提唱されているようなのだが、
私の理解では、
個々の処理(関数なり手続き)の徹底した「部品化」であって、
この部品を組み合わせて1つの一貫した処理にするというのがメイン・ルーチンの役割であるという、
そういう見通しを立ててのプログラミング技法であると理解している。

もちろん、このような見方はプログラミングの世界での特有のものではなくて、
私らのようなモノづくりに従事している職人の世界では、
製作過程での個々の段階で確実に加工がされていることを確認して、
次の工程に進むという手順なのだが、
そのことによって、最終的な製品の品質が保証されるということになっている。
モノづくりの世界での品質保証の考え方が、プログラミングの世界にも適用されたものと、
いうことなのだろうと考えている。

(この項は後に続きます)

sokuhan:
構造化プログラミング、イコール、個々のルーチンの部品化、とみなした場合、
その個々のルーチンの独立性を保証するものが、ローカル変数という変数仕様である。
そのルーチンの「入り口」と「出口」を押さえておくと、
ルーチンそれ自体を「ブラックボックス」とすることが出来る。

局所変数であることが基本であるということは、
現在にあってはむしろ当然のことと考えられそうなのだが、
Basic言語の歴史においては決して当然のことではなかったことに留意したい。

Basic言語における変数はことごとくがグローバル変数であることが原則であった時代においては、
メインルーチンにおける変数の値が、
関数や手続きというローカルな処理に際して意図せざるうちに書き換えられるという、
そういう類の「事故」は良くある過ちであった。
TBasicでは、関数や手続きのうちの変数がことごとくローカル変数であるとされることで、
本当の意味での構造化プログラミングが無理なく履践できることになった。

このことは、逆に言えば、何がグローバル変数であるかを、事前に定義しておくべき、という、
そういうマナーが要請されていると考えないといけない。
グローバル変数を定義して、そこに一定の値を代入しておけば、「定数」の定義になる。

原則が局所変数であるという仕様がもたらす効果はいろいろあるのだが、
些細な場面で言うと、
メインルーチンを記述してEND文で完了させ、
その下に関数や手続きをずらずらと並べる、というのが、1つのスタイルであって、
編集画面をスクロールさせながら、メインルーチンとの間で、
変数の「置き換わり」がないか、値の「すり替わり」がないか、検証したりするのだが、
ごく小規模なプログラミングなら可能な方法であっても、
少し規模の大きなプログラムや煩雑な処理になると、なかなかにこの検証方法では誤りが発見しがたい。
これに対して、関数や手続きで使用された変数が局所変数であるならば、
それ自体を別ファイルで作成して、作成後にメインルーチンとマージするということで済ませられる。
マージする、即ち、メインルーチンの冒頭でこれら関数や手続きをINCLUDE文で読み込めばいい。

こうして、構造化プログラミングの作法が(形式的にも)出来上がる。

(この項、更に続きます)


sokuhan:
「構造化」プログラミングという技法は、
入力されたデータから求めるべき結果を析出すべき1つの処理の流れを設定し、
その流れを段階化し分節化して、
その段階化され分節化された各々のルーチンを磨き上げるという、
結論から言えば、そのような分析的な視角からするプログラミング・スタイルである。
ただ、「何のために分析するか?」と問われれば、
つまり、その「構造化」と言うためには、一定の「目的」に導かれた、
目的実現のために設定されたプロセスであるということを意味する。

ここまでは、むしろ常識的なことであって、敢えて指摘するまでもないことではあるだろう。

プログラム全体の見通しが簡明になる。従って、理解しやすい。
個々のルーチンの修正が容易で、追加や削除の場合において全体に対する影響を抑えられる。
他の言語に書き換えるべき場合でも、対応は容易である。
その他、その他のメリットが強調されるから、
最初から構造化プログラミングの作法を習得することになる。

TBasicの修得に際しては、当然、この構造化プログラミングの作法を学ぶことになる。

しかしながら、私らが最初に学び始めた頃は、これらは当然の常識ではなかったわけで、
かなり意識して学ばねばならないことであった。
昔のBasic言語は、いわゆる「書式フリー」の言語だったから、
どのようにプログラムを記述しても、一応は動かすことができる。
動かせて一応所期の結果が出せるプログラムであったら、「それで良いじゃない?」と思えれば、
それで良いと(自分勝手に)思い込むことができる。
Basic言語が「初心者・入門者向けの言語」と決め付けられたのは、
この言語が「書式フリー」であるという側面から語られたことなのである。

構造化プログラミングを修得しようと望むならば、
この書式フリーの言語でプログラミングを行う際に、
厳密な書式のルールに従って記述するというマナーを身に付けなければならない。
教育用言語としてPascalが推奨されたのは、この点が大きな理由であった。
遠回りなように思えるのだが、Pascalを学んで、それを踏まえてBasic言語でプログラミングする。

この「お作法」を身に付けることで、随分と世界が変わってくる。

(この話は、更に続けます)

sokuhan:
プログラミングの作法として、
全体の処理の流れをメイン・ルーチンとしてフロー・チャートに書き、
その後に、その各々の段階を詳細設計して処理ルーチンを書く、ということになるのだが、
構造化プログラミングという作法は、
この作業を素直に反映させたものと言える。
従って、特に構造化プログラミングの作法というものを意識しなくとも、
ごく当たり前のように構造化ということが実現できる作法であるということである。

しかしながら、実際のプログラミングにおいて、
フロー・チャートを書いたことがあるかと問われれば、書いたことがなくて、
個々の処理ルーチンをどう構築するかに主力が注がれて、
その結果をつなぎ合わせることでメイン・ルーチンが出来上がるという順序であることが、
正直な実際であったのだった。

例えば。
必要なデータを順次記録するためのプログラム。
データ入力を行って、そのデータをデスクに書き出すプログラム。
データをデスクから読み込んで、そのデータを処理するプログラム。
単純にデータを並び替える、あるいは、分類・集計する処理を行う。
結果を、これもデスクに保存する。
さらには、処理されたデータを読み込んで、一定の書式にプリント・アウトするべきプログラム。

つまり、デスクにデータを保存する、保存されたデータを活用し、結果を出すという。
この点を中心にして、
必要な処理プログラムを個別に複数作成すれば、目的は充分に達成できる。
個々のプログラムは単純なものであるから、間違うことはなくて、却って、洗練されていく。
こういうプログラミングの作法では、
構造化が意識されることはなくて、実務的にも、何の差し障りもない。

肝要なことは、デスクに保存されたデータであって、
どういうデータを保存し、あるいは活用していくかという必要に応じて、
個別の処理プログラムが追加・変更するという立場を採れば、メンテナンスも簡単に済む。

しかしながら、処理の必要に応じて個別の処理プログラムを立ち上げるというのは如何にも煩雑で、
1つのアプリケーション・ソフトとしてまとめようとすると、
これら個別の処理プログラム間にある「重複」をどう解決するかに突き当たる。
つまり、単純に言うと、
処理ごとにデスクにあるデータを読み込むのではなく、
デスクに書き込まれたデータを一旦全部読み込んで、
それを処理目的に応じて加工。活用するというプログラムになる。
つまり、処理全体を「統合する」という場合の、その「統合」が「構造化」と言うことに行き着く。

(この項は、更に続きます)

sokuhan:
構造化という問題が意識されるのは、
このように、いくつかの処理ルーチンを統合化して一本のアプリケーション・ソフトにまとめる場合、
処理の重複を解消する、あるいは、全体の流れをすっきりと簡明にするという場合であるだろう。

この「統合化」を図る場合、
「バグ」が出やすいという問題に悩まされる。
それぞれの個別の処理ルーチンにおいて、
どのような変数を使っていたか、いちいち覚えているわけではない。
個別の処理ルーチンで使った変数は言わばグローバル変数であるから、
統合化に際して、変数の値がすり替わったりすることは良くある事態で、
従って、全体を何度も見直して、変数の値が衝突したりすり替わったりしていないかどうか、
充分に検証しないといけなかったりする。

だから、
Pascalのように、処理ルーチン(これは、独立したプログラムである場合なのだが)ごとに、
きちんと変数宣言を行ってからその変数を使用するという場合、
後から行う諸々の婦処理ルーチンの統合化を図る場合、
混乱するということがごく限られてくるのだが、
Basic言語の場合、何時でもどこででも変数を設けることができることになっているから、
構造化プログラミングは確かに可能なのだが、
それなりには非常に注意しなければならない局面が多い言語なのであった。

TBasicの場合、個別の処理ルーチンを、サブ・ルーチンや関数・手続きに落とし込めば、
そこで用いられていた変数は局所変数の扱いになるから、変数検証は随分と楽になる。

もっとも、何が何でも構造化プログラミングでなければならないかどうかは別問題で、
構造化を図るべき時はそれなりの構えが必要となる。

(この項は一応終わります)

Navigation

[0] Message Index

[#] Next page

Go to full version