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

第4回 コードフォーマットのルール

この記事を読むのに必要な時間:およそ 6 分

導入

前回に続いてコーディングのルールを学習しましょう。今回はコードフォーマットのルールです。コードフォーマットとは,コードの体裁のことです。適切に体裁が整えられたコードはとても読みやすく,それによってバグを防ぐことさえできます。仮に自分だけが使うコードであってもコーディングルールを定めて守り続けましょう。コーディングルールの守られたコードは,将来のあなたを過去から支援してくれる強力な味方になります。

展開

コードフォーマットのルールについて,小さなものから順に紹介していきます。コードを書く際に,まずは小さな部分を丁寧に書き上げましょう。何行にもわたるコードを見渡すとき,細かいところが不統一だと全体としても落ち着きません。

基本的には自由

Java言語のソースコードはとても自由に書くことができます。一行にずらずらっと続けて書いても良いし,数行の空白をあけて,広々と空間をとりながら書いても良いのです。例えば,次のコードfreewheeling.pdeのように自由奔放な書き方でもきちんと動きます。

freewheeling.pde

int c = 1;boolean P;
for(int i = 0; i<10; i++)for(int j = 0; j<10; j++){
P = true;if(c == 1)P = false;
else for(int n=2; n<c; n++)
if (c % n == 0){P = false;
break;}if (P)fill(255,0,0);
else fill(255,255,255);rect(j*10,i*10,10,10);c++;}

さてしかし,こんなに自由奔放に書かれたコードを読むことになった「別の人」は大変なめにあいます。一目見ただけでは何をするプログラムか分からないことでしょう。

プログラミングの世界には「3日後の自分は他人」という格言があります。自分で書いたコードでも,3日経つと意図を忘れてしまっていてコードを読むのに苦労するよ,という戒めの意味があります。将来読んで分かりにくくないように体裁よくコーディングしようと勧めているわけです。将来読んで分かりやすいコードは,一定のルールにしたがって書かれたものです。ルールが将来のあなたの時間を確保し,ストレスから守ってくれると思えば,このルールは是非学び,使っておくべきです。ルールがあなたに自由を与えるのです。

[作業] freewheeling.pdeが何をするsketchか読み取ってみましょう。5分間で結構です。それ以上の時間をかけるのは時間の無駄ですから。

式は自然な形で書きましょう

コードの書き方は様々です。目的に応じて書き分けます。最もポピュラーなのが「実行速度を優先するのか,コードの読みやすさを優先するのか」という書き分けです。おおよそ実行速度を優先すると,コードは読みにくくなりがちです。本来の計算の意図以外の要素が入り込むからです。

最も単純な例として次のコードSpeedOrClear.pdeを紹介しましょう。

SpeedOrClear.pde

//スピード重視
int x = 2;
x = x << 1;
println("x * 2 = " + x);

//分かりやすさ重視
int y = 2;
y = y * 2;
println("y * 2 = " + y);

スピード重視の計算式では変数xに格納した整数値を1ビット左へシフトしています。これは2進数の数値を左へ1ビットシフトすることが,数値を2倍することと同じであることを利用しています。分かりやすさ重視の計算式では,そのものずばり,変数yの値を2倍しています。

ほんのわずかでも実行速度を高めたいならば,ビット演算のような「一般の人には普通ではない」計算方法を使っても良いでしょう。1回だけの計算では差は出ませんが,これを数多く繰り返せば差が出ます。

しかしながら,数値の計算式の中に突然ビット演算子が現れれば「どっきり」するのが人情です。よほど速度にシビアな計算を行うのでなければ,素直にかけ算の記号*を用いた方が誤解が無いでしょう。

[作業] ビットシフト演算子を使って整数値の2を10回2倍する操作を100万回行う時間を測定しましょう。乗算で同じことをするのとどれほど時間の違いがあるでしょうか。時刻はmillis()メソッドで取得できます。

不等式では右ほど大きく

数値の大小を条件判断文で判定する場合,大きな値であることが期待されるものを右側に置くようにしましょう(sketch GoodIsLess.pde)⁠どちらが大きくなるか全く予想がつかない場合にも,比較演算子の<を使って式をたてましょう。文化的に,習慣的にその方が自然である人が多いと思われるからです。

GoodIsLess.pde

int a = 1;
int b = 2;

// Good example
if (a < b) {
  println("That's natural!");
} else {
  println("That's funny!");
}

// Bad example
if (a > b) {
  println("That's natural!");
} else {
  println("That's funny!");
}

カッコを使って式の曖昧さを解消しましょう

早速ですが次の例題2問を検討してください。

例題1

整数変数a, bに代入された数値の平均を取りたいとします。次の式が正しい結果を得られるように変更してください。

Divide_Conquer.pde

x = a + b / 2 

このまま計算すると,除算が優先されabの半分」の合計をとることになります。題意にそった結果を得るためには,式を次のように書き換える必要があります。

x = (a + b) / 2

果たして正しい平均値が得られるはずです。

例題2

次の式を正しく計算するコードを書いてください(図4.1)⁠

ちょっとした分数計算

画像

先ほどの例題とよく似た形です。今度は分母にも注意が必要です。次のようにコードを書くと正しく計算されません。

x = 9.53 + 5.32 / log(1.81) * sqrt(7.52)

理由は2つあります。

  • 分子の加算をカッコで囲む必要があります。加算より除算が優先されるからです。
  • 分母全体をカッコで囲むか,平方根の項の直前の乗算を除算に変更する必要があります。カッコが無ければ,対数の直前の除算演算子で表現したかった分数が平方根の直前で終了してしまうからです。

正しく計算するためには次のように書きます。

x = (9.53 + 5.32) / (log(1.81) * sqrt(7.52)) ...(A)

あるいは次のように書きます。

x = (9.53 + 5.32) / log(1.81) / sqrt(7.52) ...(B)

式(A)の方が例題の式の形をイメージしやすいので,(A)の書き方をお勧めします。煩雑にならない程度に,カッコを几帳面に使いましょう。

[作業] 次の式を誤解の無いように,分かりやすいコードで書いてください。

               273 + t
   v = 287.03 ---------
                  p

      v = 体積[m^3]
      p = 圧力[Pa]
      t = 温度[℃]

著者プロフィール

平田敦(ひらたあつし)

地方都市の公立工業高等学校教諭。趣味はプログラミングと日本の端っこ踏破旅行。やがては結城浩氏のような仕事をしたいと妄想している。

Twitter : @hirata_atsushi

コメント

コメントの記入