Parameterübergabe mit Referenzen



  • #include <iostream.h>
    5:
    6: void swap(int &x, int &y); // Prototyp
    7:
    8: int main()
    9: {
    10: int x = 5, y = 10;
    11:
    12: cout << "Main. Vor Vertauschung, x: " << x
    << " y: " << y << "\n";
    13: swap(x,y);
    14: cout << "Main. Nach Vertauschung, x: " << x
    << " y: " << y << "\n";
    15: return 0;
    16: }
    17:
    18: void swap (int &rx, int &ry)   :warning: 
    19: {
    20: int temp;
    21:
    22: cout << "Swap. Vor Vertauschung, rx: " << rx << " ry: " << ry << "\n";
    23:
    24: temp = rx;
    25: rx = ry;
    26: ry = temp;
    27:
    28: cout << "Swap. Nach Vertauschung, rx: " << rx << " ry: " << ry << "\n";
    29:
    30: }
    

    Hallo allesamt,

    kann mir jemand bitte erklären, weshalb im Prototyp (Zeile 6) &x und &y angegeben werden und in Zeile 18 &rx und &ry??!!

    -Wäre es ein Fehler wenn ich statt &rx und &ry einfach auch &x und &y schreiben würde?

    -Habe es einfach mal im Code abgeändert und das Resultat ist das gleiche.

    Doch: Wieso hat der Autor dieses Beispieles &rx und &ry geschrieben?
    Das verstehe ich einfach nicht.

    Vielen Dank für eure Hilfe!!!



  • Das war wahrscheinlich ein Flüchtigkeits"fehler" des Autors oder des Übersetzers. Natürlich kannst du das r weglassen.



  • Du musst im Prototyp auch noch gar keine Variablennamen angeben soweit ich weiß. Die können sich getrost von den im Rumpf gewählten Namen unterscheiden.

    MfG SideWinder



  • Danke für eure Hilfe zu diesem Thema! Das ich so schnell eine Antwort erhalte hätte ich nie gedacht!! 🙂
    Viel Spass am Gerät!

    Anbei der obige Code stammt aus dem Buch: C++ in 21 Tagen



  • SideWinder schrieb:

    Du musst im Prototyp auch noch gar keine Variablennamen angeben soweit ich weiß. Die können sich getrost von den im Rumpf gewählten Namen unterscheiden.

    Du musst generell keine Variablennamen angeben 😉



  • Die Variablennamen sind nur Aliase, da kann also stehen was will.
    Im Prototyp sollten sie aber benannt werden, nicht das man sie in der Implementierung analog verwenden muss, aber zur Verständlichkeit macht man das so.
    Diese Variablen sind ja lokal zur Klasse. Wenn ich also in der Implementierung x und y angebe, dann werden die Werte mit dem Aliasnamen x und y der Klasse übergeben. Wenn man marie + luise angibt dann sind die Aliasnamen halt marie + luise. Interessiert also keinen.
    ABER: Derjenige der mal "deinen" Code lesen soll/muss, und in der Prototypisierung-Implementierung immer unterschiedliche Variablen sieht, der wird dir was husten weil man sich denken kann das die Übersichtlichkeit doch sehr darunter leidet.



  • foo(int &, char &);
    //...
    
    foo(int &bla1, char &bla2){
     //...
    }
    

    So sieht es der Standart vor.

    Ghost



  • ich wollte nur mal so was dazu schreiben. hat zwar nicht unbedingt mit den referenzen was zu tun aber aben mit dieser swap funktion.
    Du kannst die auch ohne hifsvariable schreiben. so:

    inline void myswap(int &x, int &y){
        x^=y^=x^=y;
    }
    

    funktioniert aber glaub ich nur mit ints. 😕



  • Ich schätze der xor-swap ist teurer als ein Dreieckstausch.



  • Ich schätze mein Compiler wirds schon wissen 😉

    MfG SideWinder



  • Walli schrieb:

    Ich schätze der xor-swap ist teurer als ein Dreieckstausch.

    ..XOR swap ist ein klein wenig schneller.



  • Habe keine Lust das auszumessen, aber ich habe was dazu gefunden...

    However on modern (desktop) CPUs, the XOR technique is considerably slower than using a temporary variable to do swapping. This is because modern CPUs strive to execute commands in parallel. In the XOR technique, the operands of all commands depend on the results of the previous command so they must be executed in strictly sequential order. If efficiency is of tremendous concern, it is advised to test the speeds of both the XOR technique and temporary variable swapping on the target architecture.

    ~Quelle: http://en.wikipedia.org/wiki/Xor_swap_algorithm#Usage_in_practice~


  • Mod

    nur mal so schrieb:

    ich wollte nur mal so was dazu schreiben. hat zwar nicht unbedingt mit den referenzen was zu tun aber aben mit dieser swap funktion.
    Du kannst die auch ohne hifsvariable schreiben. so:

    inline void myswap(int &x, int &y){
        x^=y^=x^=y;
    }
    

    funktioniert aber glaub ich nur mit ints. 😕

    funktioniert gar nicht wegen fehlender sequence points. im übrigen hatten wir das thema schon mal. xor kann - theoretisch - günstiger als dreieckstausch sein, wenn für den dreieckstausch variablen in den speicher ausgelagert werden müssen um ein freies register zu bekommen. in allen anderen fällen hat es keinerlei vorteile. und ganz nebenbei ist ein defekt drin wenn man versucht, eine variable mit sich selbst zu tauschen...



  • Walli schrieb:

    Habe keine Lust das auszumessen, aber ich habe was dazu gefunden...

    However on modern (desktop) CPUs, the XOR technique is considerably slower than using a temporary variable to do swapping. This is because modern CPUs strive to execute commands in parallel. In the XOR technique, the operands of all commands depend on the results of the previous command so they must be executed in strictly sequential order. If efficiency is of tremendous concern, it is advised to test the speeds of both the XOR technique and temporary variable swapping on the target architecture.

    Halt ich aber für wenig aussagekräftig, da bei der Version mit der temporären Variable die Operanden auch voneinander abhängen. Vorteile durch parallel arbeitende Instruction Pipelines lassen sich somit nur erzielen, wenn die Funktion geinlined und mit anderem Code gemischt werden kann. Dies ist aber bei der xor Variante genauso möglich. Für mich sind deshalb beide Möglichkeiten in der Theorie gleichschnell, sofern die CPU 'movs' und 'xors' gleichschnell verarbeiten kann.
    Der einzige Vorteil liegt hier bei xor, da dort kein zusätzlicher Speicher verbraucht wird.

    camper schrieb:

    und ganz nebenbei ist ein defekt drin wenn man versucht, eine variable mit sich selbst zu tauschen

    Kannst du das mal genauer erklären? Kann ich irgendwie nicht nachvollziehen.



  • ...geht schief

    void tausch (int& a, int& b)
    {
        a ^= b;
        b ^= a;
        a ^= b;        
    }
    
    ...
    tausch (a,a);
    ...
    


  • naja... ok es geht schief. stimmt 😕 aber wann "tauscht" man eine variabel mit siche selbst? ó_Ò



  • Green_Ghost schrieb:

    foo(int &, char &);
    //...
    
    foo(int &bla1, char &bla2){
     //...
    }
    

    So sieht es der stan**** vor.

    Ghost

    Standard hin oder her - meiner Meinung nach ist der Code leichter lesbar, wenn man im Prototyp Namen angibt. Was meinst du dazu?
    😉



  • camper schrieb:

    funktioniert gar nicht wegen fehlender sequence points.

    ich glaube, in diesem fall ist dem nicht so, da keine variable 2mal verändert wird:

    x=(y=(x^=y));

    bin mir aber nimmer sicher wegen der genauen regeln.


  • Mod

    x wird zweimal verändert



  • ...der XOR-Tausch nicht mit doubles.


Anmelden zum Antworten