ちゃんとコメント書こうかなって

アバター
spaaaark・∀・
記事: 66
登録日時: 12年前
住所: 埼玉
連絡を取る:

ちゃんとコメント書こうかなって

投稿記事 by spaaaark・∀・ » 11年前

トピックで出したメカスロを作るために、再びC++を触りだしました。
過去のソースコードを見ると、自分が書いたコードでも何をやっているかよく分からないという事があるというのは
よく聞く話です。僕が以前作ってた物もそうでした。そこで今度のプロジェクトではちゃんとコメントを書こうって決めたのです。

CODE:

#include "_header\keyexport.h"
/* CKeyExport_Sクラス ///////////////////////////////////////////
// 目的:各クラスへのキー入力状態を出力             //
// 変数:m_NowKeyState[256]; キーが連続で入力されているフレーム //
///////////////////////////////////////////////////////////////*/

CKeyExport_S::CKeyExport_S(){
/* コンストラクタ ///////////////////////////////////////////////
// 引数:なし                          //
// 動作:変数m_NowKeyStateを初期化する             //
///////////////////////////////////////////////////////////////*/
	for(int i=0;i=LessFlame);
}
int CKeyExport_S::ExportFlame(int KeyHandle){
/* ExportFlame関数 //////////////////////////////////////////////
// 引数:p1;入力をチェックするキーのハンドル          //
// 動作:指定のキーが連続で押されているフレーム数を返す     //
// 戻値:指定したキーが押されているフレーム数を整数値で返す	  //
///////////////////////////////////////////////////////////////*/
	return m_NowKeyState[KeyHandle];
}
プレビューするとちょっと四角がずれましたが気にしません。
実際にコメントを書くとやっぱり面倒なんですよね。ちょっとやっただけで思ってしまいます。
ですが大規模プログラムの訓練だと思って頑張って続けて行こうと思います。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前

Re: ちゃんとコメント書こうかなって

投稿記事 by softya(ソフト屋) » 11年前

ちょっとコメントがクドいかなって気がします。後々書くのに疲れてきます。
クラス名、メンバ関数名、変数名を工夫したほうが良いと感じました。

[補足]
この場合はflameではなくframeだと思います。
最後に編集したユーザー softya(ソフト屋) on 2014年3月03日(月) 11:52 [ 編集 2 回目 ]

アバター
usao
記事: 1889
登録日時: 12年前

Re: ちゃんとコメント書こうかなって

投稿記事 by usao » 11年前

/* */ という形式を使わなくていい個所では,//で全て統一した方がいいと思います.
あと,記号で四方を囲むのは書きにくくて,右端をきれいに揃えようとかいう無駄な労力が毎回発生しそう.

私は,関数の仕様的なのは関数の上に書きますね.

CODE:

//鳴く.rOstrmに鳴き声を出力する.
//[args]
//  rOStrm : 出力先
//  strength : 鳴き声の強さ
//[ret]
//  rOStrm を返す.
std::ostream &Cat::SayMew( std::ostream &rOStrm, int strength )
{
  rOstrm << "Mew";
  for( int i=0; i<strength; i++ ){  rOStrm << "!";  }
  return rOStrm;
}

Rittai_3D
記事: 525
登録日時: 12年前

Re: ちゃんとコメント書こうかなって

投稿記事 by Rittai_3D » 11年前

コメントで

CODE:

///////////////////
//コメント
///////////////////
って入力が面倒で、読みづらくなると思うのですが、自分だけでしょうか?

自分は

CODE:

/*!
*   @brief 関数の情報(この場合は当たり判定)
*   @param px,py,pr : プレイヤの座標と当たり判定の大きさ(引数の意味)
*   @param ex,ey,er : 雑魚の座標と当たり判定の大きさ
*   @return true : 被弾 false : 被弾してない(戻り値)
*/
bool IsHit( double px, double py, double pr, double ex, double ey, double er )
{
    // コメントは;以降はあまり書かない派
    double x = ( px - ex )*( px - ex );
    double y = ( py - ey )*( py - ey );
    double r = ( pr + er )*( pr + er );

    return x+y<r ? true : false;
}
みたいな感じです。何処かで見た書き方を真似してたらこうなりました。
オフトピック
#追記
Update関数はvoid型でいいのでは?falseは返さないっぽいので。
あとは、256をconst intとか#defineで定義した方がわかりやすいと思います。
if文やfor文は{}をつけた方が良いと思います。
本文と関係の無いことなのですが気になりましたので、書かせて頂きました。
(まともなプログラム書けない奴が何偉そうなことを言ってるんだ)
最後に編集したユーザー Rittai_3D on 2014年3月03日(月) 13:55 [ 編集 2 回目 ]

