web-dev-qa-db-ja.com

Cの変数と関数に使用される命名規則

Cで大きなプロジェクトをコーディングしているときに問題が発生しました。さらにコードを書き続けると、コードを整理するのが困難になることがあります。つまり、プログラムのさまざまな部分の関数と変数の名前が混同されているように見える場合があります。

それで、Cの変数と関数に使用できる便利な命名規則があるかどうか考えていましたか?

ほとんどの言語は命名規則を提案しています。しかし、Cにとってこれまで読んだ唯一のことは、名前がコードを読みやすくするために説明的なものであることです。

編集:

推奨される命名規則のいくつかの例の例:

Javaの命名規則をもう少し読みましたが、どこにあるか思い出せませんでした。

13
Aseem Bansal

さらにコードを書き続けると、コードを整理するのが困難になることがあります。

これがあなたの問題です。組織を正しく設定すれば、スタイルがより簡単に流れるはずです。

コードを整理するために待機しないでください。言語はあなたのためにそれをしませんが、コードは依然として低い結合と高い凝集度を持つモジュールに編成されるべきです。

これらのモジュールは自然に名前空間を提供します。衝突を避けるために、モジュール名(長い場合)を省略し、関数名の前にモジュールを付けます。

個々の識別子のレベルでは、これらは主観性の大まかな順になっています。

  1. 慣習を選んでそれを守る
    • たとえば、function_like_this(struct TypeLikeThis variable)は一般的です
  2. ハンガリー語の表記は絶対に避けてください(申し訳ありませんがJNL)

    • 最初に意図したとおりに使用するつもりがない限り、つまり、ひどいシステムバージョンではなくSimonyiのapps表記

      どうして?私はこれについてエッセイを書くことができますが、代わりにJoel Spolskyによる この記事 を読んで、興味があればさらに探すことをお勧めします。下部にSimonyiのオリジナルペーパーへのリンクがあります。

  3. 本当に不透明なCookie型でない限り、ポインタのtypedefを避けてください。混乱を招くだけです。

    struct Type *ok;
    typedef struct Type *TypePtr;
    TypePtr yuck;
    

    不透明なCookieタイプとはどういう意味ですか?クライアントコードに渡す必要があるモジュール(またはライブラリなど)の内部で使用されるものを意味しますが、そのクライアントコードは直接useできません。それをライブラリに返すだけです。

    たとえば、データベースライブラリは、次のようなインターフェイスを公開します。

    /* Lots of buffering, IPC and metadata magic held in here.
       No, you don't get to look inside. */
    struct DBContextT;
    /* In fact, you only ever get a pointer, so let's give it a Nice name */
    typedef struct DBContexT *DBContext;
    
    DBContext db_allocate_context(/*maybe some optional flags?*/);
    void db_release_context(DBContext);
    int db_connect(DBContext, const char *connect);
    int db_disconnect(DBContext);
    int db_execute(DBContext, const char *sql);
    

    これで、内部を見ることができないため、コンテキストはクライアントコードに対してopaqueになります。あなたはそれをライブラリに戻すだけです。 FILEのようなものも不透明であり、整数ファイル記述子もcookieですが、不透明ではありません。


設計上の注意

説明なしで上記の低カップリングと高凝集度というフレーズを使用しましたが、それについて少し気分が悪いです。あなたはそれを検索することができ、おそらくいくつかの良い結果を見つけることができますが、私は簡単にそれを取り上げます(ここでも、エッセイを書くことはできますが、しないようにします)。

上でスケッチしたDBライブラリは、小さなインターフェースを外部に公開しているため、低結合を示しています。実装の詳細を(部分的には不透明なCookieのトリックで)非表示にすることで、クライアントコードがそれらの詳細に依存することを防ぎます。

不透明なCookieの代わりに、その内容が表示されるようにコンテキスト構造体を宣言し、これにTCPデータベースへの接続用のソケットファイル記述子が含まれることを想像してください。その後、実装を変更して、同じマシンでDBが実行されているときに共有メモリセグメントを使用すると、クライアントは単に再リンクされるのではなく再コンパイルされる必要があります。さらに悪いことに、クライアントはusingファイル記述子。たとえば、setsockoptを呼び出してデフォルトのバッファーサイズを変更すると、コードの変更も必要になります。これらの詳細はすべて、モジュール内で非表示にする必要があります。これにより、カップリングが低くなりますbetweenモジュール。

この例では、モジュールのすべてのメソッドが同じタスク(DBアクセス)に関連しているため、high cohesionも示しています。これは、実装の詳細(つまり、Cookieの内容)を知る必要があるが必要なコードだけが実際にそれらにアクセスできることを意味し、デバッグを簡素化します。

また、単一の懸念事項があるため、これらの関数をグループ化するための接頭辞を簡単に選択できることがわかります。

