Warsztat » Forum

[Gamedev.pl] Komentarze poprawiające czytelność kodu

Mar 14, 2004 | Kwazar |
27 wypowiedzi na 2 stronach:
1 2
Kwazar
Mar 14, 2004

Komentarze poprawiające czytelność kodu

By poprawić czytelność swojego kodu stosuję specjalne znaczniki dzięki czemu od razu widać gdzie rozpoczyna się funkcja lub klasa.
Do każdego projektu dołączam taki plik:

Template.txt:
Kod: 

///####################Constructors

///####################Destructor

///####################Friends

///####################Statics

///####################Operators

///####################

///#////////////////CONSTRUCTORS/////////////////////////////////////

///#////////////////DESTRUCTOR///////////////////////////////////////

///#/////////////////////////////////////////////////////////////////

//*******************************************************************
//*******************************************************************

///#CLASS////////////////////////////////////////////////////////////

//#NAMESPACE/////////////////////////////////////////////////////////

///#////////////////OPERATORS////////////////////////////////////////


Fragment kodu testowy
///@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@


Example class:

#pragma once
///#CLASS////////////////////////////////////////////////////////////
class
{
public:
   void Clear();
   void Destroy();
   void Init();

   ///####################Constructors
   ///####################Destructor
   ///####################Statics

private:

};
///#/////////////////////////////////////////////////////////////////
Ciunu
Mar 14, 2004

Odp: Komentarze poprawiające czytelność kodu

Hmmm co do komentarzy wewnątrz klas, to wg. mnie jest to pasienie kodu niepotrzebnymi znakami zwiększającymi jego objętość. Wg. mnie sposób komentarzy jest indywidualna sprawą i sposobem "patrzenia na kod". Jedni wolą duże przerwy, inni są minimalistami. Ale jak tam kto lubi, każdy znajdzie zapewne coś dla siebie :P
shyha
Mar 14, 2004

Odp: Komentarze poprawiające czytelność kodu

Osobiscie za dobre używam coś takiego

Kod: cpp]
for ( int x=1; x < 10; x++ )
{
 (...)
} // for x=

if ( fun(x)=v1)
{
 (...)
} // fun(x)=v1


Wprawdzie większość środowisk wspiera zaznaczanie klamr ale takie coś daje jednoznaczne odpowiedzi bez konieczności użwania suwaczka :)
RageX
Mar 16, 2004

Odp: Komentarze poprawiające czytelność kodu

Ale wymaga przekopiowania, no i to zawsze kolejne znaki które rozpraszają uwagę. Wolę zajrzeć w kontekst (większość środowisk coś takiego też dostarcza) żeby wiedzieć w czym robię, jeśli już. Ale oczywiście dyskutujemy o gustach. :)
Moim ulubionym przerywnikiem jest pusta linia. Widziałem też pewne przegięcie - dwie puste linie.  :)

A i wyrobiłem sobie nawyk pisania(oczywiście z wcięciami, ale nie wiem jak je tu sformatować).
Kod: 

class A
{
public:
string name;
public:
int id;
}

To oczywiście niepotrzebne, ale mi w głowie ułatwia kompatybilność z C#.
ŁukaszB
Mar 14, 2004

Odp: Komentarze poprawiające czytelność kodu

powiem szczerze że według mnie zapełnianie klasy takimi komentarzami jest zaciemniająca choć ja np. w kasach zawsze trzymam sie jakiegoś mojego porządku:) np.
na początku definicja zmiennych, potem kontstukory,destruktor(y), metody statyczne, metody, operatory wewnetrzene, zaprzyjaznione classy, operatory, funkcje globalne.
Haxy.M
Mar 15, 2004

Odp: Komentarze poprawiające czytelność kodu

Ja mam dość specyficzny sposób pisania kodu. Oto mały przykład:
Kod: 

void shape :: setI()
{
unsigned int i;
Ix = 0.0;
Iy = 0.0;
Iz = 0.0;
for(i = 0;i < num;i++)
{
  Ix += (((points[i].y - masscenter.y) * (points[i].y - masscenter.y)) + ((points[i].z - masscenter.z) * (points[i].z - masscenter.z)));
  Iy += (((points[i].x - masscenter.x) * (points[i].x - masscenter.x)) + ((points[i].z - masscenter.z) * (points[i].z - masscenter.z)));
  Iz += (((points[i].x - masscenter.x) * (points[i].x - masscenter.x)) + ((points[i].y - masscenter.y) * (points[i].y - masscenter.y)));
}
Ix *= partmass;
Iy *= partmass;
Iz *= partmass;
}

