LoginSignup
13
14

More than 1 year has passed since last update.

Cプログラミング診断室という思想書

Last updated at Posted at 2021-04-23

技術者としての土台

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 !

13
14
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
14