こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

あなたのC言語コーディング規約

勤務先・学校・趣味でC言語を使用してプログラムをしている方の多くは組織内で決めているコーディング規約に沿ってプログラムをしていると思います。
しかし、全てに関して規約化されていることは少なく、ある程度プログラマの裁量に任せていることがあると思います。

そこで、質問です。
「あなたの中で決めているコーディング規約は何ですか?」
「また、その理由は何ですか?」

私が決めているコーディング規約を一例挙げると以下の通りです。
(基本は他人が見ても直ぐに理解できるように心がけてます。)
------
□変数名の前には必ず型を現す文字を書く
理由:観ただけで型が分かるから。
例 :int型は、iData
   char配列は、stData
   ポインタは、pData

□関数の復帰値は、一旦必ず変数に代入する。
理由:代入しないとデバックがしにくい。
例 :iRetCode=func();
   switch(iRetCode){
     case文
   }
   の、ように色んな値を試すときに不便。

□if文には、極力「!」(NOT)は使用しない。
理由:複数の論理和・積などが入った場合ややこしいので
   elseで代用する。(真の時の処理はわざと書かない)

□if文の判定には必ず定数値を左辺に持ってくる。
理由:if(iData=0)とかの"=="を"="にしてしまうミスを防ぐため。
   (コンパイラによっては、警告が出るものもありますが…)
例 :if(0=iData)など

□while(1)は、基本的に使用しない。
理由:無限ループに陥らないようにするため。
------

投稿日時 - 2006-07-12 19:27:16

QNo.2271876

暇なときに回答ください

このQ&Aは役に立ちましたか?

16人が「このQ&Aが役に立った」と投票しています

回答(19)

ANo.19

みなさんの回答を読み、「なるほど」と唸りました。
いろいろなのがあるんですね。

わたしが気をつけている事を挙げます。

・システムコールの戻り値は、falseと比較する。
  →falseは0、trueは非0と教わりました。
   ir( true == XXX ) ってやらないようにしています。

・コーディング規約、と言えるかは微妙ですけど、
 手書きでフローチャートを書く。
  →紙にフローを書ける位なら、後で何とか読めるかな。
   ネストが深すぎる関数は、後付けの設計書を書けず、
   納品時に困った事があるので。

・どこ行っても「やるな」といわれるので当たり前かも
 しれませんけど、goto は使わない。
  →goto使うくらいなら、do{ }while(0); でbreakして、
   と言われた事があったけど、どっちも微妙。。。

そんな所でしょうか。

そういえば以前、STLを使うなと言われて閉口した事があります。

投稿日時 - 2011-07-28 17:57:33

ANo.18

既約が特にあるわけでないけど自分で特に意識していることで他の方が
あまりあげてないことだけ書きます.
1.変数宣言は値が初めて発生したときに書く.
(忘れやすいので)
2.変数名,メソッド名等なるべく英語のフルスペルで書き省略しない.
英単語は複数を表していても単数形.
(正確に省略するのが難しいので統一が難しい.
人によりぶれがあるのでローマ字なども使用しない)
3.できるだけ小文字を使用し大文字はテンプレート引数やマクロに限定する.
(これは単なる好み.なんとなく見やすい.)
4.private,protectedメンバには前にアンダースコアを付ける.
(publicとの間での変更はあまり無いと思うので)
5.計算途中の値はなるべく変数にする.
int x = 0;
int y = 1;
int z = x + y;
int w = x - y;
int s = z * w;
のように書き一本の式になるべくしない
6.論理的な切れ目に空行・コメントをいれリストを短くするより見やすくなるよう心がける.

投稿日時 - 2010-10-17 12:20:09

ANo.17

■ if文の判定には定数値を右辺に持ってくる
理由:可読性を考慮して。定数値を左辺だと読みにくい

■ なるべくwhile(1)は使用しない
理由:脱出条件が分かりにくく、無限ループに陥る可能性もあるから

■ 変数名は分かる範囲でなるべく短いものにする
理由:好み。コーディングのしやすさから。あと、英単語そのままだと長すぎだから

■ #defineの定数はなるべく使用しない
理由:手軽だから沢山作って分岐とかに色々使う人がいる。その人のコードが非常に分かりにくかったから。あと、安全性の問題で。

■ 関数名は大文字から始める。
理由:可読性考慮。

■ インデントは2。
理由:好み。4だと空き過ぎで読みにくいと感じる。特にif文がいくつか重なると。

まぁ色々ありますが、結構でてるのでこれくらいで