void shape :: recalculatemasscenter()
{
unsigned int i;
masscenter.x = 0.0;
masscenter.y = 0.0;
masscenter.z = 0.0;
for(i = 0;i < num;i++)
{
  masscenter.x += partmass * points[i].x;
  masscenter.y += partmass * points[i].y;
  masscenter.z += partmass * points[i].z;
}
masscenter.x = masscenter.x / totalmass;
masscenter.y = masscenter.y / totalmass;
masscenter.z = masscenter.z / totalmass;
}


Moim zdaniem komentarze, do czytelności kodu są raczej zbędne.

Oraz kilka zasad których się trzymam:
- żadnych tabów (tylko rozwalają kod i nijak nie można się połapać przy bardziej złożonych fragmentach)
- każde wcięcie jedną spacją (łatwo widać, co się gdzie kończy, a gdzie zaczyna, przy wiekszej ilości linijek, można przejechać kursorem góra/dół)
- nawiasy klamrowe zawsze w nowej linii (z tej samej przyczyny co wyżej)
- spacja między operatorami (czytelniejsze równania)
- na odstęp jedna pusta linia

Tych zasad jest jeszcze kilka, ale reszta nie ma jakiegoś racjonalnego uzasadnienia, tylko estetyczne ;D

W każdym razie komentarze sprowdzają się albo do wykomentowania kawałków kodu, których nie chce usówać (np.: są już równania, ale nie działa cos jeszcze, więc tylko by wysypały program), albo do zaznaczenia, co jeszcze trzeba dopisać.

I sorry, za przydługi kawalek kodu jako przykład :P
revo
Mar 17, 2004

Odp: Komentarze poprawiające czytelność kodu

Haxy.M, wiem, że to jest subiektywne, ale Twój kod wygląda brzydko. Jakieś podstawowe zasady są 'w obiegu' i powinno się do nich stosować, żeby ułatwić innym czytanie naszego kodu. Ja ten sam sformatowałbym tak (parę rzeczy napisałbym inaczej, ale to inna sprawa ;) ):

Kod: void shape::setI()
{
   unsigned int i;
   
   Ix = 0.0;
   Iy = 0.0;
   Iz = 0.0;

   for(i = 0; i < num; i++)
   {
      Ix += (((points[i].y - masscenter.y) * (points[i].y - masscenter.y)) + ((points[i].z - masscenter.z) * (points[i].z - masscenter.z)));
      Iy += (((points[i].x - masscenter.x) * (points[i].x - masscenter.x)) + ((points[i].z - masscenter.z) * (points[i].z - masscenter.z)));
      Iz += (((points[i].x - masscenter.x) * (points[i].x - masscenter.x)) + ((points[i].y - masscenter.y) * (points[i].y - masscenter.y)));
   }
   
   Ix *= partmass;
   Iy *= partmass;
   Iz *= partmass;
}

void shape::recalculatemasscenter()
{
   unsigned int i;
   
   masscenter.x = 0.0;
   masscenter.y = 0.0;
   masscenter.z = 0.0;

   for(i = 0; i < num; i++)
   {
      masscenter.x += partmass * points[i].x;
      masscenter.y += partmass * points[i].y;
      masscenter.z += partmass * points[i].z;
   }
   
   masscenter.x = masscenter.x / totalmass;
   masscenter.y = masscenter.y / totalmass;
   masscenter.z = masscenter.z / totalmass;
}


Z istotnych uwag:
- pojedyńcza spacja zamiast tabów to zły pomysł, kod jest zbyt płaski (a Twoje uzasadnienie można zastosować również do tabów ;>)
- stosujesz spacje przy operatorach ale jakoś w for przy ; się już zapomina - IMO brak konsekwencji
- brak pustych linii w kodzie - wydaje mi się, że to po części kwestia doświadczenia (próbowałem się zastanowić kiedy to robię, ale to jest już odruchowe, tak jak cała reszta formatowania) ale w niektórych miejscach kodu powinny pojawiać się puste linii dla poprawienia czytelności
Netrix
Mar 17, 2004

