コンピュータができることは少ない,
言語を駆使して思い通りに動かそう
講師 矢沢 久雄
プログラミング手法
四則演算,命令の順序,関数
ここからは,コンピュータがプログラム・コードをどのように実行するかを解説し,正しい命令の与え方を説明する。プログラムは,プログラマがコンピュータに与える命令である。しかし,アラジンの魔法のランプから出てくる大魔人のように,コンピュータが何でも命令を聞いてくれるわけではない。プログラマは,コンピュータができることを理解して,コンピュータができる範囲のことだけを命令しなければならない。では,コンピュータは何ができるのだろうか。
3つのことしかできないコンピュータ
![]() |
図7●コンピュータができる3つの処理 コンピュータは,入力,演算,出力しかできない |
CPUは,メモリーに記憶されたプログラムの内容に従って,I/Oからデータを入力し,データの演算結果をI/Oに出力する*14。プログラム自体や,演算の途中結果のデータを記憶するためにもメモリーが使われる。I/Oの先には,キーボードやマウスなどの入力装置,ディスプレイやプリンタなどの出力装置,およびフロッピ・ディスクやハード・ディスクなどの補助記憶装置が接続されている。CPUが行える3つの機能が幾重にも組み合わされて,様々なプログラムの機能を実現している。
機能が3つしかないと分かれば,プログラミングなど楽なものだと思えてくるだろう。ただし,これはハードウエアのレベルの話である。アセンブラでプログラミングするなら,入力,演算,出力が1行ずつのプログラム・コードとなるが,BASICやC言語などの高水準言語を使った場合は,1行のプログラム・コードの中に,3つの機能が盛り込まれることもあり,やや複雑になる。例えば,A=B+123というプログラム・コードの中では,「Bという変数が表すメモリーの内容をCPUの内部に入力する」,「CPUの内部で123という値を加算する」,「加算結果をAという変数が表すメモリーに出力する」という3つの機能が使われている。
プログラムの構造は,入力,演算,出力の3つ
コンピュータは3つの機能を持っているため,コンピュータ上のプログラムも,入力,演算,出力の3つの基本的な構造に分けて考えることが重要だ。
コンピュータは,自ら物事を考えて新しいデータを生み出すことはできない。従って,必ずデータの入力が必要となる。コンピュータは,データのゴミ箱ではない。入力されたデータがコンピュータの内部に捨てられることはなく,演算されてから必ず出力される。コンピュータに入力されたデータをそのまま出力するのでは,何の意味もない。入力されたデータには必ず何らかの演算が行われる。
プログラムを入力,演算,出力という基本的な3つの機能に分けて考える習慣を身に付けることは大事なことだ。これは,大きなシステム全体を考える場合でも,プログラムの一部分を考える場合でも同様だ。何が入力され,それがどのように演算され,そしてどのように出力されるか,という考え方でプログラミングするのだ。
プログラムには流れがある
もしもプログラミング経験がまったくない人に「プログラムという言葉から何を想像するか?」と尋ねたら,何と答えるだろう。競技種目や演奏曲目の順序が示された「運動会やコンサートのプログラム」と答えるだろう。プログラムという言葉の意味は,コンピュータの場合でも全く同じだ。コンピュータに実行させることの順序を示したものが,プログラムに他ならない。プログラム・コードの順番は,コンピュータに指示する命令の順番を示している。
単純なプログラムなら,たった1行のプログラム・コードだけで目的が達成できるかもしれない。だがほとんどのプログラムは,複数行のプログラム・コードから成り立つ。基本的にどのようなプログラム言語であっても,プログラム・コードが記述された順に,上から下に向かってプログラムは実行される。これは,記述された順序でプログラム・コードがメモリーに格納され,CPUがメモリーに格納された順序でプログラム・コードを実行するからである。何はともあれ,プログラムには,川のような「流れ」があることを知ってほしい。
![]() |
図8●プログラムの流れ プログラムは何も指定しなければ,先頭行から順次流れていく(実行していく)。条件分岐や繰り返しを指定し,プログラムの流れを制御することも可能である |
皆さんは,「フロー・チャート」という言葉を聞いたことがあるだろう。フロー・チャートは,プログラムの設計図の一種である。フロー・チャートのことは,「流れ図」とも呼ぶ。その名が示すとおり,プログラムの流れを設計したものである。プログラマがプログラムを設計する時には,「ここでまっすぐ流れて,ここで分岐して,ここで繰り返して...」といった流れを常にイメージしている。
順次進行だけのプログラムで目的の結果が得られることもあるが,条件分岐や繰り返しを使った方が,効率的なプログラミングが実現できることが多い。例を挙げよう。「1から10までの整数をディスプレイに出力する」というプログラムを作成するとしよう。単純に考えると,
Print 1
Print 2
・
・
Print 10
となる。このプログラム・コードは,図9[拡大表示]のように,繰り返しを用いて記述することもできる。図9の方が明らかにプログラム・コードの量が少ない。このように,繰り返しや条件分岐を用いた方が,効率よくプログラミングできるものなのだ。
コンピュータに無駄な処理をさせない
![]() |
図9●繰り返しを用いて1~10までの整数を出力する |
まず,図9のプログラム・コードで使っているFor~Nextを例に,繰り返しの仕組みを説明しよう。For i=1 to 10 Step 1の部分は「変数iの値を1から10まで1ずつ増加させろ」という命令で,Next iの部分は「変数iを次の値にせよ」という命令だ。For~Nextで囲まれたPrint iの部分は,iの値の変化と共に10回実行し,1~10までの整数をディスプレイに出力する。
重要なのは,10回で繰り返しを終える仕組みである。その仕組みは,プログラム・コードを見ただけではなかなか読み取れない。10回繰り返したかどうかを判断するには,変数iの値を常に監視する必要がある。コンピュータは,図9のプログラムを以下のように実行する。
・変数iに1を格納。10を超えていないからOK。Print iを実行。
・変数iに2を格納。10を超えていないからOK。Print iを実行。
・
・
・変数iに11を格納。10を超えたからNG。Next iの次の行に流れよう。
といった具合だ。繰り返し処理をコンピュータがどのように実行するか,ご理解いただけただろうか。
![]() |
図10●実行速度の遅いプログラム a*2の演算を毎回行うため実行速度が低くなる |
![]() |
図11●実行速度の速いプログラム a*2の演算を1回しか行わないため実行速度が高くなる |
条件分岐の仕組み
次は,条件分岐の仕組みを説明しよう。条件分岐とは,コンピュータに条件の判定を行わせ「もし条件が成立すればAという流れ,そうでないならBという流れ」というように流れを分岐させることだ。BASICではIf~Then...Elseという構文を使って条件分岐を表すのが一般的だ*15。例えば,変数aに格納した数値が100より小さいかどうかで処理を分岐し,異なるメッセージをディスプレイに表示するプログラムは,図12[拡大表示]のようになる。
![]() |
図12●条件分岐の例 |
IfとThenの間にあるa < 100が調べる条件である。数値を処理するコンピュータは,条件が成立するかどうかも数値で表す。BASICでは,条件が一致しないことを0,条件が成立することを0以外の値としている*16。このような条件成立を表す数値を知っていれば,条件部分のプログラム・コードを省略して記述することも可能だ。
例えば,ベテランのプログラマは,If a Thenのようなプログラム・コードを記述することがある。この場合,条件に相当する部分は「a」だけであり,初級のプログラマにはプログラム・コードの意味が理解できないかもしれない。条件成立を0か0でないかで表すのだから,If a Thenは,If a <> 0 Thenと同じ意味である*17。「もしもaなら」と言うのは,「もしもaが条件成立を表す数値なら」と言い換えることができる。それなら,意味的に分かりやすいIf a <> 0 Thenと記述した方がよいと思われるかもしれない。だが,プログラム・コードを短くしたいと願うベテラン・プログラマの中には,If a Thenというスタイルを好む人も多い。これは,純粋に好みの問題だ。
数学と共通点が多いプログラム
プログラムは,数学と同じように「変数」や「関数」を使う。これは,数学とプログラムには,数値だけを取り扱う,という共通点があるからだ。コンピュータはコード化することで情報を何でも数値で表し,数値を演算することで様々な機能を実現する。数値を格納する場所は,物理的にはメモリー上のどこかである。数値を格納したメモリー上の位置を,変数で名前を付けて表す。関数は,数値を処理する方法に名前を付けたものである。数学とプログラムは,共通点が多い。
中学生の数学の関数は,y=f(x)という構文になっている。これは,変数xにfという処理を行うと,結果がyに格納されることを表している。プログラムの関数も基本的に同じである。y=MyFunc(x)というプログラムの場合,変数xにMyFuncという処理を行うと,結果を変数yに格納する。この場合,変数xを「パラメータ」,MyFuncを「関数」,変数yに格納する値を「戻り値」と呼ぶ。y=MyFunc(X1,X2,X3)のように複数のパラメータをとる場合もある。
コンピュータの「データの入力」,「データの演算」,および「データの出力」の3つの機能にも,関数はよく当てはまる。パラメータが入力,関数が演算,そして戻り値が出力を表しているからである*18。
関数の組み合わせでプログラムを作る
![]() |
図13●InStr関数の構文 |
InStr関数は,i = InStr(a, "ABC")のように使うことができる。この場合,変数aの中に格納した文字列の中から,“ABC”という文字列を探し,見つかった位置を変数iに格納する。関数のパラメータには,変数を与える場合もあれば,直接数値を与える場合もある。
![]() |
図14●4つの関数で構成されたプログラムの例 |
プログラムの生産効率を向上させるには,プログラム全体を再利用可能ないくつもの関数に分けることが重要だ。関数に分けなければ,プログラム・コードの切れ目が不明確になり,一まとまりのプログラム・コードが長く,読みにくくなるという問題も生じてしまう。小さな関数に分けたプログラムなら,全体の構造が見わたしやすい。1つの関数を記述したプログラム・コードの長さは,プリンタ用紙1枚に収まることを目標にしてほしい。
まとめと次回予告
プログラム言語の種類やプログラミング手法の基本的な考え方を説明した。十分にご理解いただけただろうか。どんなに高度なプログラムであっても,内部は単純な命令の組み合わせである。プログラマは,寝ても醒めても頭を悩ませ続け,目的の動作をコンピュータに実行させようとする。プログラミングは,はっきり言ってつらい作業だ。しかし,プログラムが完成し,コンピュータが思い通りの動作をした時は,拍手をしたくなるような感激がある。それがあるからこそ,プログラミングが楽しいものになる。
次回は,「OSとアプリケーション」というテーマで,OSの役割と,アプリケーションからOSの機能を利用する方法などを説明する予定である。