Navngivningskonvensjoner brukt for variabler og funksjoner i C [lukket]

Stengt. Dette spørsmålet er utenfor emnet . Det aksepteres for øyeblikket ikke svar.

Kommentarer

  • Nevn noen eksempler på språk med foreslåtte navnekonvensjoner. Og hvor vi kan finne disse navnekonvensjonene.
  • @Philip Lagt til eksempler
  • Det burde ikke være ' ikke et problem med variabler når du ikke ' ikke bruk globaler. Og for funksjonsnavn: Hvis modulen ' heter order.c, kan du gi navn til funksjonene order_add(), order_del() og slikt. Det kan være gamle systemer som forteller deg at navnet må være unikt innen de første 8 tegnene. Når du bytter til c ++ senere ved et uhell, vil du ' gjerne skrive order::add() og order::del() da.

Svar

Hvis jeg fortsetter å skrive mer kode, så vil det være en tid da det vil være vanskelig for meg å organisere koden.

Dette er problemet ditt: få organisasjonen riktig, og stilen skal flyte lettere.

Ikke vent for å organisere koden din: hold koden din organisert mens du går. Selv om språket ikke gjør det for deg, kode bør fortsatt være organisert i moduler med lav kobling og høy kohesjon.

Disse modulene gir da naturlig et navneområde. Forkort modulnavnet (hvis det er langt) og prefiks funksjonsnavn med modulen for å unngå kollisjoner.

På nivået til individuelle identifikatorer er disse omtrent i økende rekkefølge av subjektivitet:

  1. velg en konvensjon og hold deg til den
    • f.eks. function_like_this(struct TypeLikeThis variable) er vanlig
  2. absolutt unngå ungarsk notasjon (beklager JNL)

    • med mindre du «er villig til å bruke den som opprinnelig ment, noe som betyr Simonyis apps notasjon i stedet for den forferdelige systemversjonen

      Hvorfor? Jeg kunne skrive et essay om dette, men jeg vil i stedet foreslå at du leser denne artikkelen av Joel Spolsky, og så jakter på litt til hvis du er interessert. Det er en lenke til Simonyis originale papir nederst.

  3. Unngå pekertypetypene med mindre de egentlig er ugjennomsiktige informasjonskapseltyper – de bare forvirre ting

    struct Type *ok; typedef struct Type *TypePtr; TypePtr yuck; 

    Hva mener jeg med en ugjennomsiktig cookietype ? Jeg mener noe som brukes i en modul (eller et bibliotek, eller hva som helst som må overføres til klientkode, men klientkoden kan «t bruke direkte. Den sender den bare tilbake til biblioteket.

    For eksempel kan et databasebibliotek avsløre et grensesnitt 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); 

    Nå, konteksten er ugjennomsiktig for klientkoden, fordi du ikke kan se innover. Du sender den bare tilbake til biblioteket. Noe som FILE er også ugjennomsiktig, og en helfilsbeskrivelse er også en informasjonskapsel , men er ikke ugjennomsiktig.


En merknad om design

Jeg brukte uttrykket lav kobling og høy kohesjon ovenfor uten forklaring, og føler meg litt dårlig om det. Du kan søke etter det, og sannsynligvis finne noen gode resultater, men jeg prøver å adressere det kort (igjen, jeg kan skrive et essay, men vil prøve å ikke gjøre det).

DB-biblioteket som er skissert over viser lav kobling fordi den utsetter et lite grensesnitt mot omverdenen. Ved å skjule implementeringsdetaljene (delvis med det ugjennomsiktige informasjonskapseltrikset), forhindrer det at klientkoden kommer til å avhenge av disse detaljene.

Tenk deg i stedet for den ugjennomsiktige informasjonskapselen, erklærer vi kontekststrukturen slik at innholdet er synlig, og det inkluderer en sokkelfilbeskrivelse for en TCP-forbindelse til databasen. Hvis vi deretter endrer implementeringen for å støtte ved hjelp av et delt minnesegment når DB kjører på samme maskin, klienten må kompileres på nytt i stedet for bare å kobles på nytt. Enda verre, klienten kunne ha startet å bruke filbeskrivelsen, for eksempel å ringe setsockopt for å endre standard bufferstørrelse, og nå trenger den også en kodeendring. Alle disse deta ils skal være skjult inne i modulen vår der det er praktisk, og dette gir lav kobling mellom moduler.

Eksemplet viser også høy kohesjon ved at alle metodene i modulen er opptatt av den samme oppgaven (DB-tilgang). Dette betyr at bare koden trenger for å vite om implementeringsdetaljene (det vil si innholdet i informasjonskapselen vår) som faktisk har tilgang til dem, noe som forenkler feilsøking.

Du kan også se at det å ha et enkelt anliggende gjorde det enkelt å velge et prefiks for å gruppere disse funksjonene.

