Warsztat - Programowanie gier

Marzec 17, 2010, 00:06:16 *
Witamy, Gość. Zaloguj się, lub zarejestruj proszę.

Zaloguj się podając nazwę użytkownika, hasło i długość sesji
Aktualności: Warsztat, Regulamin forum, #warsztat, Wiki, FAQ, NoPaste, Mapa
 
   Strona główna   Pomoc Szukaj Zaloguj się Rejestracja  
Strony: 1 2 [3]
  Drukuj  
Autor Wątek: Czytelność kodu  (Przeczytany 5432 razy)
Charibo
Member2000
*******

wiadomości: 2321



Zobacz profil WWW
« Odpowiedz #30 : Luty 22, 2008, 20:07:36 »

Cytuj
Nie stosuję żadnych namespace'ów, czy innych rzeczy, imo są one niepotrzebne, tylko zaśmiecają kod i utrudniają pisanie.
Taak? To zobacz na Irrlichta + Tokamaka (miałem nieszczęscie coś w takim połączeniu pisac) - oba używają tych samych nazw i gdyby nie to, że irr ma jednak tego namespace to jak myślisz, co by się działo?

Cytuj
i powiedział to koleś, który się o to samo czepia...
Kurak tak ma - jak mi sam mówił - po rodzicach Tongue Cheesy
Zapisane

Now these points of data make a beautiful line
And we're out of beta we're releasing on time.

Blogassek.
Kurak
SuperHero Member
******

wiadomości: 1146


Zobacz profil
« Odpowiedz #31 : Luty 22, 2008, 20:22:52 »

Taak? To zobacz na Irrlichta + Tokamaka (miałem nieszczęscie coś w takim połączeniu pisac) - oba używają tych samych nazw i gdyby nie to, że irr ma jednak tego namespace to jak myślisz, co by się działo?
Ja nie lubię śmiecić w zakresie globalnym w ogóle.

Cytuj
i powiedział to koleś, który się o to samo czepia...
Visual używam w zastępstwie Visual C++ - ale nie o to idzie. To dalej nazwa własna, nie mająca odpowiednika w języku polskim (w polskich sklepach kupujemy dalej Visual Studio). Ciebie czepiłem się (raz!) o użycie słowa "part" zamiast "część" - w języku polskim taki wyraz występuje, nie jest żadnym archaizmem ani neologizmem, jest w powszechnym użyciu i znany przez przytłaczającą część społeczeństwa. Sam "part" także w naszym języku występuje, ale znaczy co innego. Nie masz podstaw do oskarżeń - bo to dwie zupełnie różne kwestie Tongue
Zapisane

^ tam nie ma nic ciekawego
Ondo
Newbie
*

wiadomości: 3


Zobacz profil
« Odpowiedz #32 : Luty 23, 2008, 13:33:26 »

Ja mogę krótko podsumować mój styl..
Wcięcia, umieszczene klamer, itp.
Mam swoje, dosyć specyficzne. Jestem raczej zwolennikiem 'minimalizmu' - zbyt dużo pustych linii i umieszczczanie każdego '{' i '}' w osobnych liniach niezbyt mi pasuje.
Ale tak naprawdę, to mało istotne jest jakie mamy upodobnia. "Święta wojna" spacje vs tabulatory (i podobne) nie ma zbytniego sensu, skoro IDE potrafi przetworzyć z jednego stylu na drugi. Wystarczy jedno kliknięcie (albo nawet z automatu - podczas ładowania i zapisu). Każdy sobie oglądnie jak chce Wink
(Osobiście używam 4 spacji.. wciskając klawisz Tab Wink).

Nazw zmiennych, funkcji, itp.
Zdecydowanie namespace zamiat przedrostków (poza g_ dla globalych (których i tak raczej być nie powinno) i m_ dla składowych klas). Również brak dodatków TClass, CClass, IClass, itp. Notacji węgierskiej nigdy nie mogłem strawić, nie mówiąc o jej stosowaniu.
Kwestie wielkości liter (funkcje z małej czy może z dużej litery?), stosowania_podkreślenia lub stosowaniaTakiegoStylu uważam za mniej istotne i - mimo, iż posiadam swój własny styl - bez większych problemów mogę pisać w innym. Jest jeden warunek: konsekwencja. (A z tym trudno jak kilka osób o różnych preferencjach i mocnych charakterach pracuje przy jednym projekcie.)