投稿日時 - 2010-07-24 03:09:34

ANo.16

SE の傍ら PG っぽいこともやっている者です。
# 人手不足なもので。。。

私のいるプロジェクトの場合、コーディング規約は必要最低限のことしか決められていないですね。

で、私の場合ですが、こんな感じかなぁ。

●変数名は名詞、関数名は動詞、ブール変数 (TRUE/FALSE) は疑問形にする。
こうすると全体が読みやすくなる(気がする)。

●変数名の先頭に型名をつけない。
型と変数には関連がないことが多く、また全体として読みにくくなることが多い (気がする)。

●整数との比較には switch-case を使用する。
if ( hoge == 1 )
{

}
else if ( hoge == 2 )
{

}


なんてことを書くくらいなら

switch ( hoge )
{
case 1:

break;

case 2:

break;


}

を使用する。

●ブール変数 (TRUE/FALSE) には == TURE や == FALSE をつけない。
なんとなくその方が読みやすい気がする。

if ( enabled )
{

}

とか

if ( !enabled )
{

}

とかを使う。

●関数の戻り値は極力いったん変数に代入する。
そのほうが読みやすいことが多い。

hoge = do_something();
if ( hoge != -1 )
{

}

など。
ただし、こんな場合は仕方ないとあきらめる。

while ( ( hoge = do_something() ) != -1 )
{

}


他にもあると思いますが、パッと思いついたのはこんな感じかな。

投稿日時 - 2006-07-16 17:55:20

ANo.15

回答ではないのですが、No.7の方が書かれている奴は結構良いと思います。
そもそもそんな書き方したらまともに動かんだろうってのが多いので、コーディング規約と言えるかは微妙な所ですが。。。

お暇な方は一読を!
https://sec.ipa.go.jp/download/200504eb.php

投稿日時 - 2006-07-14 10:57:53

ANo.14

演算子と変数やリテラル文字列などの間には必ずスペースを入れる
→その値の構成要素を明確に分離する為

関数名と引数との間には必ずスペースを入れる
→処理(関数名)と値を明確に分離する為

Breakは使用しない
→長いループ等で脱出条件が分かりにくくなる為

returnは関数の終わりに1回のみ
→関数の脱出する場所が分かりにくくなる為

インクリメント,デクリメントは使用しない
→2以上の加減算や加減乗除等との記法統一を行い読みやすくする為

省略はしない
→そんな事をしたとするならば私の場合直ぐに間違いを見つけられなくなります

グローバル変数は使わない
→ネーミング衝突を回避する為

staticは必須で無い限り使わない
→過去の値に挙動を左右されるリスクを負わない為

変数は必須の事情が無い限り初期化する
→初期化されていない値に挙動を左右されるリスクを負わない為

他にも沢山の制限を設けているのだとは思うのですが直ぐに思い出せるのはこれ位ですね。

投稿日時 - 2006-07-13 18:47:06

ANo.13

たびたびすみません。#8では理由を書かなかったので、補足することにします。

1. 可能な限り規格厳密合致プログラムにする。
2. 規格厳密合致が無理な場合、処理系に対する仮定を明確にする。
3. 処理系に依存する部分を分離する。

1.~3.の理由は二つあります。一つは移植性を向上させること。もう一つは、規格厳密合致プログラムを書いたり、厳密合致にできないと判断して別の方法を採用するには、コードの各部の振る舞いが正確に把握できている必要があります。つまり、この規約を守ることで、少なくともコーディングを行った本人の静的検証が同時に行われることになります。

4. 例外安全にする。

これは当たり前のことなので、特に理由を挙げるまでもありませんが、例外安全でなければ信頼性のあるプログラムにはなりません。

5. 可能な限り静的にエラー検出を行う。

動かしてみてからバグを見つけるのではなく、問題のあるコードはコンパイルまたはリンクができないようにすることで、ビルドが通れば大多数のバグを潰せます。C++だけでなく、本来はCでもこのようにすべきなのですが、言語仕様上大したことは期待できません。

全体にいえることとして、言語の仕様や特性を十分に理解していないと守れない規約を設定することで、初級者の参入を拒む目的もあります。初級者が参入すると、どんなに厳格な規約を作ってもまともなプログラムはできませんし、平均以下のスキルではメンテナンスできないようにしておくのも(業者変更されたり、買い叩かれるリスクを軽減する意味で)ビジネス的には重要だったりします。

投稿日時 - 2006-07-13 17:10:59

ANo.12

