Java Kurze Frage: Warum bleiben die Werte nicht außerhalb der Funktion getauscht?

PGJ

Lt. Junior Grade
Registriert
Mai 2005
Beiträge
398
Hallo werte Java Experten,

da ich nicht so häufig programmiere, stolpere ich sehr schnell über scheinbar kleine Probleme. So auch bei diesem
Programm:
package test;

/**
*
*/
public class test{
/*
* Pointer-Tausch-Funktion
*/
public static void inplace_swap (int pointer_x, int pointer_y){
pointer_x = pointer_x ^ pointer_y; //Schritt 1
pointer_y = pointer_x ^ pointer_y; //Schritt 2
pointer_x = pointer_x ^ pointer_y; //Schritt 3
}

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
int x = 0b0101;
int y = 0b0011;

System.out.println("Pointer vor dem Tausch:");
System.out.println("X: " + Integer.toBinaryString(x));
System.out.println("Y: " + Integer.toBinaryString(y));
inplace_swap(x,y);
System.out.println();
System.out.println("Pointer nach dem Tausch:");
System.out.println("X: " + Integer.toBinaryString(x));
System.out.println("Y: " + Integer.toBinaryString(y));
}
}

Ausgabe:
Pointer vor dem Tausch:
X: 101
Y: 11

Pointer nach dem Tausch:
X: 101
Y: 11

Was macht das Programm? Es sollen einfach nur die Binär-Werte von X und Y getauscht werden. Dies geschieht aber leider nur innerhalb der interlace_swap Funktion (überprüft mit einem einfachen System.out.prinln der Werte innerhalb der Funktion). Jedoch ändern sich die Werte außerhalb / nach Aufruf der interlace_swap Funktion nicht.

Und ich möchte gerne wissen:
a) wieso ist das so? und
b) wie kann ich das beheben, so dass die Werte durch die Funktion auch wirklich geändert werden?

Schon mal im Voraus Danke für eure Hilfe ;-)
 
Warum nicht einfach:

Code:
public static void inplace_swap (int pointer_x, int pointer_y){
  int cache_pointer;
  cache_pointer = pointer_x; //Schritt 1
  pointer_y = pointer_x; //Schritt 2
  pointer_x = cache_pointer; //Schritt 3
}

Denn soweit ich weiß, kann Java gar nicht direkt auf Speicheradressen arbeiten.
 
java unterstützt kein call by reference. Die Variablen werden beim Aufruf kopiert, weshalb die ursprünglichen Variablen unverändert bleiben.
 
NiThDi schrieb:
Warum nicht einfach:

Code:
public static void inplace_swap (int pointer_x, int pointer_y){
  int cache_pointer;
  cache_pointer = pointer_x; //Schritt 1
  pointer_y = pointer_x; //Schritt 2
  pointer_x = cache_pointer; //Schritt 3
}

Denn soweit ich weiß, kann Java gar nicht direkt auf Speicheradressen arbeiten.

Es ist auch nicht mein Ziel wirklich auf die Adressen zuzugreifen, wie das in C möglich ist. Deine Lösung kenne ich auch, aber ich will gerne die Funktion so belassen wie sie ist.

Merkwürdigerweise werden die Warte ja getauscht... aber leider nur innerhalb der Funktion.
 
Du tauscht ja auch in der swap-Methode nur die Methodenparameter(pointer_x ; pointer_y).
Der Wert von x und y wird der Funktion ja nur übergeben, es wird nicht mit der Variable selber gearbeitet.
Du müsstest wenn dann auch etwas mit return zuweisen.
 
Wie schon gesagt kopierst du nur den Wert und übergibst keinen Pointer.
D.h. du änderst nur den Wert der lokalen Variablen.

Das gleichte gilt übrigens auch für Referenzen. Auch diese werden nur als Wert in eine neue Variable übergeben.
Man kann zwar direkt auf das Objekt, auf das die Referenz verweist zugreifen und dieses auch ändern (was dann auch außerhalb der Funktion wirksam wäre), wenn du der Referenz aber ein neues Objekt zuweist betrifft das nur der lokalen Referenzvariable.

Das hier könnte auch interessant sein:
http://stackoverflow.com/questions/40480/is-java-pass-by-reference
 
Du könntest x und y noch zu Klassenvariablen machen. Mit lokalen Variablen funktioniert das klassische Swap nicht.
 
Danke für eure Hilfe.

Wie carom es vorgeschlagen hat, habe ich die Variablen x und y jetzt als Klassenvariabeln deklariert. In der swap-Funktion musste ich entsprechend die Werte noch einmal diesen Variabeln zuordnen:
package aufgabe8;


/**
*
*
*/
public class Aufgabe8 {
static int x = 0b0101;
static int y = 0b0011;

/*
* Pointer-Tausch-Funktion
*/
public static void inplace_swap (int pointer_x, int pointer_y){
pointer_x = pointer_x ^ pointer_y; //Schritt 1
pointer_y = pointer_x ^ pointer_y; //Schritt 2
pointer_x = pointer_x ^ pointer_y; //Schritt 3

x=pointer_x;
y=pointer_y;
}

/**
* @param args the command line arguments
*/
public static void main(String[] args) {

System.out.println("Pointer vor dem Tausch:");
System.out.println("X: " + Integer.toBinaryString(x));
System.out.println("Y: " + Integer.toBinaryString(y));
inplace_swap(x,y);
System.out.println();
System.out.println("Pointer nach dem Tausch:");
System.out.println("X: " + Integer.toBinaryString(x));
System.out.println("Y: " + Integer.toBinaryString(y));
}
}
 
Nur warum dann noch als Parameter übergeben, so würde es ja auch gehen:

Code:
public static void inplace_swap (){
  x = x ^ y; //Schritt 1
  y = x ^ y; //Schritt 2
  x = x ^ y; //Schritt 3
}
 
Gibts in java kein ref oder out Keyword wie in C#?

Dämliche Frage evtl. aber ich kenne nur C# und die Sprachen sind ja recht ähnlich. :)
 
Zurück
Oben