Zamiast pisać jakiegoś komentarza można zamiast int i napisać int iLicznik Jeśli mamy np. mała pętle
Kod:
for(int i=0; i<10;i++){}
no to to raczej nie ma sensu ale są momenty gdzie po kilkudziesięciu liniach kodu w koncu pojawi sie ta zmienna i można szybko wywnioskować do czego to służy. Również na podstawie nazwy zmiennej można wywnioskować czy coś liczymy czy odnosimy sie do jakiejś tablicy.
IMHO funkcja nigdy nie pownna mieć tyle linii kodu, żeby zajmowała więcej niż 2-3 "ekrany". Wtedy nie będziemy mieli takiego problemu.
Oczywiście nie zawsze można tego uniknąć, wtedy int licznik; jest lepszy niż int i; (choć to kiepski przykład - tego typu zmienne powinny być definiowane w miejscu użycia).

Komentarze
Nie za dużo, nie za mało.
Przede wszystkim, IMHO, kod powinien być czytelny sam w sobie. Np. zamiast:
Kod
// Oblicza costam..
// angle - kat podany w radianach
void calculateCostam( double angle );
lepiej napisać:
Kod
// Oblicza costam..
void calculateCostam( double radians );

Zamiast
Kod
void funkcja_cos_obliczajaca( z jakimis argumentami )
{
   // inicjalizacja bufora, jesli nie byl wczesniej stworzony
   if( buffer.empty() ) {
       ..
       tutaj
       bardzo
       duzo
       kodu
       zwlaszcza
       petli
       i
       wciec
       ..
   }
 
   // obliczenie nowych wspolrzednych
   ..
   tutaj
   bardzo
   duzo
   kodu
   zwlaszcza
   petli
   i
   wciec
   ..
   
   // obliczenie normalnych
   ..
   tutaj
   bardzo
   duzo
   kodu
   zwlaszcza
   petli
   i
   wciec
   ..
}
 
wolę napisać:
Kod
void funkcja_cos_obliczajaca( z jakimis argumentami )
{
   if( buffer.empty() )
       buffer.init();
 
   calculateNewCoordinates( buffer );
   calculateNormals();
}
i zero komentarzy Wink
Odpowiednie nazwy zmienych, funkcji i dekompozycja.. i mamy "samokomentujący się" kod.
Jest to zgodne z podanym przez k_b cytatem "źle napisany kod wymaga obszernych komentarzy".

