Professional Documents
Culture Documents
CPP Enkel Stilguide
CPP Enkel Stilguide
CPP Enkel Stilguide
Innehll
Inledning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Kllkodsfiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Uppdelning av kllkod . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Filnamn . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Inkluderingsfiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
Kommentarer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Namngivning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
Kodningsstil . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Tomrum . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
Satsblock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Styrsatser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Funktioner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
Pekare och referenser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Meddelanden och ledtexter. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Utmatning . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Variabler och konstanter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Variabler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Konstanter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
Uttryck . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
Styrsatser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
If-satsen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
switch-satsen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
for-satsen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
while-satsen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
do-while-satsen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
vrigt rrande styrsatser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
Funktioner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Funktionsparametrar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Funktionsverlagring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Returtyper och returvrden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Inline-funktioner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Temporra objekt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Allmnt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Pekare och dynamisk minneshantering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Pekare . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Dynamisk minneshantering . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
Klasser . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
tkomstrttighet . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Inline-funktioner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
const-medlemsfunktioner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Konstruktorer och destruktorer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
Tilldelningsoperatorer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Operatorverlagring . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Returtyper fr medlemsfunktioner . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Arv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Undantag . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Kodmallar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Inkluderingsfiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
Inline-definitionsfiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Implementeringsfiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Klassbeskrivningar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
Funktionsbeskrivningar . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
ii
Inledning
Stil r en ofta frbisedd men mycket viktig aspekt d man skriver. Sttet att skriva en text har en direkt
inverkan p lsbarhet och frstelse. Programmeringsstil, i meningen hur man skriver kllkod, r ocks
ngot som ofta frbises. Program mste vara lsbara och frsteliga fr mnskliga lsare och inte bara
fr maskiner. Detta r viktigt fr att skapa programvara av god kvalitet, som inte enbart uppfyller
anvndarens krav utan ocks kan utvecklas inom givna tids- och kostnadsramar.
Ett program vars innebrd r klar och tydlig har en strre sannolikhet att ocks vara korrekt och
plitligt. D man ska modifiera ett program krvs en ingende frstelse av programkoden, vilket i hg
grad stds av klarhet. Underhll av programvara (ofta en frga om utveckling) r kostsamt och pgr
under ett systems hela livstid. Klarhet spelar drmed en viktig roll i att hlla underhllskostnader nere.
Vad utmrker en klar, lsbar och begriplig text? Det kan vara allt frn smtt till stort. En del kan man
relatera till hur vi skriver vanlig text, fr att gra den lsbar och begriplig. Vi bygger upp text med
lmpligt och korrekt ordval, delar upp texten i satser, som sammanstlls i stycken, osv. ven insttning
av mellanrum och tomma rader, liksom interpunktering r viktigt. Uppdelning av en text i stycken,
avsnitt och kapitel kan man i program jmfra med t.ex. anvndning av sammansatta satser, underprogram, moduler och liknande. Sedan finns naturligtvis en hel del som r specifikt fr programkod.
God lsbarhet uppnr man bl.a. genom enhetlighet, enkelhet (krngla inte till koden i ondan), uppdelning av strre problem i mindre delproblem (sndra och hrska) och genom att undvika underfrstdda
eller svrbegripliga egenskaper hos programsprket. Bra program skapas vanligtvis genom ett gediget
ingenjrsarbete.
Mnga programvarufretag har programmerarhandbcker med regler och rekommendationer fr hur
fretagets programvara ska skrivas. Syftet r att programvara som produceras inom olika projekt och av
olika programmerare ska vara ltt att lsa, frst och underhlla och ven vara enhetlig.
Denna stilguide r framtagen fr att anvndas i kurser. Ett syfte r att frska visa p god programmeringsstil (detaljer kan alltid diskuteras!) i allmnhet och speciellt fr C++-programmering. Ett annat
syfte r att dessa regler och rekommendationer ska kunna anvndas fr bedmning av laborationsuppgifter och projekt.
Fljande beteckningar anvnds i denna stilguide (vad som ska vara regel resp. rekommendation kan
naturligtvis ocks diskuteras):
Regler markeras med indragna stycken med ett i vnstermarginalen. Regler r normalt tvingande,
men det kan finnas enstaka tillfllen d det kan vara motiverat att frng en regel.
! Rekommendationer anges med indragna stycken med ett utropstecken i vnstermarginalen.
Rekommendationer r lmpliga att flja, svida det ej finns goda skl att gra annat.
Stil kan anses vara en frga om personlig smak. S lnge man skriver enbart fr sig sjlv fr man naturligtvis vlja den stil man sjlv fredrar. Ska man arbeta i ett projekt eller i ngot annat sammanhang
med flera inblandade, fr man vara beredd p att gemensamma stilregler kan finnas och ska fljas.
Kllkodsfiler
Uppdelning av kllkod
Moduluppdelning kan gras genom att programkod frdelas mellan olika kllkodsfiler.
deklarationer som utgr det externa grnssnittet fr en modul skrivs i en inkluderingsfil.
kod som implementerar en modul, t.ex. funktionsdefinitioner, skrivs i en implementeringsfil.
inline-deklarerade funktioner skrivs med frdel i en inline-deklarationsfil.
Filnamn
Deklarationer av intresse fr en anvndare, t.ex. funktionsdeklarationer, klassdefinitioner, etc., skrivs i
inkluderingsfiler. Definitioner av funktionerna respektive klassers medlemsfunktioner skrivs i motsvarande implementeringsfiler.
};
#ifndef DEBUG
#include Stack.icc
#endif
// Fil: Stack.cc
#include STACK.hh
#ifdef DEBUG
#define inline
#include Stack.icc
#undef inline
#endif
Fljande rekommendationer avser att ge vgledning fr hur kllkod br delas upp mellan olika filer.
! En inkluderingsfil br ej innehlla mer n en klassdefinition. Det r ofta enklare att underhlla
program om denna rekommendation fljs.
! En inkluderingsfil som innehller en klassdefinition br ha ett namn p formen klassnamn.hh.
! Placera maskinberoende kod i speciella filer, s att sdan kod blir ltt att lokalisera d koden ska
anpassas till en annan maskintyp.
Inkluderingsfiler
Varje inkluderingsfil ska innehlla en mekanism fr att frhindra upprepad inkludering av filen, en
gard. Garder konstrueras med fljande preprocessorteknik:
#ifndef STACK_HH
#define STACK_HH
...
#endif
Klassdefinitioner fr klasser som enbart refereras via pekare (*) eller referenser (&) ska ej infogas
via inkluderingsfiler. Det r i dessa fall tillrckligt med en deklaration, t.ex.:
class A;
Alternativt kan varje deklaration av en pekare eller referens till klassen ange nyckelordet class, t.ex.:
class B
{
class A*
};
a_ptr;
Kommentarer
Att skriva bra kommentarer r svrt! Man ska kommentera lagom mycket och rtt saker. Ett viktigt
syfte med kommentarer r att den som lser programkoden ska kunna stta sig in i hur programmet
fungerar, fr att t.ex. rtta fel eller modifiera programmet. En grundfrutsttning man ska anta r att
lsaren r datorkunnig och har (grundlggande) kunskaper om programsprket. Kommentera drfr
inte sdant som r uppenbart av sjlva koden och inte heller detaljer.
Utg dremot frn att lsaren vet nstan inget om vad programmet ska gra. Tnk p att ett kodavsnitt
som frefaller intuitivt fr dig, d du skriver det, kanske inte r det fr en annan lsare eller ens fr dig
sjlv senare. Kommentarer i program br i hg grad beskriva vad som hnder.
Ibland kan det ocks vara ndvndigt att frklara hur saker grs, t.ex. att ett komplicerat kodavsnitt kan
vara en implementering av en knd algoritm (men att det kanske inte r uppenbart av koden och dessutom kan det vara vrdefullt att f den upplysningen serverad) eller, om s inte r fallet, man i stllet
beskriver hur det gr till.
Annat som r viktigt att beskriva r begrnsningar, t.ex. att en datastruktur har en begrnsad storlek.
Kommentering ska gras p ett kompakt och ltt lokaliserbart stt. En strategisk kommentar skrivs fre
en klass eller ett funktion och beskriver klassens resp. funktionens syfte och egenskaper. En taktisk
kommentar beskriver vad en enskild rad eller ett kortare satsavsnitt i koden gr. Om en taktisk kommentar avser en enskild rad br den, om mjligt, placeras sist p raden.
Med en systematisk och vl genomtnkt namngivning och genom vlstrukturerad kod blir behovet av
taktiska kommentarer i koden mindre.
Varje kllkodsfil ska dokumenteras inledningsvis, dr dess namn och innehll framgr.
Varje klass och funktion ska ha en strategisk kommentar som beskriver dess roll.
! Kommentera efter hand som olika programdelar frdigstlls.
! Se till att kommentarer r korrekta. Var kortfattad men fullstndig.
! Uppdatera kommentarer samtidigt som ndringar grs i koden.
Namngivning
Namngivning r centralt fr lsbarhet och frstelse av program. Genom att tillmpa en systematiska
namngivning underlttas identifieringen av olika namngivna storheter och frstelsen av koden kar,
samtidigt som behovet av kommentering minskar.
Anvnd alltid meningsfulla och rttvisande namn p variabler, konstanter, funktioner, datatyper,
klasser, programlgen, etc.
Undvik frkortningar eftersom andra kan gra en helt annan uttydning av en frkortning n den man
sjlv tycker r helt intuitiv.
Kodningsstil
Regler och rekommendationer som rr kodningsstil kan ven finnas under andra avsnitt. Fr klasser
hnvisas helt till avsnittet om klasser.
Format
! Skriv en deklaration per rad, t.ex. en variabeldeklaration eller en enkel sats per rad.
! Indrag av rader frn vnstermarginalen ska systematiskt avspegla det logiska nstlingsdjupet och ska
vara 2, 3 eller 4 positioner (ej blandat).
! Olika kodstycken (t ex delbearbetningar) avgrnsas med en tomrad eller med en kommentar.
Tomrum
Tomrum spelar en viktig roll fr lsbarheten. Grundregeln r att anvnda tomrum i enlighet med hur
mellanrum stts in och styckesuppdelning grs i vanlig text. Anvnd omsorgsfullt tomrum fr att dela
upp och dra uppmrksamhet till olika delar av program.
Stt in ett mellanrumstecken efter varje komma i en parameterlista, men ej fre.
Stt in ett mellanrumstecken fre och efter varje tvstllig operator. Operatorerna -> och . ska dock
ej ska ha ngot mellanrum fre eller efter sig. I sammansatta uttryck, d det gller deluttryck p den
innersta nivn, kan man ibland utelmna mellanrum och t.ex. skriva x = a*b + c*d - e/f.
Stt ej in mellanrumstecken omedelbart efter en vnsterparentes eller fre en hgerparentes.
Stt ej in mellanrumstecken fre semikolon.
Stt in ett mellanrumstecken fre en vnsterparentes, utom fre en parameterlista.
Stt in en tom rad fr att separera deklarationer frn satser, fr att separera satsavsnitt som motsvarar
olika delmoment i en berkning, fr att separera funktionsdefinitioner frn varandra, etc. Var
systematisk med antalet tomma rader i olika situationer. Stt inte in fr mnga tomma rader i fljd,
en eller tv kan ofta vara lagom.
! Stt ej in tomma rader som delar upp kod som hr intimt samman. T.ex. en tom rad fre while i en
do-while-sats ger ju ltt intrycket av att det i stllet r frga om en while-sats som pbrjas.
Satsblock
I C++ behver satsblocket, till fljd av de sammansatta satserna syntax, ofta komma till anvndning fr
att gruppera sammanhrande satser. Satsblockets patenteser r dock svrplacerade, om man vill ha en
snygg och enhetlig kod. Hur parenteserna ska placeras har debatterats en hel del och det har utvecklats
olika stilar, med sina fr- och nackdelar. En variant r att placera blockparenteserna p egna rader och i
samma kolumn direkt fre och efter blocket. Parenteserna placeras med samma indrag som den styrsats
de tillhr. Denna stil anses av mnga vara att fredra ur lsbarhetssynpunkt. Exempel:
if (...)
{
...
}
else
{
...
}
while (...)
{
...
}
do
{
...
}
while (...);
En liten variation p ovanstende r att dra in blockparenteserna motsvarande ett indragssteg och
satserna i blocket ytterligare ett steg. Det har flera nackdelen, dels fr koden ett mer oroligt intryck
och dessutom motsvarar inte indraget frn vnstermarginalen lngre det logiska nstlingsdjupet.
Ett alternativ till ovanstende r att flytta upp inledande blockparenteser till sist p raden innan. Detta
ger ngot kompaktare kod och ytterligare fokusering p det vsentliga, nmligen nyckelorden i styrsatsen ifrga (den enda intressanta parentesen r egentligen den allra sista). Exempel:
if (...) {
}
else {
while (...) {
do {
}
while (...);
Man se ibland kod enligt exemplen ovan dr else i if-atsen respektive while i do-while-satsen placerats
efter spetsparentesen p raden innan. Det har den eventuella frdelen att eliminera en tom rad men
nackdelen att matchande nyckelord (if-else respektive do-while) inte fr samma indrag, vilket ger en
viss obalans.
Styrsatser
! I styrsatser, (if, else, for, while och do-while) br alltid satsdelen utgras av ett satsblock, ven om
enbart en sats ingr. Detta medfr enhetlighet, klarhet och ndringsbarhet.
! Styrsatser br vara korta.
Funktioner
Program, som inte r mycket enkla, ska delas upp i funktioner. Varje funktion ska helst bara gra en sak.
En sak kan naturligtvis vara ngot komplext, men i sdana fr man dela upp arbetet p flera funktioner, som var och en gr sin del.
Funktionsdeklarationer ska skrivas p prototypformat, dvs. med datatyperna fr argumenten
angivna, drfr att detta ger kompilatorn mjlighet att gra typkontroll.
! I en funktionsdeklaration br den inledande parentesen och frsta argumentet, om sdant finns,
skrivas p samma rad som funktionsnamnet. Om utrymme finns br ven vriga argument och den
avslutande parentesen skrivas p samma rad., t.ex.:
double fun(int, double);
I annat fall ska varje ytterligare parameter skrivas p en egen rad och med den avslutande parentesen direkt
efter det sista parametern.
next;
Node*
Node_Pointer;
Namngivning av vrden kan ocks stadkommas med variabler, men dr kommer en annan viktig egenskap hos konstanter in, nmligen att de r just konstanta. Konstanters vrden fr ej ndras och den
egenskapen kontrolleras av kompilatorn.
Ngra av reglerna fr variabler ovan, kan ven tillmpas fr konstanter.
Konstanter ska definieras genom anvndning av const eller enum, aldrig med #define (det r
gammal C-stil).
Undvik numeriska vrden i koden. Anvnd symboliska konstanter i stllet.
Uttryck
Det finns ett antal vanliga fallgropar i samband med berkning av sammansatta uttryck. C++ har mnga
operatorer och mnga prioritetsniver att hlla reda p, vilket bidrar till att det kan vara svrt att uttolka
sammansatta uttryck korrekt, om inte uttrycken skrivs p ett stt som stdjer uttolkningen.
Fr sammansatta uttryck dr ingende operatorer har samma prioritet, gller dessutom associativitetsregler. Dessa bestmmer om uttryck ska berknas frn vnster till hger eller frn hger till vnster.
Vnsterassociativitet gller fr de flesta prioritetsniverna, hgerassociativitet endast p ngra.
! Anvnd inte kommaoperatorn, av lsbarhetsskl.
! Den tilldelningsoperator som normalt br anvndas r =. vriga tilldelningsoperatorer (+=, -=, *=,
/=, %=, <<=, >>=, &=, |=, ^=) frsmrar ofta lsbarheten.
! Villkorsoperatorn ? : br normalt undvikas, av lsbarhetsskl.
! Anvnd parenteser fr att frtydliga berkningsordningen fr operatorer och deluttryck i komplicerade sammansatta uttryck.
Styrsatser
I C++ finns tv styrsatser fr selektion (if och switch) och tre fr repetition (for, while och do-while).
Vilken sats br man anvnda i en viss situation, eller kvittar det? Ibland ger det sig sjlvt, drfr att en
viss sats inte (enkelt) kan anvndas i en viss situationer. Det gller t.ex. switch-satsen, vars styruttryck
mste vara ett int-kompatibelt uttryck och dessutom mste vrdena i case-lgena vara konstanter. Detta
gr switch-satsen mer begrnsad n if-satsen, men dremot passar den mycket bra i vissa fall och ger
d enklare kod n motsvarande if-satsen.
Repetitionssatserna kan vara svrare att vlja bland, ven om det finns ngra grundregler man kan g
efter fr att frska anvnda rtt sats fr en viss typ av repetition, se rekommendationerna fr respektive sats nedan. Tnk noga igenom valet av repetitionssats, ditt val kan vara vsentligt fr att ge lsaren
rtt signal om vad fr slags repetition det r frga om (utan att behva luslsa koden).
Av utrymmesskl anvnds den s.k. javastilen fr att visa rekommenderad syntax nedan.
If-satsen
If-satsen br i princip skrivas enligt fljande syntax:
if (uttryck) {
satser
}
else if (uttryck) {
satser
}
else {
satser
}
Styruttrycket i if-satsen ska vara ett villkorsuttryck eller en boolsk variabel eller boolsk funktion.
! Om samtliga uttryck beror av samma variabel br en switch-sats anvndas i stllet fr en if-sats.
! if-satser br ha maximal 7 grenar och ett maximalt nstlingsdjup av 3.
7
switch-satsen
switch-satsen br i princip skrivas enligt fljande syntax:
switch (uttryck) {
case vrde:
satser
break;
case vrde:
case vrde:
satser
break;
default:
satser
break;
}
En switch-sats ska alltid innehlla ett avslutande default-alternativ, i vilket ovntade fall hanteras.
Koden i ett case-alternativ i en switch-sats ska avslutas med break, eller return. D flera casealternativ delar p samma kodblock anvnds break endast fr det sista av alternativen. Sdana fall
br kommenteras.
for-satsen
for-satsen br i princip skrivas enligt fljande syntax:
for (initieringssats uttryck2; uttryck3) {
satser
}
for-satsen ska endast anvndas fr repetitioner dr antalet varv kan bestmas d satsen brjar, dvs.
d uttryck2 r ett konstant uttryck under exekveringen av for-satsen, och d slingvariabeln stegas
med ett konstant steg i varje varv. I annat fall anvnds while (frtestade slingor) eller do-while
(eftertestade slingor).
for (int index = 0; i < number_of_elements; ++index) {
cout << vector[index];
}
while-satsen
while-satsen br i princip skrivas enligt fljande syntax:
while (styruttryck) {
satser
}
! while-satsen br endast vljas d styruttrycket p ett naturligt stt kan frtestas. Genom detta undviker man ologiska initieringar av variabler som ingr i uttrycket (ofta r ett tecken p att do-while
br vljas i stllet). Det kan vara aktuellt att avbryta slingan utan att utfra den ngon enda gng.
p = list;
while (p != 0) {
cout << p->name << endl;
p = p->next;
}
do-while-satsen
do-while-satsen br i princip skrivas enligt fljande syntax:
do {
satser
}
while (styruttryck);
! do-while anvnds d satserna i slingan alltid ska utfras minst en gng. I annat fall anvnds while.
cout << Ange vre grns (heltal strre n 0): ;
do {
cin >> upper_limit;
if (upper_limit < 1)
cout << vre grns ska vara strre n 0, ge ett nytt vrde: ;
}
while (upper_limit < 1);
! Anvnd unsigned fr variabler som rimligtvis ej kan anta negativa vrden. Variabler som representerar storlek eller lngd r lmpliga att deklarera som unsigned. Genom detta kan en del otrevliga
fel undvikas.
Det finns tillfllen d unsigned kan ge upphov till problem. Fljande for-sats kommer aldrig att avslutas,
till fljd av moduloaritmetiken som anvnds fr heltalstyper utan frtecken. P en Sun SPARC kommer variabeln i att cykliskt genomlpa 9, 8, , 0, 4294967295, 4294967294, :
for (unsigned int i = 9; i >= 0; i--)
! Anvnd alltid inklusiva undre grnser och exklusiva vre grnser, t.ex. 0 <= i och i < 10. Genom
att vara konsekvent i detta avseende kan svra fel undvikas.
! Anvnd ej continue om ej ptaglig lsbarhetsvinst eller frenkling kan erhllas med. Det r ofta mer
lsbart att anvnda else-gren i stllet; continue anvnds ju alltid tillsammans med en if-sats.
! Anvnd normalt break endast fr att avsluta case-alternativ i switch-satser. break kan tilltas fr
att g ur en slinga, om detta innebr att anvndning av flaggor undviks.
! Skriv ej logiska uttryck p formen if (ptr), if (!ptr) eller if (!!ptr), om ptr r en pekare. Mnga finner
dessa former svra att lsa. Skriv if (ptr != 0) eller if (ptr == 0).
! Efterstrva en return-sats i en funktion, p sista raden i funktionen. Om ptaglig frenkling kan erhllas genom flera return-satser, kan det tilltas. Endast en return-sats stdjer regeln att varje konstruktion ska ha endast en utgng (och endast en ingng). Fr en funktion som returnerar void kan
return helt utelmnas.
Funktioner
Funktionsparametrar
Anvnd inte ospecificerade funktionsargument (ellips, );
! Undvik funktioner med mnga argument.
! Om en funktion lagrar en pekare till ett objekt som tkoms via en parameter, ska parametern vara av
typen pekare. I annat fall ska referensparameter anvndas.
! Anvnd konstanta referenser (const &) fr vrdeanrop, svida ej parametertypen r av frdefinierad
typ eller r en pekare. (Undvika kopiering och eventuellt aktivering av en destruktor fr kopian).
Funktionsverlagring
! Alla variationer av ett verlagrat funktionsnamn br ha samma innebrd (semantik).
Returtyper och returvrden
Ange alltid en returtyp fr en funktion, eller void om inget vrde ska returneras.
En funktion ska aldrig returnera en referens eller pekare till en lokal variabel.
Inline-funktioner
Anvnd ej preprocessordirektivet #define fr att generera effektivare kod; anvnd i stllet inlinedeklarerade funktioner.
! Anvnd inline-deklaration endast d detta verkligen r pkallat.
Temporra objekt
! Minimera antalet temporra objekt som skapas fr funktionsparametrar och som returvrden.
Allmnt
! Undvik lnga och invecklade funktioner. Frsk att dela upp komplicerade funktioner i flera sm.
! Undvik om mjligt pekare till pekare, **. Ofta kan referens till pekare anvndas i stllet, *&, t.ex. i
samband med funktionsparametrar.
! Anvnd typedef fr att frenkla programsyntaxen vid deklaration av lnkade strukturer och
funktionspekare.
Dynamisk minneshantering
Anvnd ej malloc, calloc eller free, fr att tilldela och terlmna dynamiskt minne, utan new
och delete. Om, av ngon anledning, de frra anvnds, blanda aldrig med new och delete!
! Skapa ej dynamiskt minne och frvnta att ngon annan ska terlmna det.
! Tilldela alltid en pekare som pekar till terlmnat minne ett nytt vrde (0 om ej annat). Om pekarens
deklarationsblock r p vg att lmnas, r detta naturligtvis ej ndvndigt.
10
Klasser
Klasser br i princip definieras enlighet fljande syntax, javastil t.h.:
class Derived : public Base
{
public:
protected:
private:
};
protected:
private:
};
Man kan diskutera om tkomstskyddsdeklarerarna, public:, protected: och private:, ska dras in ett
steg, som ovan, eller ej.
public-, protected- och private-avdelningarna ska deklareras i den ordningen.
Genom denna deklarationsordning kommer det som r av intresse fr anvndaren, public, frst i klassdefinitionen. Drefter fljer protected-delen med sdant som r av intresse om man avser att hrleda frn klassen.
Sist private-delen som r av minst intresse allmnt.
tkomstrttighet
Specificera ej datamedlemmar i en klass som public eller protected.
I grnssnitt mot andra sprk kan det vara ndvndigt att definiera public-specificerade datakomponenter.
Att specificera en datamedlem som public innebr att anvndare av klassen fritt kan operera p en sdan datamedlem. Detta strider mot den grundlggande principen i objektorienterad programmering att data ska vara
inkapslade och enbart ska kunna manipuleras p ett kontrollerat stt, dvs. via klassens medlemsfunktioner. Om
public-data undviks kan dess interna representation ndras utan att detta pverkar anvndarens kod.
Anvndning av protected-variabler i en klass rekommenderas ej, eftersom sdana variabler blir synliga i hrledda klasser. Namnen p sdana variabler kan d ej ndras, eftersom hrledda klasser kan vara beroende av
namnen. Om en hrledd klass mste komma t data i frldraklassen, kan detta lsas genom att gra ett speciellt l protected-grnssnitt i basklassen med funktioner som returnerar private-data. Detta behver ej pverka
effektiviteten om funktionerna definieras som inline-funktioner.
Inline-funktioner
! tkomstfunktioner br vara inline-funktioner.
const-medlemsfunktioner
En medlemsfunktion som ej ndrar ett objekt tillstnd ska vara const-deklarerad.
Medlemsfunktioner som r const-deklarerade r de enda funktioner som kan anropas fr const-objekt. Frutom att const-deklaration kar mjligheterna fr kompliatorn att utfra kontroller, kar den fljaktligen ven
funktionens anvndbarhet. Ibland verlagrar man en viss funktion, eller operator, fr att ha olika versioner fr
const- och icke-const-objekt.
11
Tilldelningsoperatorer
En klass som anvnder new fr att skapa minne som hanteras av klassen ska normalt definiera en
tilldelningsoperator (operator=).
Operatorverlagring
! Anvnd operatorverlagring sparsamt och p ett enhetligt stt. Tolkningen ska vara intuitiv.
! Nr tv operatorer r varandras motsats (t ex == och !=) r det lmpligt att definiera bda.
Returtyper fr medlemsfunktioner
En public medlemsfunktion ska aldrig returnera icke-konstant referens/pekare till medlemsdata.
En public medlemsfunktion ska aldrig returnera en icke-const referens eller pekare till data utanfr
objektet, svida inte objektet delar data med andra objekt.
Arv
! Undvik arv fr del-av-relationer.
! Ge hrledda klasser tkomst till medlemsdata via skyddade tkomstfunktioner.
Undantag
Anvnd undantag (exceptions) enbart fr verkligt exceptionella hndelser, hantering av fel eller
ptagligt ovanliga eller viktiga situationer.
Hantera varje undantag p lmplig designniv.
Kodmallar
Dokumentation r en viktig del i framstllning av programvara. Hr behandlas den form av dokumentation som utgrs av kommentarer i kllkoden. Kllkodskommentarer kan delas in i strategiska och
taktiska kommentarer:
en strategisk kommentar placeras fre ett kodavsnitt, t.ex. fre en moduldeklaration eller en
funktionsdefinition, och beskriver vad det beskrivna kodavsnittet fyller fr funktion.
en taktisk kommentar rr vanligtvis en enskild rad kod, eller ngra rader. Om kommentaren rr en
enskild rad placeras den med frdel sist p raden om detta r mjligt, i annat fall fre raden ifrga.
En taktisk kommentar som rr flera rader placeras fre raderna, som en rubrik.
Strategiska kommentarer vnder sig i frsta hand till anvndare av en modul eller en funktion, medan
taktiska kommentarer vnder sig till den som ska underhlla koden. Fr mycket taktiska kommentarer
gr ltt koden olslig och br drfr undvikas. Taktisk kommentering kan ocks ofta undvikas genom
den strategiska kommenteringen, vl valda namn och vlskriven kod fr vrigt. Endast komplicerad
kod br kommenteras taktiskt.
Nedan visas mallar fr olika slags filer, inkluderingsfiler, inline-definitionsfiler och implementeringsfiler, samt fr strategiska kommentarer fr funktioner. Att standardisera sttet att kommentera kan gra
det mjligt att med lmpliga verktyg automatiskt generera annan dokumentation, t.ex. manualsidor.
12
Inkluderingsfiler
/*
* IDA Programvaruproduktion AB (u.p.a.)
*
* IDENTIFIERING
*
* Filnamn:
Stack.hh
* Enhetsnamn:
Stack
* Typ:
Moduldeklaration
* Revision:
2.1
* Skriven av:
H. Acker
*
*
* BESKRIVNING
*
* Denna modul ...
*
* REVISIONSBERTTELSE
*
* Revision Datum
Frndringar
*
* 1
970319 Ursprungsversion
* 1.1
970407 ...
* ...
* 2.0
970821 ...
*
*/
#ifndef STACK_HH
#define STACK_HH
/*
* REFERERADE BIBLIOTEK OCH MODULER
*/
#include <*.hh>
#include *.hh
...
/*
* VILLKORLIG INKLUDERING AV INLINE-DEFINITIONSFILEN
*
* Vid normal kompilering inkluderas inline-definitionsfilen
* Stack.icc hr. Vid kompilering fr avlusning inkluderas filen
* i stllet i Stack.cc. Detta styrs i kompileringskommandot med
* preprocessorflaggan -D och DEBUG som argument, dvs. -DDEBUG.
*/
#ifndef DEBUG
#include Stack.icc
#endif
/*
* SLUT P FILEN Stack.hh
*/
#endif
13
Inline-definitionsfiler
/*
* IDA Programvaruproduktion AB (u.p.a.)
*
* IDENTIFIERING
*
* Filnamn:
Stack.icc
* Enhetsnamn: Stack
* Typ:
Inline-definitioner hrande till modul Stack
* Revision:
2.1
* Skriven av: H. Acker
*
*
* BESKRIVNING
*
* Denna definitionsfil...
*
* REVISIONSBERTTELSE
*
* Revision Datum
Frndringar
*
* 1
970319 Ursprungsversion
* 1.1
970407 ...
* ...
* 2.0
970821 ...
*
*/
/*
* FUNKTION is_empty()
* ...
*/
template <class T>
inline
int
Stack<T>::
is_empty()
{
...
}
/*
* FUNKTION ...
* ...
*/
template <class T>
inline
...
/*
* SLUT P FILEN Stack.icc
*/
14
Implementeringsfiler
/*
* IDA Programvaruproduktion AB (u.p.a.)
*
* IDENTIFIERING
*
* Filnamn:
Stack.cc
* Enhetsnamn: Stack
* Typ:
Definitioner hrande till modul Stack, ej inline
* Revision:
2.1
* Skriven av: H. Acker
*
*
* BESKRIVNING
*
* Denna implementeringsfil...
*
* REVISIONSBERTTELSE
*
* Revision Datum
Frndringar
*
* 1
970319
Ursprungsversion
* 1.1
970407
...
* ...
* 2.0
970821
...
*
*/
/*
* REFERERADE BIBLIOTEK OCH MODULER
*/
#include Stack.hh
/*
* VILLKORLIG INKLUDERING AV INLINE-DEFINITIONSFILEN
*
* Vid kompilering fr avlusning inkluderas inline-definitionsfilen
* Stack.icc hr, samtidigt som inline-deklarationerna avlgsnas.
* Vid normal kompilering inkluderas filen i stllet i Stack.hh.
* Detta styrs i kompileringskommandot med preprocessorflaggan -D
* och DEBUG som argument, dvs. -DDEBUG.
*/
#ifdef DEBUG
#define inline
#include Stack.icc
#undef inline
#endif
15
/*
* LOKALA DEFINITIONER
*/
/*
* BESKRIVNING
* ...
*/
static ...
// ...
...
/*
* LOKALA FUNKTIONER (DEKLARATIONER)
*/
void f(...);
// ...
...
/*
* KONSTRUKTOR Stack()
* ...
*/
template <class T>
Stack<T>::
Stack()
{
...
}
/*
* LOKALA FUNKTIONER (DEFINITIONER)
*/
/*
* FUNKTION push(const T& item)
* ...
*/
void
push(const T& item)
{
...
}
/*
* SLUT P FILEN Stack.cc
*/
16
Klassbeskrivningar
Nedan visas hur klasser kan dokumenteras i inkluderingsfilen.
/*
* KLASS X
*
* BASKLASSER
*
* ...
*
* BESKRIVNING
*
* ...
*
* TILLSTND
*
* ...
*
* KONSTRUKTORER
*
* ...
*
* OPERATIONER
*
* ...
*
* DATAMEDLEMMAR
*
* ...
*
* REVISIONSBERTTELSE
*
* Revision Datum
Frndringar
*
* 1
970319 Ursprungsversion
* ...
*/
class X
{
friend ...
...
public:
...
protected:
...
private:
...
};
17
Funktionsbeskrivningar
I filmallarna ovan har strategiska kommentarer fr funktioner markerats med t.ex.:
/*
* FUNKTION funktionsnamn
* ...
*/
18