さて、この例が良いと言うのは簡単ですが(特に完全ではないため)、すぐには役に立ちません。秘訣は、コードを記述して拡張するときに、似たようなことをする関数や同じ型で動作する関数(独自のモジュールの候補となる可能性がある)、および多くの別々のことを行う関数を監視することです。本当に関係があり、分割の候補となる可能性があります。

17
Useless

私の意見では、3つのことを覚えておけば、命名の問題の90%は解決されます。a)変数と関数の名前をできるだけわかりやすくします。 b)コード全体で一貫している(つまり、関数がaddNumbersという名前の場合、2番目の関数は、numbersMulではなくmultiplyNumbersという名前にする必要があります)およびc)名前を入力する必要があるため、可能であれば名前を短くしてください。

このトピックの他の側面を確認したい場合は 命名規則 のWikipediaページに、覚えておくべき良いリストがあります。また、CおよびC++に関するセクションもあります。

CおよびC++では、キーワードと標準ライブラリ識別子はほとんど小文字です。 C標準ライブラリでは、略称が最も一般的です(たとえば、文字が英数字であるかどうかをテストする関数のisalnum)。C++標準ライブラリでは、多くの場合、単語の区切り文字としてアンダースコアが使用されます(out_of_rangeなど)。マクロを表す識別子は、慣例により、大文字とアンダースコアのみを使用して記述されます(これは、定数にすべて大文字の識別子を使用する多くのプログラミング言語の慣例に関連しています)。 2つのアンダースコアを含む名前、またはアンダースコアと大文字で始まる名前は、実装(コンパイラ、標準ライブラリ)用に予約されているため、使用しないでください(たとえば、reserved__または_Reserved)。[5] [6]これは表面的にはストロピングに似ていますが、意味は異なります。アンダースコアは(ストロピングのように)文字を引用するのではなく、識別子の値の一部です:__fooの値はfooではなく__foo(予約されています)です別の名前空間で)。

5
Daniel Scocco

Cの唯一の厳しい制約は、名前空間がないことです。したがって、filesystemライブラリのrename()関数をmediarename()関数と区別する方法を見つける必要があります=ライブラリ。通常の解決策は、filesystem_rename()media_rename()などの接頭辞です。

その他の一般的なアドバイスは、プロジェクトまたはチーム内で一貫性を保つことです。読みやすさが向上します。

5
mouviciel

グローバルに受け入れられているフォーマットを探している場合

MISRA/JSF/AUTOSARは、C/C++コードの命名と編成に関する業界標準のほぼすべてをカバーしています。問題は、無料で手に入れることができないことです。つまり、各ガイドブックにはいくらかの費用がかかります。 MISRA 2008 C/C++コーディング標準の本はおそらく約50米ドルかかることを知っています。

これらは、ジャーナルを書くときの参考文献と追加の読みのためのハーバード参照と考えることができます。私はMISRAを使用しました。これは、関数と変数に名前を付け、適切に使用できるように整理するための良い方法です。

一時的なものを探している場合

PythonとJavaに提供した参照は大丈夫だと思います。私は、javadocスタイルのコメント、命名、およびコードの整理を採用している人を見てきました。問題として実際、前回のプロジェクトでは、Javaのような関数/変数名でC++コードを記述しなければなりませんでした。

1)明らかに従うのが簡単でした。

2)量産コード要件は、安全性が重要なソフトウェアシステム標準の根拠に触れていません。

3)レガシーコードは(どういうわけか)その形式でした。

4)DoxygenはJavadocスタイルのコメントを許可しました。その瞬間、私たちはdoxygenを使用して、制作担当者向けのドキュメントを生成していました。

多くのプログラマーがこれに反対するでしょうが、私は個人的に、C/C++でjavadocスタイルの関数/変数の命名を採用することに何の問題もないことを理解しています。はい、もちろん、フロー制御、スレッドの安全性などを整理する方法は、関係なく扱う必要があります。ただし、こちらは応募者ではありません。また、プロダクションコードのフォーマット要件がどれほど厳しいかわかりません。それをトピック外の領域に流用せずに、要件を確認し、特定の命名規則にどの程度依存しているかを確認し、私や他の人の回答に記載されている解決策を検討することをお勧めします

これが役に立てば幸い!?

2
hagubear

名前を付ける際に考慮すべき重要な点はほとんどありません。

  1. ActionObjectまたはObjectActionタイプを調べます(Cの場合はオブジェクトではありませんが、一般的には、他のオブジェクト指向言語にアクセスする場合) これは役立つはずです

  2. 残りは一貫性があり、簡潔で説明的であることは確かです。

  3. また、すべての変数と関数を定義するという唯一の目的があります。例:値を一時的に保存する場合は、intのnTempValと名前を付けます。
  4. 変数は名詞で、メソッドは動詞である必要があります。
0
JNL