Jeszcze o komentarzach..
Kod:
int i; // licznik pętli
Przesada Smiley
Nie przesada, jeśli doda się jeszcze parę słów na temat pętli, do której ów licznik należy, na przykład:
Kod:
int i; // licznik pętli wczytującej powierzchnie kafli
Wtedy wolałbym dodać ten opis przed pętlą.
Kod:
int iLicznik;
// wczytanie powierzchni kafli
for( ...
Jako, że tego typu zmienne powinny być definowane zaraz przed miejscem wykorzystania i przyjął się pewien standard ich nazewnictwa (i, j).. to nie widzę powodu by je opisywać. Co innego pętle - te niekiedy robią coś "ciekawego" Wink


Na zakończenie..
Pisząc tego posta przypomniałem sobie, że mam kilka wydrukowanych tekstów na temat "ładnego/dobrego/efekywnego/etc. pisania kodu". W jednym był link do wersji online: http://www.csc.lsu.edu/~kosmas/C++guidelines.pdf. Po krókim przejrzeniu myślę, że zgadzam się z większością tego, co autor napisał w tym tekście.

P.S.
BTW.. witam wszystkich.. to mój pierwszy post na tym forum  Smiley
Zapisane
kedan
Jr. Member
**

wiadomości: 97



Zobacz profil
« Odpowiedz #33 : Luty 23, 2008, 14:38:30 »

Cytuj
Taak? To zobacz na Irrlichta + Tokamaka (miałem nieszczęscie coś w takim połączeniu pisac) - oba używają tych samych nazw i gdyby nie to, że irr ma jednak tego namespace to jak myślisz, co by się działo?

Właśnie przekonałeś mnie do używanie namespace'ów Wink

A tak ogólnie rzecz biorąc, to nie ma znaczenia czy ktoś wstawia taby czy spacje, czy ktoś pisze:
Kod:
for(;;){
}

//czy

for(;;)
{
}
Osobiście do krótkich funkcji, np inline piszę nawet:
Kod:
inline void SomeFunction(){ cośtam; };
Najważniejsze jest to żeby trzymać się konsekwentnie jakiejś konwencji nazw, np:
Kod:
class csSomeClass{
private:
int _someVariable;
public:
void _SomeMethod();
};

void SomeFunction(float argument_){
};
I nazywać obiekty, zmienne, funkcje itp, tak aby od razu było wiadomo do czego służą (najlepiej po angielsku).
Wtedy nawet komentarze są zbędne.
Zapisane

Nie ma rzeczy trudnych - są tylko mniej łatwe
Porke
Full Member
***

wiadomości: 102


Zobacz profil
« Odpowiedz #34 : Luty 23, 2008, 15:32:12 »

Ja jestem zwolennikiem 'komentatorskiego minimalizmu', zwykle wstawiam je tylko w miejscach, gdzie nazwy argumentów funkcji bądz ogólniej zmiennych nie 'mówią dość' aby dalo się bez zastanowienia rozpracować dany kawałek kodu albo przy stosowaniu niejasnych na pierwszy rzut oka konstrukcji, i oczywiście jeśli jest potrzebna dokumentacja to w nagłowkach również opisuję co istotniejsze funkcje wraz z argumantami.


Co do konwencji nazewnictwa i szeroko pojętego stylu to ewidentnie mogę powiedzieć de gustibus non est disputandum, acz z jednym 'ale' (wspomnianym zresztą przez kedana) - konsekwencją.

Zapisane
Reg
Member2000
*******

wiadomości: 3617



Zobacz profil WWW
« Odpowiedz #35 : Luty 24, 2008, 13:12:24 »

Ondo: Witaj na forum. Gdyby każdy kto tutaj przychodzi zaczynał pisanie od postów na takim poziomie jak Ty to forum byłoby lepsze Cheesy

Z jednym tylko nie potrafię się zgodzić. Mianowicie nie potrafię wyobrazić sobie nazywania parametrów w taki sposób jak:

float FactorBetweenZeroAndOne
float YawInRadians, float PitchInRadians, float RollInRadians
float RadiansBetweenZeroAndTwoTimesPi
MyClass *Object_CanBeNull
unsigned Index_MaxUintMeansNotInitialized
itp.

A takie rzeczy jak dopuszczalny zakres, jednostki, specjalne wartości jakie może przyjmować czy fakt że jakiś wskaźnik może pozostać zerowy a inny nie powinien trzeba jednak gdzieś określić.

Tylko żeby tu bies nie wyskoczył ze swoimi typami szablonowymi typu FloatRange<0.0f, 1.0f> bo wtedy spytam czy profesjonaliści w gamedev naprawdę coś takiego stosują Smiley
Zapisane

Porke
Full Member
***

wiadomości: 102


Zobacz profil
« Odpowiedz #36 : Luty 24, 2008, 13:51:35 »

To fakt, podane przez Ciebie przykłady są już skrajnością Tongue

Część z nich można skrócić poprzez odpowiednią konwencję (zwłaszcza radianowe), inne uściślić przez komentarze i dla większych partii kodu ew. co bardziej szczegółową dokumentację
Zapisane
RageX
Gość
« Odpowiedz #37 : Luty 24, 2008, 14:32:20 »

Nie trzeba typów szablonowych, tym samym mogą się zajmować właściwości w danej klasie która korzysta ze zmiennej.
Specjalne wartości także powinny być odseparowane switchami, czy if'ami w właściwościach.
Zapisane
infernus
Jr. Member
**

wiadomości: 89


Ave Satan


Zobacz profil
« Odpowiedz #38 : Luty 24, 2008, 15:25:13 »

Mysle ze styl ktory ja stosuje bylby pewnie przez wiekszosc odebrany jako bardzo nieczytelny. Mnie za to draznia niepotrzebne spacje, unikam ich gdzie tylko sie da. Zamiast:
Kod:
int funkcja( int argument )
{
     for ( int i = 0 ; i < 100 ; i++ )
     {
           // bla bla bla
     }
}
napislbym:
Kod:
int funkcja(int argument){
     for(int i=0;i<100;i++){
           // bla bla bla
     }
}
W dodatku czesto zdarza mi sie uzywac operatora ? Moze moj kod wydaje sie nieczytelny, ale mnie wlasnie przeszkadza nadmierna ilosc spacji, wszystko jest bardziej rozstrzelone i trudniej to naraz obiac wzrokiem. Wole wszystko scisnac w jednym miejscu. Z notacji wegierskiej nie korzystam bo w jezyku o scislej kontroli typow jakim jest C++ wcale mi ona nie pomaga.
W Code::Blocks (niewiem jak w innych IDE) jest automatyczne reformatowanie kodu wiec kazdy, nawet najbardziej zagmatwany kod jednym kliknieciem mozemy zmienic w taki, jaki najlepiej nam sie czyta. Niema sensu narzucac innym swojego (jedynego slusznego) stylu.
Zapisane

"Dopóki nie skorzystałem z Internetu, nie wiedziałem, że na świecie jest tylu idiotów." -S.Lem
novo
Hero Member
*****

wiadomości: 505



Zobacz profil WWW
« Odpowiedz #39 : Luty 24, 2008, 15:55:47 »

Ondo: ale nie zawsze jest sens wydzielac dany kawalek w oddzielna f-cje, bo np bedzie uzywana tylko w jednym miejscu(f-cja z ktorej zostala wydzielona) i jak sie chce dokladnie przejrzec kod trzeba skakac. Zgadzam sie ze przydlugawe f-cje to tez bez sens, ale osobiscie preferuje krotkie komentarze przed blokiem kodu cos robiacym. Ma to dodatkowa zalete, bo komentarze maja inny kolor i latwo je odroznic od reszty kodu. Z przykladu(link) ktory podalem, mozna szybko nawet nie przegladajac kodu wyciagnac komentarze:
Kod:
1. Only aliases can be added after the game initialization.
2. Find the command.
3. Cannot register the command twice.
4. Add new command.

I odrazu widac co sie w f-cji dzieje. Szczegolnie przydatne jak trzeba sobie przypomniec jak dzialaja f-cje/metody napisane dawno temu. Sam mam u siebie troche kodu z przed 2-3 lat i w takich wypadkach tego typu komentarze oszczedzaja duzo czasu. Komentarze przed f-cja/metoda/klasa pisze rozlegle bo pozniej z nich generuje dokumentacje, a ze nigdy nie wiadomo czy ktos z tego kodu nie bedzie korzystal.
Co do spacji/wciec itd to juz kwestia gustu jak napisali przedmowcy. Jedna rzecz mi sie tylko spodobala jak przegladalem zrodla hl2. Przy b. prostych f-cjach pisze definicje w jednej linii, cos takiego:
Kod:
struct float3{
float3(){}
float3(const float2 &param, float _z=0.0f) :x(param.x), y(param.y), z(_z){ }
float3(const float3 &param) :x(param.x), y(param.y), z(param.z){ }
float3(float _x, float _y, float _z) :x(_x), y(_y), z(_z){ }

void set(float _x, float _y, float _z) { x=_x; y=_y; z=_z; }

operator float*() const { return (float*)&x; }
operator float2() const { return float2(x, y); }

float3 operator+ (const float &rs) const { return float3(x+rs, y+rs, z+rs); }
float3 operator- (const float &rs) const { return float3(x-rs, y-rs, z-rs); }
float3 operator* (const float &rs) const { return float3(x*rs, y*rs, z*rs); }
float3 operator/ (const float &rs) const { return float3(x/rs, y/rs, z/rs); }
float3& operator+=(const float &rs) { x+=rs; y+=rs; z+=rs; return *this; }
float3& operator-=(const float &rs) { x-=rs; y-=rs; z-=rs; return *this; }
float3& operator*=(const float &rs) { x*=rs; y*=rs; z*=rs; return *this; }
float3 operator+ (const float3 &rs) const { return float3(x+rs.x, y+rs.y, z+rs.z); }
float3 operator- (const float3 &rs) const { return float3(x-rs.x, y-rs.y, z-rs.z); }
float3 operator* (const float3 &rs) const { return float3(x*rs.x, y*rs.y, z*rs.z); }
float3 operator/ (const float3 &rs) const { return float3(x/rs.x, y/rs.y, z/rs.z); }
float3& operator+=(const float3 &rs) { x+=rs.x; y+=rs.y; z+=rs.z; return *this; }
float3& operator-=(const float3 &rs) { x-=rs.x; y-=rs.y; z-=rs.z; return *this; }
float3& operator*=(const float3 &rs) { x*=rs.x; y*=rs.y; z*=rs.z; return *this; }
float3 cross(const float3 &rs) const { return float3(y*rs.z-z*rs.y, z*rs.x-x*rs.z, x*rs.y-y*rs.x); }
float dot(const float3 &rs) const { return x*rs.x+y*rs.y+z*rs.z; }
float length() const { return sqrt(dot(*this)); }
float length2() const { return dot(*this); }

friend float3 operator+(float ls, const float3 &rs)
{ return float3(ls+rs.x, ls+rs.y, ls+rs.z); }
friend float3 operator*(float ls, const float3 &rs)
{ return float3(ls*rs.x, ls*rs.y, ls*rs.z); }
bool operator==(const float3 &rs) const{
return (
( fabs(x-rs.x) < std::numeric_limits<float>::epsilon()) &&
( fabs(y-rs.y) < std::numeric_limits<float>::epsilon()) &&
( fabs(z-rs.z) < std::numeric_limits<float>::epsilon())
   );
}
bool operator!=(const float3 &rs) const{
return !(operator==(rs));
}
float3& normalize(){
float len=length();
x/=len;
y/=len;
z/=len;
return *this;

}

float3 normalized() const{

float len=length();

return float3(x/len, y/len, z/len);

}





float x, y, z;

};

Pozdr.
novo.
« Ostatnia zmiana: Luty 24, 2008, 15:57:45 wysłane przez novo » Zapisane

From all the things I've lost I miss my mind the most.
devblog
Ondo
Newbie
*

wiadomości: 3


Zobacz profil
« Odpowiedz #40 : Luty 25, 2008, 15:34:41 »

Z jednym tylko nie potrafię się zgodzić. Mianowicie nie potrafię wyobrazić sobie nazywania parametrów w taki sposób jak:

float FactorBetweenZeroAndOne
float YawInRadians, float PitchInRadians, float RollInRadians
float RadiansBetweenZeroAndTwoTimesPi
MyClass *Object_CanBeNull
unsigned Index_MaxUintMeansNotInitialized
itp.

A takie rzeczy jak dopuszczalny zakres, jednostki, specjalne wartości jakie może przyjmować czy fakt że jakiś wskaźnik może pozostać zerowy a inny nie powinien trzeba jednak gdzieś określić.

Nazwy nie muszą być gramatycznie poprawne.
float radians_0to2pi
zamiast
float RadiansBetweenZeroAndTwoTimesPi
czy
float factor_0to1
zamiast
float FactorBetweenZeroAndOne

Ale i tak najważniejsze to.. Rozsądek.
Jak zwykle to kwestia umiaru. 20-znakowe identyfikatory to niezbyt dobry pomysł.
W moim poście nie wyraziłem się precyzyjnie.
Nie miałem na myśli sytuacji, w których trzeba dodawać do identyfikatorów piękny opis "BetweenZeroAndTwoTimesPi" znacząco je wydłużając.
Nie myślałem również o "kwiatkach" typu "float radians_0to2pi", które często bardziej zaciemniają kod niż poprawiają jego czytelność.

Takie informacje jak zakres, specjalne wartości, itp. oczywiście muszą być zapisane w komentarzach.

Skoro nie o tym, to o czym pisałem w tym poście?
O przypadkach, w których wystarczy znaleźć inne słowo (lub dwa), aby identyfikator przekazywał znacznie więcej informacji.
Często jest to łatwe i nie ma wcale dużo więcej pisania.. a mimo to nagminnie spotykam się ze identyfikatorami "str", "ptr", itp.
A, IMHO, naprawdę w łatwy sposób można przekazać niektóe informacje dobrym doborem nazw, np:
Kod
void funkcja( float yaw, float pitch, float roll );
void funkcja2( float x, float y, float z );
void funkcja3( std::string str1, std::string str2 );
 
vs.
 
void funkcja( float yawRadians, float pitchRadians, float rollRadians );
void funkcja2( float eyeX, float eyeY, float eyeZ );
void funkcja3( std::string title, std::string description );
 

Wiele IDE po rozpoczęciu pisania wywołania funkcji np. "funkcja(" podpowiada tooltipem sygnaturę tej funkcji "void funkcja( float yawRadians, float pitchRadians, float rollRadians );"
Przy dobrze nazwanych parametrach nie muszę przechodzić do odpowiedniego pliku nagłówkowego z jej deklaracją i sprawdzać w komentarzach "to stopnie czy radiany?".


Ondo: ale nie zawsze jest sens wydzielac dany kawalek w oddzielna f-cje, bo np bedzie uzywana tylko w jednym miejscu(f-cja z ktorej zostala wydzielona) i jak sie chce dokladnie przejrzec kod trzeba skakac.
Zgadzam się. To znów kwestia rozsądku i umiaru.
Niekiedy rozdzielenie na funkcję tylko zaciemni kod.

IMHO, nie ma to sensu, gdy:
A) funkcja jest krótka i logiczne fragmenty na jakie można ją podzielić są krótkie
Dokładnie tak jest w podanym przez Ciebie przykładzie.
B) trudno podzielić funkcję na fragmenty, bo (mimo iż przydługawa) stanowi jedną zwartą całość i nawet ciężko określić na jakie kawałki ją podzielić.
Najczęściej objawia się to tym, że wyodrębnione funkcje musiały by przyjmować wiele argumentów i zwracać wiele wartości. Większość tymczasowych, przekazywanych z jednej funkcji do drugiej. Często również trudno wymyślić nazwy dla takich funkcji.