アバター
せんちゃ
記事: 50
登録日時: 14年前

Re: ちゃんとコメント書こうかなって

投稿記事 by せんちゃ » 11年前

その関数の説明を書くのがコメントなのに関数名は書く必要があるのでしょうか。
そして行末に//を入れるのはそのうち嫌になると思います。
/*を打って改行すると自動的に*が付くIDEが割りと多いので使うなら/* ~ */か//に統一したほうがいいと思います。
最後に編集したユーザー せんちゃ on 2014年3月03日(月) 13:05 [ 編集 1 回目 ]

アバター
usao
記事: 1889
登録日時: 12年前

Re: ちゃんとコメント書こうかなって

投稿記事 by usao » 11年前

コメント減らすには
変数名とかの略称みたいなのを自分なりに決めておくといいでしょうね.

CODE:

//cx,cyは中心座標,Sqは2乗,rは半径, みたいな
const double SqDx = ( Obj1_cx - Obj2_cx ) * ( Obj1_cx -  Obj2_cx );
const double SqDy = ( Obj1_cy -  Obj2_cy ) * ( Obj1_cy -  Obj2_cy );
const double SqBound_r = ( Obj1_r +  Obj2_r ) * ( Obj1_r +  Obj2_r );
return ( SqDx + SqDy < SqBound_r );
あと,こういう処理の塊が出てきたときに,これが「何を書いてるのか」を注釈に残しておくと良いかと.
(まぁこの例だと,ぱっと見でもわかりますが,この話が自分にとって自明とは言えないような内容なのだと仮定して)

CODE:

//2つのオブジェクトの当たり判定領域が円形であるものとして衝突判定
みたく,やってることの意味を書く.
さらに,その判定計算のために,書かれている数式が何書いてるかわかりにくいとしたら

CODE:

//二つの円{A,B}が衝突しているかどうかは
// (A,Bの中心間の距離) < (Aの半径+Bの半径)
//となっているかどうかを確認すればよい.
//※なお,これを馬鹿正直にやると両辺共にsqrt()が出てくることになるが,
// 値の大小関係を見ればいいだけなので,ここでは,sqrtを省いて(両辺を2乗した値で)比較.
とか書きますね.馬鹿丁寧に.
最後に編集したユーザー usao on 2014年3月03日(月) 13:30 [ 編集 1 回目 ]

アバター
spaaaark・∀・
記事: 66
登録日時: 12年前
住所: 埼玉
連絡を取る:

RE: ちゃんとコメント書こうかなって

投稿記事 by spaaaark・∀・ » 11年前

ん…?どういう風に書き換えればいいんだろう?
説明を真摯に書きすぎなのかあるいは…

CODE:

// header
#pragma once
#include "ISingleton.h"
#include "keyinput.h"
class CKeyExport_S : public ISingleton{
// [mov]各クラスへのキー入力状態を出力
	friend ISingleton;
	friend CKeyInput_S;	// Update関数
	CKeyExport_S();
	~CKeyExport_S(){};
	bool Update(char* pInput);
// [var]
// キーが連続で入力されているフレーム(m1)
	int m_NowKeyState[256];	

public:
	bool Export(int KeyHandle,int LessFrame=1);
	int ExportFrame(int KeyHandle);
};

// cpp source
#include "_header\keyexport.h"

CKeyExport_S::CKeyExport_S(){
// [prm]none
// [mov]m1を初期化
	for(int i=0;i=LessFrame);
}
int CKeyExport_S::ExportFrame(int KeyHandle){
// [prm]p1;入力をチェックするキーのハンドル
// [mov]指定のキーが連続で押されているフレーム数を返す
// [ret]同上
	return m_NowKeyState[KeyHandle];
}

アバター
せんちゃ
記事: 50
登録日時: 14年前

