Java - Call-by-value-, reference, name?

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 ]

HosseinEpiCure 
Beitragsersteller
 13.07.2023, 21:18

Ich danke dir ;)

0

By-value passt.

By-reference passt.

By-Name glaube nicht. Aber keine Ahnung, was das genau machen soll (evtl. erst beim Zugriff evaluieren?)


regex9  13.07.2023, 21:11

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.

1

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?

Woher ich das weiß:Hobby – Interessierter Hobby-Softwareentwickler seit 2016

Destranix  13.07.2023, 19:55

Ich denke er soll anhand eines gegebenen Programms (in java-Pseudocode) sageb, was für Ergebnisse rauskommen, wenn man Call-by-... verwendet.

0
HosseinEpiCure 
Beitragsersteller
 13.07.2023, 20:11
@Destranix

Ja. Genau darum geht es. Ich würde von euch gerne meine Frage beantwortet haben bitte. Ich brauche die Lösung dringend. Danke

0