Odp: Komentarze poprawiające czytelność kodu

Tu mój mały offtop:

Temat ten jest podobny do tematu znajdującego się pod tym linkiem: http://forum.gamedev.pl/index.php?topic=5948.msg81130#msg81130 proponowałbym scalenie obu tematów w jeden.
Regedit
Mar 17, 2004

Odp: Komentarze poprawiające czytelność kodu

Netrix: To nie jest żaden offtop tylko bardzo cenna informacja, ale scalenia tematów nie zrobimy.

Mój styl pisania komentarzy stale się zmienia, a obecnie wygląda tak:

W pliku nagłówkowym staram się przy przed każdą funkcją opisać w komentarzach // co ona robi, jakie parametry przyjmuje, co zwraca, jak zgłasza błąd, jakie ma wymagania, kiedy wolno ją wywoływać itd. Oczywiście bez fanatyzmu, w końcu nie piszę MSDN-a ani nie używam żadnego generowania dokumentacji typu Doxygen, żebym czuł potrzebnę opisania każdego pola, metody czy każdego parametru. Raczej tylko to co jest niejasne - np. że kąt podawany w parametrze Angle jest w radianach i powinien być w zakresie od 0 do 2PI.

Komentarzy separujących używam do oddzielania miejsc w pliku CPP gdzie leżą implementacje metod kolejnych klas (bo u mnie jeden plik to nie jest jedna klasa, inaczej pogubiłbym się w gąszczu małych plików - wolę jeden duży otworzyć na raz w 2 albo 3 zakładkach).

Kod: //HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH
// Entity

Entity::Entity()
{
}

...


Ponadto do grupowania pól i metod klasy w jakieś logiczne grupy (jeśli klasa ma swoich składników kilkadziesiąt albo setkę - wiem że to nieeleganckie ale tak mi się zdarza :)) używam takiego komentarza (wymyśliłem go niedawno):

Kod: ////// Metody implementujące interfejs IFrameObject
virtual bool OnKeyDown(uint4 Key);
virtual bool OnKeyUp(uint Key);
...


Komentarzy w kodzie właściwym używam dość rzadko, ale zawsze kiedy to co robię nie jest jasne na pierwszy rzut oka. Na przykład kiedy w kodzie jest jakaś sztuczka, jakiś niebanalny algorytm albo zmienna przyjmuje jakąś wartość o specjalnym znaczeniu. Za kluczowe uważam tutaj nadawanie zmiennym nazw które potrafią coś powiedzieć o ich zawartości (a nie samych i, j, k, x, y, z, a, b, c, jak to robią ci którzy naczytali się za dużo ksiązek od matematyki ;)).

Czasami jeszcze dzielę sobie kod funkcji na sekcje za pomocą komentarzy takich jak ten poniżej (chociaż wiem że powinienem raczej rozbić taką funkcję na więcej funkcji).

Kod: ////// 1. Wczytanie pliku

// Otwórz plik
...
// Sparsuj plik
...

////// 2. Przepisanie danych do struktury...
...
Kurak
Mar 18, 2004

Odp: Komentarze poprawiające czytelność kodu

Ja bardzo nie lubię takich komentarzy, które mają niby pomagać. Wolę dać 2 entery więcej, by wydzielić blok z konstruktorami czy operatorami (a informacji o tym, że konstruktor to konstruktor nie potrzebuję ;))

Jeśli już komentuję, to najczęściej w nagłówku pliku - co to za klasa (bądź inny "byt"), do czego służy, jak jej używać. Potem tylko jakieś krótkie wzmianki w kodzie, jeśli na pierwszy rzut oka nie wiadomo o co chodzi.
Pockey
Mar 18, 2004

Odp: Komentarze poprawiające czytelność kodu

Ciekawy temat :)

ja od dluzszego czsu stosuje ten sam styl:
- poczatek kazdego pliku: sporej objetosci opis np.
Kod: 

/*-------------------
opis
--------------------*/

