Kommentarer
Svara
Om jag fortsätter att skriva mer kod då kommer det att bli svårt för mig att organisera koden.
Detta är ditt problem: få rätt i organisationen, och stilen ska flyta lättare.
Var inte vänta för att organisera din kod: håll koden ordnad när du går. Även om språket inte gör det åt dig, kod bör fortfarande organiseras i moduler med låg koppling och hög sammanhållning.
Dessa moduler ger då naturligtvis ett namnområde. Förkorta modulnamnet (om det är långt) och prefix funktionsnamn med deras modul för att undvika kollisioner.
På nivån för enskilda identifierare är dessa ungefär i ökande ordning av subjektivitet:
- välj en konvention och håll fast vid den
- t.ex.
function_like_this(struct TypeLikeThis variable)
är vanligt
- t.ex.
-
undvik definitivt ungerska notationer (sorry JNL)
-
såvida du inte är villig att använda den som ursprungligen avsedd, vilket betyder Simonyis appar notation snarare än den hemska systemversionen
Varför? Jag kunde skriva en uppsats om detta, men jag föreslår istället att du läser den här artikeln av Joel Spolsky, och sedan jagar lite mer om du är intresserad. Det finns en länk till Simonyis originalpapper längst ner.
-
-
undvik pekartypsnitt såvida de inte verkligen är ogenomskinliga kaketyper – de bara förvirra saker
struct Type *ok; typedef struct Type *TypePtr; TypePtr yuck;
Vad menar jag med en ogenomskinlig cookietyp ? Jag menar något som används i en modul (eller ett bibliotek, eller vad som helst som måste överföras till klientkod, men den klientkoden kan ”t använda direkt. Det skickar det bara tillbaka till biblioteket.
Till exempel kan ett databasbibliotek exponera ett gränssnitt som
/* Lots of buffering, IPC and metadata magic held in here. No, you don"t get to look inside. */ struct DBContextT; /* In fact, you only ever get a pointer, so let"s give it a nice name */ typedef struct DBContexT *DBContext; DBContext db_allocate_context(/*maybe some optional flags?*/); void db_release_context(DBContext); int db_connect(DBContext, const char *connect); int db_disconnect(DBContext); int db_execute(DBContext, const char *sql);
Nu är sammanhanget är ogenomskinlig för klientkoden, eftersom du inte kan se inuti. Du skickar den bara tillbaka till biblioteket. Något som
FILE
är också ogenomskinligt och ett heltals filbeskrivare är också en cookie men är inte ogenomskinlig.
En anmärkning om design
Jag använde frasen låg koppling och hög sammanhållning ovan utan förklaring, och jag känner mig lite dålig om det. Du kan söka efter det och förmodligen hitta några bra resultat, men jag försöker ta itu med det kort (igen, jag kunde skriva en uppsats men kommer att försöka att inte göra det).
DB-biblioteket som skisseras ovan visar låg koppling eftersom det exponerar ett litet gränssnitt mot omvärlden. Genom att dölja dess implementeringsdetaljer (delvis med det ogenomskinliga cookietricket) förhindrar det att klientkod beror på dessa detaljer.
Föreställ dig istället för den ogenomskinliga cookien, vi förklarar kontextstrukturen så att dess innehåll är synligt, och det inkluderar en sockelfilbeskrivare för en TCP-anslutning till databasen. DB körs på samma maskin, klienten behöver sammanställas snarare än bara länkas igen. Ännu värre kunde klienten ha börjat använda filbeskrivaren, till exempel ringa setsockopt
för att ändra standardbuffertstorleken, och nu behöver den också en kodändring. Alla dessa deta ils ska vara gömda i vår modul där det är praktiskt, och detta ger låg koppling mellan moduler.
Exemplet visar också hög sammanhållning genom att alla metoder i modulen handlar om samma uppgift (DB-åtkomst). Detta innebär att endast koden som behöver för att veta om implementeringsdetaljerna (det vill säga innehållet i vår cookie) faktiskt har tillgång till dem, vilket förenklar felsökning.
Du kan också se att det att ha en enda fråga gjorde det enkelt att välja ett prefix för att gruppera dessa funktioner.
Att säga att detta exempel är bra är enkelt (särskilt eftersom det inte är ”t ens komplett), men hjälper dig inte omedelbart. Tricket är att titta på, när du skriver och förlänger din kod, för funktioner som gör liknande saker eller fungerar på samma typer (som kan vara kandidater för sin egen modul), och även för funktioner som gör massor av separata saker som inte är ” är inte riktigt relaterad och kan vara kandidater för att dela upp.
Kommentarer
- Kan du hjälpa mig att förstå varför undviks ungerska? Bara nyfiken på att veta mer om det. 🙂
- @JNL: En kommentar är för kort för att förklaras ordentligt. Jag föreslår att du lägger upp den som en ny fråga.
-
with low coupling and high cohesion
. Vad betyder det? Och snälla förklara om ogenomskinliga cookietyper. Jag har ingen aning om vad det betyder. - Jag försökte ta itu med både kort och uppriktigt misslyckades kortfattat. Förhoppningsvis skulle det få dig började dock.
- Jag svarar efter några dagar. Ledsen för det. Jag läste din beskrivning av
low coupling and high cohesion
. Så det betyder i princip att kapsla in saker när jag kan och det bör göras på ett sätt som funktioner som faktiskt behöver bör ha åtkomst. Vissa saker gick över mitt huvud men ändå tror jag att jag förstår din poäng.
Svar
Enligt min mening 90 % av namngivningsproblemet löses om du har tre saker i åtanke: a) gör dina variabel- och funktionsnamn så beskrivande som möjligt, b) vara konsekvent i hela din kod (dvs. om en funktion heter addNumbers, bör en andra funktion namnges multiplyNumbers och inte numbersMul) och c) försök att göra namnen korta om möjligt, eftersom vi behöver skriva dem.
Med detta sagt om du vill titta på andra aspekter om detta ämne har Wikipedia-sidan på Namngivningskonventioner en bra lista över saker du borde kom ihåg. Det har också en sektion på C och C ++:
I C och C ++ är nyckelord och standardbiblioteksidentifierare mest små bokstäver. I C-standardbiblioteket är förkortade namn de vanligaste (t.ex. isalnum för en funktion som testar om ett tecken är alfanumeriskt), medan C ++ standardbiblioteket ofta använder en understrykning som en ordseparator (t.ex. out_of_range). Identifierare som representerar makron är enligt konvention skrivna med endast stora bokstäver och understrykningar (detta är relaterat till konventionen i många programmeringsspråk för att använda stora bokstäver för konstanter). Namn som innehåller dubbel understrykning eller som börjar med en understrykning och en stor bokstav är reserverade för implementering (kompilator, standardbibliotek) och bör inte användas (t.ex. reserverad__ eller _Reserverad). [5] [6] Detta liknar ytligt ytan på stropping, men semantiken skiljer sig åt: understrykningarna är en del av värdet på identifieraren snarare än att citera tecken (liksom stroppen): värdet på __foo är __foo (som är reserverat), inte foo (men i ett annat namnområde).
Kommentarer
- " försök att göra namnen korta om möjligt " Använd en IDE med automatisk komplettering, då kan dina funktionsnamn vara så långa och beskrivande som de behöver vara som du bara behöver att skriva sedan en gång.
- @Joel fruktansvärda råd. Inte alla kommer att använda samma IDE som du.
- @James De behöver inte ' de behöver inte, de kan bara använda någon anständig IDE. Då behöver du ' inte behöva offra klarhet för produktivitet.
- Termen IDE sträcker sig lite tunn nu om dagen. Tekniskt är Notepad ++ en IDE eftersom du kan konfigurera den för att kompilera och köra ditt projekt, men det ' är främst en textredigerare. Och det slutförs automatiskt.
Svar
Den enda hårda begränsningen i C är att det inte finns några namnområden. Därför måste du hitta ett sätt att göra rename()
-funktionen i ditt filsystem -bibliotek annorlunda från rename()
funktion i ditt media bibliotek. Den vanliga lösningen är ett prefix, såsom: filesystem_rename()
och media_rename()
.
Det andra allmänna rådet är: stanna konsekvent inom ett projekt eller ett team. Läsbarheten förbättras.
Kommentarer
- +1: Det gäller särskilt för exporterade symboler i ett bibliotek. " Jag är ledsen, men det filsystembiblioteket går inte med det mediebiblioteket, eftersom båda har ett exporterat funktionsnamn.
Svar
OM du letar efter ett globalt ACCEPTERAT FORMAT
MISRA / JSF / AUTOSAR täcker nästan 100% av alla branschstandarder för namngivning och organisering av C / C ++ – kod. Problemet är att de inte är gratis att få tag på, dvs. varje guidebok kostar lite pengar. Jag vet att MISRA 2008 C / C ++ kodning standardbok förmodligen kostar cirka 50 USD.
Du kan tänka dig dessa som Harvard-referensen för bibliografi och tilläggsläsning när du skriver en tidskrift. Jag har använt MISRA och det är ett bra sätt att namnge dina funktioner och variabler och organisera dem för korrekt användning.
OM DU Söker efter något tillfälligt
De referenser du angav för Python och Java är okej antar jag. Jag har sett människor anta javadoc-stil kommentera, namnge och organisera kod. I mitt senaste projekt var jag tvungen att skriva C ++ – kod i Java-liknande funktioner / variabelnamn. Två skäl bakom detta:
1) Det var tydligen lättare att följa.
2) Krav på produktionskod berör inte marken för säkerhetskritiska mjukvarusystemstandarder.
3) Äldre kod var (på något sätt) i det formatet.
4) Doxygen tillät Javadoc-systemkommentarer. I det ögonblicket använde vi doxygen för att generera dokumentation för produktions killarna.
Många programmerare kommer att vara motståndare till detta, men jag personligen tycker att det inte är något fel med att använda javadoc-stilfunktion / variabelnamn i C / C ++. JA SÄRSKILT, praxis för att organisera din flödesreglering, trådsäkerhet etc. måste hanteras oavsett. Jag är dock inte en sökande här. Jag vet inte heller hur stränga dina krav på produktionskodformat är. Utan att omdirigera det till ett område utanför ämnet föreslår jag att du granskar dina krav, ta reda på hur beroende du är av en specifik namngivning och gå med en lösning som nämns i mina och andra ”svar
Hoppas det hjälpte !?
Kommentarer
- Egentligen frågade jag detta om personliga C-koder . Men jag ' kommer att komma ihåg ditt förslag.
- @AseemBansal Personligt eller professionellt, det är bra att lära sig och också bra att sätta på ditt CV 🙂 … Upp till dig.
Svara
Få viktiga saker att tänka på vid namngivning skulle vara;
-
Titta på actionObject eller ObjectAction-typen. (Objekt inte för C. Men i allmänhet när du går till andra objektorienterade språk) Detta bör hjälpa
-
Vila skulle vara KONSEKVENT, säkert och beskrivande.
- Har också det enda syftet med varje definierad variabel och funktion, t.ex. om det är att lagra ett värde tillfälligt, namnge det som nTempVal för int
- Variabler ska vara substantiv och metoder ska vara verb.
Kommentarer
- Ungerska notationen (prefix en variabel med bokstäver som anger typen) leder till att smärtan inte slutar. Det har tack och lov för det mesta gått ur modet.
- @StevenBurnap Var bara nyfiken på varför undviks ungerskt format? Jag tror att ' är vad de lärde oss i skolan och jag har sett en sådan kod också på vissa arbetsplatser. Vilken skulle du rekommendera om inte ungerska. Tack
- Den bästa namngivningskonventionen är bara en konsekvent, med tydliga, beskrivande namn som helst hålls relativt korta utan överdriven förkortning och undviker redundanta prefix. Ungerska notationen har liten faktisk nytta, gör koden svårare att läsa och gör det svårare att byta typ.
- Här är en beskrivning av den ursprungliga avsikten och den styggelse som den ungerska notationen har blivit: joelonsoftware.com/articles/Wrong.html
- @Residuum Det var en bra länk. Hjälpte mycket. Uppskatta det.
Svar
De flesta av svaren är bra, men jag vill säga några saker om namngivning konventioner för bibliotek och inkluderade filer, som att använda namnytor på andra språk som C ++ eller Java:
Om du bygger ett bibliotek, hitta ett vanligt prefix för dina exporterade symboler, dvs globala funktioner, typsnitt och variabler. Detta förhindrar kollisioner med andra bibliotek och identifierar funktionerna som kommer från din. Det här är en liten bit av appar ungerska notationer.
Kanske gå ännu längre och gruppera dina exporterade symboler: libcurl använder curl_ * för globala symboler, curl_easy_ *, curl_multi_ * och curl_share_ * för de olika gränssnitten.Så förutom att använda curl_ * för alla funktioner, har de lagt till en annan nivå av ”namnområden” för de olika gränssnitten: att ringa en curl_easy_ * -funktion på ett curl_multi_ * handtag ser nu fel ut, se funktionsnamnen på http://curl.haxx.se/libcurl/c/
Om du behåller reglerna för exporterade symboler bör du använda dem för statiska funktioner i #include
ed-filer: Försök hitta ett gemensamt prefix för dessa funktioner. Kanske har du statiska strängfunktioner i en fil som heter ”min_sträng”? Prefixa alla dessa funktioner med my_string_ *.
Kommentarer
- Med exporterade symboler menar du globala variabler, funktioner, typsnitt etc. om jag har rätt. Kan du förklara lite om gruppering av de exporterade symbolerna? Jag trodde att du redan förklarade det i föregående stycke. Vad lade du till i tredje stycket?
order.c
, kan du namnge funktionernaorder_add()
,order_del()
och liknande. Det kan finnas gamla system som säger att namnet måste vara unikt inom de första 8 tecknen. När du byter till c ++ senare av misstag kommer du ' gärna att skrivaorder::add()
ochorder::del()
då.