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.コーディングスタイル
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
ここでも書かれている通り、昔の書き方なので、やめましょう。
トリッキーなコードを書くと、上達したように感じるでしょうが、それは自己満足であり、可読性を損ないます。