#技術者としての土台
Cプログラミング診断室という書籍をご存じだろうか。
初版は平成5年(1993年)で、当時のパソコンはこんな感じである。
通信環境はこの有様で、携帯電話はdocomo誕生直後だ。
その後、この書籍は途中絶版を挟んで改訂を重ね、現在に至る。
この書籍は技術書というより、誤解を恐れずに言うなら思想書である。
例題のプログラミング言語はC言語だが、言語は問題ではない。
この書籍の趣旨は、悪いコード例を取り上げて
- どこが悪いのか?
- なぜ悪いのか?
- 悪い実装に至った理由は何か?
- 思想をどう切り替えるべきか?
- そしてどう作るべきか?
について、丁寧に解説した書籍である。
一時絶版したため、著者のご厚意で一冊丸ごとWebで公開されている。
なんと無料である。
ではWeb上の内容をベースに、大切なところを紹介していく。
概要の紹介に留めるので、実際の記事も参照してほしい。
なおリンク先はSSL非対応であることに注意されたい。
#開院準備
ここは技術的内容の前の導入部である。深く読む必要はない。
古株の技術者にとってはクスっとする内容もあるかもしれない。
平成生まれのエンジニアにとってはピンとこないかもしれない。
#第1章 普通の初心者
ここはコードを設計・実装するための基本の基本を解説している。
- 関数などの処理単位を長くしすぎない(100行以下)
- 処理単位は機能に着目して適切な長さに分割する
- 意味のわかるコメントを残す
- 車輪の再発明をしない(ライブラリを活用する)
- 命名規則は開発環境における標準的なものを採用する
#第2章 これでもプロ
ここは第1章よりもひどいコードが登場する。
コードはリンク先を見てじっくり堪能してほしい。実に味わい深い。
ここでの趣旨はこうだ。
- コメントを書く
- 処理単位を長くしすぎない
- 悪いとされている goto を使わない(例外はある)
- ほかはC/C++に依存した部分が多いので割愛する
#第3章 上司が問題
これまでとは別の意味で味わい深いコードである。
- 命名規則はその環境で標準的な形式を使用する
- グローバル変数を極力使わない
- フラグの乱用を避ける
- ユーザ定義型やコード片をコピペしない
ここで重要だと思うのは最後の2つである。
ある処理単位において、実装にフラグが増えるほど難易度も上がる。
条件分けの数が
- フラグ1つ>2通り
- フラグ2つ>4通り
- フラグ3つ>8通り
条件分けが2のべき乗で増えていく。こういう実装はバグを呼ぶ。
さらに、次のコード片のコピペはより深刻である。
- コピペしたコード片にバグがあったらすべて修正が必要
- そもそもコピペでコードの総量を増やすのは悪である
- コピペを考える前にリファクタリングを考えるべきである
- いかなる理由でもコピペで解決してはならない
#第4章 キャストが好き
C/C++依存のため割愛。リンク先を参照されたい。
#第5章 管理は複雑に
C/C++依存のため割愛。リンク先を参照されたい。
#第6章 不慣れ
X-Window、というかウィンドウシステムでのプログラミング問題。
ここでの趣旨はこうだ。
- 長い処理単位を避ける
- 適切なインデント
- 読みやすい1行の文字数(これは当時の環境での話)
- メモリの動的確保は必要な場合に限る
#第7章 文字列処理は得意
C/C++依存のため割愛。リンク先を参照されたい。
コードは味わい深いので興味のある人は堪能してほしい。
#第8章 Pascalが好き
C/C++依存のため割愛。リンク先を参照されたい。
開発者の姿勢としては論外である。
#第2部 集中治療室
#第9章 珠玉の力作
ここでの趣旨はこうだ。
- 言語仕様は正しく理解して楽をしよう
- ライブラリの使い方を学習しよう
- コメントアウトで古いコードを残すのはやめよう(*1)
- ウィンドウシステムのサービスコールを確認しよう
- ライブラリやOSの提供機能を把握して極限までサボろう
*1については理由があってあえて残しているケースも存在する。
だが基本としては一時的な利用に限定するべきである。
#第10章 最長不到関数
ここでの趣旨はこうだ。
- 処理単位が一定の行数(目安100行)を超えたら立ち止まろう
- 動的なメモリの確保・解放は必要最小限にしよう
- 複雑な条件判断は正常判定より異常判定を優先しよう
なお、C/C++限定だが、delete演算子とfree()関数にnullptrを
渡すのは問題ないことが保証されている。
#第11章 奇っ怪な条件
ここでの趣旨もこれまでの繰り返しになる。
- OSのサービスコールの機能はよく調べておこう
- すでにあるものを使って無駄なコード書くのはやめよう
#第12章 芸術的字下げ
ここでの趣旨はこうだ。
- エラー処理を優先しよう
- エラー処理限定の関数内ジャンプであればgotoにも価値がある
個人的な経験則だが、インデントが3段以上のコードには問題がある。
#第13章 計算は自分で
ここでの趣旨はこうだ。
- コンパイラ(処理系)の自動計算を活用しよう
- 環境ごとにデータを差し替えるならリソース化しよう
#第14章 メモリが足りない
ここでの趣旨はこうだ。
- 巨大なデータを扱う必要がある時は「扱える単位」に分割しよう
- 性能ネックになりやすい(遅い)実装に注意しよう
- 実行しても無駄な処理を実装しないようにしよう
- 本当に遅くて問題ならプロファイラを活用(ネック部分に対処)
#まとめ
たくさんコードを書くと、たくさんデバッグすることになる。
プログラマの三大美徳でも言われる通り前向きな怠惰になろう。
- より少ないコード量で済ませる方法はないか?
- ライブラリやサービスコールでやらせることはできないか?
- 力ずくでコードを書いていないか?(コピペは論外)
- 正常系判定を優先してコードが長くなっていないか?
目安としては処理単位の行数とインデントの段数である。
関数などの処理単位が100行を超える場合は立ち止まろう。
処理単位の中でインデントが3段以上なら注意しよう。
1行の長さは気にしなくてもいいが、目安は200文字以下だろう。
この傾向は処理単位の中に複数の機能が存在することを示唆する。
処理単位を精査して、機能ごとに単位を分割しよう。
これは現在に至るまで通用する法則だと自分は信じている。
言うまでもないがコピペは厳禁である。
なおC/C++プログラマにはこちらもお勧めしたいのだが絶版のようだ。
Good Luck !