ZeigerA-rithmetik



  • Hallo SeppJ,

    vielen Dank für Deine Antwort. Die von Dir angegebenen Links habe ich schon weitgehend durchgeschaut. Ich glaube, dass man, neben vielen Programmtests, auch durch Lesen in diesem Forum gut weiterkommt.
    Mit Deiner Trennung von C und C++ hast Du vom Programmierparadigma her natürlich Recht. Andererseits liest man immer wieder (und es ist wohl auch "allerweitestgehend" Tatsache), dass C quasi vollständig in C++ enthalten ist (ein C-Programm ist (quasi) immer auch ein C++-Programm). Das kann ich auch (weitestgehend) in Visual Studio feststellen, wenn ich ein lauffähiges C++-Projekt mit reinem C-Code erstelle.

    Kannst Du mir gute C-Bücher nennen (außer K&R) ?

    Freundliche Grüße
    cfrig


  • Mod

    C in C++ auszuführen gelingt vielleicht auf "Hello World"-Niveau, aber sobald du nur ein bisschen was Komplexes tust, wird es nicht mehr gehen. Sieh C und C++ als getrennte Sprachen an und sei skeptisch gegenüber jedem, der etwas anderes behauptet. Insbesondere ist C keine Lernhilfe für C++! Der manchmal empfohlene Pfad, über C zu C++ zu kommen, ist ein Holzweg.

    Ich kenne kein anderes C-Buch, das ich empfehlen würde, außer K&R.



  • cfrig schrieb:

    Andererseits liest man immer wieder (und es ist wohl auch "allerweitestgehend" Tatsache), dass C quasi vollständig in C++ enthalten ist (ein C-Programm ist (quasi) immer auch ein C++-Programm). Das kann ich auch (weitestgehend) in Visual Studio feststellen, wenn ich ein lauffähiges C++-Projekt mit reinem C-Code erstelle.

    Naja, ich würde mal sagen, dass "weitestgehend" nicht besonders weit kommt. Beispiel:

    #include <stdlib.h>
    
    int main() {
        int *a = malloc(sizeof(int));
        free(a);
    }
    

    Und C-Programme ohne malloc sind sehr selten. Und schon haben wir das Problem. Von daher würde ich mal behaupten, dass sich kein einigermaßen große C-Programm als C++ übersetzen lässt, es sei denn, es wurde von einem C++-Programmierer geschrieben.



  • Hallo SeppJ, hallo wob,

    vielen Dank für Eure Antworten. Ich lasse mich sehr gern belehren und nehme Eure Belehrungen aber auch deswegen an, weil ich sie, was die Praxis angeht, für richtig halte. Die Aussage, dass C in C++ enthalten ist, wird gar nicht selten an Unis oder FHs gelehrt (ist nur Kern-C (Sprachumfang) ohne die Bibliotheken gemeint?).

    Dennoch konnte ich folgendes, leicht modifizierte, "Programm" in Visual Studio 2008 fehler- und warnungsfrei kompilieren:

    #include <stdlib.h>
    
    int main() {
        int *a;
    	a=(int*)malloc(sizeof(int));
        free(a);
    }
    

    Freundliche Grüße
    cfrig


  • Mod

    Mit Casts kann man alles irgendwie so lange verbiegen, bis es funktioniert. Obiger Code hat zwar nun die gleiche Funktionalität wie das Original, aber du hast sämtliche Sicherheitsmechanismen der Sprache abgeschaltet. Ein falscher Code würde nun ebenso compilieren (und dann zur Laufzeit fehlschlagen) wie dieser richtige Code. Das ist ja wohl kaum im Sinne des Erfinders.

    Die Aussage, das C in C++ enthalten ist, hat schon ihre Herkunftsberechtigung, insofern als dass man
    1. Die Standardbibliothek von C, wie sie 1989 war, in C++ aufgenommen hat.
    2. In den Anfangszeiten von C++ versucht hat, möglichst kompatibel zu bleiben.

    Das ist aber alles 30 Jahre her und seither haben sich beide Sprachen unabhängig voneinander weiter entwickelt. Und die Punkte 1 und 2 waren bei diesen Entwicklungen auch nicht mehr so wichtig. Von Zeit zu Zeit hat man in beiden Sprachen auch mal nützliche Neuerungen der anderen übernommen, aber bei weitem nicht alle.

    Die von wob gezeigte Inkompatibilität ist sicherlich die wichtigste, weil jedes halbwegs komplexe C-Programm implizite Zeigerkonvertierungen benutzt, die in C++ nicht erlaubt sind. Ansonsten hat der C++-Standard ein ganzes Kapitel über Inkompatibilitäten mit C.

    Du kannst dich ja mal da dran versuchen, dieses vollkommen valide C-Programm (zugegeben: Es ist teilweise ziemlich schlechter C-Stil) als C++ zu übersetzen:

    #include <stdio.h>
    
    struct X { int i; struct X *next; };
    static struct X a;
    static struct X b = { 0, &a };
    static struct X a = { 1, &b };
    
    typedef int X;
    
    struct S
    {
      X x;
      int X;
    };
    
    enum color { red, blue, green };
    enum color c = 1;
    
    void arbitrary_args() {}
    
    void inline_type_def( struct S { int a; } arg ) {}
    
    struct W {
      struct Y {int i;} y;
    };
    struct Y yy;
    
    main(argc, argv)
    int argc;
    char *argv[];
    {
      if (sizeof(' ') > 1)
        puts("alles richtig");
      auto X virtual = 123;
      int vla[virtual];
      printf("main at: %p\n", &main);
      implicit_function(1, 1.2);
      char arr[100];
      if (sizeof(0, arr) == sizeof(char*))
        puts("Dies ist C");
      goto label;
      int initialized = 456;
      label:
      arbitrary_args(1,2,3);
      char array[4] = "abcd";
    }
    
    int implicit_function(int i, double d) {}
    

    Manche C++-Compiler werden manche der hier benutzten C-Features eventuell unterstützen. Also nicht wundern, wenn einzelne Zeilen ohne Änderung funktionieren 😃 . Das heißt aber noch lange nicht, dass sie gültiges C++ sind, dass überall funktioniert.
    Wie du vielleicht auch merkst, sind einige der hier demonstrierten Sachen relativ harmlos aussehend.



  • Hallo SeppJ,

    danke für Deine Antwort. Das von Dir angegebene C-Programm wird bei mir in Visual Studio 2008 nicht kompiliert und auch nicht in einem anderen reinen C-Compiler. Ich denke, dass es nichts bringt, jetzt detailliert auf die Fehlermeldungen der Compiler einzugehen.

    Aber im Prinzip hast Du Recht mit deinen Ausführungen.
    Ich kenne übrigens ein C-Programm, das nicht in meinem Visual Studio kompiliert wird, aber in meinem (zugegeben alten) C-Compiler und auch einwandfrei funktioniert:

    #include "stdio.h";
    int v,i,j,k,l,s,a[99]; 
    main () 
    { for(scanf("%d",&s);*a-s;v=a[j*=v]-a[i],k=i<s, 
    j+=(v=j<s&&(!k&&!!printf(2+"\n\n%c"-(!l<<!j), 
    " #Q"[l^v?(l^j)&1:2])&&++l||a[i]<s&&v&&v-i+j&&v+i-j)) 
    &&!(l%=s),v||(i==j?a[i+=k]=0:++a[i])>=s*k&&++a[--i]) 
    ; 
    }
    

    Es löst das n-Damenproblem (Schachbrett) und hat, wohl wegen seiner extremen Kompaktheit, mal einen Preis gewonnen.
    Ansonsten denke ich, dass meine Fragen sehr gut geklärt werden konnten und ich einiges gelernt habe.

    Freundliche Grüße
    cfrig


  • Mod

    Dann kann VS wohl weder die old style Funktionen (die sind auch nicht mehr offiziell, daher braucht ein C-Compiler das nicht zu können), noch C99 (weil Microsoft nicht auf C setzt). Ein "richtiger" C-Compiler hätte es schlucken sollen. Der Punkt, dass C keine strikte Untermenge von C++ ist, ist aber wohl vermittelt worden.



  • cfrig schrieb:

    int a;
    int b;
    a = 0;
    b = &a;
    ...
    cout << "b[-1] ist " << b[-1] << endl;
    cout << "
    (b-1) ist " << (b-1) << endl;
    cout << "b - 2 ist " << b - 2 << endl;
    cout << "b[-2] ist " << b[-2] << endl;
    cout << "
    (b-2) ist " << *(b-2) << endl;
    }

    Eieiei, was soll das denn? Da schüttelt es mich.



  • cfrig schrieb:

    Hallo SeppJ, hallo wob, [...]Ich lasse mich sehr gern belehren und nehme Eure Belehrungen aber auch deswegen an, [...] Die Aussage, dass C in C++ enthalten ist, wird gar nicht selten an Unis oder FHs gelehrt

    Und wenn mir jemand was Anderes erzählen wollte, wäre ich skeptisch.

    Daß C und C++ zwei vollkommen getrennte Sprachen seien, ist ausgemachter Käse.

    C++ ist historisch entstanden als objektorientierte, später auch generische, Erweiterung von C, und die Kompatibilität von C++ mit C ist weder Zufall noch unerwünschte Nebenwirkung, sondern ein Feature. Und was für eins!

    Die C-Kompatibilität ist eines der Features von C++, eines der wichtigsten. Denn damit war von Anfang an der Zugriff auf viele vorhandene C-Libraries sichergestellt, was dem Durchbruch von C++ geholfen haben dürfte.

    Mangel an vorhandenen Libraries ist nämlich ein Problem, das dem Durchbruch neuer Programmiersprachen öfters im Wege steht. Dieses Problem hatte C++ nicht. Dank C-Kompatibilität. Alles klar?



  • Hallo zufallswert,

    Dir auch vielen Dank für Deinen Beitrag. Ich denke, über das Ausmaß, die Ausprägung der Verschiedenheit von C und C++ kann man lange (endlos?) streiten und es ist wohl auch so, dass im
    Laufe der Zeit die Verschiedenheit eher zugenommen hat.
    Jedenfalls ist das, was Du schreibst, auch alles sehr richtig und plausibel.

    (Zu meinem ersten Beitrag von gestern (Testprogramm Zeigerarithmetik) muss ich schon heute sagen,
    dass es mir vorkommt wie wenn ein Kleinkind eine Glasflasche aus dem 3. Stock auf den Betonboden
    wirft, um zu sehen, ob sie auch wirklich kaputt geht. Es ist mir jetzt klar, dass über sowas nichts in irgendeinem Buch steht.)

    Nochmal vielen Dank an alle!


Anmelden zum Antworten