ymlab式コーディングスタイル(VC++編)


ymlab式コーディングスタイル(C++)


1.概要


 本文章は、C言語C++言語(メインは、C++かな)でのコーディングスタイルを定義するものである。コーディングスタイルは、K&R(プログラミングC第二番共立出版;ISBN:4320026926)、金子式コーディングスタイルを非常に参考にして、ymlabの今までの経験から勝手に定義するものである。詳細については、ymlabの気分で微妙に異なる可能性があったり、数年後には、まったく違うスタイルに変化する可能性があるので、そこんとこは、よろしくである。


2.はじめに

コーディングスタイルが何故重要か。

  • 要するに、ymlabがプログラマを辞めてから、教師になったので、全然今の傾向がわからんし、どんどんコーディングスタイルを忘れていっているので、備忘録というところ.
  • なんだか、学校現場にいると、非常に非生産的な仕事がやたらと多い。

いまだにはんこやし。公務文書は、なかなか電子化できないみたいだが、ある程度ならば、ソフトウェアを開発した方がよいよいな場合もあり、コーディングすることが多くなってきたので。

  • 今後、万が一開発できる教師が入ってくれるかもしれんので、そのときに、人に読みやすいコーディングスタイルを身に着けたいのさ。

どうせなら、世界標準(に近い)スタイルを!!


3.変数命名規則

ハンガリアン記法ベース

どうも、ハンガリアン記法は、M$(わかっているとおもうけど、某Wxxxxxで有名なOS開発会社のことね)が嫌いな人が多かったり、最近のトレンドに合わなかったり、可読性に欠けるという批判もあるけど、これはこれで、慣れというメリットがある。

変数命名規則は、以下の通り。

  • 基本的に母音省略はあまりしない。昔みたいに変数名の文字数に上限がある時代ではないのだから。
  • でも、あまりたらたらたらたら長くなると、うっとうしいし、誤解を招くので、長く書きすぎないこと。
だから、isVisibleや、lMemberNumなどは、いいけれども、iThisClassMemberNumbersDataなどは、NG。わかるだろう。わかってくれるだろう。そもそも、そんなに長い変数になる前に機能を分割すべきです。
  • 短い範囲でのスコープで消滅する変数以外、一文字や二文字の変数名は避ける。簡単なカウンタなどで、
for ( int i; i < this->iMemberNum; i++ ) {
    (処理)
}

なんかはありだと思うけど、変数名が変更する場合や、どこに変数が使われているかをチェックするのに、検索するときに、関係ないところまで引っかかってくれる場合があるからね。ちなみにどうでもいいけど、このiは、iterator(反復子)の頭文字の略ね。つまり、この後で、j,k,と続いていきます。だから、意味があるならいいけど、意味もなく、 t とか q を使わんように。びっくりするから。

  • 第二プレフィックスは大文字で始めよう。例icounterよりもiCounterの方がすき。
これは気分の問題

第一プレフィックス命名例

表記 データ型 プレフィックス
int, INT 整数型 i int iCounter
unsigned int,UINT 符号なし整数型 ui unsigned int uiCounter;
long,LONG 倍長整数型 l long lCounter
unsigned long,ULONG 符号なし倍長整数型 ul unsigned long ulCounter;
float 単精度浮動小数点型 fl っていうか、double使え
double,DOUBLE 倍精度浮動小数点型 d,db double dResult
boolean,BOOL 論理型 f,is if ( isVisible == true )
char,TCHAR 文字型 c,ch char cFirst;
unsigned char,BYTE 符号なし文字型 b BYTE bFirst;
short,SHORT 短整数型 s short sCounter;
unsigned short,USHORT 符号なし短整数型 us unsigned short usCounter;
WCHAR wc ?
CString, char[] 文字列配列 sz CString szMessage;
HWND ウインドウハンドル hwnd,h HWND hCombo1;
vector ベクタ v vector <int>viHoge;
iterator イテレータ itr vector>int< viHoge; vector<int>::iterator itrHoge;


4.コーディングスタイル

  • 基本は、K&Rスタイルだけど、インデントに関しては、GNU/BSDスタイルでもよい。{}については、改行を作らず、完全にK&Rスタイルを採用
BAD PATTERN
for_(_int_iCounter_=_0;_iCounter_<_5;_iCounter++_)
{
    [処理];
}
GOOD PATTERN
for_(_int_iCounter_=_0;_iCounter_<_5;_iCounter++_)_{
    [処理];
}
入れるのと入れないのとで、全然見易さが違います。ただし、ドット演算子と、アロー演算子は例外。あいつらは、VCで開発してると、インテリセンス?機能で認識するためには、くっつけないといけないからね。
iMod=iCounter%iClassNum; と、 iMod = iCounter % iClassNum;
どっちがみやすいかな〜
  • 関数の前は、javadoc形式で良い。
doxygenで読めれば何でもいい。でも、別に大規模な開発やるんでもなかったら、javadocにしておけばよいでしょう。あ、ちなみに、一番最初の行は、この関数の簡単な機能を一行で書く。っていうか一行で書けないということは、やっぱり関数を分けるべき。それと、なんでか知らないけれども最初の一行の文末は句読点ではなくて、半角ドット.で終了しよう。なぜかは、gVimとかで、コーディングしていたら、すぐ分かる。Syntax Colorの設定で、最初の一行だけ反転表示になるが、それが.を入力するまでいつまでも反転表示のままなのだよ。

例.

/** 該当クラスの人数を抽出する.
 *  該当クラスの人数を抽出します.クラスの人数は、親クラス
 * にあるため、親クラスから取得します.
 * @param iGrade 学年
 * @param iClass 組
 * @return iMembers メンバの数
 */
  • 四則演算の順位とかは、わかっていても、()をつけた方が無難.
掛け算が先なんて小学生から習うから、常識だから必要ないと思うことは、プチ危険。仕様変更が多発すると、あれを消したり、これを消したりとしていくうちに、元の式が不明になる。

例。

 iDummy = iT + (int)lA * iX * iY - iZ * iU;

おちついて考えりゃーわかるんだけど、これのiXやらiYをごちゃごちゃ動かしてみよう。
本当は、こういう風に長くなったら、式を2回3回に分けたほうがいいんだろうけど、物理計算などは、一度に書いた方が逆に見やすかったりするからね。

  • インデント(字下げ)は、2文字か4文字か8文字.

たまに、6文字とかでインデントしてくれる人がいる。Fortranか、お前は。といいたくなる。K&Rだったら4文字が基本かな。でも、8文字にしておくと、すぐに、行末までいっちゃうので、そういう意味ではネストを深く掘りすぎずいいかも。Emacs Userなら、2文字なんだろうけど、あれ本当にみにくいなぁ。なれなんだと思うけど。


100.K&Rの真似をしてはいけないところ

コラム:C言語の聖書? K&R
ここでも書かれている通り、昔の書き方なので、やめましょう。
トリッキーなコードを書くと、上達したように感じるでしょうが、それは自己満足であり、可読性を損ないます。