- w kazdej klasie i w wiekszych funkcjach umieszczam komentarz na poczatku (ciala funkcji/definicji klasy)
Kod: 

   __declspec(dllexport) class Scheduler
   {
      /*
         glowny task-manager. zarzadza
         wszystkimi funkcjami i ich
         parametrami
      */

      private: // koniecznie wciecie przez private,public itd: :)
         Timer clock;
         float diff_time;

- standardowe komentarze na koncu wazniejszych linii:
Kod: 

   to_erase.clear(); // !! czyscimy

nie stosuje zadnych linii oddzielajacych/ozdobnikow (jak Kwazar ;) to tylko zmniejsza czytelnosc i 'rozrzuca' kod na wieksza ilosc miejsca :D, nie stosuje tez zadnych spacji przed/po operatorami, znakami ';', ',' itd. przez to mozna 'objac' wzrokiem wiecej informacji ;) tez przeszkadza mi za duza ilosc komentarzy (np. co linijke :D lub co doprowadza mnie do szalu: opisy dzialania funkcji w definicji klas, definicja ma byc czytelna a najlepszym komentarzem deklaracji funkcji ma byc jej nazwa ;) ). no ale czasem lepiej za duzo niz wogole. np. w moich programach okolo 20-35% to komentarze (sprawdzalem nawet chyba programem jakiegos uzytkownika tego forum ;) ) pozdrawiam
Kwazar
Mar 19, 2004

Odp: Komentarze poprawiające czytelność kodu

Cytat:

nie stosuje zadnych linii oddzielajacych/ozdobnikow (jak Kwazar ;) to tylko zmniejsza czytelnosc i 'rozrzuca' kod na wieksza ilosc miejsca :D


Ok to spójrz na te 2 kawałki kodu:

Kod: cpp]
#include "PCH.h"

///#////////////////CONSTRUCTORS/////////////////////////////////////
Game::Objects::Carpet::Carpet()
{
       this->Clear();
       Game::ObjectManager::Get()->AddSObject( this );
}
///#/////////////////////////////////////////////////////////////////

//*******************************************************************
Game::Objects::Carpet* Game::Objects::Carpet::Get()
{
       return Singleton;
}
//*******************************************************************
void Game::Objects::Carpet::Clear()
{
       this->Rolled = false;
}
//*******************************************************************
void Game::Objects::Carpet::Create()
{
       this->CreateObject( "Carpet", "Carpet.mesh" );
       this->CreateBody( new NxOgre::CubeShape( 2485.775471, 7.888872, 2136.561966 ) );
       this->SetPosition( -79.027843, 3.986771, 83.108735 );
       this->GetEntity()->setCastShadows( false );
       this->AddAnimation( "Roll" );
}
//*******************************************************************
void Game::Objects::Carpet::SelfReaction()
{
       static Game::Tools::CBoundBox AlphaBound;
       AlphaBound.SetPosition( Ogre::Vector3( 586.297464, 747.377777, 18.064368 ) );
       AlphaBound.SetSize( 1511.055088, 1494.755554, 2869.057465 );

       if( this->GetAnimation( "Roll" )->hasEnded() )
              return;

       if( AlphaBound.IsObjectInBB( Game::Objects::Armchair::Get() ) &&
           !Game::Objects::Crate::Get()->Broken )
                     Game::Interface::TextManager::Get()->Tell( 9 );
       else if( AlphaBound.IsObjectInBB( Game::Objects::Armchair::Get() ) )
              Game::Interface::TextManager::Get()->Tell( 10 );
       else if( !Game::Objects::Crate::Get()->Broken )
              Game::Interface::TextManager::Get()->Tell( 11 );
       else
              this->GetAnimation( "Roll" )->setEnabled( true );
}
//*******************************************************************
void Game::Objects::Carpet::OnFrame()
{
       if( this->GetAnimation( "Roll" )->hasEnded() )
       {
              if( !this->Rolled )
              {
                     this->GetBody()->raiseActorFlag( NX_AF_DISABLE_COLLISION );
                     this->Rolled = true;
              }
       }
}
//*******************************************************************


I ten:

Kod: cpp]
#include "PCH.h"