Nå er det enkelt å si at dette eksemplet er bra (spesielt fordi det ikke er «t engang komplett), men hjelper deg ikke umiddelbart. Trikset er å se på, mens du skriver og utvider koden, for funksjoner som gjør lignende ting eller opererer på de samme typene (som kan være kandidater til sin egen modul), og også for funksjoner som gjør mange separate ting som ikke er » er ikke veldig relatert, og kan være kandidater til å dele opp.

Kommentarer

  • Kan du hjelpe meg med å forstå hvorfor ungarsk unngås? Bare nysgjerrig på å vite mer om det. 🙂
  • @JNL: En kommentar er for kort til å kunne forklares ordentlig. Jeg foreslår at du legger den ut som et nytt spørsmål.
  • with low coupling and high cohesion. Hva betyr det? Og vær så snill å forklare om ugjennomsiktige informasjonskapsler. Jeg aner ikke hva det betyr.
  • Jeg prøvde å adressere begge kort, og mislyktes ærlig talt kort. Forhåpentligvis skulle det få deg startet skjønt.
  • Jeg svarer etter noen dager. Beklager det. Jeg har lest beskrivelsen av low coupling and high cohesion. Så det betyr i utgangspunktet å kapsle ting når jeg kan og det skal gjøres på en måte som funksjoner som faktisk trenger, skal ha tilgang. Noen ting gikk over hodet på meg, men jeg tror fremdeles at jeg har poenget ditt.

Svar

Etter min mening 90 % av navneproblemet er løst hvis du husker tre ting: a) gjør variabel- og funksjonsnavnene dine så beskrivende som mulig, b) være konsistent i hele koden din (dvs. hvis en funksjon heter addNumbers, bør en annen funksjon hete multiplyNumbers og ikke numbersMul) og c) prøver å gjøre navnene korte hvis mulig, da vi trenger å skrive dem.

Når det er sagt hvis du vil se på andre aspekter om dette emnet, har Wikipedia-siden på Navngivningskonvensjoner en god liste over ting du bør Husk. Den har også en sekjon på C og C ++:

I C og C ++ er nøkkelord og standard bibliotekidentifikatorer stort sett små bokstaver. I C-standardbiblioteket er forkortede navn de vanligste (f.eks. Isalnum for en funksjon som tester om et tegn er alfanumerisk), mens C ++ -standardbiblioteket ofte bruker understrek som ordskiller (f.eks. Out_of_range). Identifikatorer som representerer makroer, er, etter konvensjon, skrevet med bare store bokstaver og understrekninger (dette er relatert til konvensjonen i mange programmeringsspråk for bruk av store bokstaver for konstanter). Navn som inneholder dobbelt understrek eller begynner med understrek og stor bokstav er reservert for implementering (kompilator, standardbibliotek) og bør ikke brukes (f.eks. Reservert__ eller _Reservert). [5] [6] Dette ligner overflatisk på stropping, men semantikken er forskjellig: understrekningene er en del av verdien til identifikatoren, i stedet for å sitere tegn (som stropping): verdien av __foo er __foo (som er reservert), ikke foo (men i et annet navneområde).

Kommentarer

  • " prøv å gjøre navnene korte hvis mulig " Bruk en IDE med automatisk fullføring, så kan funksjonsnavnene dine være så lange og beskrivende som de trenger å være som du bare trenger å skrive en gang.
  • @Joel forferdelige råd. Ikke alle vil bruke samme IDE som deg.
  • @James De trenger ikke ' de trenger ikke, de kan bare bruke hvilken som helst anstendig IDE. Da trenger du ikke ' å ofre klarhet for produktivitet.
  • Begrepet IDE strekkes litt tynn nå om dagen. Teknisk er Notepad ++ en IDE fordi du kan konfigurere den til å kompilere og kjøre prosjektet, men det ' er først og fremst en tekstredigerer. Og den fullføres automatisk.

Svar

Den eneste harde begrensningen i C er at det ikke er noen navneområder. Derfor må du finne en måte å skille rename() -funksjonen til filsystem -biblioteket ditt fra rename() funksjonen til media biblioteket ditt. Den vanlige løsningen er et prefiks, for eksempel: filesystem_rename() og media_rename().

Det andre generelle rådet er: opphold konsistent i et prosjekt eller et team. Lesbarheten forbedres.

Kommentarer

  • +1: Dette gjelder spesielt for eksporterte symboler i et bibliotek. " Jeg beklager, men at filsystembiblioteket ikke følger med det mediebiblioteket, fordi begge har et eksportert funksjonsnavn.

Svar

HVIS DU LETER GLOBALT AKSepterT FORMAT

MISRA / JSF / AUTOSAR dekker nesten 100% av enhver bransjestandard for navngivning og organisering av C / C ++ -kode. Problemet er at de ikke vil være gratis å få tak i, dvs. hver av guidebøkene koster litt penger. Jeg vet at MISRA 2008 C / C ++ koding standardbok sannsynligvis koster ca 50 USD.

Du kan tenke på disse som Harvard Referencing for bibliografi og tilleggslesing når du skriver en journal. Jeg har brukt MISRA, og det er en god måte å navngi funksjonene og variablene dine, og organisere dem for riktig bruk.

HVIS DU LETTER TIDLIGT MIDLERTIDIG

