Warum kann man Pointer nicht addieren?



  • Hallo liebe Gemeinde.

    Ich hätte eine Frage bzgl. Pointer.

    Hier einmal ein einfacher Programmcode:

    #include <iostream>
    using namespace std;
    
    int main()
    {
      float a,b,c;
      float *pa=0, *pb=0, *pc=0;
    
      cout << "\tAddieren ueber Pointer!" << endl;
      cout << "Geben Sie zwei Zahlen ein!" << endl;
      cin  >> a >> b;
    
      cout << endl;
      cout << "Normale Addition: " << endl;
      c = a+b;
      cout << "\t" << a << " + " << b << " = " << c << endl;
      cout << endl;
    
      cout << "Addition ueber Pointer: " << endl;
      pa = &a;
      pb = &b;
      pc = &c;
      pc = pa + pb;
      cout << "\t" << pa << " + " << pb << " = " << pc << endl;
      cout << endl;
    
      return 0;
    }
    

    Nun kommt jedoch bei mir folgende Fehlermeldung:

    error 2110: '+': Zwei Zeiger können nicht addiert werden.
    

    Nun zu meiner Frage...

    Ich dachte, ich kann so den Inhalt der Adressen miteinander addieren? Wenn es so nicht funktioniert, wie funktioniert es dann??

    Vielen Dank für die Antworten im Voraus.

    Gruß

    Max


  • Mod

    Das ist keine erlaubte Operation, weil es einfach keinen Sinn macht. Das wäre wie die Addition zweier Telefonnummern. Dadurch, dass dies nicht unterstützt wird, kann verhindert werden, dass es versehentlich passiert. Wenn du es unbedingt mit Gewalt versuchen musst, wandele die Adressen in zwei intptr_t um und addiere dann diese.

    edit: Wie ich sehe, ist genau das passiert, was ich gesagt habe: Du hast es versehentlich gemacht (bzw. aus Unkenntnis). Dem Text in deinem Programm nach zu urteilen, willst du nicht die Pointer adiieren, sondern das worauf sie zeigen. Letzteres ist natürlich überhaupt kein Problem. Du müsstest bloß erst einmal lernen, wie das mit den Pointern geht:
    http://www.youtube.com/watch?v=i49_SNt4yfk&feature=youtube_gdata



  • Hallo,
    Zeiger lassen sich verschieben. Es macht aber doch überhaupt keinen Sinn einen Zeiger um einen Wert zu verschieben, der in einem anderen Zeiger steht. Als Enwickler interessiert dich doch gar nicht, welcher Wert ein Zeiger hat, du willst doch nur, dass der Zeiger auf das richtige zeigt. Du würdest deinen Zeiger also um irgendeinen Wert verschieben, den du gar nicht kennst, und der Zeiger würde irgendwo hinzeigen (höchst wahrscheinlich gehörte dir der Speicher gar nicht, worauf er zeigen würde)
    Kurz und knapp: Es macht keinen Sinn.



  • SeppJ schrieb:

    Das ist keine erlaubte Operation, weil es einfach keinen Sinn macht. Das wäre wie die Addition zweier Telefonnummern. Dadurch, dass dies nicht unterstützt wird, kann verhindert werden, dass es versehentlich passiert. Wenn du es unbedingt mit Gewalt versuchen musst, wandele die Adressen in zwei intptr_t um und addiere dann diese.

    Ersteinmal Danke für die Antworten.

    Aber was meinst Du mit intptr_t?? Meinst Du damit, die Adressen int int Pointer umzuwandeln??

    Bei http://www.pronix.de/comment/site-958/open-2517/site-1.html heißt es, dass ein intptr_t ein signed Integer ist, von der gleichen Bitbreite wie ein Pointer.

    Stimmt das? Stimmt es auch, dass ich stdint.h mit einbeziehen muss? Kann man den intptr_t ganz einfach wie einen Pointer deklariern oder muss ich dabei etwas beachten? Leider kenne ich diesen Datentyp noch nicht...



  • Vergiss das mit dem intptr_t lieber ganz schnell wieder, der ist nicht für deinen Anwendungsfall gedacht. Schnapp dir lieber dein C++ Buch und arbeite das Kapitel über Pointer und Pointerarithmetik noch einmal durch.



  • Habe endlich die Lösung des "Problems".

    Hier der richtige Programmcode:

    #include <iostream>
    using namespace std;
    
    int main()
    {
      float x;
      float *px = &x;
      float y;
      float *py = &y;
      float z;
      float *pz = &z;
    
      cout << "\t Addition!" << endl;
      cout << endl;
    
      cout << "Geben Sie zwei Zahlen ein!" << endl;
      cin  >> x >> y;
    
      cout << "Normale Addition!" << endl;
      z = x + y;
      cout << x << " + " << y << " = " << z << endl;
      cout << endl;
    
      cout << "Addition ueber Pointer!" << endl;
      *pz = *px + *py;
      cout << *px << " + " << *py << " = " << *pz << endl;
      cout << endl;
    
      return 0;
    }
    

    Ich hoffe, dass es dem Standard entspricht???

    Falls nicht, bitte sagen.

    Gruß

    Max



  • Warum ständig endl ?



  • Dann wird es in der Ausgabe übersichtlicher...



  • Er meint, warum endl statt '\n'. endl macht neben dem Zeilenumbruch noch ein flush.



  • Wie?? Was meinst Du mit flush??





  • Habe ich das richtig verstanden, dass die Anweisung

    cout << endl;
    

    alles auf null setzt und nur für einen Zeilenumbruch die Anweisung

    cout << "\n"
    

    besser ist??



  • Eigentlich ist es total egal, solange du nix I/O-lastiges schreibst.

    Hintergrund ist, dass auf die Konsole schreiben sehr langsam ist, deswegen wird Text im Stream gesammelt und viel auf einmal geschrieben. Mit flush/endl sagst du dem Stream, dass er SOFORT alles schreiben soll, dh. möglicherweise werden mehr langsame Schreiboperationen ausgeführt.

    Im Zweifelsfall einfach '\n'. endl/flush nur, wenn du die Ausgabe sofort brauchst und eine Verzögerung nicht akzeptabel ist.



  • Ok ... werde ich mir merken...

    Mein Dozent im Fach Datenverarbeitungstechnik, wozu eben diese C++ Programmierung gehört, verwendet eigentlich nur

    cout << endl;
    

    Anweisungen, um einen Zeilenumbruch zu machen.

    Dass es den Hintergrund hat, wusste ich an der Stelle nicht.

    Gruß



  • Wie gesagt, es ist egal ob das Programm jetzt 300ms oder 400ms läuft.
    Nur zb in einem Logging-Framework, das 100 Ausgaben pro Sekunde schreibt, kann so ein Flush Probleme machen.



  • std::endl() beinhaltet auch die unterschiedlichen Line-Endings (\n vs \r\n).



  • theta schrieb:

    std::endl() beinhaltet auch die unterschiedlichen Line-Endings (\n vs \r\n).

    New-line in C++ ist immer '\n', wie die Repräsentation des Betriebssystems aussieht ist egal.


  • Mod

    theta schrieb:

    std::endl() beinhaltet auch die unterschiedlichen Line-Endings (\n vs \r\n).

    Diese Konvertierung spielt sich auf viel tieferer Ebene ab (das ist zum Beispiel das, was das binary bei fstreams beeinflusst). endl ist wirklich nur eine Abkürzung für '\n' << flush() .


Anmelden zum Antworten