Zeiger



  • rudiM schrieb:

    @Braunstein - Solch einen Kommentar hätte ich von Dir nicht erwartet, schade.
    Gruß Rudi

    Dein Code war einfach völlig falsch.
    1. Die Deklaration der Funktionsparameter stimmt nicht. Dort nur einen Typ angeben und dann mehrere Parameter aufführen geht vielleicht in Pascal, aber nicht in C++.
    2. Du übergibst in der Funktion Referenzen auf int und willst denen Zeiger auf int zuweisen. Auch falsch.
    Ich wollte eigentlich nur darauf hinweisen, dass man sich den Code ansehen sollte bevor man ihn postet. Wenn es zu hart rübergekommen ist, dann entschuldige ich mich hiermit bei dir. Ok?



  • alti23 schrieb:

    Hallo,

    @ _DocShoe_: Ich seh da keinen Sinn drin, komplizierten Code hier zu posten, wo doch die einfache Funktion swap mein Problem ganz gut erklärt.

    Nur für mich zum Verständnis:

    void swap(int *x, int *y)
    {
    int *temp = x;

    x = y;
    y = temp;
    }

    Nach Verlassen der Funktion ist x bzw der Speicherbereich, auf den x zeigt, ungültig, da das lokale temp auch darauf zeigt und nach Verlassen der Funktion der Bereich von temp und somit auch von x freigegeben wird ?

    Tja, und genau da sehe ich das Problem. Du postest einen Codeschnipsel, der ein einfaches Problem kompliziert löst. Ich hätte jetzt sofort sagen können, dass du deine swap Funktion wegwirfst und stattdessen std::swap benutzt, aber vorher wollte ich noch einmal nachfragen, ob du nicht vielleicht doch etwas anderes machst, was man mit std::swap nicht lösen kann. Genausogut könnte ich keinen Sinn darin sehen, auf ein Posting zu antworten, dass das Problem nicht präzise beschreibt. Häufig sind sich Fragesteller auf Anfängerniveau über die Art des Problems nicht bewusst bzw. es fehlt Basiswissen, um das Problem zu beschreiben. Und genau aus diesem Grund möchte ich wissen, was genau du machen willst um ggf. Alternativen anzubieten.
    Nach allen Informationen, die ich jetzt habe, rate ich dir:
    Wirf deine swap Funktion weg und benutze std::swap.



  • PS:
    Mit kompliziertem Code meine ich nicht den Zitierten, sondern den aus dem Eingangsposting.



  • DocShoe schrieb:

    [...] Häufig sind sich Fragesteller auf Anfängerniveau über die Art des Problems nicht bewusst bzw. es fehlt Basiswissen, um das Problem zu beschreiben. [...]

    Ganz genau 👍 Vor nicht allzu langer Zeit war ich selbst noch blutiger Anfänger (jetzt bin ich nur noch Anfänger 😉 ) und bin immer wieder überrascht, wohin meine Ausgangsfragen führen... Das kann man aber nur erleben, wenn man mit seinen Quelltexten und Gedanken nicht hinterm Berg hält und nicht zu faul ist ordentlich (auf dem derzeitigen Niveau vollständig und durchdacht) zu posten. Ausserdem sollte man bereit sein den Hinweisen der erfahrenen Nutzer nachzugehen, auch wenn man im 1. Moment keinen Bezug zur gefragten Problematik herstellen kann.
    JM2C 🙂



  • Hallo,

    @Kolumbus: Du warst der Lösung wohl am nächsten, ich war wie so oft voreilig.

    void swap(int *&x, *&y) 
    { 
        int *temp;
        temp = x; 
        x = y; 
        y = temp; 
    }
    

    ich hab die beiden Sternchen wohl selbst nicht beachtet. Schande über mich.
    @ Braunstein: is ok.
    Gruß Rudi



  • Da fehlt noch ein int.
    So ist es dann OKer. 😉

    void swap(int *&x, int *&y)
    {
        int *temp = x;
        x = y;
        y = temp;
    }
    


  • Oops, i did it again..............

    Aber das bringt mich auf die Frage: Wieso schafft es der Compiler mehrere Variablen den gleichen Typs anlegen zu lassen:

    void f()
    {
    int a,b,c,d;
    
    usw.
    }
    

    aber nicht innerhalb eines Funktionsaufrufes? Wäre doch praktisch, oder?
    Gruß, der schreibfaule Rudi



  • rudiM schrieb:

    aber nicht innerhalb eines Funktionsaufrufes?

    Innerhalb eines Funktionsaufrufes darfst du ohnehin nichts deklarieren.

    Daß du in Funktionssignaturen (auf die du dich vermutlich beziehst) nicht mehrere Variablen des gleichen Typs ohne erneute Nennung desselben deklarieren kannst, dürfte darin begründet sein, daß dir in deklarativem Kontext zwei Terminalsymbole zur Verfügung stehen (' , ' und ' ; '), in der Funktionssignatur jedoch nicht. Der Compiler betrachtet Variablendefinitionen in Funktionssignaturen insofern nicht gesondert, nur eben mit einem anderen Terminalsymbol. Auch in normalem Kontext geht folgendes nicht:

    int a, b, float c;
    

    In diesem Kontext trennt ' ; ' Deklarationen und ' , ' Bezeichner. In einer Funktionssignatur trennt ' , ' Deklarationen, und ' ; ' ist nicht erlaubt. Wäre das anders, so stünde auch einer Mehrfachverwendung von Typen wie in Pascal nichts im Wege:

    void foo (int a, b; float c) { ... }
    


  • Hi,

    zu dem viel geliebten Thema Zeiger und gerade dem Beispiel in diesem Thread habe ich noch eine Frage. Mir sind folgende 2 Versionen bekannt:

    Vertauschen von 2 Variablen mittels Zeiger

    void swap(int *x, int *y) 
    { 
     int temp = *x; 
     *x = *y; 
     *y = temp; 
    }
    

    Vertauschen mittels Referenzen

    void swap(int &x, int &y) 
    { 
     int temp = x; 
     x = y; 
     y = temp; 
    }
    

    Doch was bedeutet diese Version ? Einen Zeiger auf eine Referenz ?

    void swap(int *&x, int *&y) 
    { 
     int *temp = x; 
     x = y; 
     y = temp; 
    }
    

    Kann mir das bitte jemand erklären, macht das Sinn, das so zu tun ? Vorteile ?



  • Bei den oberen beiden Versionen werden die Werte getauscht (auf die die Zeiger zeigen). Bei der letzten Version werden die Zeiger getauscht (die Werte werden nicht geändert, dafür zeigen die Zeiger nun jeweils auf den anderen Wert).

    Gruß KK



  • Vielen Dank für Deine Erklärung, KK. Um das Ganze noch abzurunden, kannst Du mir noch sagen wann man welche Methode benutzt, also wäre die Variante 3 deutlich schneller als die andern zwei oder ist das egal ?



  • Variante 3 macht etwas ganz anderes als die anderen beiden Varianten (Zeigertausch wie schon erklärt). Varianten 1 und 2 sind ebenfalls nicht äquivalent einsetzbar da der Aufrufsyntax unterschiedlich ist.
    Was habt ihr alle gegen std::swap? 🙂


Anmelden zum Antworten