Kommentarer
Svar
Hvis jeg fortsætter at skrive mere kode, så vil der være et tidspunkt, hvor det vil være svært for mig at organisere koden.
Dette er dit problem: få organisationen rigtig, og stilen skal flyde lettere.
Vent ikke vent på at organisere din kode: hold din kode organiseret, mens du går. Selvom sproget ikke gør det for dig, kode skal stadig være organiseret i moduler med lav kobling og høj samhørighed.
Disse moduler giver naturligvis et navneområde. Forkort modulnavnet (hvis det er langt) og prefiks funktionsnavne med deres modul for at undgå kollisioner.
På niveauet for individuelle identifikatorer er disse omtrent i stigende rækkefølge af subjektivitet:
- vælg en konvention og hold fast ved den
- f.eks.
function_like_this(struct TypeLikeThis variable)
er almindelig
- f.eks.
-
absolut undgå ungarsk notation (undskyld JNL)
-
medmindre du “er villig til at bruge den som oprindeligt beregnet, hvilket betyder Simonyis” apps notation snarere end den forfærdelige systemversion
Hvorfor? Jeg kunne skrive et essay om dette, men jeg vil i stedet foreslå, at du læser denne artikel af Joel Spolsky, og derefter jager nogle mere, hvis du er interesseret. Der er et link til Simonyis originale papir i bunden.
-
-
undgå markørtyper, medmindre de virkelig er uigennemsigtige cookietyper – de kun forvirre ting
struct Type *ok; typedef struct Type *TypePtr; TypePtr yuck;
Hvad mener jeg med en uigennemsigtig cookietype ? Jeg mener noget, der bruges i et modul (eller et bibliotek eller uanset hvad) der skal overføres til klientkode, men den klientkode kan “t bruge direkte. Det sender det bare tilbage til biblioteket.
For eksempel kan et databasebibliotek muligvis udsætte en grænseflade 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 er konteksten er uigennemsigtig for klientkoden, fordi du ikke kan se ind. Du sender den bare tilbage til biblioteket. Noget som
FILE
er også uigennemsigtigt, og en heltal-filbeskrivelse er også en cookie men er ikke uigennemsigtig.
En note om design
Jeg brugte sætningen lav kobling og høj samhørighed ovenfor uden forklaring, og det føler jeg mig lidt dårlig om. Du kan søge efter det og sandsynligvis finde nogle gode resultater, men jeg vil prøve at adressere det kort (igen, jeg kunne skrive et essay, men vil prøve ikke).
DB-biblioteket skitseret ovenfor viser lav kobling fordi den udsætter en lille grænseflade for omverdenen. Ved at skjule dens implementeringsoplysninger (delvis med det uigennemsigtige cookie-trick) forhindrer det, at klientkode afhænger af disse detaljer.
Forestil dig i stedet for den uigennemsigtige cookie, erklærer vi kontekststrukturen, så dens indhold er synligt, og det inkluderer en sokkelfilbeskrivelse til en TCP-forbindelse til databasen. Hvis vi efterfølgende ændrer implementeringen til understøttelse ved hjælp af et delt hukommelsessegment, når DB kører på den samme maskine, klienten skal kompileres igen snarere end bare genlinkes. Endnu værre, klienten kunne have startet ved hjælp af filbeskrivelsen, for eksempel at ringe til setsockopt
for at ændre standardbufferstørrelsen, og nu skal den også ændre kode. Alle disse deta ils skal være skjult inde i vores modul, hvor det er praktisk, og dette giver lav kobling mellem moduler.
Eksemplet viser også høj samhørighed , idet alle metoder i modulet vedrører den samme opgave (DB-adgang). Dette betyder, at kun den kode, der skal for at vide om implementeringsoplysningerne (dvs. indholdet af vores cookie) faktisk har adgang til dem, hvilket forenkler fejlretning.
Du kan også se, at det at have en enkelt bekymring gjorde det let at vælge et præfiks for at gruppere disse funktioner sammen.
At sige, at dette eksempel er godt, er let (især da det ikke er “t engang færdig), men hjælper dig ikke med det samme. Tricket er at se, mens du skriver og udvider din kode, for funktioner, der gør lignende ting eller fungerer på de samme typer (som måske er kandidater til deres eget modul), og også for funktioner, der gør mange separate ting, der ikke er ” t virkelig relateret, og kan være kandidater til at splitte.
Kommentarer
- Kan du hjælpe mig med at forstå, hvorfor man undgår ungarsk? Bare nysgerrig efter at vide mere om det. 🙂
- @JNL: En kommentar er for kort til korrekt at kunne forklare. Jeg foreslår, at du sender den som et nyt spørgsmål.
-
with low coupling and high cohesion
. Hvad betyder det? Og forklar venligst om uigennemsigtige cookietyper. Jeg aner ikke hvad det betyder. - Jeg forsøgte at adressere både kort og ærligt mislykkedes kortfattet. Forhåbentlig skulle det give dig startede dog.
- Jeg svarer efter et par dage. Undskyld det. Jeg læste din beskrivelse af
low coupling and high cohesion
. Så det betyder grundlæggende at indkapsle ting, når jeg kan og det skal gøres på en måde, som funktioner, der faktisk har brug for, skal have adgang. Nogle ting gik over mit hoved, men jeg tror stadig, at jeg har din mening.
Svar
Efter min mening 90 % af navngivningsproblemet løses, hvis du holder tre ting i tankerne: a) gør dine variabel- og funktionsnavne så beskrivende som muligt, b) være ensartet i hele din kode (dvs. hvis en funktion hedder addNumbers, skal en anden funktion hedde multiplyNumbers og ikke numbersMul) og c) prøv at gøre navnene korte, hvis det er muligt, da vi skal skrive dem.
Når det er sagt, hvis du vil se på andre aspekter om dette emne, har Wikipedia-siden på Navngivningskonventioner en god liste over ting, du bør huske. Det har også en sektion på C og C ++:
I C og C ++ er nøgleord og standardbiblioteksidentifikatorer for det meste små bogstaver. I C-standardbiblioteket er forkortede navne de mest almindelige (f.eks. Isalnum for en funktion, der tester, om et tegn er alfanumerisk), mens C ++ -biblioteket ofte bruger en understregning som en ordseparator (fx out_of_range). Identifikatorer, der repræsenterer makroer, er ved konvention kun skrevet med store bogstaver og understregninger (dette er relateret til konventionen i mange programmeringssprog ved anvendelse af store bogstaver til konstanter). Navne, der indeholder dobbelt understregning eller begynder med en understregning og et stort bogstav, er forbeholdt implementering (kompilator, standardbibliotek) og bør ikke bruges (f.eks. Forbeholdt__ eller _Reserveret). [5] [6] Dette svarer overfladisk til stropping, men semantikken adskiller sig: understregningerne er en del af værdien af identifikatoren snarere end at citere tegn (som det er stropping): værdien af __foo er __foo (som er reserveret), ikke foo (men i et andet navneområde).
Kommentarer
- " prøv at gøre navnene korte, hvis det er muligt " Brug en IDE med automatisk udfyldelse, så kan dine funktionsnavne være så lange og beskrivende, som de skal være, som du kun har brug for at skrive en gang.
- @Joel forfærdeligt råd. Ikke alle bruger den samme IDE som dig.
- @James De har ikke ' de behøver ikke, de kan bare bruge enhver anstændig IDE. Så behøver du ikke ' ikke ofre klarhed for produktivitet.
- Udtrykket IDE strækkes lidt tyndt nu om dage. Teknisk set er Notepad ++ en IDE, fordi du kan konfigurere det til at kompilere og køre dit projekt, men det ' er primært en teksteditor. Og den fuldføres automatisk.
Svar
Den eneste hårde begrænsning i C er, at der ikke er nogen navneområder. Derfor er du nødt til at finde en måde at gøre rename()
-funktionen til dit filsystem -bibliotek adskilt fra rename()
funktion af dit medie bibliotek. Den sædvanlige løsning er et præfiks, såsom: filesystem_rename()
og media_rename()
.
Det andet generelle råd er: ophold konsistent inden for et projekt eller et team. Læsbarheden forbedres.
Kommentarer
- +1: Dette gælder især for eksporterede symboler i et bibliotek. " Jeg er ked af, men at filsystembiblioteket ikke følger med dette mediebibliotek, fordi begge har en eksporteret funktionsomdøbning.
Svar
HVIS DU LETTER EN GLOBALT ACCEPTERET FORMAT
MISRA / JSF / AUTOSAR dækker næsten 100% af enhver industristandard til navngivning og organisering af C / C ++ -kode. Problemet er, at de ikke er gratis at få fat i, dvs. hver af guidebøgerne koster nogle penge. Jeg ved, at MISRA 2008 C / C ++ kodning standardbog sandsynligvis koster omkring 50 USD.
Du kan tænke på disse som Harvard Referencing for bibliografi og tilføjelseslæsning, når du skriver en dagbog. Jeg har brugt MISRA, og det er en god måde at navngive dine funktioner og variabler og organisere dem til korrekt brug.
HVIS du leder efter noget midlertidigt
De referencer, du har angivet til Python og Java, er okay, tror jeg. Jeg har set folk vedtage javadoc-stil, kommentere, navngive og organisere kode. Faktisk måtte jeg i mit sidste projekt skrive C ++ – kode i Java-lignende funktioner / variabelnavne. To grunde bag dette:
1) Det var tilsyneladende lettere at følge.
2) Krav til produktionskoder berørte ikke grunden til sikkerhedskritiske softwarestandardstandarder.
3) Ældre kode var (på en eller anden måde) i det format.
4) Doxygen tillod Javadoc-system at kommentere. I det øjeblik brugte vi doxygen til at generere dokumentation til produktionsgutterne.
Mange programmører vil være modstandere af dette, men jeg personligt siger, at der ikke er noget galt med at vedtage javadoc-stilfunktion / variabel navngivning i C / C ++. JA AF SELVFØRENDE, fremgangsmåderne med at organisere din flowkontrol, trådsikkerhed osv. Skal behandles uanset. Jeg er dog ikke ansøger her. Jeg ved heller ikke, hvor strenge dine krav til produktionskodeformat er. Uden at omdirigere det til et område uden for emnet, foreslår jeg, at du gennemgår dine krav, finder ud af, hvor afhængig du er af en bestemt navngivningskonvention, og følger en nævnt løsning i mine og andre “svar
Håber dette hjalp !?
Kommentarer
- Faktisk bad jeg dette om personlige C-koder . Men jeg ' Jeg husker dit forslag.
- @AseemBansal Personlige eller professionelle, de er gode at lære og også gode at sætte på dit CV 🙂 … Op til dig.
Svar
Få vigtige ting, der skal tages i betragtning under navngivning, ville være;
-
Se på actionObject eller ObjectAction-typen. (Objekt ikke til C. Men generelt når du går til andre objektorienterede sprog) Dette skal hjælpe
-
Hvil vil være KONSEKVENT, helt sikkert og kort beskrivende.
- Har også et eneste formål med enhver defineret variabel og funktion, f.eks. Hvis det er at gemme en værdi midlertidigt, skal du navngive den som nTempVal for int
- Variabler skal være substantiv og metoder skal være verb.
Kommentarer
- Ungarsk notation (forud for en variabel med bogstaver, der angiver typen) fører til ingen ende af smerte. Det er heldigvis for det meste gået af mode.
- @StevenBurnap Var bare nysgerrig, hvorfor undgås ungarsk format? Jeg tror, at ' er, hvad de lærte os i skolen, og jeg har også set en sådan kode nogle steder. Hvilken vil du anbefale, hvis ikke ungarsk. Tak
- Den bedste navngivningskonvention er kun en konsekvent brugt med klare, beskrivende navne, der ideelt set holdes relativt korte uden overdreven forkortelse og undgår overflødige præfikser. Ungarsk notation har ringe faktisk nytte, gør koden sværere at læse og gør skiftende typer sværere.
- Her er en beskrivelse af den oprindelige hensigt og den vederstyggelighed, som den ungarske notation er blevet: joelonsoftware.com/articles/Wrong.html
- @Residuum Det var et godt link. Hjalp meget. Værdsat det.
Svar
De fleste af svarene er gode, men jeg vil sige nogle ting om navngivning konventioner for biblioteker og inkluderede filer, der ligner brug af navneområder på andre sprog som C ++ eller Java:
Hvis du bygger et bibliotek, skal du finde et fælles præfiks til dine eksporterede symboler, dvs. globale funktioner, typefejl og variabler. Dette forhindrer sammenstød med andre biblioteker og identificerer, at funktionerne kommer fra din. Dette er en smule apps-ungarske notationer.
Måske gå endnu længere og gruppere dine eksporterede symboler: libcurl bruger curl_ * til globale symboler, curl_easy_ *, curl_multi_ * og curl_share_ * til de forskellige grænseflader.Ud over at bruge curl_ * til alle funktioner, har de tilføjet et andet niveau af “navneområder” til de forskellige grænseflader: at kalde en curl_easy_ * -funktion på et curl_multi_ * håndtag ser nu forkert ud, se funktionsnavne på http://curl.haxx.se/libcurl/c/
Hvis du holder reglerne for eksporterede symboler, skal du bruge dem til statiske funktioner i #include
ed-filer: Prøv at finde et fælles præfiks til disse funktioner. Måske har du statiske strengværktøjsfunktioner i en fil kaldet “my_string”? Prefix alle disse funktioner med my_string_ *.
Kommentarer
- Med eksporterede symboler mener du globale variabler, funktioner, typedefs osv., Hvis jeg har ret. Kan du forklare lidt om gruppering af de eksporterede symboler? Jeg troede, du forklarede det allerede i forrige afsnit. Hvad tilføjede du i 3. afsnit?
order.c
, kan du navngive funktionerneorder_add()
,order_del()
og lignende. Der kan være gamle systemer, der fortæller dig, at navnet skal være unikt inden for de første 8 tegn. Når du skifter til c ++ senere ved et uheld, vil du ' elske at skriveorder::add()
ogorder::del()
derefter.