C++ Kodo Standartas
Paskutinis keitimas: 2004-11-04
Parengė GoniX
Šis dokumentas gali būti laisvai platinamas ir/ar naudojamas, kol už tai neimamas joks mokestis. Tam jis ir parengtas. Jei pastebėjote klaidų arba jei norite pasiūlyti patobulinimą, galite rašykite man.
Turinys
Įvadas
Standarto svarba
Kiekvienas individualus programuotojas dažniausiai rašo kodą taip, kaip jam atrodo teisingiausia ir įskaitomiausia. Tačiau kitam žmogui perskaityti kito visiškai kitokiu stiliumi parašytą kodą gali būti gana sudėtinga. Kadangi 100% nusistovėjusio standarto programavime nėra ir, tikriausiai, negali būti, aš siūlau vieną iš variantų.
Standartų pliusai
- Programuotojai gali pažiūrėti į bet kurią kodo vietą ir suprasti kas ten vyksta
- Nauji žmonės gali greičiau įsijungti į projektą
- Naujokams nebereikia išsiugdyti savo stiliaus ir ginti jo visą gyvenimą
- Naujokams nebereikia kartoti klaidų
- Žmonės daro mažiau klaidų pastovioje aplinkoje
- Programuotojai turi bendrą priešą :-)
Standartų minusai
- Standartai yra kvaili, nes paptastai sudaromi žmonių, kurie nieko nesupranta
- Standartai yra kvaili, nes yra ne tai ka aš darau
- Standartai sumažina kūribingumą
- Standartai nereikalingi, kol žmonės yra pastovūs
- Žmonės vistiek jų nesilaiko
- Standartai gali būti NIH (not invented here) priežastimi, nes naujas/pasiskolintas kodas nesusilies su naudojamu standartu
Literatūra
Vardai
Vardas turi tikti
Vardus stenkitės sudaryti, kad jie atspindėtų funkcijos, klasės, metodo, kintamojo paskirtį.
Kalba
Vardai (jei įmanoma) turėtų būti anglų kalba.
Argumentai
Anglų kalbą, tikriausiai, supranta visi programuotojai. Net jei kodas skaitomas tik ribotam kiekiui programuotojų, kurie tikrai supranta jūsų pasirinktą kalbą, vistiek rekomenduojama programavime vartoti anglų kalbą.
Santrumpos
Jei varde reikia naudoti santrumpą kaip HTML, URL, ir t.t. nerašykite jo viso didžiosimis raidėmis. Elkites su juo, kaip su paprastu žodžiu.
Argumentai
Dažniausiai sunkiau suprasti sutrumpinimą, kai jis yra visas didžiosiomis raidėmis (ypač jei po jo eina kitas žodis prasidedantis didžiąja)
Pavyzdys
Neteisingai:
class MyXVZ
Teisingai:
class MyXvz
Klasės
- Kiekvieną žodį pradėkite didžiąja raide, likusią dalį mažosiomis
- Nenuadokite žemutinių brūkšnių ("_")
Argumentai
- Daugelis programuotojų šį būdą pripažysta geriausiu kompromisu
Pavyzdys
class SomeObject
Rekomenduojama, kad klasės vardas būtų daiktavardis.
Metodai
- Naudokite tą pačią taisyklę kaip ir klasių vardams
Argumentai
- Daugelis programuotojų šį būdą pripažysta geriausiu kompromisu
Pavyzdys
class SomeObject
{
public:
int DoIt();
int GetValue();
void HandleError();
}
Rekomenduojama, kad metodo vardas būtų reikštų veiksmą.
Metodų parametrai
- Turi prasidėti raide "a"
- Po raidės "a" naudokite tą pačią taisyklę kaip ir klasių vardams
- "a" raidė turi būti visada prieš "p" ar "r"
Argumentai
- Padeda išvengti konfliktų tarp klasės atributų ir metodo argumentų
- Galima naudoti panašius vardus kaip ir klsės vardas
- Visada aišku, kurie kintamieji yra perduoti kaip parametrai
Pavyzdys
class SomeObject
{
public:
int MyMethod(FooBar& arFooBar);
}
Klasių atributai
- Turi prasidėti raide "m"
- Po raidės "m" naudokite tą pačią taisyklę kaip ir klasių vardams
- "m" raidė turi būti visada prieš "p" ar "r"
Argumentai
- Padeda išvengti konfliktų tarp klasės atributų ir metodų, kurie dažniausiai turi panašius vardus
- Iš kintamojo vardo galima nusakyti jo scope
Pavyzdys
class SomeObject
{
public:
int GetLastError();
private:
int mErrorNumber;
char* mpErrorMessage;
}
Steko kintamieji
- Tik mažosios raidės
- Žodziams atskirtu naudokite žemutinį brūkšnį ("_")
Argumentai
- Iš kintamojo vardo galima nusakyti jo scope
Pavyzdys
SomeObject::DoIt()
{
FooBar foo_bar;
int index;
}
Globalūs kintamieji
- Kintamojo vardas turi prasidėti raide "g"
- Kintamojo vardo kiekvienas žodis turi prasidėti didžiąja raide
- "g" raidė turi būti visada prieš "p" ar "r"
Argumentai
- Iš kintamojo vardo galima nusakyti jo scope
Pavyzdys
int gErrorNumber;
Globalios konstantos
- Tik dodžiosios raidės
- Žodžiams atskirti naudokite žemutinį brūkšnį ("_")
Argumentai
- Tai labai aiškiai parodo, kad reikšmė yra nepakeičiama
Pavyzdys
const int A_GLOBAL_CONSTANT = 5;
Rodyklės (pointers)
- Turi prasidėti raide "p"
- Po raidės "p" naudokite tą pačią taisyklę kaip ir klasių vardams
- Rekomenduojama * rašyti prie tipo, o ne prie kintamojo
Argumentai
- Iš kintamojo vardo iš karto galima numatyti, kad jis yra rodyklė
- Rodyklės iš tikųjų yra kitas tipas, todėl * priklauso tipui, o ne kintamojo vardui. Pradedančiuosius tai gali klaidinti, nes * priklauso artimiausiam kintamajam, o ne jiems visiems. Bet tikriausiai vsitiek norėsite aprašyti tik po viena kintamajį eilutėje, kad galėtumėte jį tinkamai dokumentuoti.
Pavyzdys
String* pName;
String* pMessage, address; // atkreipkite dėmesį, kad tik pMessage yra rodyklė
Adresai (references)
- Turi prasidėti raide "r"
- Po raidės "r" naudokite tą pačią taisyklę kaip ir klasių vardams
Argumentai
- Iš kintamojo vardo iš karto galima numatyti, kad jis yra adreses (reference)
Pavyzdys
SomeObject& rSomeObject;
Statiniai kintamieji
- Kintamojo vardas turi prasidėti raide "s"
- Kintamojo vardo kiekvienas žodis turi prasidėti didžiąja raide
- "s" raidė turi būti visada prieš "p" ar "r", bet po "m", "a", "g"
Argumentai
- Iš kintamojo vardo galima nusakyti jo scope
Pavyzdys
int SomeObject::DoSomthing()
{
static int sCount;
}
C++ funkcijos
- Naudokite tą pačią taisyklę kaip ir klasių vardams
Argumentai
- Daugelis programuotojų šį būdą pripažysta geriausiu kompromisu
Pavyzdys
int MyFunction()
{
}
C funkcijos
- Tik mažosios raidės
- Žodziams atskirtu naudokite žemutinį brūkšnį ("_")
Argumentai
- Taip C funkcijų vardai tampa išskirtiniai tarp kitų vardų
Pavyzdys
int my_function()
{
}
Tipų vardai
- Naudokite tą pačią taisyklę kaip ir klasių vardams
- Gale drašykite žodį "Type"
- Kai įmanoma sukurkite savo tipus iš naudojamų pagrindinių tipų naudodami typedef
Argumentai
- Žodis "Type" leidžia suprasti, kad tai nėra klasė
- Sukurdami savo tipus iš pagrindinių, išvengsite problemų, jein orėsite sukompiliuoti programą kitu kompiliątoriumi ar kitame kompiuteryje (pvz.: int ne visur yra 32 bitų dydžio ir t.t.)
Pavyzdys
typedef uint16 ModuleType;
typedef uint32 SystemType;
Enum
- Tik dodžiosios raidės
- Žodžiams atskirti naudokite žemutinį brūkšnį ("_")
Argumentai
- Tai labai aiškiai parodo, kad reikšmė yra nepakeičiama
Pavyzdys
enum
{
STATE_UNKNOWN,
STATE_OPENED,
STATE_CLOSED
};
#define and macro komandos
- Tik dodžiosios raidės
- Žodžiams atskirti naudokite žemutinį brūkšnį ("_")
Argumentai
- Tai labai aiškiai parodo, kad reikšmė yra nepakeičiama
- Makro komandų atveju, tai parodo, kad į šį konstruktą reikia atkreipti dėmesį
Pavyzdys
#define ERR_NOT_FOUND 5;
Formavimas
Atitraukimas/Tarpai/Tab'ai
- Naudokite 4 arba 3 tarpus atitraukimui
- Nenaudokite tab'ų, naudokite tarpus. Daugelis editor'ių naudoja tarpus vietoj tab'ų
- Tab'ai turėtų būti nustatyti 8 tarpų pločio. Nestatykite kitokio pločio, vietoj to naudokite tarpus
- Atitraukite tiek kartų kiek reikia, bet ne daugiau. 4 ar 5 lygių paprastai turėtų užtekti. Jei reikia daugiau tikriausiai verta perorganizuoti kodą
Argumentai
- Tab'ai nenaudojami todėl 8 tarpų pločio atitraukimas labai apriboja atitraukimo lygių skaičių. Kai kurie editor'iai leidžia nustatyti tab'o plotį, bet šis nustatymas yra lokalus ir jei kas pabando atspausdinti kodą ar peržiųrėti jį su kitu editor'iumi vaizdas visiškai iškraipomas
- Kai žmonės naudoja skirtingus tab'ų pločius, kodo dažniasuiai neįmanoma perskaityti, todėl tarpai yra tinkamesni nei tab'ai
Pavyzdys
void func()
{
if (something bad)
{
if (another thing bad)
{
while (more input)
{
}
}
}
}
Eilutės ilgis
- Visada kada įmanoma eilutė neturėtų būti ilgesnė nei 80 simbolių
Argumentai
- Kodą daug lengviau skaityti, kai nereikia slankioti (scroll'inti)
- Nors beveik kiekvienas dabar turi palyginti didelį monitorių, bet platesnių langų mažiau telpa ekrane, o daugiau langų yra geriau už platesnius langus
- Kad ir kaip keista, bet dar yra žmonių, kuriems tenka peržiųrėti, spausdinti, etc. kodą konsolėje, kur eilutės ilgis yra ribotas ir nevisur eilutės nukeliamos
Skliausteliai () su funkcijomis ir keyword'ais
- Tarp keyword'o (if, for, while) ir sklaustelio turi būti tarpas
- Nenaudokite sklaustelių su return keywordu, jei tai nėra būtina
- Trap funkcijos pavadinimo ir sklaiustelių neturi būti tarpo
- Tarp sklaustelio ir funkcijos/keyword'o parametrų gali būti tarpas, jei tai palengvina kodo skaitomumą
Argumentai
- Keword'ai nėra funkcijos, todėl po jų turi būti naudojamas tarpas, kad jie būtų išksiriami
Pavyzdys
if (something)
{
}
while (something)
{
}
strcpy(s1, s2);
return 1;
Skliausteliai []
- Tarp skliaustelių ir kintamojo neturi būti tarpo
- Tarp sklaustelio ir parametrų gali būti tarpas, jei tai palengvina kodo skaitomumą
Argumentai
- Kodas daug lengviau skaitomas kai [] sklausteliai yra prie kintamojo
Pavyzdys
char* pName = new char[20];
pName[0] = '\0';
Skliausteliai {}
Iš dviejų pagrindinių būdų, pirmasis yra tinkamesnis:
Argumentai
If Then Else formavimas
Nors tai priklauso nuo programuotojo, bet vienas priimtiniausių būdų yra šis:
if (condition) // komentaras
{
...
}
else if (condition) // komentaras
{
...
}
else // komentaras
{
...
}
Konstantas rekomenduojama rašyti kairėje pusėje lygumo/nelygumo salygose. Pvz.:
if (6 == aErrorNum) ...
Nors iš pradžių tai atrodo kiek keistai, bet taip išvengsite klaidų, kai atsitiktinai nepadedamas antras lygybės ženklas. Kompiliatorius iškart suras klaidą.
switch formavimas
- Jei case turi pereiti į sekanti case būtina tai atitinakmai dokumentuoti
- default visada turi būti aprašytas ir, jei neturi būti pasiektas, pranešti apie klaidą
- Jei reikia sukurti kintamajį, rašykite viską kodą bloke
Pavyzdys
switch (...)
{
case 1:
...
// FALL THROUGH
case 2:
{
int v;
...
}
break;
default:
}
Operatoriai
- Visada iš abiejų pusių palikite po tarpą aplink visus lyginimo, priskyrimo ir matematinius (=, ==, !=, <, >,+, -, *, /, etc.) operatorius
- Prieš kablelį atskiriantį funkcijos parametrus neturi būti tarpo
- Po kablelio atskiriančio funkcijos parametrus turi būti tarpas
- Nenaudokite kablelio keliems kintamiesiems aprašyti. Aprašykite kiekvieną atskiroje eilutėje
- Kur įmanoma nenaudokite kablelio kelioms išraiškoms sujungti į vieną
Viena išraiška vienoje eilutėje
Visada rašykite tik vieną išraišką veinoje eilutėje, nebent išraiškos yra viena su kita labai atrimai susijusios. pastaruoju atvėju nepaminrškite padeti papildomą tarpą.
Taip pat visada aprašykite tik vieną kintamajį vienoje eilutėje.