Jednak w wielu przypadkach rozdzielenie na kilka funkcji można łatwo przeprowadzić. IMHO należy to robić, gdy (A) i (B) nie jest spełione, oraz:
1. Któryś z fragmentów jest używany (lub z dużym prawdopodobieństwem będzie) w innym miejscu.
To chyba jasne. Lepiej funkcja niz kopiuj+wklej.
2. Funkcja jest bardzo długa* i fragmenty jakie można wydzielic są długie*.
Ja wydzielam nawet, gdy taki fragment jest wykorzystywany tylko raz, wiec funkcja będzie wywołana tylko z tego miejsca. Taka sytuacja zdarza mi się rzadko. Najczęściej prędzej czy później ta wydzielona funkcja jest użyta w innym miejscu (niekiedy z niewielkimi przeróbkami, ale jednak).

*, ** - jak zwykle problem: Co oznacza "długa funkcja", "długi fragment"? Zależy od kontekstu - co ta funkcja robi i jak. Nie ma jednej najlepszej wartości. (Ale funkcja długa na 200 liniek na pewno jest za długa.)

Gdyby było tak prosto, to było by pięknie. Oczywiście nie jest. Są wyjątki od każdej reguły.
Niekiedy należy przeprowadzić jeszcze dalej idącą dekompozyję.. nie tylko wydzielić funkcje, ale wydzielić nową klasę, która będzie reprezentowała dane pojęcie i zawierała w sobie całą logikę wykonywaną przez daną funkcję. Często przydługa funkcja kończy jako wywołanie jednej metody z nowej klasy.. bo reszta jest zaszyta gdzieś w konstruktorze i destruktorze (vide: uproszczenie niektórych fragmentów dzięki inteligentnym wskaźnikom).
Niestety kiedy, co i jak stosować oraz gdzie zrobić wyjątek.. tego nie da się opisać. To kwestia doświadczenia. Trzeba kodzić, kodzić, kodzić Wink