高度に整った環境で働いている人もいれば、足りないメモリをやりくり
するために言語機能削って苦戦する人もいます。
書いてあることをみれば、どういう環境なのかはわかりますし、環境的
に無理な話もあるでしょうから、お互い「へぇー」くらいの気分でいい
んですよね。

中間データにメモリ変数名を付けてやらないとデバッガで見にくいって
話は私も経験あります。
レジスタに割り当てられちゃうとアセンブラモードにしないと見えない
ので難儀しました。
組み込み系ならよくある話ですよね。

ちなみに私は組み込みでたまにPCで、主に68000,M16C,
SH2,H8,6801のマイコン用Cソースをいじってます。

○ループはfor()に統一すること
○ループ処理内の最初の行に必ず終了条件を書くこと
私はこれでやってます。

○外部参照する関数、変数のプロトタイプ宣言は必ずexternをつける。
○外部参照しない関数、変数は必ずstaticをつける。
検索時に同じ名前でヒットするとどれが本物かわかりにくいので。

○変数は全て#defineやtypedefで置換したユーザ定義型を使用する。
CPUが変わるとint=shortだったりchar=unsigned charだったり
して置換作業に困ったので。

○標準ライブラリの関数を各ソースから直接呼ばず置換関数を作る。
上記と同じ問題で、引数の型が変わってしまうために移植すると
型違いのワーニングの嵐になったので、呼び処理を1つのファイル
内に集めてキャストなど対策して、影響を受けるソースを減らして
います。
sprintf()とかはROMの容量不足でライブラリを実装できないこと
が多いので、%d,%xあたりだけ自作して使うことも多いです。

投稿日時 - 2006-07-13 12:46:05

ANo.11

要点という意味ではNo.8のjactaさんの回答でかなりカバーされてるかと思います。
(書かれていることは私も意識して守ってますし)

質問者さんの意識はもっと細かい個々のコーディングに焦点があるようなので、
もしかすると直接の役には立たないと思われたりするのかもしれませんが、
実際にはそういう細かい書き方とかは些事なので、
あまりこだわると木を見て森が見えないことになりかねません。
程々がよいかと思います。

> そこで、質問です。
> 「あなたの中で決めているコーディング規約は何ですか?」
> 「また、その理由は何ですか?」

正解も無いので、質問というよりはアンケートが妥当かと。

投稿日時 - 2006-07-13 12:36:08

ANo.10

他の方々と同様に、質問者さんが提示されているコーディング規約に対しても少しコメントしておきます。

> □変数名の前には必ず型を現す文字を書く
> 理由:観ただけで型が分かるから。

変数が存在する有効範囲が十分に狭ければ、このような配慮は不要です。
変数名に型情報をつけて便利なのは、関数がやたら長いとか、大域変数を多用した場合であり、それ自体が問題です。
なお、ハンガリアン記法そのものは悪くありません。ただし、某社が流行させた間違った用法ではなく、本来のハンガリアン記法を使うことが重要です。
http://www.radiumsoftware.com/hungarian_notation.html

> □関数の復帰値は、一旦必ず変数に代入する。
> 理由:代入しないとデバックがしにくい。

必要に応じて変数に格納する方がよいと思います。
C++なら、無意味な変数を介すことで、コピーコンストラクタや代入演算子が呼ばれることになります。結果として、(例外が送出されるかもしれないので)実行パスを複雑にし、例外安全にするのが難しくなります。

> □if文には、極力「!」(NOT)は使用しない。
> 理由:複数の論理和・積などが入った場合ややこしいので
>    elseで代用する。(真の時の処理はわざと書かない)

真の処理を書かないと、実装漏れとの区別が付きにくいので、個人的には好きではありませんが、そういう書き方もあっていいと思います。ただ、強制すべきものではないように思います。

> □if文の判定には必ず定数値を左辺に持ってくる。
> 理由:if(iData=0)とかの"=="を"="にしてしまうミスを防ぐため。

そういう書き方をしてもよいとは思いますが、直感的ではありませんし、やはり強制すべきではないと思います。
また、==ならまだよいのですが、不等号にまで拡大すると、0 ≦ x < 10を表すには if (0 <= x && x < 10)、その否定には if (x < 0 || 10 <= x) と書いた方が直感的であるにも関わらず、こうした書き方ができなくなります。

> □while(1)は、基本的に使用しない。
> 理由:無限ループに陥らないようにするため。

意図からすると for (;;) も禁止のような気がします。「基本的に」というのがよくわかりませんが、全面禁止であれば、無限ループを作るには goto を使わざるを得ず、組み込みシステムなどでは非常に不便です。

