Namenskonventionen für Variablen und Funktionen in C [geschlossen]

geschlossen. Diese Frage ist nicht zum Thema . Derzeit werden keine Antworten akzeptiert.

Kommentare

  • Nennen Sie einige Beispiele für Sprachen mit vorgeschlagenen Namenskonventionen. Und wo wir diese Namenskonventionen finden können.
  • @Philip Beispiele hinzugefügt
  • ' sollte kein Problem mit Variablen sein, wenn Sie dies nicht tun ' Verwenden Sie keine Globals. Und für Funktionsnamen: Wenn der Name des Moduls ' order.c lautet, können Sie die Funktionen order_add(), order_del() und so weiter. Möglicherweise gibt es alte Systeme, die Ihnen mitteilen, dass der Name innerhalb der ersten 8 Zeichen eindeutig sein muss. Wenn Sie später versehentlich zu c ++ wechseln, werden Sie ' gerne order::add() und order::del() dann.

Antwort

Wenn ich weitermache Wenn ich mehr Code schreibe, wird es eine Zeit geben, in der es für mich schwierig sein wird, den Code zu organisieren.

Dies ist Ihr Problem: Machen Sie die Organisation richtig, und der Stil sollte leichter fließen.

Warten Sie nicht, , um Ihren Code zu organisieren: Halten Sie Ihren Code organisiert, während Sie gehen. Obwohl die Sprache dies nicht für Sie tut, Code sollte weiterhin in Modulen mit geringer Kopplung und hoher Kohäsion organisiert sein.

Diese Module stellen dann natürlich einen Namespace bereit. Kürzen Sie den Modulnamen (falls er lang ist) und die Präfixfunktionsnamen mit ihrem Modul ab, um Kollisionen zu vermeiden.