Referansene du ga for Python og Java er greit antar jeg. Jeg har sett folk vedta javadoc-stil, kommentere, navngi og organisere kode. Faktisk, i mitt siste prosjekt, måtte jeg skrive C ++ – kode i Java-lignende funksjoner / variabelnavn. To grunner bak dette:

1) Det var tilsynelatende lettere å følge.

2) Krav til produksjonskoder berørte ikke bakken for sikkerhetskritiske programvaresystemstandarder.

3) Eldre kode var (på en eller annen måte) i det formatet.

4) Doxygen tillot Javadoc-systemkommentarer. For øyeblikket brukte vi doxygen til å generere dokumentasjon for produksjonsgutta.

Mange programmerere vil være motstandere av dette, men jeg personlig mener at det ikke er noe galt med å ta i bruk javadoc-stilfunksjon / variabel navngivning i C / C ++. JA AV KURS, må praksis for å organisere strømningskontroll, trådsikkerhet osv. Behandles uansett. Imidlertid er jeg ikke søker her. Jeg vet ikke hvor strenge kravene til produksjonskodeformatet ditt er. Uten å omdirigere det til et område utenfor emnet, foreslår jeg at du går gjennom kravene dine, finner ut hvor avhengig du er av en spesifikk navnekonvensjon, og følger en løsning i mine og andre «svar

Håper dette hjalp !?

Kommentarer

  • Egentlig ba jeg dette om personlige C-koder . Men jeg ' Husker ditt forslag.
  • @AseemBansal Personlig eller profesjonell, de er gode å lære og også gode å sette på CVen din 🙂 … . Opp til deg.

Svar

Få viktige ting du bør vurdere når du navngir, vil være;

  1. Se på actionObject eller ObjectAction-typen. (Objekt ikke for C. Men generelt når du går til andre objektorienterte språk) Dette burde hjelpe

  2. Hvile vil være VÆRE KONSEKVENT, kort og beskrivende helt sikkert.

  3. Har også et eneste formål med alle variabler og funksjoner som er definert, f.eks. Hvis det er å lagre en verdi midlertidig, kan du gi den navnet nTempVal for int
  4. Variabler skal være substantiv og metoder skal være verb. >

    Kommentarer

    • Ungarsk notasjon (foran en variabel med bokstaver som angir typen) fører til at slutten på smerte ikke slutter. Heldigvis har det for det meste gått av moten.
    • @StevenBurnap Var bare nysgjerrig på hvorfor unngås ungarsk format? Jeg tror at ' er det de lærte oss på skolen, og jeg har sett en slik kode også på noen arbeidsplasser. Hvilken vil du anbefale hvis ikke ungarsk. Takk
    • Den beste navngivningskonvensjonen er bare en konsekvent brukt, med klare, beskrivende navn ideelt sett holdt relativt korte uten overdreven forkortelse og unngår overflødige prefikser. Ungarsk notasjon har liten faktisk nytte, gjør koden vanskeligere å lese og gjør skiftende typer vanskeligere.
    • Her er en beskrivelse av den opprinnelige hensikten og avskyen som den ungarske notasjonen har blitt: joelonsoftware.com/articles/Wrong.html
    • @ Residuum Det var en god lenke. Hjalp mye. Setter pris på det.

Svar

De fleste svarene er gode, men jeg vil si noen ting om navngivning konvensjoner for biblioteker og inkluderte filer, som ligner på å bruke navneområder på andre språk som C ++ eller Java:

Hvis du bygger et bibliotek, finn et vanlig prefiks for de eksporterte symbolene, dvs. globale funksjoner, typeforhold og variabler. Dette vil forhindre sammenstøt med andre biblioteker og identifisere funksjonene som kommer fra din. Dette er litt apper for ungarske notasjoner.

Kanskje gå enda lenger og gruppere de eksporterte symbolene: libcurl bruker curl_ * for globale symboler, curl_easy_ *, curl_multi_ * og curl_share_ * for de forskjellige grensesnittene.Så i tillegg til å bruke curl_ * for alle funksjoner, har de lagt til et annet nivå med «navnerom» for de forskjellige grensesnittene: Å ringe en curl_easy_ * -funksjon på et curl_multi_ * håndtak ser nå feil ut, se funksjonsnavnene på http://curl.haxx.se/libcurl/c/

Hvis du holder reglene for eksporterte symboler, bør du bruke dem til statiske funksjoner i #include ed-filer: Prøv å finne et vanlig prefiks for disse funksjonene. Kanskje du har statiske strengfunksjoner i en fil som heter «min_string»? Prefiks alle funksjonene med my_string_ *.

Kommentarer

  • Med eksporterte symboler mener du globale variabler, funksjoner, typedefs etc. hvis jeg har rett. Kan du forklare litt om gruppering av de eksporterte symbolene? Jeg trodde du forklarte det allerede i forrige avsnitt. Hva la du til i tredje ledd?

Legg igjen en kommentar

Din e-postadresse vil ikke bli publisert. Obligatoriske felt er merket med *