C lernen, wenn Sie C++ bereits kennen?

Lesezeit: 10 Minuten

Benutzer-Avatar
KeatsPeeks

Ich glaube, ich habe fortgeschrittene Kenntnisse in C++ und würde gerne C lernen.

Es gibt viele Ressourcen, die Leuten helfen, von C zu C++ zu wechseln, aber ich habe nichts Nützliches gefunden, um das Gegenteil davon zu tun.

Speziell:

  1. Gibt es weit verbreitete Allzweckbibliotheken, die jeder C-Programmierer kennen sollte (wie Boost für C++)?
  2. Was sind die wichtigsten C-Idiome (wie RAII für C++)?
  3. Soll ich C99 lernen und anwenden oder bei C89 bleiben?
  4. Irgendwelche Fallstricke/Fallen für einen C++-Entwickler?
  5. Sonst noch etwas Nützliches zu wissen?

Benutzer-Avatar
Quark

Hier gibt es bereits eine Menge, also ist dies vielleicht nur eine kleine Ergänzung, aber hier sind meiner Meinung nach die größten Unterschiede.

Bibliothek:

  • Ich setze dies an die erste Stelle, weil dies meiner Meinung nach der größte Unterschied in der Praxis ist. Die C-Standardbibliothek ist sehr (!) spärlich. Es bietet ein absolutes Minimum an Dienstleistungen. Für alles andere müssen Sie selbst rollen oder eine Bibliothek finden, die Sie verwenden können (und viele Leute tun dies). Sie haben Datei-I/O und einige sehr einfache String-Funktionen und Mathematik. Für alles andere müssen Sie selbst rollen oder eine Bibliothek finden, die Sie verwenden können. Ich finde, ich vermisse erweiterte Container (insbesondere Maps) stark, wenn ich von C++ nach C wechsele, aber es gibt viele andere.