Auf der Ebene der einzelnen Bezeichner sind diese ungefähr in aufsteigender Reihenfolge der Subjektivität:

  1. Wählen Sie eine Konvention und bleiben Sie dabei
    • z. B. function_like_this(struct TypeLikeThis variable) ist häufig
  2. Vermeiden Sie auf jeden Fall die ungarische Notation (sorry JNL)

    • , es sei denn, Sie sind bereit, sie wie ursprünglich beabsichtigt zu verwenden, was bedeutet, dass Simonyis Apps -Notation statt die schreckliche Systemversion

      Warum? Ich könnte einen Aufsatz darüber schreiben, aber ich schlage stattdessen vor, dass Sie diesen Artikel von Joel Spolsky lesen und dann bei Interesse noch etwas herumjagen. Unten befindet sich ein Link zu Simonyis Originalpapier.

  3. Vermeiden Sie Zeigertypedefs, es sei denn, sie sind wirklich undurchsichtige Cookie-Typen – nur sie Dinge verwirren

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

    Was meine ich mit einem undurchsichtigen Cookie-Typ ? Ich meine etwas, das in einem Modul (oder einer Bibliothek oder verwendet wird) was auch immer), das an den Client-Code weitergegeben werden muss, aber dieser Client-Code kann nicht direkt verwendet werden. Es wird nur an die Bibliothek zurückgegeben.

    Beispielsweise kann eine Datenbankbibliothek eine Schnittstelle wie

    /* 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); 

    Nun den Kontext verfügbar machen ist für den Client-Code undurchsichtig , da Sie nicht hineinschauen können. Sie geben ihn einfach an die Bibliothek zurück. So etwas wie FILE ist ebenfalls undurchsichtig Ein Integer-Dateideskriptor ist ebenfalls ein Cookie , jedoch nicht undurchsichtig.


Ein Hinweis zum Design

Ich habe den Ausdruck niedrige Kopplung und hohe Kohäsion oben ohne Erklärung verwendet, und ich fühle mich ein bisschen schlecht dabei. Sie können danach suchen und wahrscheinlich einige gute Ergebnisse finden, aber ich werde versuchen, es kurz anzusprechen (ich könnte wieder einen Aufsatz schreiben, werde es aber nicht versuchen).

Die oben skizzierte DB-Bibliothek zeigt niedrige Kopplung , da dadurch eine kleine Schnittstelle zur Außenwelt verfügbar gemacht wird. Durch das Ausblenden der Implementierungsdetails (teilweise mit dem undurchsichtigen Cookie-Trick) wird verhindert, dass Clientcode von diesen Details abhängt.

Stellen Sie sich vor, anstelle des undurchsichtigen Cookies deklarieren wir die Kontextstruktur so, dass ihr Inhalt sichtbar ist. Dazu gehört ein Socket-Dateideskriptor für eine TCP-Verbindung zur Datenbank. Wenn wir anschließend die Implementierung ändern, um die Verwendung eines gemeinsam genutzten Speichersegments zu unterstützen, wenn die Die Datenbank wird auf demselben Computer ausgeführt. Der Client muss neu kompiliert und nicht nur neu verknüpft werden. Schlimmer noch, der Client hätte mit dem Dateideskriptor starten können, z. B. mit dem Aufruf von setsockopt, um die Standardpuffergröße zu ändern, und jetzt muss auch der Code geändert werden. Alle diese Details ils sollten in unserem Modul versteckt sein, wo dies praktikabel ist, und dies führt zu einer geringen Kopplung zwischen Modulen.

Das Beispiel zeigt auch hohe Kohäsion , in der alle Methoden im Modul befassen sich mit derselben Aufgabe (DB-Zugriff). Dies bedeutet, dass nur der Code, den über die Implementierungsdetails (dh den Inhalt unseres Cookies) wissen muss, tatsächlich Zugriff darauf hat, was das Debuggen vereinfacht.

Sie können auch sehen, dass es mit einem einzigen Anliegen einfach war, ein Präfix zum Gruppieren dieser Funktionen auszuwählen.

Nun ist es einfach zu sagen, dass dieses Beispiel gut ist (zumal es nicht so ist) „noch nicht einmal vollständig), hilft dir aber nicht sofort. Der Trick besteht darin, beim Schreiben und Erweitern Ihres Codes auf Funktionen zu achten, die ähnliche Aufgaben ausführen oder mit denselben Typen arbeiten (die möglicherweise Kandidaten für ein eigenes Modul sind), sowie auf Funktionen, die viele separate Aufgaben ausführen, die nicht vorhanden sind. “ t wirklich verwandt und könnte Kandidaten für eine Trennung sein.

Kommentare

  • Können Sie mir helfen zu verstehen, warum Ungarisch vermieden wird? Nur neugierig, mehr zu wissen darüber. 🙂
  • @JNL: Ein Kommentar ist zu kurz, um ihn richtig zu erklären. Ich schlage vor, Sie stellen ihn als neue Frage.
  • with low coupling and high cohesion. Was bedeutet das? Und bitte erläutern Sie undurchsichtige Cookie-Typen. Ich habe keine Ahnung, was das bedeutet.
  • Ich habe versucht, beide kurz anzusprechen, und bin offen gesagt in Kürze gescheitert. Hoffentlich sollte es Ihnen helfen Ich habe jedoch nach ein paar Tagen geantwortet. Entschuldigung. Ich habe Ihre Beschreibung von low coupling and high cohesion gelesen. Das bedeutet also im Grunde, Dinge zu kapseln, wenn ich kann und es sollte so gemacht werden, dass die Funktionen, die tatsächlich benötigt werden, sollten Zugriff haben. Einige Dinge gingen mir über den Kopf, aber ich glaube immer noch, dass ich Ihren Standpunkt verstanden habe.

Antwort

Meiner Meinung nach 90 % des Namensproblems ist gelöst, wenn Sie drei Dinge beachten: a) Machen Sie Ihre Variablen- und Funktionsnamen so beschreibend wie Möglicherweise ist b) im gesamten Code konsistent (dh wenn eine Funktion den Namen addNumbers trägt, sollte eine zweite Funktion multiplyNumbers heißen und nicht numbersMul) und c) versuchen, die Namen möglichst kurz zu machen, da wir sie eingeben müssen.

Wenn Sie sich jedoch andere Aspekte zu diesem Thema ansehen möchten, finden Sie auf der Wikipedia-Seite unter Namenskonventionen eine gute Liste von Dingen, die Sie sollten merken Sie sich. Es gibt auch einen Abschnitt in C und C ++:

In C und C ++ werden Schlüsselwörter und Standardbibliothekskennungen meist in Kleinbuchstaben geschrieben. In der C-Standardbibliothek sind abgekürzte Namen am häufigsten (z. B. isalnum für eine Funktion, die prüft, ob ein Zeichen alphanumerisch ist), während die C ++ – Standardbibliothek häufig einen Unterstrich als Worttrennzeichen verwendet (z. B. out_of_range). Bezeichner, die Makros darstellen, werden konventionell nur mit Großbuchstaben und Unterstrichen geschrieben (dies hängt mit der Konvention in vielen Programmiersprachen zusammen, Bezeichner in Großbuchstaben für Konstanten zu verwenden). Namen, die einen doppelten Unterstrich enthalten oder mit einem Unterstrich und einem Großbuchstaben beginnen, sind für die Implementierung reserviert (Compiler, Standardbibliothek) und sollten nicht verwendet werden (z. B. reserviert__ oder reserviert). [5] [6] Dies ähnelt oberflächlich dem Strippen, aber die Semantik unterscheidet sich: Die Unterstriche sind Teil des Werts des Bezeichners, anstatt Zeichen zu zitieren (wie das Strippen): Der Wert von __foo ist __foo (das reserviert ist), nicht foo (aber in einem anderen Namespace).

Kommentare

  • " Versuchen Sie, die Namen möglichst kurz zu machen. " Verwenden Sie eine IDE mit automatischer Vervollständigung. Dann können Ihre Funktionsnamen so lang und beschreibend sein, wie sie nur benötigt werden dann einmal tippen.
  • @Joel schrecklicher Rat. Nicht jeder wird dieselbe IDE wie Sie verwenden.
  • @James Sie müssen ' nicht, sie können einfach jede anständige IDE verwenden. Dann müssen Sie ' nicht auf Klarheit für Produktivität verzichten.
  • Der Begriff IDE ist heutzutage ein bisschen dünn gestreckt. Technisch gesehen ist Notepad ++ eine IDE, da Sie es so konfigurieren können, dass es Ihr Projekt kompiliert und ausführt. ' ist jedoch hauptsächlich ein Texteditor. Und es wird automatisch vervollständigt.

Antwort

Die einzige harte Einschränkung in C ist, dass es keine Namespaces gibt. Daher müssen Sie einen Weg finden, um die Funktion rename() Ihrer Dateisystembibliothek von der Funktion rename() zu unterscheiden Funktion Ihrer Medien Bibliothek. Die übliche Lösung ist ein Präfix wie: filesystem_rename() und media_rename().

Der andere allgemeine Rat lautet: bleiben konsistent innerhalb eines Projekts oder eines Teams. Die Lesbarkeit wird verbessert.

Kommentare

  • +1: Dies gilt insbesondere für exportierte Symbole in einer Bibliothek. " Es tut mir leid, aber diese Dateisystembibliothek passt nicht zu dieser Medienbibliothek, da beide eine exportierte Funktion umbenennen.

Antwort

WENN SIE GLOBAL SUCHEN AKZEPTIERTES FORMAT

MISRA / JSF / AUTOSAR deckt fast 100% aller Industriestandards zum Benennen und Organisieren von C / C ++ – Code ab. Das Problem ist, dass sie nicht kostenlos erhältlich sind, d. H. Jeder der Reiseführer kostet etwas Geld. Ich weiß, dass das Standardbuch für die C / C ++ – Codierung von MISRA 2008 wahrscheinlich etwa 50 USD kostet.

Sie können sich diese als Harvard-Referenzierung für Bibliographie und zusätzliches Lesen vorstellen, wenn Sie ein Tagebuch schreiben. Ich habe MISRA verwendet und es ist eine gute Möglichkeit, Ihre Funktionen und Variablen zu benennen und für die ordnungsgemäße Verwendung zu organisieren.

WENN SIE ETWAS VORÜBERGEHEND SUCHEN

Die Referenzen, die Sie für Python und Java angegeben haben, sind in Ordnung, denke ich. Ich habe Leute gesehen, die den Javadoc-Stil übernommen haben, um Code zu kommentieren, zu benennen und zu organisieren. Tatsächlich musste ich in meinem letzten Projekt C ++ – Code in Java-ähnlichen Funktionen / Variablennamen schreiben. Zwei Gründe dafür:

1) Es war anscheinend einfacher zu befolgen.

2) Die Anforderungen an den Produktionscode haben den Boden sicherheitskritischer Standards für Softwaresysteme nicht berührt.

3) Legacy-Code war (irgendwie) in diesem Format.

4) Doxygen erlaubte das Kommentieren von Javadoc-Systemen. In diesem Moment haben wir Doxygen verwendet, um Dokumentation für die Produktionsmitarbeiter zu generieren.

Viele Programmierer werden dagegen sein, aber ich persönlich bin der Meinung, dass es nichts Falsches ist, in C Funktionen im Javadoc-Stil / Variablennamen zu übernehmen / C ++. JA, natürlich müssen die Praktiken zur Organisation Ihrer Flusskontrolle, Thread-Sicherheit usw. unabhängig davon behandelt werden. Ich bin hier jedoch kein Bewerber. Ich weiß auch nicht, wie streng Ihre Anforderungen an das Format des Produktionscodes sind. Ohne sie auf einen Bereich außerhalb des Themas umzuleiten, empfehle ich Ihnen, Ihre Anforderungen zu überprüfen, herauszufinden, wie abhängig Sie von einer bestimmten Namenskonvention sind, und eine erwähnte Lösung zu wählen in meinen und anderen „Antworten

Hoffe, das hat geholfen!?

Kommentare

  • Eigentlich habe ich dies nach persönlichen C-Codes gefragt . Aber ich ' werde mich an Ihren Vorschlag erinnern.
  • @AseemBansal Persönlich oder beruflich, diese sind gut zu lernen und auch gut, um Ihren Lebenslauf zu erstellen 🙂 … Bis zu Ihnen.

Antwort

Einige wichtige Dinge, die bei der Benennung berücksichtigt werden müssen, sind:

  1. Sehen Sie sich den actionObject- oder ObjectAction-Typ an. (Objekt nicht für C. Aber im Allgemeinen, wenn Sie zu anderen objektorientierten Sprachen wechseln) Dies sollte helfen

  2. Ruhe wäre BESTÄNDIG, kurz und sicher beschreibend.

  3. Auch haben Ein einziger Zweck jeder definierten Variablen und Funktion, z. B.: Wenn ein Wert vorübergehend gespeichert werden soll, benennen Sie ihn als nTempVal für int
  4. Variablen sollten Nomen und Methoden Verb sein.

Kommentare

  • Die ungarische Notation (vor einer Variablen mit Buchstaben, die den Typ angeben) führt zu keinem Ende des Schmerzes. Zum Glück ist es größtenteils aus der Mode gekommen.
  • @StevenBurnap War nur neugierig, warum das ungarische Format vermieden wird? Ich glaube, dass ' das ist, was sie uns in der Schule beigebracht haben, und ich habe solchen Code auch an einigen Arbeitsplätzen gesehen. Welches würden Sie empfehlen, wenn nicht ungarisch. Danke
  • Die beste Namenskonvention ist nur eine, die konsequent verwendet wird. Klare, beschreibende Namen werden idealerweise relativ kurz gehalten, ohne übermäßige Abkürzungen und ohne Vermeidung redundanter Präfixe. Die ungarische Notation ist wenig nützlich, erschwert das Lesen von Code und erschwert das Ändern von Typen.
  • Hier finden Sie eine Beschreibung der ursprünglichen Absicht und des Gräuels, zu dem die ungarische Notation geworden ist: joelonsoftware.com/articles/Wrong.html
  • @Residuum Das war ein guter Link. Hat mir sehr geholfen. Schätzen Sie es.

Antwort

Die meisten Antworten sind gut, aber ich möchte einige Dinge zum Benennen sagen Konventionen für Bibliotheken und eingeschlossene Dateien, ähnlich der Verwendung von Namespaces in anderen Sprachen wie C ++ oder Java:

Wenn Sie eine Bibliothek erstellen, suchen Sie ein gemeinsames Präfix für Ihre exportierten Symbole, dh globale Funktionen, Typedefs und Variablen. Dies verhindert Konflikte mit anderen Bibliotheken und identifiziert die Funktionen als von Ihnen stammend. Dies sind ein paar ungarische Apps-Notationen.

Gehen Sie vielleicht noch weiter und gruppieren Sie Ihre exportierten Symbole: libcurl verwendet curl_ * für globale Symbole, curl_easy_ *, curl_multi_ * und curl_share_ * für die verschiedenen Schnittstellen.Zusätzlich zur Verwendung von curl_ * für alle Funktionen haben sie eine weitere Ebene von „Namespaces“ für die verschiedenen Schnittstellen hinzugefügt: Das Aufrufen einer curl_easy_ * -Funktion auf einem curl_multi_ * -Handle sieht jetzt falsch aus, siehe die Funktionsnamen unter http://curl.haxx.se/libcurl/c/

Unter Beibehaltung der Regeln für exportierte Symbole sollten Sie diese für statische Funktionen in ed files: Versuchen Sie, ein gemeinsames Präfix für diese Funktionen zu finden. Vielleicht haben Sie statische Zeichenfolgen-Dienstprogrammfunktionen in einer Datei namens „my_string“? Stellen Sie all diesen Funktionen my_string_ * voran.

Kommentare

  • Mit exportierten Symbolen meinen Sie globale Variablen, Funktionen, Typedefs usw., wenn ich richtig bin. Können Sie das Gruppieren der exportierten Symbole erklären? Ich dachte, Sie haben das bereits im vorherigen Absatz erklärt. Was haben Sie im 3. Absatz hinzugefügt?

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.