Anzeige:
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 15 von 16

Thema: Call-by-Value und Call-by-Reference

  1. #1
    Registrierter Benutzer
    Registriert seit
    02.12.2005
    Ort
    Ebern
    Beiträge
    19

    Call-by-Value und Call-by-Reference

    Hi!

    Es geht gerade auf die Prüfungen zu, und da kam folgende Frage auf:

    In Java wird einer Funktion ein Parameter vom Typ array automatisch per Call-by-Reference übergeben, oder? Bei c/c++ ist das umgekehrt, also wenn ich kein & in der Parameterliste dazu schreibe dann wird das array doch Call-by-value übergeben und mit dem & Call-By-Reference? Wenn dem so ist, kann ich in Java auch Call-By-Value machen?

    Wir sind da grad alle etwas verwirrt.
    MfG

  2. #2
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    In Java kannst du nicht auswählen. Alle Basisdatentypen (int, char, double) werden via Call-By-Value übergeben, alle alle Objekte/Arrays (auch Int-Objekte) werden by Reference übergeben.

    Arrays in C++ übergibst du übrigens auch immer by Reference.
    Code:
    #include <iostream>
    
    void func(int ref[]) {
            ref[0] = 3;
    }
    
    int main(int argc, char* argv[]) {
            int a[] = { 1, 2, 3 };
            std::cout << a[0] << a[1] << a[2] << std::endl;
            func(a);
            std::cout << a[0] << a[1] << a[2] << std::endl;
            return 0;
    }
    gibt:
    Code:
    peschmae@sid:/tmp$ ./a.out 
    123
    323
    Grund: Der Name des Arrays wird durch die Speicheradresse ersetzt, an der der Arrayinhalt beginnt (manche Leute nennen das dann einen "const pointer").

    Für andere Sachen kannst du in C++ aber wählen was du tun willst.

    MfG Peschmä
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  3. #3
    Registrierter Benutzer
    Registriert seit
    02.12.2005
    Ort
    Ebern
    Beiträge
    19
    Ok, danke. Das bringt dunkel ins Licht. D.h. man müsste sich in C++ noch selbst eine Kopierfunktion schreiben, wenn man mit einer Array-Kopie arbeiten wollte, richtig?

    Für andere Sachen kannst du in C++ aber wählen was du tun willst.
    Indem ich & in der Parameterliste dahinterschreibe, oder bin ich da aufn Holzweg?

    Grosses Dankeschön nochmal.

    MfG

  4. #4
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Zitat Zitat von miracoli Beitrag anzeigen
    Ok, danke. Das bringt dunkel ins Licht. D.h. man müsste sich in C++ noch selbst eine Kopierfunktion schreiben, wenn man mit einer Array-Kopie arbeiten wollte, richtig?
    Für eine deep-copy ja. Wobei es da in der STL sicher fertige Algorithmen für den Zweck gibt.

    Indem ich & in der Parameterliste dahinterschreibe, oder bin ich da aufn Holzweg?
    Genau - entweder ein & für als reference; ein * für als pointer und nichts für als value.

    In Java wird dir halt gleich das vorgeschrieben was meist das "richtige" ist.

    MfG Peschmä
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  5. #5
    Registrierter Benutzer
    Registriert seit
    09.07.2001
    Beiträge
    10
    Java hat kein Call by reference, sondern Call by value bzw. Kopien der Objektreferenzen.

    Code:
    void called(Foo barcopy) {
        // die kopierte Referenz referenziert null, nicht mehr das
        // ursprüngliche Objekt
        barcopy = null; 
    }
    
    void caller() {
        Foo barorg = new Foo();
    
        // die erste Referenz barorg zeigt noch immer auf das erzeugte 
        // Objekt, ist nicht null!
        called(barorg); 
    }

  6. #6
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Genau das ist ja Call by Reference. Das macht in C++ auch genau das - die Referenz oder der Pointer kommt quasi an Stelle des Values aufn Call-Stack. Ist ja klar dass nur die Referenz aufm Stack geändert wird, wenn du das in der Funktion machst.

    MfG Peschmä
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  7. #7
    Registrierter Benutzer
    Registriert seit
    09.07.2001
    Beiträge
    10
    Nein, das ist nicht gleich in C++ und Java.

    Code:
    #include <iostream>
    #include <string>
    using namespace std;
    
    class Blah {
    	string x;
    
    	public:
    		void blah (string);
    		string getX() { return x; }
    };
    
    void Blah::blah(string a) {
    	x = a;
    }
    
    void swap(Blah &b1, Blah &b2) {
    	Blah tmp = b1;
    	b1 = b2;
    	b2 = tmp;
    }
    
    int main() {
    	Blah foo;
            Blah bar;
    	foo.blah("foo");
    	bar.blah("bar");
    	swap(foo, bar);
    	cout << "foo.x: " << foo.getX();
    	cout << "bar.x: " << bar.getX();
    	return 0;
    }
    Code:
    public class Blah {
    	String x = null;
    	
    	Blah() {
    	}
    
    	void setX(String a) {
    		x = a;
    	}
    	
    	/**
    	 * @param args
    	 */
    	public static void main(String[] args) {
    		Blah bar = new Blah();
    		bar.setX("bar");
    		Blah foo = new Blah();
    		foo.setX("foo");
    		swap(bar, foo);
    		System.out.println("bar: "+ bar.x);
    		System.out.println("foo: " +foo.x);
    	}
    
    	public static void swap(Blah b1, Blah b2) {
    		Blah tmp = b1;
    		b1 = b2;
    		b2 = tmp;
    	}
    }
    C++: Variable foo zeigt auf das alte Objekt "bar", Variable bar auf das alte Objekt "foo" nach dem Austausch

    Java: Die Variablen (Referenzen) foo und bar zeigen auf die ursprünglichen Objekte, beim swappen werden nur die kopierten Referenzen (lokal in der swap-Funktion) geändert.

  8. #8
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Oh, stimmt. Mein Fehler.

    Java ist also quasi da hier:
    Code:
    #include <iostream>
    #include <string>
    using namespace std;
    
    class Blah {
        string x;
    
        public:
            void blah (string);
            string getX() { return x; }
    };
    
    void Blah::blah(string a) {
        x = a;
    }
    
    void swap(Blah b1, Blah b2) {
        Blah tmp = b1;
        b1 = b2;
        b2 = tmp;
    }
    
    int main() {
        Blah foo;
        Blah& rfoo = foo;
        Blah bar;
        Blah& rbar = bar;
        rfoo.blah("foo");
        rbar.blah("bar");
        swap(rfoo, rbar);
        cout << "foo.x: " << rfoo.getX() << endl;
        cout << "bar.x: " << rbar.getX() << endl;
        return 0;
    }
    MfG Peschmä
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  9. #9
    Registrierter Benutzer Avatar von BlueJay
    Registriert seit
    27.08.2004
    Beiträge
    825
    Wenn ihr Pointer und Konsorten mit ins Spiel bringt, hört lieber auf, zu diskutieren. Das geht aus wie's Hornberger Schießen, und letztendlich hat jeder recht. Hatten wir alles in dclj schon.
    Eigentlich ganz einfach, wenn man's weiss!

  10. #10
    Registrierter Benutzer
    Registriert seit
    02.12.2005
    Ort
    Ebern
    Beiträge
    19
    Danke nochmal!

    MfG

  11. #11
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Zitat Zitat von krabat Beitrag anzeigen
    ...Java: Die Variablen (Referenzen) foo und bar zeigen auf die ursprünglichen Objekte, beim swappen werden nur die kopierten Referenzen (lokal in der swap-Funktion) geändert.
    Aber nur dann, wenn Du mit den Objekten an sich hantierst! Wenn Du in einer lokalen Funktion z. B. eine Property eines übergebenen Objekts änderst, dann wird gar nix kopiert, sondern mit der übergebenen Objektreferenz gearbeitet:
    Code:
    jan@jack:~/Development/workspace/RefTest/src> cat RefCalled.java
    
    public class RefCalled {
    
            private String x = null;
    
            public String getX() {
                    return x;
            }
    
            public void setX(String x) {
                    this.x = x;
            }
    }
    jan@jack:~/Development/workspace/RefTest/src> cat RefCaller.java
    
    public class RefCaller {
    
            public static void main(String[] args) {
                    RefCalled cls = new RefCalled();
                    cls.setX("main");
                    System.out.println(cls.getX());
                    callRef(cls);
                    System.out.println(cls.getX());
            }
    
            private static void callRef(RefCalled r) {
                    r.setX("callRef");
            }
    
    }
    jan@jack:~/Development/workspace/RefTest/bin> /usr/java/jdk1.5.0_04/jre/bin/java RefCaller
    main
    callRef
    Jan

  12. #12
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Das war ja auch das was er gesagt hat

    MfG Peschmä
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  13. #13
    ekseil
    Gast
    Zitat Zitat von krabat Beitrag anzeigen
    Java hat kein Call by reference, sondern Call by value bzw. Kopien der Objektreferenzen.

    Code:
    void called(Foo barcopy) {
        // die kopierte Referenz referenziert null, nicht mehr das
        // ursprüngliche Objekt
        barcopy = null; 
    }
    
    void caller() {
        Foo barorg = new Foo();
    
        // die erste Referenz barorg zeigt noch immer auf das erzeugte 
        // Objekt, ist nicht null!
        called(barorg); 
    }
    Augenblick mal. Wenn nur die Objektreferenzen kopiert werden, dann heißt das schon call by value?

    ... wieder was gelernt.

  14. #14
    Registrierter Benutzer Avatar von peschmae
    Registriert seit
    14.03.2002
    Ort
    Schweizland
    Beiträge
    4.549
    Achso, nein, das natürlich nicht. Zumindest würde ich das nicht so bezeichnen. Ich hab das jetzt als "call by value der Objektreferenzen" verstanden.

    MfG Peschmä, mit der Hoffnung mal gerade noch darum herum gekommen zu sein, Blödsinn geschrieben zu haben
    The greatest trick the Devil ever pulled was convincing the world he didn't exist. -- The Usual Suspects (1995)
    Hey, I feel their pain. It's irritating as hell when people act like they have rights. The great old one (2006)

  15. #15
    Registrierter Benutzer
    Registriert seit
    09.07.2001
    Beiträge
    10
    In Java-FAQs, Uniskripte etc. wird es normalerweise als "Call by value" bezeichnet, siehe bspw.

    http://www-128.ibm.com/developerwork...raxis/pr1.html
    http://www.pst.ifi.lmu.de/lehre/SS03...folien6a_6.pdf

    Aber wichtig ist natürlich zu verstehen, dass die Objekte selbst bei der Parameterübergabe nicht kopiert werden. Ein lapidares "Call by value" kann da sicherlich schnell zu einem Mißverständnis führen

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •