Processingで学ぶ 実践的プログラミング専門課程

第5回制御構造を整理する

導入

今回から4回程度を用いて構造化プログラミングを学習します。コードの構造を整理し、共通部分をまとめるといったことを取り上げます。構造化プログラミングはコードをシンプルにし、読みやすくするために編み出された技術です。今後学習する様々なプログラミングのスキルは、構造化プログラミングの技術を前提としています。ぜひとも丁寧に学習してください。

今回は構造化プログラミングの第一歩として、プログラミング言語に用意されている制御構造を学習します。

展開

制御構造とは

制御構造とは、コードの流れをコントロールする仕組みのことで、典型的な流れを作るための命令がいくつか用意されています。これらの命令を上手に使い分けることで、読みやすいコードを綴るのです。

制御構造の一覧
名称 働き 命令
順次 上から下へ順番にコードブロックを実行する ありません
分岐 条件に応じて実行するコードブロックを選ぶ if, switch
反復 条件が成り立つ間コードブロックを繰り返し実行する while, for

勘違いを防止するために一言述べておくと、これらの制御構造がまずあり、問題をあてはめて解決するのではありません。解決したい問題がこれらの制御構造で表現できる場合に、言語に用意されている制御構造の命令を用いるのです。無理をしないとコードにならないようならば、どこかで勘違いをしてしまっている可能性があると思いましょう。

これらの制御構造が考案されるまでは、ジャンプ命令goto文など)によって問題解決の手順に合うようプログラムの構造を作り出していました。ジャンプ命令の欠点は移動先が不明瞭なため、プログラムの構造を理解しにくいコードになることです。そのため、高級言語ではなるべくジャンプ命令を用いず、上記の制御構造を形作る命令を用いることを推奨するのです。

まずは取り組んでいる問題をしっかり分析しましょう。その次に制御構造をあてはめます。すると、似た構造をもったコードが浮かび上がります。こうして次回から学ぶコードの整理に入ることができるわけです。

順次

順次実行構造は、上に書かれた命令が先に実行され、下に書かれた命令が後に実行される構造のことです。なるべくこのようなシンプルで自然な構造になるようコードを書くべきです。

意味ごとにまとまりよくコードを書きましょう。意味が異なる、あるいは意味が変わる場所では改行やコメント文を上手に使ってコードブロックを際立たせましょう。コードブロックとは、1行以上のコードの集まりのことです。ブレース{}でコードを囲めばコードブロックが明確になります。

