Kann man überhaupt noch in C und ohne OOP programmieren?



  • Ich interessiere mich für das Programmieren von kleinen 2D und 3D Games. Das habe ich früher schon in Assembler auf dem C64 gemacht und möchte jetzt wieder auf dem PC damit anfangen. Nun hat sich ja viel getan und alle reden über OOP, Design Pattern, RAII und was weiß ich noch alles. Kann man heute überhaupt noch ohne diese Techniken vernünftig programmieren?

    Ich komme mit dieser neuen Denkweise nämlich überhaupt nicht klar und bin immer gut ohne Vererbung und was weiß ich alles klar gekommen, auch wenn mal Änderungen an standen.

    Da C zu meiner Art zu programmieren mehr zu Assembler passt als C++ oder Java, würde ich es mir gerne genauer anschauen. Aber wenn heute alles OOP sein muss, dann bin ich mit C natürlich nicht so gut bedient. daher meine Frage ob man heute überhaupt noch ohne OOP programmieren kann?


  • Mod

    "Können" ist ein starkes Wort. Klar, kannst du. Es ist sowohl technisch möglich und die Polizei kommt auch nicht bei dir vorbei, wenn du es versuchst. Die Frage ist, ob du wirklich komplexe Programme so schreiben solltest. Das ist schließlich die gesammelte Erfahrung von vielen Generationen von Programmierern, die besagt, dass Quick&Dirty Spaghetticode nicht so toll ist und dass man mit strukturierter Programmierung, abstrakten Problemlösungen, objektorientierter Modellierung, usw. besser fährt.



  • Naja, das muss man ein bisschen differenziert sehen.

    Zunächst ist es keineswegs unmöglich, in C objektorientierten Code zu schreiben, nur halt etwas umständlich (weil man vieles von Hand machen muss). Es ist nicht die Programmiersprache, die objektorientiert ist, sondern das Modell, dass der Programmierer sich für sein Programm ausdenkt.

    Aber, frei nach Bjarne Stroustrup: Objektorientierung ist ein toller Weg, manchen Code zu schreiben und ein schrecklicher Weg, allen Code zu schreiben. Nicht alles passt in eine Vererbungshierarchie, und was das beste Werkzeug ist, muss man im Einzelfall entscheiden. Von daher: Klar kannst du ohne Objektorientierung Code schreiben, und in manchen Fällen ist das sogar sinnvoll.

    Allerdings werden dir Fälle über den Weg laufen, bei denen ein Verständnis objektorientierter Programmierung echt praktisch wäre. Mach dir nichts vor: OOP ist heute das zentralste Programmierparadigma, und sich einfach nicht damit zu beschäftigen, ist eigentlich keine Option.


  • Mod

    seldon schrieb:

    Zunächst ist es keineswegs unmöglich, in C objektorientierten Code zu schreiben,

    Oh, ich glaube ich habe die Frage komplett falsch verstanden. Ich dachte der TE wollte wissen, ob es noch üblich/möglich ist, in C ohne OOP zu programmieren und da ist die Antwort eben eher "Nein, das ist nicht üblich". Mir war gar nicht klar, dass der TE davon ausging, dass man in C überhaupt nicht OOP kann. Ich dachte er wäre durch Angucken von professionellem Code zu dem gegenteiligen Schluss gekommen.

    Aber das sagt sicherlich auch etwas darüber aus, wie modernes C meistens aussieht, wenn man die Frage auf diese Weise falsch verstehen kann.



  • Angenommen, ein C-API böte die folgenden Funktionen an
    (und nehmen wir an, die Funktionen tun das, was 'draufsteht'):

    typedef struct tBuf{
     unsigned char* data;
     size_t sz;
    }Buf;
    
    Buf* compress(const Buf* src);
    Buf* decompress(const Buf* src);
    

    Also irgendwelche Daten werden entweder komprimiert oder dekomprimiert.
    Ich frage mich, warum man jetzt diese (hypothetische) C-API lieber mit
    OOP-Mitteln implementieren hätte sollen.
    In der C-Version könnte man die Funktionen auch bequem in eine .dll packen
    und dann in fast jeder anderen Hochsprache damit arbeiten.
    Was leider mit den Member-Funktionen einer OOP/C++/Java Klasse nicht
    ohne weiteres möglich wäre.
    Also für 'freistehende' Funktionen, die klar umrissene Aufgaben lösen können
    sollen, und die man eventuell in anderen HochSprachen wiederverwenden
    möchte (z.B. per .dll), sollte man lieber C verwenden.
    Für unklare oder unkonkrete Aufgabenstellungen kann man sich mit OOP begnügen,
    allerdings kommen dabei auch eher selten konkrete Lösungen heraus ...

    Ich lach mich z.T. kaputt beim Thema Anti-Design-Patterns, was man alles
    angeblich nicht machen sollte, weil ehrlich gesagt müsste man die Funktionen
    im obigen Beispiel mindestens als 'böse' Magic Pushbuttons bezeichnen, weil
    sie das Leben des Aufrufers dieser Funktionen gar zu sehr vereinfachen würden.
    Und im OOP-Sinne geht das nun mal gar nicht, dass man existierende Lösungen
    in gar zu einfacher Weise in seinem Programm AUFRUFEN kann, wenn man sie
    benötigt. Nein, im Sinne von OOP muss man ja alles zuerst
    in irgendein abstrakt-virtuelles Klassen-Chaos verpacken, und zwar möglchst so,
    dass derjenige, der eine Funktionaliät davon bräuchte, sie nur ja nicht
    findet, bevor er sich jahrelang durch eine mangelhafte Doku gequält hat.
    Irony off::

    😃



  • Das mag wohl häufig vorkommen, dass als Schnittstelle eine C++ Schicht angeboten wird und wenn man dann mal genauer nachschaut, werden intern nahezu ausschließlich C-(System)Aufrufe verwendet. Aber das ist ja auch gerade der Vorteil von C, sehr handlich und flexibel einsetzbar zu sein, eine C-Lib sollte auch heutzutage von nahezu jeder Modesprache verwendbar sein, und eine C++-Lib ist das eben nicht.



  • Das Beispiel, das du beschreibst, würde sehr gut in ein objektorientiertes Konzept passen, weil man bei größeren Datenmengen (auf die man als Kompressionsbibliothek ja vorbereitet sein muss) im Zweifel die Daten blockweise verarbeiten will und dementsprechend einen Zustand halten muss. Mal ganz simpel hingekladdet:

    typedef struct { ... } compressor;
    
    void compressor_init    (compressor *context, FILE *output);
    void compressor_compress(compressor *context, unsigned char const *data_block, size_t block_len);
    void compressor_finalise(compressor *context);
    
    ...
    
    compressor comp;
    FILE *fd, *fd_out;
    ssize_t r;
    char buffer[512];
    
    fd = fopen("uncompressed.txt", "rb");
    fd_out = fopen("compressed.dat", "wb");
    
    compressor_init(&comp);
    
    while((r = fread(buffer, 1, 512, fd))) {
      compressor_compress(&comp, buffer, r);
    }
    
    compressor_finalise(&comp);
    fclose(fd_out);
    fclose(fd);
    

    Jetzt ist compressor eine Klasse, comp ein Objekt und der Code objektorientiert.

    Dein Ansatz kann große Datenmengen schlicht nicht erschlagen -- wenn meine Datei jetzt ein Blu-Ray-Image ist, hast du ein großes Problem. Und dabei haben wir noch nicht mal davon gesprochen, was passieren soll, wenn der Kompressionsalgorithmus mal nicht zur Compilezeit feststeht.


Anmelden zum Antworten