Redewendungen:

  • Beide Sprachen verfügen über eine manuelle Speicherverwaltung (Ressourcenverwaltung), aber C++ bietet Ihnen einige Tools, um die Notwendigkeit zu verbergen. In C werden Sie viel häufiger Ressourcen von Hand verfolgen, und daran müssen Sie sich gewöhnen. Besondere Beispiele sind Arrays und Strings (C++ vector und string viel Arbeit ersparen), Smart Pointer (Sie können “Smart Pointer” als solche nicht wirklich in C ausführen. Sie kann Referenzen zählen, aber Sie müssen die Referenzen selbst hoch- und runterzählen, was sehr fehleranfällig ist — der Grund, warum Smart Pointer überhaupt zu C++ hinzugefügt wurden) und das Fehlen von RAII im Allgemeinen, was Sie überall bemerken werden, wenn Sie es tun sind an den modernen Stil der C++-Programmierung gewöhnt.
    • Sie müssen sich ausdrücklich mit Aufbau und Zerstörung auseinandersetzen. Sie können über die Vorzüge von Fehlern streiten, aber als Ergebnis gibt es viel expliziteren Code.
  • Fehlerbehandlung. Es kann schwierig sein, C++-Ausnahmen richtig hinzubekommen, sodass nicht jeder sie verwendet, aber wenn Sie sie verwenden, werden Sie feststellen, dass Sie der Fehlerbenachrichtigung viel Aufmerksamkeit schenken müssen. Die Notwendigkeit, bei allen wichtigen Aufrufen nach Rückgabewerten zu suchen (einige würden argumentieren alle Aufrufe) erfordert viel Disziplin und eine Menge C-Code da draußen tut es nicht.
  • Strings (und Arrays im Allgemeinen) tragen ihre Größe nicht mit sich herum. Sie müssen viele zusätzliche Parameter in C übergeben, um damit fertig zu werden.
  • Ohne Namensräume müssen Sie Ihren globalen Namensraum sorgfältig verwalten.
    • Es gibt keine explizite Bindung von Funktionen an Typen wie bei class in C++. Sie müssen eine Konvention einhalten, indem Sie allem, was Sie mit einem Typ verknüpfen möchten, ein Präfix voranstellen.
  • Sie werden viel mehr Makros sehen. Makros werden in C an vielen Stellen verwendet, an denen C++ Sprachfunktionen hat, um dasselbe zu tun, insbesondere symbolische Konstanten (C hat enum aber viele ältere Code verwendet #define stattdessen) und für Generika (wobei C++ Templates verwendet).

Rat:

  • Erwägen Sie die Suche nach einer erweiterten Bibliothek für den allgemeinen Gebrauch. Schauen Sie sich an GLib oder APR.
    • Auch wenn Sie keine vollständige Bibliothek möchten, sollten Sie eine Karte / ein Wörterbuch / eine Hashtabelle für den allgemeinen Gebrauch finden. Erwägen Sie auch, einen nackten Knochentyp “String” zu bündeln, der eine Größe enthält.
  • Gewöhnen Sie sich daran, allen öffentlichen Namen Modul- oder “Klassen”-Präfixe hinzuzufügen. Das ist ein wenig mühsam, aber es wird Ihnen eine Menge Kopfschmerzen ersparen.
  • Verwenden Sie die Vorwärtsdeklaration stark, um Typen undurchsichtig zu machen. Wo in C++ Sie möglicherweise private Daten in einem Header haben und sich darauf verlassen private den Zugriff verhindert, möchten Sie in C Implementierungsdetails so weit wie möglich in die Quelldateien schieben. (Eigentlich möchten Sie das meiner Meinung nach auch in C++ machen, aber C macht es einfacher, also machen es mehr Leute.)

    C++ offenbart die Implementierung im Header, obwohl es sie technisch vor dem Zugriff außerhalb der Klasse verbirgt.

    // C.hh
    class C
    {
        public:
           void   method1();
           int    method2();
    
       private:
           int    value1;
           char * value2;
    };
    

    C schiebt die ‘class’-Definition in die Quelldatei. Der Header besteht ausschließlich aus Vorwärtsdeklarationen.

    // C.h
    typedef struct C C;           // forward declaration
    
    void c_method1(C *);
    int  c_method2(C *);
    
    // C.c
    struct C
    {
        int    value1;
        char * value2;
    };   
    

  • Was den ‘Smart Pointer’-Teil angeht, können Sie das in C nicht wirklich tun. Sie können eine manuelle Referenzzählung für Speicher oder andere Ressourcen durchführen, aber das ist genauso schlau wie … naja, überhaupt nicht schlau. Ich denke, Sie sollten es in “Referenzzählung” umformulieren (beachten Sie das scoped_ptr und unique_ptr sind auch intelligente Zeiger, in C ist die Speicherverwaltung manuell, nicht intelligent)

    – David Rodríguez – Dribeas

    17. Dezember 2009 um 23:18 Uhr

  • @dribeas: Einverstanden. Ich habe versucht, auf “intelligente Zeiger” als den in C++ verwendeten Begriff zu verweisen, um deutlich zu machen, was ich besprochen habe, aber ich stimme zu, dass es so etwas in C wirklich nicht gibt. Bearbeitet.

    – Quark

    21. Dezember 2009 um 16:40 Uhr

Glib ist ein guter Ausgangspunkt für modernes C und gewöhnt Sie an Konzepte wie undurchsichtige Typen und Halbobjektorientierung, die stilistisch in modernem C üblich sind. Am anderen Ende des Spektrums sind Standard-POSIX-APIs eine Art “klassisches” C.

Die größte Lücke beim Übergang von C++ zu C ist nicht die Syntax, sondern die Sprache, und da gibt es, wie bei C++, verschiedene Programmierschulen. Sie werden ziemlich unterschiedliches C schreiben, wenn Sie einen Gerätetreiber oder beispielsweise einen XML-Parser verwenden.

  • Ich werde mir auf jeden Fall GLib ansehen (ich habe gesehen, dass es hier und da viele Male erwähnt wurde).

    – KeatsPeeks

    16. Dezember 2009 um 20:51 Uhr

Q5. Sonst noch etwas Nützliches zu wissen?

Kaufen Sie eine Kopie von K&R2 und lesen Sie es durch. Gemessen an den Kosten pro Seite wird es wahrscheinlich das teuerste Buch über Computer sein, das Sie jemals von Ihrem eigenen Geld kaufen werden, aber es wird Ihnen eine tiefe Wertschätzung für C und die dahinter stehenden Denkprozesse vermitteln. Das Durchführen der Übungen wird auch Ihre Fähigkeiten verfeinern und Sie daran gewöhnen, was in der Sprache im Gegensatz zu C++ verfügbar ist.

  • Nach all den Jahren immer noch mein Ideal eines Lehrbuchs für Computersprachen!

    anon

    16. Dezember 2009 um 16:56 Uhr

  • Ich bin mir nicht sicher, ob ihm das wirklich viel beibringen wird. Soweit ich mich erinnere, behandelt das Buch hauptsächlich recht grundlegende C-Syntax und Ideen, die das OP bereits kennt.

    – Edan Maor

    16. Dezember 2009 um 17:34 Uhr

  • In der Tat, aber ich brauche sowieso ein Nachschlagewerk, also danke für den Rat, auch wenn es nicht wirklich das ist, wonach ich gefragt habe

    – KeatsPeeks

    16. Dezember 2009 um 20:49 Uhr

  • @Edan Maor: Wenn er C++ kennt, kennt er die C-Syntax. C-Ideen kennt er nicht unbedingt. K&R2 ist sehr kompakt (ich hatte einmal einen Maschinenbaulehrer, der buchstäblich alles andere empfohlen hat) und keine gute Wahl, um das Programmieren zu lernen, aber für jemanden, der Programmierkenntnisse hat, ist es eine großartige schnelle Einführung und Referenz.

    – David Thornley

    18. Dezember 2009 um 16:58 Uhr

Benutzer-Avatar
Jerry Sarg

Ihre Fragen der Reihe nach:

  1. Leider gibt es nichts Vergleichbares zu Boost für C.
  2. Auch nichts, was wirklich in der Größenordnung von RAII liegt.
  3. Der einzige Compiler, der versucht, C99 zu implementieren, ist Comeau.
  4. Viele von ihnen überall, fürchte ich.
  5. Ziemlich viel. C hat eine ganz andere Denkweise als C.

Einige davon mögen ziemlich knapp erscheinen, aber so ist das Leben. Es gibt einige gute Bibliotheken für C, aber an keiner Stelle wie Boost wurden sie gesammelt oder mit einer relativ einheitlichen Oberfläche versehen, wie es Boost für C++ getan hat.

Es gibt viele Redewendungen, aber viele davon beziehen sich darauf, wie Sie Ihren Code bearbeiten, z. B. eine Art RAII zu imitieren, indem Sie an schreiben fopen() und ein passendes fclose() kurz hintereinander, und erst danach zwischendurch den Code schreiben, um die Daten zu verarbeiten.

Die Fallstricke/Fallen, die hinter jeder Ecke lauern, stammen meist aus dem Mangel an dynamischen Datenstrukturen wie String und Vektor, sodass Sie solche Dinge häufig selbst schreiben müssen. Ohne das Überladen von Operatoren, Konstruktoren usw. ist es erheblich schwieriger, sie wirklich allgemeingültig zu machen. Viele Bibliotheken haben sie, aber am Ende rollen Sie Ihre eigenen, weil:

  1. die Bibliothek tut nicht ganz das, was Sie wollen, oder
  2. Die Benutzung der Bibliothek ist mehr Arbeit, als sie wert ist.

Der Unterschied in der Denkweise ist mit ziemlicher Sicherheit das Größte, zumindest für mich. Wenn ich C++ schreibe, konzentriere ich fast meine gesamte wirkliche Anstrengung darauf, möglichst saubere Schnittstellen zu entwerfen, und ich tendiere dazu, die Implementierung einer Schnittstelle so zu behandeln fast Wegwerfcode. Meistens habe ich nicht vor, an diesem Teil des Codes kleine Änderungen vorzunehmen – solange die Schnittstelle gut ist, ist das Ersetzen der gesamten Implementierung normalerweise einfach genug, dass ich mir darüber keine großen Gedanken machen muss.

In C scheint es (zumindest für mich) viel schwieriger, die Schnittstelle von der Implementierung annähernd so gründlich oder sauber zu trennen. Daher verbringe ich viel mehr Zeit damit, jeden Teil des Codes so sauber wie möglich zu implementieren, da spätere Änderungen schwieriger sind und das Wegwerfen und Ersetzen von Teilen, die nicht sehr gut sind, wesentlich weniger wahrscheinlich funktioniert sehr gut aus.

Bearbeiten (da Leute Fragen zur C99-Unterstützung aufgeworfen haben): Während meine Aussage über den Mangel an C99-Unterstützung hart erscheinen mag, ist die Tatsache, dass sie wahr ist.

MS VC++: unterstützt C95 und hat ein paar C99-Funktionen (z. B. Kommentartrennzeichen im C++-Stil), hauptsächlich weil C99 standardisierte, was sie zuvor als Erweiterung hatten.

Gnu: Laut Status der C99-Funktionen Seite hat die neueste Version von gcc (4.4) einige C99-Features, aber einige (einschließlich VLAs) werden als “kaputt” und andere als “fehlend” gekennzeichnet. Einige der fehlenden “Features” sind wirklich ganz Bereichenicht einzelne Merkmale.

PCC: Die PCC-Website behauptet C99-Konformität nur als Ziel für die Zukunft, nicht als gegenwärtige Realität.

Embarcadero Technologies (geborene Borland) scheint überhaupt nichts über die Konformität mit C99 zu sagen – so wie es aussieht, war das letzte Mal, als sie am C-Compiler gearbeitet haben, möglicherweise schon vor der Veröffentlichung von C99.

Microsoft sagt offen dass sie derzeit keine Pläne haben, C99 zu unterstützen, und sie werden es nicht einmal in Betracht ziehen, bis VS 2010 veröffentlicht wird. Obwohl ich keine öffentlichen Erklärungen darüber finden kann, erscheint Embarcadero ungefähr gleich: kein Hinweis auf einen aktuellen Plan, und nicht einmal, dass sie in Betracht ziehen werden, bald daran zu arbeiten.

Während gcc und pcc beide Pläne zu haben scheinen, sind sie derzeit genau das: Pläne. Beide geben offen zu, dass sie derzeit noch nicht einmal annähernd C99-konform sind.

Hier ist ein Kurzübersicht von einigen der wichtigsten Dinge, die Sie wissen wollen.

Benutzer-Avatar
Karl Smotricz

Dies ist ein Rat, um den Sie nicht gebeten haben: Ich denke, die meisten potenziellen Arbeitgeber gehen davon aus, dass Sie C++ beherrschen, wenn Sie C++ beherrschen. Das Erlernen der Feinheiten von C ist zwar eine interessante akademische Übung, wird Ihnen aber meiner Meinung nach nicht viel Berechtigung einbringen Punkte.

Wenn Sie jemals in der Lage sind, C zu machen, werden Sie die Unterschiede schnell genug erkennen.

Aber hör nicht auf mich. Ich war zu faul und dumm um C++ zu lernen 🙂

Benutzer-Avatar
vitaly.v.ch

Sonst noch etwas Nützliches zu wissen?

C99 ist keine Teilmenge von C++ irgendeiner Revision, sondern eine separate Sprache.

  • C90 ist nicht vollständig eine Teilmenge von C++, und auf jeden Fall würden Sie Programme in C90 und C++ anders schreiben.

    – David Thornley

    18. Dezember 2009 um 16:55 Uhr

1311320cookie-checkC lernen, wenn Sie C++ bereits kennen?

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

Privacy policy