|
|
|
1-2-7. C言語のスタイルC言語は、フリースタイルのプログラミング言語ですので、いろいろな書法があります。しかし、あまりに独自の書法では、個人として使用するのは良いのですが、グループで作成する時や、完成したソースコードを公開・提供する場合に困ったことになります。最近はオープンソースコードの運動も盛んです。ソースコードは非常に重要な資産ですので、その書法にもオープン性を取り入れ、ここでもう一度自分のスタイルについて考えてください。スタイルの考慮点
コメント コメントは、コードの一部と考えるべきです。自分で作成したコードでも3ヶ月も立つと(時には1週間で)、そのコードが何のためにあるのか、どういう役割をもつのか分からなくなることもあります。よって適切なコメントは絶対に必要な要素です。まず関数の先頭で、その関数の役割とパラメータの意味や用法をコメントで説明します。この場合は、すべての関数で書式を統一し、「適正」な分量にすべきです。ある大手のソフトウェア企業のコードを見たことがありますが、そこでは、コードよりコメントの方が多くの量を費やしてしました。またパラメータも関数の説明も1行で済ませる例もあります。よって「適正」な分量に定型はありません。作成者の用途や考えで異なります。私は、コンポーネントや他者に公開を予定する場合は増やします。その関数があちこちで使わないプライベートなものや、他との関連の薄い関数は1行だけのこともあります。
コメントは行間にも記入します。関数内で、処理がいくつかに分離している場合は、その処理ごとにコメントを入れます。また用途の分かり難い文を解説することもあります。ただし以下の様なコメントはやめましょう。
インデントとタブ C言語では、インデントを多用しますので、タブは重要です。しかしタブは少し考えなくてはいけません。まずインデントの量の問題です。これは昔なら8文字でしょうか。しかし現在は4文字のことが多いと思います。1つの文は1行に記述するのが、コードを分かり易くします。よって多くのインデント量を取ると、少し深い文はスペースが不足しますので、4つぐらいが適当でしょう。 次にタブです。これはハードタブとスペースで代用したソフトタブのどちらを使うかの問題です。これは一長一短ありますが、ソフトタブを推薦します。ハードタブは、1キーでインデントの挿入・削除が可能なので、便利です。しかし、インデントの量は昔のFortranの頃から8タブがデフォルトなので、別環境では思った表示ができません。 さらに1行の文字数は、今なら自由ですが、印刷や別環境でも問題の少ない80文字をお勧めします。 {と}の位置 C言語のスタイルで一番いろいろなスタイルがあるのがこの{・}の位置です。この位置は見易さか情報量かの観点と一貫性の2つの観点から少し考えたいと思います。(A) if (code > '0' && code <= '9'){
f = ID_NUMBER; ...
} else {
f = ID_ETC; ...
}
(B) if (code > '0' && code <= '9')
{
f = ID_NUMBER; ...
}
else
{
f = ID_ETC; ...
}
皆さんは(A)と(B)のどちらのスタイルを使っているでしょうか。(A)は行が節約でき多くの情報を盛り込めます。(B)はより見易いコードになります。私はカーニハン&リッチが(A)だったので、最初はこの方法で記述していました。しかし現在は(B)を使っています。DOSの頃はソースコードは24行の表示がやっとでしたが、WIndowsになって40行以上を一度の表示できるのが変わった最大の理由です。ただ(B)のスタイルならすべて統一すべきでしょうか。
(A) typedef struct { enum {
int x,y: ERR_NOT,ERR_NOTMEMORY,...
} XYPOS; };
↓ ↓
(B) typedef struct enum
{ {
int x,y: ERR_NOT,ERR_NOTMEMORY,...
} };
XYPOS;
enumは(B)に統一しました。しかしtypedefやstructは、XYPOSは、}の後に続けて記述しています。しかしできるだけ、スタイルの統一は重要です。
スペースの入れ方 スペースの入れ方も決めた方が良いでしょう。以下の部位でスペースを入れるか入れないか決めておきましょう。
(A) INT x,y; LPRECT prc; LPCREATESTRUCT pcs; (B) INT x,y; LPRECT prc; LPCREATESTRUCT pcs;(A)と(B)はどちらが良いでしょうか。私は折衷方式を取っています。極端に長い型の場合は、1つだけインデントせずに、他はスペースでインデントして仮変数名を揃えます。 switch文のスタイル switch文は使う人によってインデントの方法が異なります。皆さんはどの方法を取っているでしょうか。(A) switch (*cmd) {
case 'A': opt = AOPT; break;
case 'B': opt = BOPT; break;
default: opt = ERROPT; break;
}
(B) switch (*cmd)
{
case 'A': opt = AOPT; break;
case 'B': opt = BOPT; break;
default: opt = ERROPT; break;
}
(A)はカーニハン&リッチの書法です。(B)は我々が使用しているスタイルです。またこの折衷のスタイルや、caseの中の書法も数々あります。
関係演算子の左辺と右辺 if 文で変数と定数を論理演算(関係演算子で判断)する場合は、定数を左辺にして変数を右辺にすることがあります。 char *p;
:(他のコード)
if (NULL == p) // (A)定数が左辺
{
:(他のコード)
}
if (p == NULL) // (B)定数が右辺
{
:(他のコード)
}
上記の(A)が定数を左辺にした例で、(B)が右辺にした例です。私は、通常(B)の方法を使っていますので、(A)には違和感があるのですが、(A)には1つ大きな利点があります。
関係演算子と等値演算子は、==,!=,<,>,<=,>= などですが、== の等値演算子を = と間違って入力することがあります。長くプログラマをやっていれば、1度や2度は誰でも経験していると思います。困るのは、= としてもCの構文上はエラーにならないことです。
|