Re: ちゃんとコメント書こうかなって

投稿記事 by せんちゃ » 11年前

個人の好みだとは思いますがvarとかmovというタグは必要ありますでしょうか。
データ型宣言している段階でvarと記述しなくても変数であることは分かりますよね。
movは主に移動とか動くという意味合いで使われますが、説明を差すのであればdescriptionとかdescという記述のほうがプログラマ的にはわかりやすいと思います。
パラメータは素直にparamでもいいと思います

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前

Re: ちゃんとコメント書こうかなって

投稿記事 by softya(ソフト屋) » 11年前

例えばですね。このメンバ関数ですが

CODE:

int CKeyExport_S::ExportFrame(int KeyHandle){
// [prm]p1;入力をチェックするキーのハンドル
// [mov]指定のキーが連続で押されているフレーム数を返す
// [ret]同上
    return m_NowKeyState[KeyHandle];
}
ハンドルなのは名前を見ればわかるので、まず私は書きません。書くならハンドルが何処のヘッダで定義されているかの補足情報ですかね。
あと CKeyExport_SのSが何なのわかりませんで、クラスの情報として、こっちを説明して欲しい感じです。
ExportFrameも何の情報が返却されるか分かりづらいので、ExportKeyPushedFrameNum(適当すぎ?)とか、ここの名前をクドくします。
戻り値もメンバ関数で明確になるので、必要なのは「指定のキーが連続で押されているフレーム数を返す」程度となります。これもいらないかもしれません。

会社の資料的に意味があるとかドキュメント自動生成とか考えるな別ですが、自作ソフトではメンテナンス性を考えてもここまで必要なのは関数名などネーミングなどに問題があると考えるようにしています。

【補足】
言いたいことは、端的にいうと力の入れどころを間違っていませんか?と言う話なんです。
分かりやすくすることは良いことなんですが、メンテ漏れでコメントと内容がずれたり、入力に疲れ果ててどうでも良くなったり、害のほうが大きいのではと心配しているんですね。
最後に編集したユーザー softya(ソフト屋) on 2014年3月03日(月) 15:39 [ 編集 1 回目 ]

アバター
usao
記事: 1889
登録日時: 12年前

Re: ちゃんとコメント書こうかなって

投稿記事 by usao » 11年前

クラス名の側をクドくしてみました.

CODE:

//各キーについて,連続押下フレーム数をカウントするだけのクラス
class CKeyPushedFrameCounter  //うーん,しかしすごい英語不自由感を感じるクラス名だw
{
public:
  CKeyPushedFrameCounter(){  Reset();  }
public:
  void Reset();  //m_Counters[]を0クリアする
  void Update(); //キーの情報を見に行って,m_Counters[]を更新する

  //指定キーの連続押下フレーム数を得る
  //こういうタイプの関数の注釈には,引数に不正な値を入れたら どうなるのか?あるいは何が返るのか? とかを書くかも.
  unsigned int GetCountOf( int KeyHandle ) const;
private:
  unsigned int m_Counters[ 256 ]; //カウンタ×キー個数
};
最後に編集したユーザー usao on 2014年3月03日(月) 15:34 [ 編集 1 回目 ]

ISLe
記事: 2650
登録日時: 14年前

Re: ちゃんとコメント書こうかなって

投稿記事 by ISLe » 11年前

他の方が触れていますが、Javadoc形式やDoxygen形式にすると関数リファレンスなどのドキュメントを自動生成できます。
IDEでエディタから参照できたりもするので便利です。
できるなら活用すべきだと思います。
が、それはあくまで、リファレンス、です。

わたしはコメントには、設計意図を書き、実装の説明はできるだけ書きません。
なので、基本的にコメントはコードを書く前に記述するものだと思います。
コードを書いた後に書き加えるコメントはたいていくどくど実装を説明するような質の悪いものです。
そういうコメントはもっと効率の良い実装に丸ごと入れ替えるなどのリファクタリングの妨げになります。

次々辿っていかないと全容の分からないコメントは読む気力を無くしますし、実装の変化に合わせてコメントをメンテする手間も増えます。
本末転倒です。
最後に編集したユーザー ISLe on 2014年3月03日(月) 17:03 [ 編集 3 回目 ]