流れ図で示すと次のようになります(図5.1⁠⁠。

図5.1 順次実行の流れ図
画像

典型的な順次実行の例として、GSWPよりサンプルコードを引用します。

// Example 03-13 from "Getting Started with Processing" 
// by Reas & Fry. O'Reilly / Make 2010

size(480, 120);
smooth();
strokeWeight(12);
strokeJoin(ROUND);      // Round the stroke corners
rect(40, 25, 70, 70);
strokeJoin(BEVEL);      // Bevel the stroke corners
rect(140, 25, 70, 70);
strokeCap(SQUARE);      // Square the line endings
line(270, 25, 340, 95);
strokeCap(ROUND);       // Round the line endings
line(350, 25, 420, 95);
図5.2 Ex_03_13.pdeの実行結果
画像

画面の設定から描画まで、上から下へ順に実行されます。

ごく当たり前のことのようですが、⁠意味のまとまりがあるコードは、同じ場所にまとめて書くこと」に注意してください。

サンプルコードEx_03_13.pdeでもこの要点がさりげなく示されています。

  1. 画面の設定
  2. 線の太さの設定
  3. 線端の設定
  4. 図形を描く

あとはステップ3と4がリズミカルに繰り返されます。この例の仕事ではこうしか書きようがないのですが、だからこそ見落としやすい要点です。ある仕事をするための長いコードのあちこちに、順番を見失ったコードの断片が散っていると、そのコードを読むのに苦労します。

一度書いたコードを見直して、順序よく書き直す習慣をつけましょう。

[作業] Ex_03_13.pdeにコードを書き加えて、左端の四角形は赤く塗りつぶし、左から2番目の四角形は青で塗りつぶしましょう。左から3番目の斜線は緑色にし、右端の斜線は白にしましょう。塗りつぶし色の設定はfillメソッド、線の色はstrokeメソッドで設定します。詳しい使い方はリファレンスを参照しましょう。

分岐

条件に従って実行するコードブロックを切り替える仕組みは大変便利です。図5.3はif文の流れ図です。論理式が成り立つ場合、つまり「真」ならば直下のコードブロックを実行し、論理式が成り立たなければ、つまり「偽」ならば流れは右へ分岐し、右側のコードブロックが実行されます。

図5.3 if文の流れ図
画像

基本的に、条件分岐の流れ図では、論理式が成り立つ(すなわち真の)とき真下へ向かう流れ線をたどり、論理式が成り立たない(すなわち偽の)とき横へ向かう流れ線をたどります。流れ線に真や偽、TやFといった値が記されていない場合はそのように理解してください。

この制御構造が連続する場合、次のGreeks.pdeのようにswitch文が便利です。

[作業] 次のsketchGreeks.pdeif文で書き直しましょう。

Greeks.pde
char aChar = 'b';

switch(aChar) {
  case 'a':
  case 'A':
    println("Alpha");  
    break;
  case 'b':
  case 'B':
    println("Beta");  
    break;
  case 'c':
  case 'C':
    println("Gamma");
  default:
    println("No match!");
    break;
}

switch文の構造を多重分岐と呼びます。switch文は便利ですが、その構文の仕様上、思わぬバグを作りやすい欠点があります。もうお気づきでしょうが、Greeks.pdeaCharabなどが代入されていれば正しく動作するのですが、cCが代入されたときには正しく動かないのです。break文が抜けているからです。

break文を上手に几帳面に使用しないとswitch文はたちまちおかしくなってしまいます。この仕組みを上手く利用することもできますが、抜け道的でかえって見落としバグを生むかもしれません。できれば、多重分岐の構造にもif文を上手に使うことをお勧めします。

[作業] Greeks.pdeif文を使って、正しく動くように書き直してください。

反復

同じような仕事を繰り返すことがあります。コンピュータは、繰り返しの仕事が得意です。人間なら早晩飽きて放り出してしまうことも、コンピュータは決して飽きません。

図5.4は繰り返しの基本形、while文の流れ図です。

図5.4 繰り返しの基本形、while文の流れ図
画像

while文による繰り返し構造の流れ図は次のように読みます。

  1. 論理式(条件式とも呼びます)が成り立てば、すぐ下のコードブロックへ実行が移ります。
  2. コードブロックの実行が終わると、論理式の直前に実行が戻ります。
  3. 論理式が成り立つ限り、コードブロックを繰り返し実行します。
  4. 論理式が成り立たない場合、実行は右側へ移り、コードブロックを実行せずwhile文の構造を終了します。

for文の流れ図は、while文の応用です。

  1. 初期条件を設定します。
  2. 次に条件が成り立つか確認する論理式を置きます。
  3. この論理式が成り立てば、続くコードブロックを実行します。
  4. 論理式が成り立たなければ、コードブロックも条件の更新も飛び越し、for文の構造を終了します。
  5. コードブロックの実行が終了したら、条件の更新を行います。
  6. 論理式の直前、初期条件設定の直後へ実行を戻します。

プログラミングの入門書で学習しただけの方は、while文を知らないかも知れません。while文の形はfor文でも書けるので、あえてwhile文を紹介しないこともあるからです。問題をよく分析して、適切な構造を選択しましょう。

演習ではfor文の流れ図を描いてみましょう。

[作業] 1から10までの数を合計するsketch Sigma10.pdeを書きましょう。while, forそれぞれの構文を使って書いてください。どちらがより分かりやすく問題を記述できるでしょうか。

演習

演習1(難易度:middle)

キーボードから入力されたアルファベットによって動作するようにGreeks.pdeを作り直してください。作成にあたっては、連載第2回を参照してください。sketch名はGreeksWithKey.pdeとします。

演習2(難易度:middle)

for文の流れ図を描いてください。

演習3(難易度:middle)

1+2+3+...と数を合計していき、合計が10を超えない(10を含まない)最大値と、加算の回数を求めましょう。while, forそれぞれの構文を使って書いてください。sketch名はSumTil10.pdeとします。

まとめ

  • 制御構造の種類と仕組み、使い方を学習しました。

学習の確認

それぞれの項目で、Aを選択できなければ、本文や演習にもう一度取り組みましょう。

  1. 3種類の制御構造を理解できましたか?
    1. 理解できた。十分に使えるようになった。
    2. 理解できた。しかし、演習問題が自力で解けなかった。
    3. 理解できない。

参考文献

  • 『Javaルールブック ~読みやすく効率的なコードの原則』⁠電通国際情報サービス 監修、大谷晋平、米林正明、片山暁雄、横田健彦 著、技術評論社
    • Javaのコードを書く人は必携。ほぼ見開きでコンパクトながら意を尽くした解説がある。
  • 『Java言語プログラミングレッスン 第3版(上⁠⁠結城浩 著、SBクリエイティブ
    • Java言語の入門書として最高の一冊。

演習解答

  1. GreeksWithKey.pde
  2. for文の流れ図
  3. for文の場合に軍配でしょうか。微妙な差です。SumTil10.pde

おすすめ記事

記事・ニュース一覧