Zgadzam sie ze przydlugawe f-cje to tez bez sens, ale osobiscie preferuje krotkie komentarze przed blokiem kodu cos robiacym. Ma to dodatkowa zalete, bo komentarze maja inny kolor i latwo je odroznic od reszty kodu. Z przykladu(link) ktory podalem, mozna szybko nawet nie przegladajac kodu wyciagnac komentarze:

To idealy przykład jak powinno się robić komentarze. Nie za dużo, nie za mało.
Mam na myśli te wewnątrz funkcji. Te opisujące funkcje i klasy - kwestia gustu i tego czy (i jakie) ktoś stosuje narzędzia do generowania dokumentacji.

Oczywiscie, IMHO, dobry kod to nie kod bez komentarzy "bo sam się komentuje" (chociaż takie wnioski mogli by niektórzy wysnuc z mojego poprzedniego posta). Tymbardziej nie jest to kod z dużą ilością komentarzy i nic_nie_mówiących nazw zmiennych.
Dobry kod to połączenie obu. Taki, w którym identyfikatory wskazują swoje zastosowanie i co przechowują (co, tzn. np. "title", a nie jak np. "str" lub "sTitle"), a komentarze (w razie potrzeby!) uściślaja to wskazując niedozwolone wartości, zakresy i dokładne przeznaczenie. Takie jest moje zdanie na ten temat.


