Entwurfsprinzipien, Best Practices und Entwurfsmuster für C (oder prozedurale Programmierung im Allgemeinen)? [closed]

Lesezeit: 6 Minuten

Gibt es bekannte Designprinzipien, Best Practices und Designmuster, denen man beim Entwerfen eines C-Projekts folgen kann? Oder nützliche Designprinzipien für prozedurale (imperative) Programmierung im Allgemeinen?

(Ich bin Kind der ‘objektorientierten Generation’ und muss zum ersten Mal ein großes C-Projekt entwerfen)

  • Sie könnten an Antworten auf diese Frage interessiert sein: stackoverflow.com/questions/661307/…

    – mouviciel

    22. März 2010 um 13:40 Uhr

  • Ich habe einige Internet- und Universitätsbibliotheken recherchiert, bevor ich meine Frage gestellt habe, und war definitiv nicht mit Büchern über Softwaredesign für C überfordert. Ich frage Sie nach Ihrem Favoriten (ich spreche nicht über allgemeine C-Bücher, nicht über Codierungskonventionen wie sinnvolle Variablen). Namen, sondern um eine höhere Abstraktionsebene, Softwarearchitekturebene). Außerdem teile ich Ihren Vorwurf der Abhängigkeit von anderen nicht. Sie meinen, jeder Programmierer sollte sich selbst über Best Practices und gute Design Patterns informieren? Dies ist sicherlich eine Frage, bei der die Erfahrungen anderer genutzt werden müssen.

    – Dimi

    22. März 2010 um 14:57 Uhr

  • Tut mir leid, Dimi, es ging nicht speziell um dich, und ich habe mich nicht ganz klar ausgedrückt. Dieses Zeug wurde früher genauso durch mündliche Überlieferung weitergegeben wie auf andere Weise: Es gab keinen nominellen Satz offizieller “Muster”, Jonathons Antwort war das, was Sie in den Büchern finden würden, aber alle wusste über das Verbergen von Informationen. Es scheint, dass die mündliche Überlieferung verloren geht, und viele junge Programmierer denken, dass OOP die Kapselung und Trennung erfunden hat. Diese Gemeinschaft scheint weniger Sinn für ihre eigene Geschichte zu haben, als mir lieb ist. Daher mein Eingeständnis, dass ich mich im Gebiet der mürrischen alten Männer befinde.

    – dmckee — Ex-Moderator-Kätzchen

    22. März 2010 um 15:37 Uhr

  • Ich kann Ihre rückblickende Sichtweise nicht teilen, da ich mich gerade auf dem Gebiet befinde, aber ich akzeptiere Ihren Vorschlag. Vielen Dank, dass Sie sich klarer ausdrücken, es ist immer von großem Wert, die Sicht einer erfahrenen Person zu lesen. Ich schätze Ihren Beitrag sehr.

    – Dimi

    22. März 2010 um 15:56 Uhr

  • SEI CERT C Coding Standard bietet Gutes Regelwerk und gemeinsame gute Praktiken sowie Dinge, die Sie vermeiden sollten.

    – Rand0m

    2. März 2017 um 14:23 Uhr

Information Hiding – wie von Parnas (Software Fundamentals) vertreten.

Sorgfältige Verwaltung von Kopfzeilen und Sichtbarkeit:

  • Alles in einer Quelldatei, das vor der Außenwelt verborgen werden kann, sollte; nur die dokumentierte externe Schnittstelle sollte verfügbar gemacht werden.
  • Alles, was exponiert ist, wird in einem Header deklariert.
  • Dieser Header wird dort verwendet, wo die Funktionalität benötigt wird (und wo sie definiert ist).
  • Der Header ist in sich abgeschlossen – wenn Sie ihn brauchen, verwenden Sie ihn, und Sie müssen sich nicht darum kümmern, „welche anderen Header muss ich auch einschließen“, denn der Header stellt sicher, dass er funktioniert, indem er alles enthält, was er benötigt, um ihn zu erstellen Arbeit.
  • Der Header ist selbstgeschützt – es spielt also keine Rolle, ob er mehrfach eingebunden wird.

    #ifndef HEADER_H_INCLUDED
    #define HEADER_H_INCLUDED
    ...rest of header contents, including other #include lines if necessary
    #endif /* HEADER_H_INCLUDED */
    
  • Entwerfen Sie Sätze von Funktionen, die an „Objekten“ (normalerweise Strukturen) arbeiten – und verwenden Sie diese Funktionen, anstatt im Code, der sie verwendet, in den Innereien der Struktur herumzustöbern. Betrachten Sie es als selbst auferlegte Kapselung.

  • Guter Punkt, danke, Jonathan. Abstrakte Datentypen sind ein weiteres gutes Beispiel für das Verbergen von Informationen mit einer sauberen Trennung von Verwendung und Implementierung (bekannte externe Schnittstelle und unbekannte interne Implementierung).

    – Dimi

    22. März 2010 um 15:38 Uhr

