Bei C++ Grundlagenkenntnisse in C überflüssig?



  • redrew99 schrieb:

    Hm, da C++ und C gemeinsame Grundlagen haben, dürfte es unmöglich sein , C++ zu lernen, ohne auch C zu lernen.

    Nö, ich habe C++ ohne C gelernt. Wenn ich heute Hardcore-C-Code sehe, kratze ich mich am Kopf und denke mir "Zum Glück hast du das nicht lernen müssen!". 😃

    redrew99 schrieb:

    Es gibt mit Sicherheit viele Sachen, wo C-Kenntnisse zu einem besseren Verständnis der Materie führen. So z.B. bei einem "vector", der ja, wenn ich das richtig verstanden habe, vom Kern her nichts anderes ist als eine verkettete Liste auf der Basis eines C-Arrays, die man mit C-Grundkenntnissen auch selber programmieren könnte.

    Nein, denn anscheinend hat dich das nicht weit gebracht, C zu können. Denn Vector besteht nicht aus einer verketteten Liste. Und um vector zu implementieren, hilft einem C überhaupt nicht weiter, weil ich vector mit new[] und delete[] implementieren müsste, worauf ein C-Programmierer ohne C++-Wissen nicht kommen würde. Ich brauche dafür absolut kein C-Wissen.

    redrew99 schrieb:

    Geht man diesen Gedankengang weiter, könnte man auf die Idee kommen, warum eigentlich nicht erstmal Assembler lernen, bevor man C lernt. Das Verständnis z.B. eines Arrays ist mit Sicherheit besser, wenn man das erstmal in Assembler programmiert hat. Nicht zu vergessen die detaillierte Funktionsweise der Hardware.

    Hem, nicht unbedingt. Denn Assembler ist auch eine gewisse Abstraktion. Wenn man es weiter spinnen würde, müsste man reine Hexwerte... ach ne, ist ja auch nur ne Abstraktion von zusammen gefassten Bits.

    Nein, also im Ernst: es schadet nicht, wenn man Assembler mal programmiert hat. Aber es hilft einem nicht weiter, weil man dadurch nur eine CPU-Architektur kennen lernt. Und wenn man Pech hat, noch dazu eine der mieserabelsten (x86). Also ich weiß nicht. Man bekommt dann vielleicht mit, das man Glücklich sein kann, C++ als Werkzeug zu haben. Ich habe damals 6510 und ARM2 Assembler programmiert. Aber ein Indexbasiertes Feld und wie ein Computer funktioniert, habe ich davor schon mittels BASIC und dessen PEEK und POKE gelernt. Und wie ich Daten im Speicher sequenziell ablege, habe ich davor schon mit dem DATA Befehl gelernt. Das ich mit Assembler besser wurde, um die Grundlagen zu kennen, kann ich deshalb nicht bestätigen. Es waren lediglich andere Sprachen und die ARM-Assembler-Sprache ist bis heute meiner Meinung nach die beste.

    redrew99 schrieb:

    Was also soll der Maßstab sein, um mit C oder C++ zu beginnen?

    C und C++ halte ich generell nicht für gute Einstiegssprachen, weil man neben der Sprache noch viele andere Dinge lernen muß, z.B. der Umgang mit Headern, das Linken usw.

    Ich halte immer noch eine Sprache wie BASIC (nein, nicht VisualBasic.NET, das hat meiner Meinung nicht mehr viel mit BASIC-Urgedanken gemeinsam), da sie Grundlagen der Programmierung beibringt, ohne das man sich viel mit Nebenkriegsschauplätzen auseinander setzen muß.


  • Mod

    @Artchi: Noch abstrakter. Du würdest natürlich nicht new[], delete[] benutzen, sondern einen nutzerdefinierten Allocator mit Standardwert std::allocator<T>. 🕶





  • Artchi schrieb:

    weil ich vector mit new[] und delete[] implementieren müsste, worauf ein C-Programmierer ohne C++-Wissen nicht kommen würde. Ich brauche dafür absolut kein C-Wissen.

    Ok, das wußte ich nicht. Dachte, daß new[] und delete[] Relikte aus C sind.
    Aber solche Sachen wie Schleifen oder Funktionen z.B. sind doch eigentlich C oder?


  • Mod

    redrew99 schrieb:

    Ja, in vielen Fällen braucht man es vermutlich nicht.Auf der anderen Seite - z.B. habe ich mir mal den Code einer verketteten Liste angeschaut, um zumindest ansatzweise zu verstehen, wie ein c-vector funktioniert.

    Nochmal, da du es nicht mitbekommen zu haben scheinst: Vector ist keine verkettete Liste! In keiner Implementierung! Vector ist ein netter Bedienkomfortwrapper um ein dynamisches Array. Wenn man die ganzen Memberfunktionen (und zusätzlichen Templateparameter) mal außen vor lässt, wird das nicht viel mehr sein als

    template<class T> class vector
    {
     T* begin_data, end_data, end_allocated;
    };
    

    Und fertig. Aus technischen Gründen werden die Verwaltungsdaten noch in einer Unterklasse stehen, aber von der Funktionalität her war's dies schon.



  • Nochmal, da du es nicht mitbekommen zu haben scheinst: Vector ist keine verkettete Liste! In keiner Implementierung! Vector ist ein netter Bedienkomfortwrapper um ein dynamisches Array. Wenn man die ganzen Memberfunktionen (und zusätzlichen Templateparameter) mal außen vor lässt, wird das nicht viel mehr sein als

    Ok.



  • Der vector erlaubt es, aber nicht in O(1) sondern O(N). Die verkettete Liste in der STL heißt std::list.



  • cooky451 schrieb:

    Ich als verkappter C-ler finde C++-"Profis" die nur wenig C können jedenfalls immer wieder lustig. 😃
    Aber deren Existenz beweist nun mal auch, dass man C für C++ nur unvollständig können muss.

    Was können C-ler was C++-ler nicht können? Ich hab zwar nur ganz wenig C programmiert, aber mir fällt jetzt nichts ein was da besonders war.


  • Administrator

    redrew99 schrieb:

    Aber solche Sachen wie Schleifen oder Funktionen z.B. sind doch eigentlich C oder?

    Sind für dich Schleifen oder Funktionen in Java oder C# ebenfalls C? Nur weil die Schlüsselwörter gleich heissen und das gleiche ausgeführt wird, ist dies doch nicht automatisch C! Wie kommt man auf so eine Idee?

    Grüssli



  • oberunter schrieb:

    Was können C-ler was C++-ler nicht können? Ich hab zwar nur ganz wenig C programmiert, aber mir fällt jetzt nichts ein was da besonders war.

    Da musst du jetzt die Leute fragen, die von sich behaupten gut C++ aber nur schlecht C zu können. Man könnte es ja gleich mal mit etwas Einfachem probieren.. findet irgendjemand hier so etwas schwer zu lesen?

    static void swap(void* a, void* b, size_t size)
    {
        size_t is = size / sizeof(int);
        size_t s = size - is * sizeof(int);
        while (is--)
        {
            int buf = *((int*)(a) + is);
            *((int*)(a) + is) = *((int*)(b) + is);
            *((int*)(b) + is) = buf;
        }
        while (s--)
        {
            char buf = *((char*)(a) + s);
            *((char*)(a) + s) = *((char*)(b) + s);
            *((char*)(b) + s) = buf;
        }
    }
    


  • swapt, indem zuerst ints kopiert werden und der Rest in einzenen Bytes. 😉



  • Dravere schrieb:

    redrew99 schrieb:

    Aber solche Sachen wie Schleifen oder Funktionen z.B. sind doch eigentlich C oder?

    Sind für dich Schleifen oder Funktionen in Java oder C# ebenfalls C? Nur weil die Schlüsselwörter gleich heissen und das gleiche ausgeführt wird, ist dies doch nicht automatisch C! Wie kommt man auf so eine Idee?
    Grüssli

    Ich kann mir nicht vorstellen, daß man Schleifen von Java oder C# 1:1 übertragen und kompilieren kann.

    Hingegen benutzt man die Schleifen und Funktionen, die man unter C benutzt, auch noch unter C++.

    D.h. dann lernt man doch C und nicht C++ ?



  • redrew99 schrieb:

    ..

    Genau, und wenn man Laufen lernt, lernt man Fußball und kein Basketball. Weiß doch jeder. 🙄



  • cooky451 schrieb:

    findet irgendjemand hier so etwas schwer zu lesen?

    static void swap(void* a, void* b, size_t size)
    {
        size_t is = size / sizeof(int);
        size_t s = size - is * sizeof(int);
        while (is--)
        {
            int buf = *((int*)(a) + is);
            *((int*)(a) + is) = *((int*)(b) + is);
            *((int*)(b) + is) = buf;
        }
        while (s--)
        {
            char buf = *((char*)(a) + s);
            *((char*)(a) + s) = *((char*)(b) + s);
            *((char*)(b) + s) = buf;
        }
    }
    

    Ja, aber haupsächlich, weil is und s total schlechte Namen sind. Wenn man es numberOfInts and remainingBytes nennen würde, wäre schon einiges klarer.



  • redrew99 schrieb:

    Ich kann mir nicht vorstellen, daß man Schleifen von Java oder C# 1:1 übertragen und kompilieren kann.

    Hingegen benutzt man die Schleifen und Funktionen, die man unter C benutzt, auch noch unter C++.

    D.h. dann lernt man doch C und nicht C++ ?

    Du schreibst jetzt über die Sprachen und ihre Eigenheiten. Ursprünglich ging es aber um Konzepte der Programmierung, also z.B. was ist ein Array und eine Liste. Das eine ist aber die Sprache, das andere die Theorie über Algorithmen.

    Nehmen wir mal die for-Schleife: eine solche Schleife hat erstmal nichts mit einer Programmiersprache zu tun. Mit einer Schleife kann ich allgemein gesagt, wiederkehrende Aufgaben X-Mal (bestimmt durch eine Bedingung) ausführen. Ohne mir einen Wolf zu tippen. 😉 Weil ich könnte anstatt einer Schleife auch die wiederkehrende Aufgabe X-Mal hintereinander in das Programm tippen oder Copy & Paste.

    Wo nützt mir diese Theorie? Nur in C und C++? Auch in BASIC (aus den 1950er Jahren!)? Eine Schleife kann ich sogar in Assembler programmieren.

    Es ist also völlig egal, welche Sprache ich zu erst lerne. Die Sprache ist das Werkzeug mit der ich mein theoretisches Wissen umsetzen kann. In Assembler muß ich das etwas umständlicher machen (aber immer noch nachvollziehbar!). In BASIC, C und C++ kann ich das sehr komfortabel machen, weil diese Sprachen bereits eine spezialisierte for-Schleife anbieten.

    Aber Listen, dynamische Arrays, for-Schleifen usw. sind aus der Theorie entstanden, und werden entweder direkt in die Sprache eingebaut oder ich kann sie mir aus den Sprachmitteln selber zusammen bauen.

    D.h. also, ich brauche um C++ programmieren zu können, kein C-Vorwissen. Ich muß logisch und theoretisch denken können und lernen, wie ich das in der jeweiligen Sprache umsetzen kann.

    Wenn ich eine verkettete Liste will, lerne ich erstmal, das es in C++ eine solche gibt. Wann ich diese nutze, anstatt eines Vectors, kann ich durch theoretisches Wissen und Logik entscheiden. Das kann ich aber ohne C. Da gibt es genug C++ Bücher, die einem das auch so erklären.

    Und ich bin sogar der Meinung, das man vieles mit BASIC lernen kann. Ohne sich mit dem Werkzeug C oder C++ einen abkräpeln zu müssen. Weil die Theorie und Logik kann auch BASIC vermitteln. Es gibt auch sehr gute BASIC-Dialekte, die Spagethie Code vermeiden können (z.B. BBC BASIC oder COMAL).



  • Artchi schrieb:

    Es gibt auch sehr gute BASIC-Dialekte, die Spagethie Code vermeiden können (z.B. BBC BASIC oder COMAL).

    Ich glaube, Spaghetti-Code läßt sich mit jeder Programmiersprache produzieren oder vermeiden. Es ist immer eine Frage der Selbstdisziplin, ob man sein Programm plant und sinnvoll modularisiert, oder einfach wild draufloshackt. 😉

    Eigentlich gibt es keine "bessere" oder "schlechtere" Programmiersprache, sondern nur solche, die je nach Anwendungsfall besser oder weniger gut geeignet sind.


  • Administrator

    redrew99 schrieb:

    Ich kann mir nicht vorstellen, daß man Schleifen von Java oder C# 1:1 übertragen und kompilieren kann.

    Lass mich mal schnell sehen:

    int sum = 0;
    for(int i = 0; i < 10; ++i)
    {
      sum += i;
    }
    
    int sum = 0;
    for(int i = 0; i < 10; ++i)
    {
      sum += i;
    }
    
    int sum = 0;
    for(int i = 0; i < 10; ++i)
    {
      sum += i;
    }
    

    Kompilert bei allen!

    Weisst du, was dafür lustig ist? Unter C89 kompiliert es nicht! Und von C89 wurde C++ eigentlich abgespalten. In C89 müsstest du es so schreiben:

    int i;
    int sum = 0;
    
    for(i = 0; i < 10; ++i)
    {
      sum += i;
    }
    

    Ansonsten: Siehe Beitrag von Artchi.

    Grüssli



  • 314159265358979 schrieb:

    Der vector erlaubt es, aber nicht in O(1) sondern O(N). Die verkettete Liste in der STL heißt std::list.

    Falsch. std::forward_list



  • Wrong Answer Noob schrieb:

    314159265358979 schrieb:

    Der vector erlaubt es, aber nicht in O(1) sondern O(N). Die verkettete Liste in der STL heißt std::list.

    Falsch. std::forward_list

    std::forward_list ist nicht Teil der STL.



  • Wrong Answer Noob schrieb:

    314159265358979 schrieb:

    Der vector erlaubt es, aber nicht in O(1) sondern O(N). Die verkettete Liste in der STL heißt std::list.

    Falsch. std::forward_list

    Beides sind verkettete Listen. std::list ist eine doppelt verkettete, std::forward_list eine einfach verkettete.


Anmelden zum Antworten