Co do spacji/wciec itd to juz kwestia gustu jak napisali przedmowcy. Jedna rzecz mi sie tylko spodobala jak przegladalem zrodla hl2. Przy b. prostych f-cjach pisze definicje w jednej linii, cos takiego:
Kod:
struct float3{
float3(){}
float3(const float2 &param, float _z=0.0f) :x(param.x), y(param.y), z(_z){ }
float3(const float3 &param) :x(param.x), y(param.y), z(param.z){ }
 [..]
Hmm.. też często piszę w jednej lini takie funkcje (głównie operatory i funkcje typ set*, get*), ale nie z takimi wcięciami. Będę musiał zobaczyć jak to wygląda u mnie w edytorze Wink, bo wydaje mi się troche rozdmuchane (za dużo spacji/tabów).


infernus - podobnie umieszczam nawiasy klamrowe, ale "wewnątrz" (np. for(..)) daję kilka spacji. A ?: też dość często używam.

P.S.
Ondo: Witaj na forum. Gdyby każdy kto tutaj przychodzi zaczynał pisanie od postów na takim poziomie jak Ty to forum byłoby lepsze Cheesy
Może im dalej tym gorzej. Zobaczymy jak będę pisał przy setnym poście Wink
Zapisane
bies
Gość
« Odpowiedz #41 : Luty 25, 2008, 16:13:24 »

Akceptowalne komentarze to glownie te opisujace pre/post conditions f-kcji.
Bez sensu. Akurat te są nieakceptowalne. Warunki brzegowe zapisuje się asercjami lub systemem typów (odpowiednio: test w czasie wykonania lub kompilacji).

Wystrzegam się też komentarzy "wielolinijkowych" /**/. Nowe IDE (jak chociażby VS) pozwalają na comment/uncomment całych bloków kodu za pomocą jednej kombinacji klawiszy. Wielolinijkowce dodatkowo mają tą wadę, że nie da się zakomentować większego bloku, jeśli gdzieś w środku jest już użyty inny komentarz wiel.
Kod:
#if 0
/* Tutaj kod wyłączony warunkowo.
 * Nawet z komentarzem wieloliniowym.
 */
#endif
Zapisane
yarpen
SuperHero Member
******

wiadomości: 1295


Zobacz profil WWW
« Odpowiedz #42 : Luty 25, 2008, 16:18:29 »

Akceptowalne komentarze to glownie te opisujace pre/post conditions f-kcji.
Bez sensu. Akurat te są nieakceptowalne. Warunki brzegowe zapisuje się asercjami lub systemem typów (odpowiednio: test w czasie wykonania lub kompilacji).
Asercje swoja droga, trust no one. Ale zakladajac, ze rozmawiamy o C++, bo w tym pisze sie powazne gry, to czemu mam skakac do pliku .cpp z naglowka i sprawdzac czy sa tam jakies asserty, jezeli moge to miec dostepne na 1 rzut oka na naglowek f-kcji? Kwestia wygody, dla mnie istotna.
Zapisane
bies
Gość
« Odpowiedz #43 : Luty 27, 2008, 16:51:43 »

Akceptowalne komentarze to glownie te opisujace pre/post conditions f-kcji.
Bez sensu. Akurat te są nieakceptowalne. Warunki brzegowe zapisuje się asercjami lub systemem typów (odpowiednio: test w czasie wykonania lub kompilacji).
Asercje swoja droga, trust no one. Ale zakladajac, ze rozmawiamy o C++, bo w tym pisze sie powazne gry, to czemu mam skakac do pliku .cpp z naglowka i sprawdzac czy sa tam jakies asserty, jezeli moge to miec dostepne na 1 rzut oka na naglowek f-kcji? Kwestia wygody, dla mnie istotna.
Bez żartów, skakanie między definicją a deklaracją to, nawet w kiepskim edytorze, kwestia jednego skrótu klawiszowego. A czemu takie komentarze są zbędne albo nawet szkodliwe? To proste, przeczą zasadzie pojedynczej definicji. Opisują coś, co już jest opisane w kodzie (asercje lub, lepiej, system typów są konieczne). Co oznacza, że możliwy jest stan w którym obie definicje będą rozbieżne. Co znowu oznacza, że prędzej czy później taki stan wystąpi. Najprawdopodobniej, przy kolejnej zmianie zostanie zaktualizowany kod a komentarz zostanie błędny. Dodaj do tego swoje stwierdzenie, że czytasz tylko komentarze (bo kod czytać jest ,,niewygodnie'') i masz opis potencjalnej wywrotki.

Główna zasada dotycząca komentarzy jest taka, aby nie dublowały kodu. Zatem nie powinny odpowiadać na pytanie co się dzieje w danym miejscu (przynajmniej nie na poziomie ogólności kodu źródłowego). Jak to się dzieje. Ale raczej: dlaczego to się dzieje. Opisywanie kodu int i = 2; komentarzem // ustawienie zmiennej i na wartość 2 od Twojego opisywania warunków brzegowych komentarzami nie różni się aż tak bardzo.
Zapisane
yarpen
SuperHero Member
******

wiadomości: 1295


Zobacz profil WWW
« Odpowiedz #44 : Luty 27, 2008, 17:48:36 »

Akceptowalne komentarze to glownie te opisujace pre/post conditions f-kcji.
Bez sensu. Akurat te są nieakceptowalne. Warunki brzegowe zapisuje się asercjami lub systemem typów (odpowiednio: test w czasie wykonania lub kompilacji).
Asercje swoja droga, trust no one. Ale zakladajac, ze rozmawiamy o C++, bo w tym pisze sie powazne gry, to czemu mam skakac do pliku .cpp z naglowka i sprawdzac czy sa tam jakies asserty, jezeli moge to miec dostepne na 1 rzut oka na naglowek f-kcji? Kwestia wygody, dla mnie istotna.
Bez żartów, skakanie między definicją a deklaracją to, nawet w kiepskim edytorze, kwestia jednego skrótu klawiszowego.
Jeden czy wiecej, to mnie specjalnie nie interesuje. Jezeli tego robic nie musze - to chetnie skorzystam. Jak czesto zmieniaja sie warunki brzegowe? Rzadziutko.
Zapisane
Strony: 1 2 [3]
  Drukuj  
 
Skocz do:  

Hosting: Polska Strefa - Ogłoszenia
Powered by SMF 1.1.7 | SMF © 2006, Simple Machines LLC