投稿日時 - 2006-07-13 11:40:07

ANo.9

識別名は、理論的な名称を優先して、コンパイラの都合は優先しない
(どうせ、本当に重要な変数は、class か、複合型なので、わざわざ、型を変数名に含めない)

条件判定は、「いいたいことを表すように」書く
if (fin.eof()) ... eof() のための特殊処理 = eof の時の処理
while(! fin.eof()) ファイルの通常処理 = eof でないときの処理

関数の返値を余計な変数にストアしない
result = fun();
if (result); この2行の間に、割り込みが起きて、result が壊されたら?
それに、一時変数が増えると、いつしか、ほかでも使い回しにされる危険性多し。

無限ループは、while(1)
 明示されている無限ループのほうが、明示されていない隠れ無限ループよりはるかにまし

デバッグのしやすさという基準を、コーディング規則の基準にしない
 デバッグするためなら、#define debug etc. で、システム的に
 デバッグしやすくするために工夫したつもりで、バグを呼んでは困る

ひとつのプロジェクトでは、動詞、名詞の順序を固定する
printNewItem() と newItemGet() を 混在させない

ひとつのプロジェクトで、動詞の対応をとる
getList() と writeList() を混在させない

条件式で、定数は左側
 定数が左にあると気持ち悪いから。
 (== という特殊な例のために、その他の大部分で気持ち悪いのはいや)

こんなところですかね。

投稿日時 - 2006-07-13 10:17:43

ANo.8

要点だけを挙げると...

1. 可能な限り規格厳密合致プログラムにする。
2. 規格厳密合致が無理な場合、処理系に対する仮定を明確にする。
3. 処理系に依存する部分を分離する。

これに加えて、C++では、

4. 例外安全にする。
5. 可能な限り静的にエラー検出を行う。

といった感じです。
細かな部分はいろいろありますが、それほど本質的ではありません。

投稿日時 - 2006-07-13 00:47:21

ANo.7

最近は コーディング作法ガイド というキーワードで
ググって最初に見つかるやつを使ってます。

投稿日時 - 2006-07-13 00:27:30

ANo.6

私なりの見解です。
>□変数名の前には必ず型を現す文字を書く
特にこだわりません。但し、広域変数はext_を頭につけてます。それ以外は、その関数のなかで、変数を定義するので、その定義をみれば、わかります。
>□関数の復帰値は、一旦必ず変数に代入する。
同感です。私もこの方法を採用しています。
>□if文には、極力「!」(NOT)は使用しない。
特にこだわりませんが、if文はステップが減るか、判りやすいか、の何れかを優先します。
>□if文の判定には必ず定数値を左辺に持ってくる。
その通りですが、人間の思考パターンになじまないので、採用していません。その為、if (a=1)などのコードをかいて、バグを誘発しています。但し、コードが完了した後で、if (a=1) や a == b;などの文法上はOKだが、処理内容上はNGのコードをチェックするツールを作り、この呪縛から、逃れています。
>□while(1)は、基本的に使用しない。
使っています。breakをきちんといれれば、問題ありません。

そのほかは、
1.処理速度向上と、プログラムのシンプル化のため関数間のデータをパラメータ渡しにしないようにしています。但し、ニューメリックチェックルーチンのように業務と無関係な共通関数は、パラメータ渡しにしています。
2.同じ処理はマクロでまとめています。
例えば、
if (strcmp(x,"abc")==0){
printf("abc");
return 1;
}

if (strcmp(x,"xyz")==0){
printf("xyz");
return 1;
}
のように、strcmpの右辺のみが、異なるようなコードを
何行も書くときに、
if (strcmp(x,"xyz")==0){
printf("xyz");
return 1;
}
の部分をマクロで1行にまとめて、ステップをへらします。
3.64ビットモードでのコーディングと32ビットモードでのコーディングが両方発生するので、どちらでも使えるようなコードをかくようにしています。
(例えば、ポインターのサイズを4バイトに限定しない。時間の取得は、int型で取得しない。long型を使用しない等)

投稿日時 - 2006-07-12 21:30:55

ANo.5

>「あなたの中で決めているコーディング規約は何ですか?」
私のコーディング規約はありません。
なぜなら、「個人(あなた/私/etc.)」の「コーディング規約」というものは存在しないためです。

コーディング規約はプロジェクト単位で制定されるものです。
これは、各人のコーディングの癖が混在し、ソースファイルが読みにくくなることをふせぐためであり、あなたが提示された「規約」と#2の方の意見との間でどちらが優れているかという神学論争を防ぐためでもあります。