Game::Objects::Carpet::Carpet()
{
       this->Clear();
       Game::ObjectManager::Get()->AddSObject( this );
}
Game::Objects::Carpet* Game::Objects::Carpet::Get()
{
       return Singleton;
}
void Game::Objects::Carpet::Clear()
{
       this->Rolled = false;
}
void Game::Objects::Carpet::Create()
{
       this->CreateObject( "Carpet", "Carpet.mesh" );
       this->CreateBody( new NxOgre::CubeShape( 2485.775471, 7.888872, 2136.561966 ) );
       this->SetPosition( -79.027843, 3.986771, 83.108735 );
       this->GetEntity()->setCastShadows( false );
       this->AddAnimation( "Roll" );
}
void Game::Objects::Carpet::SelfReaction()
{
       static Game::Tools::CBoundBox AlphaBound;
       AlphaBound.SetPosition( Ogre::Vector3( 586.297464, 747.377777, 18.064368 ) );
       AlphaBound.SetSize( 1511.055088, 1494.755554, 2869.057465 );

       if( this->GetAnimation( "Roll" )->hasEnded() )
              return;

       if( AlphaBound.IsObjectInBB( Game::Objects::Armchair::Get() ) &&
           !Game::Objects::Crate::Get()->Broken )
              Game::Interface::TextManager::Get()->Tell( 9 );
       else if( AlphaBound.IsObjectInBB( Game::Objects::Armchair::Get() ) )
              Game::Interface::TextManager::Get()->Tell( 10 );
       else if( !Game::Objects::Crate::Get()->Broken )
              Game::Interface::TextManager::Get()->Tell( 11 );
       else
              this->GetAnimation( "Roll" )->setEnabled( true );
}
void Game::Objects::Carpet::OnFrame()
{
       if( this->GetAnimation( "Roll" )->hasEnded() )
       {
              if( !this->Rolled )
              {
                     this->GetBody()->raiseActorFlag( NX_AF_DISABLE_COLLISION );
                     this->Rolled = true;
              }
       }
}


Jest różnica? :P
Od razu widać gdzie rozpoczyna i kończy się funkcja. Przy większej ilości funkcji, konstruktorów, destruktorów i operatorów różnica jest jeszcze większa.

To:
Kod: cpp]//*******************************************************************

Od tego:
Kod: {

Jest o wiele bardziej widoczne, do tego właściwe dobranie kolorów w IDE i czas znalezienia danej funkcji o wiele się zmiejsza.

Ja mam takie kolorki:
[URL=http://img157.imageshack.us/my.php?image=testzh3.png][IMG]http://img157.imageshack.us/img157/3559/testzh3.th.png[/img][/URL]
Kurak
Mar 19, 2004

Odp: Komentarze poprawiające czytelność kodu

Cytat:

Jest różnica? :P
Jest, jest. Ten drugi czytelniejszy :P

Poza tym, to są pierdoły :) Czytelność kodu zależy raczej od samego właśnie kodu, a nie ozdobników dookoła niego. Ideałem IMO to jest kod, do którego komentarzy (ani rozdzielających, ani wyjaśniających) nie potrzeba.
Bouzer
Mar 20, 2004

Odp: Komentarze poprawiające czytelność kodu

Dokładnie tak jak Kurak mówi. Ten czerwony to razi w oczy. Źle się przy takim czymś może pracować.
Kwazar
Mar 20, 2004

Odp: Komentarze poprawiające czytelność kodu

Cytat:

Cytat:

Jest różnica? :P
Jest, jest. Ten drugi czytelniejszy :P

Poza tym, to są pierdoły :) Czytelność kodu zależy raczej od samego właśnie kodu, a nie ozdobników dookoła niego. Ideałem IMO to jest kod, do którego komentarzy (ani rozdzielających, ani wyjaśniających) nie potrzeba.


Niektórzy mówia, że wcięcia to pierdoły... Bo wkońcu to białe znaki które nic nie robią.
Zresztą zależy kto co lubi komuś innemu mogą pomagać inne cuda mi pomagają te komentarze.  ;)
dieboy
Mar 21, 2004

Odp: Komentarze poprawiające czytelność kodu

IMHO Kwazar ma całkiem przyjemne kolory, może wrzuciłbyś gdzieś link do ustawień tego stylu dla VS?:)

A wracając do komentarzy, to ja komentuje tylko nagłówki (w stylu Doxygena), a w kodzie czasem, gdy już zupełnie nie wiadomo o co chodzi (albo są jakieś "dziwne", dłuższe fragmenty kodu...).
Strony:
1 2