Opmerkingen
Antwoord
Als ik doorga meer code schrijven dan dat er een tijd zal zijn dat het moeilijk zal zijn om de code te ordenen.
Dit is jouw probleem: zorg voor de juiste organisatie, en de stijl zou gemakkelijker moeten stromen.
wacht niet met het organiseren van uw code: houd uw code georganiseerd terwijl u bezig bent. Hoewel de taal het niet voor u doet, code moet nog steeds worden georganiseerd in modules met een lage koppeling en een hoge cohesie.
Deze modules bieden dan natuurlijk een naamruimte. Kort de modulenaam af (als deze lang is) en voeg functienamen toe aan hun module om botsingen te voorkomen.
Op het niveau van individuele identificatoren zijn deze ruwweg in oplopende volgorde van subjectiviteit:
- kies een conventie en blijf erbij
- bijv.
function_like_this(struct TypeLikeThis variable)
is gebruikelijk
- bijv.
-
vermijd zeker de Hongaarse notatie (sorry JNL)
-
tenzij je bereid bent om het te gebruiken zoals oorspronkelijk bedoeld, wat de apps -notatie van Simonyi betekent in plaats van de verschrikkelijke systeemversie
Waarom? Ik zou hier een essay over kunnen schrijven, maar in plaats daarvan raad ik je aan om dit artikel van Joel Spolsky te lezen, en dan nog wat rond te jagen als je geïnteresseerd bent. Er staat onderaan een link naar het originele papier van Simonyi.
-
-
Vermijd pointer-typedefs tenzij het echt ondoorzichtige soorten cookies zijn – ze zijn alleen dingen verwarren
struct Type *ok; typedef struct Type *TypePtr; TypePtr yuck;
Wat bedoel ik met een ondoorzichtig type cookie ? Ik bedoel iets dat in een module (of bibliotheek, of wat dan ook) die moet worden doorgegeven aan de clientcode, maar die clientcode kan “t gebruiken rechtstreeks. Het geeft het gewoon terug aan de bibliotheek.
Een databasebibliotheek kan bijvoorbeeld een interface weergeven zoals
/* 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, de context is ondoorzichtig voor de clientcode, omdat je “niet naar binnen kunt kijken. Je geeft het gewoon terug aan de bibliotheek. Iets als
FILE
is ook ondoorzichtig, en een integer bestandsdescriptor is ook een cookie , maar is niet “ondoorzichtig.
Een opmerking over ontwerp
Ik heb de uitdrukking lage koppeling en hoge cohesie hierboven zonder uitleg gebruikt, en daar voel ik me een beetje rot over. U kunt ernaar zoeken en waarschijnlijk enkele goede resultaten vinden, maar ik zal proberen er kort op in te gaan (nogmaals, ik zou een essay kunnen schrijven, maar ik zal proberen het niet te doen).
De hierboven geschetste DB-bibliotheek toont lage koppeling omdat het een kleine interface aan de buitenwereld blootstelt. Door de implementatiedetails te verbergen (deels met de ondoorzichtige cookietruc), wordt voorkomen dat clientcode afhankelijk wordt van die details.
Stel je voor dat in plaats van de ondoorzichtige cookie, we de contextstructuur declareren zodat de inhoud zichtbaar is, inclusief een socket-bestandsdescriptor voor een TCP-verbinding met de database. Als we vervolgens de implementatie wijzigen om het gebruik van een gedeeld geheugensegment te ondersteunen wanneer de DB draait op dezelfde machine, de client moet opnieuw worden gecompileerd in plaats van alleen opnieuw te koppelen. Erger nog, de client had kunnen beginnen met de bestandsdescriptor, bijvoorbeeld door setsockopt
om de standaard buffergrootte te wijzigen, en nu moet de code ook worden gewijzigd. Al deze details ils zouden waar praktisch in onze module verborgen moeten zijn, en dit geeft een lage koppeling tussen modules.
Het voorbeeld toont ook hoge cohesie , in die zin dat alle methoden in de module hebben betrekking op dezelfde taak (DB-toegang). Dit betekent dat alleen de code die nodig heeft om op de hoogte te zijn van de implementatiedetails (dat wil zeggen de inhoud van onze cookie) er daadwerkelijk toegang toe heeft, wat het debuggen vereenvoudigt.
Je kunt ook zien dat het hebben van een enkele zorg het gemakkelijk maakte om een voorvoegsel te kiezen om deze functies samen te groeperen.
Het is gemakkelijk om te zeggen dat dit voorbeeld goed is (vooral omdat het niet “zelfs niet compleet), maar helpt je niet meteen. De truc is om, terwijl je je code schrijft en uitbreidt, te kijken naar functies die soortgelijke dingen doen of op dezelfde typen werken (die kandidaten kunnen zijn voor hun eigen module), en ook naar functies die veel verschillende dingen doen die niet ” t echt gerelateerd, en kunnen kandidaten zijn om uit elkaar te gaan.
Reacties
- Kun je me helpen begrijpen waarom Hongaars wordt vermeden? Gewoon nieuwsgierig naar meer erover. 🙂
- @JNL: een opmerking is te kort om goed uit te leggen. Ik stel voor dat je het als een nieuwe vraag plaatst.
-
with low coupling and high cohesion
. Wat betekent dat? En leg alsjeblieft uit wat ondoorzichtige soorten cookies zijn. Ik heb geen idee wat dat betekent. - Ik heb geprobeerd beide kort te behandelen, maar ik slaagde er eerlijk gezegd niet kort in. Hopelijk krijg je begonnen.
- Ik reageer na een paar dagen. Sorry daarvoor. Ik heb je beschrijving van
low coupling and high cohesion
gelezen. Dus het betekent in feite dingen inkapselen wanneer ik kan en het moet worden gedaan op een manier dat de functies die werkelijk nodig zijn, zouden toegang moeten hebben. Sommige dingen gingen mijn hoofd te boven, maar toch denk ik dat ik je punt begreep.
Antwoord
Naar mijn mening 90 % van het naamgevingsprobleem is opgelost als u drie dingen in gedachten houdt: a) maak uw variabelen en functienamen zo beschrijvend als mogelijk, b) consistent zijn in uw code (als een functie de naam addNumbers heeft, moet een tweede functie de naam multiplyNumbers krijgen en niet numbersMul) en c) probeer de namen indien mogelijk kort te maken, aangezien we ze moeten typen.
Dat gezegd hebbende, als je andere aspecten van dit onderwerp wilt bekijken, heeft de Wikipedia-pagina op Naamgevingsconventies een goede lijst met dingen die je zou moeten doen onthoud. Het heeft ook een sectie op C en C ++:
In C en C ++ zijn trefwoorden en standaard bibliotheek-IDs meestal in kleine letters. In de C-standaardbibliotheek zijn afgekorte namen de meest voorkomende (bijv. Isalnum voor een functie die test of een teken alfanumeriek is), terwijl de C ++ -standaardbibliotheek vaak een onderstrepingsteken als woordscheidingsteken gebruikt (bijv. Out_of_range). Identificatoren die macros vertegenwoordigen, worden, volgens afspraak, geschreven met alleen hoofdletters en onderstrepingstekens (dit heeft te maken met de conventie in veel programmeertalen om identifiers uit alle hoofdletters te gebruiken voor constanten). Namen die een dubbel onderstrepingsteken bevatten of beginnen met een onderstrepingsteken en een hoofdletter zijn gereserveerd voor implementatie (compiler, standaardbibliotheek) en mogen niet worden gebruikt (bijv. Reserved__ of _Reserved). [5] [6] Dit lijkt oppervlakkig op stropping, maar de semantiek verschilt: de onderstrepingstekens maken deel uit van de waarde van de identifier, in plaats van aanhalingstekens te zijn (zoals stropping): de waarde van __foo is __foo (wat gereserveerd is), niet foo (maar in een andere naamruimte).
Reacties
- " probeer de namen indien mogelijk kort te maken " Gebruik een IDE met automatische aanvulling, dan kunnen uw functienamen zo lang en beschrijvend zijn als nodig is, zoals u alleen nodig hebt om dan een keer te typen.
- @Joel vreselijk advies. Niet iedereen zal dezelfde IDE gebruiken als jij.
- @James Dat hoeven ze ' niet, ze kunnen gewoon elke fatsoenlijke IDE gebruiken. Dan hoef je ' geen duidelijkheid op te offeren voor productiviteit.
- De term IDE is tegenwoordig een beetje dun uitgerekt. Technisch gezien is Notepad ++ een IDE omdat je het kunt configureren om je project te compileren en uit te voeren, maar het ' is in de eerste plaats een teksteditor. En het wordt automatisch aangevuld.
Answer
De enige harde beperking in C is dat er geen naamruimten zijn. Daarom moet je een manier vinden om de rename()
-functie van je bestandssysteem -bibliotheek te onderscheiden van de rename()
functie van uw media bibliotheek. De gebruikelijke oplossing is een voorvoegsel, zoals: filesystem_rename()
en media_rename()
.
Het andere algemene advies is: blijf consistent binnen een project of team. De leesbaarheid wordt verbeterd.
Opmerkingen
- +1: dat geldt vooral voor geëxporteerde symbolen in een bibliotheek. " Het spijt me, maar die bestandssysteembibliotheek past niet bij die mediabibliotheek, omdat beide een geëxporteerde functie hernoemen.
Antwoord
ALS JE OP ZOEK NAAR EEN WERELDWIJDE AANVAARD FORMAAT
MISRA / JSF / AUTOSAR dekt bijna 100% van elke industriestandaard voor het benoemen en organiseren van C / C ++ – code. Het probleem is dat ze niet gratis te verkrijgen zijn, d.w.z. dat elk van de reisgidsen wat geld kost. Ik weet dat het standaardboek voor codering van MISRA 2008 C / C ++ waarschijnlijk ongeveer 50 USD kost.
U kunt deze beschouwen als de Harvard Referencing voor bibliografie en het lezen van aanvullingen wanneer u een tijdschrift schrijft. Ik heb MISRA gebruikt en het is een goede manier om je functies en variabelen een naam te geven en ze te ordenen voor correct gebruik.
ALS JE IETS TIJDELIJK ZOEKT
De referenties die je hebt opgegeven voor Python en Java zijn oké, denk ik. Ik heb mensen javadoc-achtige commentaren, naamgeving en het ordenen van code zien aannemen. In mijn laatste project moest ik trouwens C ++ – code schrijven in Java-achtige functies / variabelenamen. Twee redenen hiervoor:
1) Het was blijkbaar gemakkelijker te volgen.
2) Productiecode-eisen raakten de grond van veiligheidskritische softwaresysteemstandaarden niet.
3) Legacy-code had (ergens) dat formaat.
4) Doxygen stond Javadoc-sytle-commentaar toe. Op dat moment gebruikten we doxygen om documentatie voor de productiemensen te genereren.
Veel programmeurs zullen hier tegenstander van zijn, maar persoonlijk denk ik dat er niets mis is met het adopteren van javadoc-stijlfunctie / variabelenamen in C / C ++. JA NATUURLIJK, de praktijken van het organiseren van uw stroomregeling, draadveiligheid, enz. Moeten hoe dan ook worden aangepakt. Ik ben hier echter geen sollicitant. Ik weet ook niet hoe streng de vereisten voor de indeling van uw productiecode zijn. Zonder het om te leiden naar een gebied dat niet op het onderwerp ligt, raad ik u aan uw vereisten te herzien, uit te zoeken hoe afhankelijk u bent van een specifieke naamgevingsconventie en een oplossing te kiezen die wordt genoemd in de mijne en anderen “antwoorden
Ik hoop dat dit heeft geholpen !?
Reacties
- Eigenlijk vroeg ik dit om persoonlijke C-codes . Maar ik ' onthoud je suggestie.
- @AseemBansal Persoonlijk of professioneel, die zijn goed om te leren en ook goed om op je cv te zetten 🙂 … . Aan jou.
Antwoord
Er zijn maar weinig belangrijke dingen waarmee je rekening moet houden bij het benoemen zijn:
-
Bekijk het type actionObject of ObjectAction. (Object niet voor C. Maar in het algemeen als je naar andere objectgeoriënteerde talen gaat) Dit zou moeten helpen
-
De rest zou consistent, kort en zeker beschrijvend zijn.
- een enig doel van elke gedefinieerde variabele en functie, bijv.: als het is om een waarde tijdelijk op te slaan, noem deze dan als nTempVal voor int.
- Variabelen moeten een zelfstandig naamwoord zijn en methoden moeten werkwoord zijn.
Opmerkingen
- Hongaarse notatie (voorvoegsel aan een variabele met letters die het type aanduiden) leidt tot eindeloos veel pijn. Het is gelukkig grotendeels uit de mode geraakt.
- @StevenBurnap Was gewoon nieuwsgierig waarom het Hongaarse formaat wordt vermeden? Ik geloof dat ' is wat ze ons op school hebben geleerd en ik heb dergelijke code ook op sommige werkplekken gezien. Welke zou je aanbevelen, zo niet Hongaars. Bedankt
- De beste naamgevingsconventie is er slechts een die consequent wordt gebruikt, met duidelijke, beschrijvende namen die idealiter relatief kort worden gehouden zonder overmatige afkortingen en het vermijden van overbodige voorvoegsels. Hongaarse notatie heeft eigenlijk weinig nut, maakt code moeilijker te lezen en maakt het moeilijker om van type te veranderen.
- Hier is een beschrijving van de oorspronkelijke bedoeling en de gruwel die de Hongaarse notatie is geworden: joelonsoftware.com/articles/Wrong.html
- @Residuum Dat was een goede link. Veel geholpen. Waardeer het.
Antwoord
De meeste antwoorden zijn goed, maar ik wil een paar dingen zeggen over naamgeving conventies voor bibliotheken en opgenomen bestanden, vergelijkbaar met het gebruik van naamruimten in andere talen zoals C ++ of Java:
Als u een bibliotheek bouwt, zoek dan een gemeenschappelijk voorvoegsel voor uw geëxporteerde symbolen, dwz globale functies, typedefs en variabelen. Dit voorkomt botsingen met andere bibliotheken en identificeert de functies als afkomstig van de uwe. Dit is een klein beetje Hongaarse notaties voor apps.
Ga misschien nog verder en groepeer je geëxporteerde symbolen: libcurl gebruikt curl_ * voor globale symbolen, curl_easy_ *, curl_multi_ *, en curl_share_ * voor de verschillende interfaces.Dus naast het gebruik van curl_ * voor alle functies, hebben ze een ander niveau van “namespaces” toegevoegd voor de verschillende interfaces: het aanroepen van een curl_easy_ * -functie op een curl_multi_ * -handle ziet er nu verkeerd uit, zie de functienamen op http://curl.haxx.se/libcurl/c/
Houd de regels voor geëxporteerde symbolen bij, je moet deze gebruiken voor statische functies in #include
ed-bestanden: probeer een algemeen voorvoegsel voor deze functies te vinden. Misschien heb je statische hulpprogrammas voor tekenreeksen in een bestand met de naam “my_string”? Voeg my_string_ * toe aan al deze functies.
Reacties
- Met geëxporteerde symbolen bedoel je globale variabelen, functies, typefs etc. als ik het goed heb. Kun je uitleggen hoe je de geëxporteerde symbolen groepeert? Ik dacht dat je dat al in de vorige paragraaf had uitgelegd. Wat heb je toegevoegd in de derde alinea?
order.c
is, zou je de functiesorder_add()
,order_del()
en dergelijke. Er kunnen oude systemen zijn die u vertellen dat de naam uniek moet zijn binnen de eerste 8 tekens. Wanneer je later per ongeluk naar c ++ overschakelt, ' zal je graagorder::add()
enorder::del()
dan.