したがって、私のコーディングの癖はありますが、私のコーディング規約はありません。

その「癖」でよければ、以下に記述します。
------
□ポインタ型変数名の前にはpまたはp_を書く
理由:ポインタは取り扱いに注意が必要なため

□関数の復帰値は、変数に代入するかは特に決めていない。

□if文には、極力「!」(NOT)は使用しない。
付則:複雑な判定になる場合はその判定を関数化する

□if文の判定には定数値を右辺に持ってくる。
付則:ただし、片方が関数で、その関数名が長い場合は定数値を左辺に持ってくる
例 :if(0==AllYourBaseAreBelongToUsAllYourBaseAreBelongToUsAllYourBaseAreBelongToUs())など

□while(1)ではなくfor(;;)を使う

投稿日時 - 2006-07-12 21:24:18

ANo.4

「C言語」ですか?
であればISO/IEC9899準拠、もしもC++ならISO/IEC14882準拠。

CではなくC++を選ぶ。
理由:Cよりは、便利で安全で使いやすいから。

複数のコンパイラにかけて、警告が出ないようにする。
理由:標準準拠/マルチプラットフォーム前提なら当然のことだと思う。

各言語仕様書のサンプルのような命名規約で書く。
(ラクダ表記/ハンガリアンなどは使わない/大文字は定数くらいしか出てこない)
理由:好み。C/C++に大文字が混じるのは美しくない(Java等のときは混じってかいてますが)

上記からも当然に、型名などを変数名にはつけない。
理由:意味的におかしいと思う/型変更に弱い/IDEで間単に参照できる/
(C++の場合は更に)ユーザ定義に対応できない/必要性が薄い

コンパイラがチェックできるもののために可読性を落とさない。等式を逆順になどしない。
理由:昔の知恵なのだとは思うが、自分では可読性が落ちるだけだと思う。

無限ループならwhile(1)ではなく、for(;;)を使う。
理由:警告レベルを上げたときに、定数式のループを警告されたことがあるから。

(C++なら)マクロでは無く定数を使う。
理由:型安全だから。

むやみにキャストしない。
理由:設計のしわ寄せが多いから。設計を見直すなり、templateを活用するなりを考える。

などなど。全部はとても書けませんが。

投稿日時 - 2006-07-12 21:06:10

ANo.3

はじめまして。

C++にて開発を行っているものです。
自分の勤めている組織内ではやはり規約化はされていません。
各、PGが独自の規約(?)を作ってやっていますね。

自分は、大体下記のような感じでコーディングをしています。

■変数名
 頭に変数の型をつける。
 int  iData;
char szBuff[16];
char *pIn;
struct stuData strDataRec;
などなど。

■関数名
 fnSubMain()
頭にfnをつけ、関数である事を明示しています。
 また、クラスの使用時は、Onxxxxという形で
 宣言しています。

■ループ
 ループに関しては、時と場合によりです。
 配列の添え字として使用する場合は、forループ
 主体、テーブル内のデータ検索などは、while(1)
 で無限ループを使用し、データ終端でループエンド
 という形です。

■if文の判定には必ず定数値を左辺に持ってくる
 同じく、=防止の為、極力同じようにコーディング
 しています。

■その他
 #defineの羅列がきらいなので、enumをよく
 使用しています。

以上、ご参考になりましたでしょうか。

投稿日時 - 2006-07-12 20:36:05

ANo.2

□変数名の前には型を現す文字を書かない
ユーザ定義型は無限であり、対処できない。

□関数の復帰値は、一旦必ず変数に代入しない。
必要に応じて決めることであり、規約にするのはナンセンス。

□if文には、極力「!」(NOT)を使用する。
真のとき空の{}が現れるよりずっとマシ。

□if文の判定には必ず定数値を右辺に持ってくる。
人間の思考順序に合わせないと混乱する。

□while(1)は、積極的に利用する。
無限ループを作りたいならこれが最も楽。

といった意見もあります。

投稿日時 - 2006-07-12 19:44:47

補足

意見は分かりました。
で、あなた自身の規約は無いのですか?
その日の気分で次第でデタラメに書いているのですか?

投稿日時 - 2006-07-12 19:52:20

ANo.1

組織を移動したとき、方言を矯正させられますが、
その対処方法はお考えですか?

投稿日時 - 2006-07-12 19:40:03

補足

移動の意味を教えてください。
人の異動のことですか?

投稿日時 - 2006-07-12 19:51:41

あなたにオススメの質問