My Brain is Open.

思いついたことを適当に列列と

C言語ことはじめ

改めまして、お仕事でC言語を取り扱うことになって1ヶ月ほど経ちました。

これまでシェル(bash)とかRuby on Railsとかスクリプト系が多くてすっかり忘れている感がありました。
というか、実際のところ大学の実習程度にしかやっておりません。
そんな僕に何が出来るのか。とかくぶち当たって考えていこうと思っている次第です。

さて、C言語では何が必要となるか。思いつくままに列挙してみましょう。

  1. ポインタの扱い
  2. バイト単位、ビット単位での対応
  3. 型の明示的な処理
  4. 構造体の利用と整理
  5. 関数の分割方法の整理

適当ですが少しだけ所感を。

  • ポインタの扱い

Cをやるとポインタが難しいとか昔は言われてましたが、いざやってみるとそんなに難しい物じゃないです。
どう考えるかというと、単純に変数の格納先の先頭フラグをイメージするだけです。
配列は同じ大きさのメモリ割り当てが連続しているイメージで、インクリメント(+1)で一つ分ずつずらす感じ。

  • バイト単位、ビット単位での対応

たとえば int は4バイト、char は1バイトといった単位でメモリを使います。
当然 NxN 行列とかつくると大量に消費しますし、数式の計算ロジックなどではビット単位での演算(AND, OR, ビットシフト, etc)を使うことも考えられます。
関数単位での利用メモリ空間をある程度イメージして、無駄がないか、はみ出す可能性のあるロジックはないか、扱うはずのないデータに干渉していないかなど、十分なマッピングを心がけたほうが良いと思います。

  • 型の明示的な処理

Ruby などをやっていると時々忘れるのが型の処理。
例えばintにコマンドライン引数を入れようとしてlongが入ってしまい、値が変わってしまうなどはよくあることで、明示的なキャストや、扱う型が十分見合っているか、事前に型に収まるよう入力チェックが済んでいるか、などをチェックすべきでしょう。
また、最初は型を明示しない内部コード(マクロ定数など)は作成した当人は固定の型に入ると分かっていても、複数人で管理する場合は人為的なミスや仕様変更などが起こり得ることも想定しておき、型チェックを忘れないようにしましょう。

  • 構造体の利用と整理

構造体は意味のあるデータのまとまりをメモリ配置(メンバ変数の集まり)で表すものです。先に述べたポインタのインクリメントなどでは、構造体の配列の場合も有効です。
意外と構造体は使われる局面が少ない気もしていますが、ある単位でひとまとまりになっているべきデータは構造体にして整理すべきでしょう。
理由は例えば関数の入出力にchar*やintなどで引数の多い構成になっていた場合、つぎに変数が増えた途端に改修箇所が増え、改修漏れの原因につながります。
構造体の持つ意味をきちんと定めて、そのデータ単位を扱う関数であると明示すべきでしょう。
ただし、むやみに構造体宣言をすると何をする単位かわからなくなるため、DBのモデル定義のような観点は必要でしょう。

  • 関数の分割方法と利用

関数の中身はできるだけすっきりとすべきです。
どういう意味ですっきりかというと、「この関数は何をするための関数で、それを分割するといくつかのプロセスからなる」事を明示でき、「いくつかのプロセス」が他の人にも分かりやすいことが大切だと思っています。
例えばイベントループを持つようなプログラムであれば

  • main
    • コマンドライン引数処理
      • 入力値チェック
      • 型変換
    • メインループに引き渡す前処理
      • 変数一覧の確認(抜け漏れの無いよう一覧化や構造体化)
      • 引き渡す変数の初期化処理
    • メインループで行われるべきルーチン
      • イベントコールバックの登録
    • メインループ終了後の処理
      • free()などのメモリ管理
      • 適切な値で終了コードが返ってきたかチェック

などなど、まずは大雑把な流れがあり、そこから細かい処理に派生していきます。
この流れをささっとつかめることを大切に、一つ一つの関数を記述出来れば良いと思います。

また、部分関数化するに当たり以下のことに気をつけておきたいと思っています。

  1. 部分関数は一度しか使わなくても、細かくても、見通しを悪くする部分があれば処理のカプセル化出来る部分を探して作成すべき。
  2. 入力されるべきデータや書込み先のポインタを明示する。不必要なものは入れないし、必要であれば必ず明示する。グローバル変数を使わない。

細かいところだと思うのですが、自分のセンスを問うために、よりブラッシュアップして挑みたいと思います。

そんなわけで「初心者がなにかほざいている」程度に思っていただければと思いますが、これからも成長出来ればと思います。