Benutzeravatar von Itay Maman
Itay Maman

Meine drei Ratschläge:

  • Unit-Tests schreiben. Sie werden Ihnen dabei helfen, sich auf ein Design zu konzentrieren, das zu Ihrem Problem passt, während Sie weitermachen. Viel besser, als sich (ausschließlich) auf vorsätzliches Denken zu verlassen.
  • Lassen Sie einen Speicherleckdetektor (es gibt alle Arten von Bibliotheken da draußen) installieren und vom ersten Tag an laufen. Lassen Sie diese Bibliothek alle Lecks ausdrucken, sobald das Programm/die Tests beendet werden. Auf diese Weise können Sie ein Leck sofort nach dem Einführen auffangen, wodurch die Reparatur viel weniger schmerzhaft wird.
  • Schreiben Sie OOP-Code in C. Nicht so schwierig. Obwohl es möglich ist, das Überschreiben von Methoden zu emulieren, schlage ich vor, dass Sie mit der Emulation einfacher Objekte beginnen. Selbst dieser einfache Mechanismus kann Ihnen eine große Laufleistung bescheren.

Hier ist ein Beispiel:

typedef struct Vector {
  int size;
  int limit;
  int* ints; 
} Vector;

Vector* Vector_new() {
  Vector* res = (Vector*) malloc(sizeof(Vector));
  res->limit = 10;
  res->size = 0;
  res->ints = (int*) malloc(sizeof(int) * res.limit);

  return res;
}


void Vector_destroy(Vector* v) {
  free(v->ints);
  free(v);
}

void Vector_add(Vector* v, int n) {
  if(v->size == v->limit) {
    v->limit = v->limit * 2 + 10;
    v->ints = realloc(v->ints, v->limit);     
  }

  v->ints[v->size] = n;
  ++v->size;
}

int Vector_get(Vector* v, int index) {
  if(index >= 0 && index < v->size)
    return v->ints[index];

  assert false;
}

  • 4. Cast nicht das Ergebnis von malloc.

    – SS Anne

    29. Januar 2020 um 1:07 Uhr

Es gibt ein gutes, kostenloses Online-Buch mit dem Titel Objektorientierte Programmierung mit ANSI-Cdas das Thema des Schreibens von objektorientiertem Code in C. A Google-Suche für “objektorientiertes C” liefert auch eine Reihe anderer guter Beispiele und Ressourcen.

Wenn Ihr Projekt sicherheitskritisch ist, MISRA-C ist ein gutes Regelwerk. Es ist hauptsächlich für eingebettetes C gedacht, kann aber auch in anderen Bereichen nützlich sein.

Ich betrachte mich als OO-Programmierer und arbeite viel mit Embedded-C. Der beste Rat, den ich geben kann, insbesondere bei großen Projekten, ist, es nicht zu übertreiben. Das Erstellen eines vollständigen OO-Frameworks auf ANSI C kann sehr verlockend sein, aber es erfordert viel Zeit und Mühe, es richtig hinzubekommen. Je schicker Sie werden, desto mehr Zeit werden Sie mit dem Debuggen Ihres Frameworks verbringen, anstatt an dem zu arbeiten real Projekt. Gehen Sie die Aufgabe mit klarem Kopf und einem guten, soliden Verständnis an YAGNI. Viel Glück!

  • Danke, E.James. Ich möchte kein objektorientiertes Framework auf ANSI C aufbauen, sondern suche nach speziellen und geeigneten Designprinzipien für die prozedurale Programmierung. Der MISRA-C-Hinweis ist sehr nützlich, insbesondere weil es sich tatsächlich um ein eingebettetes Projekt handelt. Ich werde es mir genauer anschauen.

    – Dimi

    22. März 2010 um 14:27 Uhr

  • Ah, die Freuden von eingebettetem C. Vergessen Sie nicht, dass Sie Ihre Variablen am Anfang Ihrer Funktion (oder am Anfang jeder anderen) deklarieren müssen { } Block). Der beißt mich immer ein- oder zweimal :)

    – e.James

    22. März 2010 um 16:44 Uhr

OOP ist eine Methodik, keine Technologie. Mein erster Ratschlag ist also, dass Sie aufhören, es als prozedurale Programmierung zu betrachten.

Um e.James zu sagen, Sie wollen nicht versuchen, eine objektorientierte Sprache neu zu erstellen oder vorzugeben, dass Sie die Fähigkeiten dazu haben. Sie können immer noch alles richtig machen, indem Sie sich an ein paar einfache Prinzipien halten:

  1. Alles Probe fahren.
  2. Finden Sie, was variiert, und kapseln Sie es.
  3. Design für Schnittstellen.
1420700cookie-checkEntwurfsprinzipien, Best Practices und Entwurfsmuster für C (oder prozedurale Programmierung im Allgemeinen)? [closed]

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy