Java - Call-by-value-, reference, name?
Hallo Freunde. Ich übe gerade für die Programmieren 1 Klausur. Könntet ihr mit bitte sagen, ob die folgenden Ergebnisse richtig sind? Danke.
"call-by-value": a[0] = 10 a[1] = 20 a[2] = 30 x = 1
"call-by-reference": a[0] = 42 a[1] = 10 a[2] = 30 x = 1
"call-by-name": a[0] = 10 a[1] = 42 a[2] = 20 x = 1
Wenn nicht richtig, dann wäre eine Begründung sehr nett.
Danke.
4 Antworten
Ja, das passt. Ich hab es mal in Java nachgebaut, um es besser prüfen zu können:
import java.util.*;
public class WSaltklausur {
static int x; // wird in main auf 0 gesetzt
static RefInt c[]; // brauchen wir für call-by-name außerhalb der main-Methode
static void magicByValue(int i, int j) {
if (i < j)
x += 1;
else
x -= 1;
j = i;
i = 42;
}
static void magicByReference(RefInt i, RefInt j) {
if (i.compareTo(j) < 0)
x += 1;
else
x -= 1;
j.value = i.value;
i.value = 42;
}
static void magicByName(String i, String j) {
if (getVariable(i).compareTo(getVariable(j)) < 0)
x += 1;
else
x -= 1;
getVariable(j).value = getVariable(i).value;
getVariable(i).value = 42;
}
public static void main(String[] args) {
// by value
x = 0;
int[] a = {10, 20, 30};
magicByValue(a[x], a[x+1]);
System.out.println(Arrays.toString(a) + " x = " + x);
// by reference
x = 0;
RefInt[] b = {new RefInt(10), new RefInt(20), new RefInt(30)};
magicByReference(b[x], b[x+1]);
System.out.println(Arrays.toString(b) + " x = " + x);
// by name
x = 0;
c = new RefInt[] {new RefInt(10), new RefInt(20), new RefInt(30)};
magicByName("c[x]", "c[x+1]");
System.out.println(Arrays.toString(c) + " x = " + x);
}
// sorry, ich hab's mir ein bisschen einfach gemacht. Geht bestimmt auch per Reflection oder so
private static RefInt getVariable(String name) {
return switch (name) {
case "c[x]" -> c[x];
case "c[x+1]" -> c[x+1];
default -> throw new IllegalArgumentException("Geht nur c[x] oder c[x+1] :-P");
};
}
}
class RefInt implements Comparable<RefInt> {
public int value;
public RefInt(int value) {
this.value = value;
}
public int compareTo(RefInt other) {
return Integer.compare(value, other.value);
}
public String toString() {
return Integer.toString(value);
}
}
Ergebnisse:
[10, 20, 30] x = 1
[42, 10, 30] x = 1
[10, 42, 20] x = 1
Also die hast du alle richtig.
Call-By-Name hab ich ehrlichgesagt zum ersten Mal gehört, aber ich hab es jetzt mal so nachgebaut, wie ich es verstanden hab.
Da bei Java alle primitiven Typen nur by value übertragen werden können und die Wrapper Klassen (z.B. Integer) alle immutable sind (also bei einer Zuweisung eines anderen Wertes wird automatisch ein neues Objekt erzeugt), habe ich eine eigene Klasse namens RefInt gebaut, wo man den Wert verändern kann.
Alle drei Antworten von dir sind richtig.
- Bei call-by-value ändern sich die Werte außerhalb der Funktion nicht.
- Bei call-by-reference ändern sich die Werte auch außerhalb der Funktion.
- Bei call-by-name werden die Argumente erst in der Funktion bei jedem Vorkommen neu evaluiert.
Herleitung für den letzten Punkt:
if a[x] < a[x+1]:
x += 1
else:
x -= 1;
a[x + 1] = a[x]
a[x] = 42
Auswertung:
a[0] < a[1] => 10 < 20 => wahr, x = 1
a[2] = a[1] = 20
a[1] = 42
=> [ 10, 42, 20 ]
By-value passt.
By-reference passt.
By-Name glaube nicht. Aber keine Ahnung, was das genau machen soll (evtl. erst beim Zugriff evaluieren?)
Also wenn ich das richtig sehe, kann der Code nicht funktionieren, da in Zeile 15 „}“ steht, obwohl diese Klammer hier nie geöffnet wurde.
Dazu stelle ich mir die Frage, was genau du bezweckst… (Bin kein Theoretiker, sondern eher Freund der praktischen Arbeit - Also kann auch sein, dass ich’s einfach nicht verstehe)
Call-By-Reference kann doch aber auch nicht funktionieren, da die Werte aus der Methode nicht wieder zurückgegeben werden oder liege ich falsch?
Ich denke er soll anhand eines gegebenen Programms (in java-Pseudocode) sageb, was für Ergebnisse rauskommen, wenn man Call-by-... verwendet.
Ja. Genau darum geht es. Ich würde von euch gerne meine Frage beantwortet haben bitte. Ich brauche die Lösung dringend. Danke
By-name evaluiert das Argument bei jedem Vorkommen im Funktionskörper neu (immer ausgehend vom Ausdruck, der übergeben wurde) und überträgt die Wertänderung auch nach außen.