Diskussion:Namensparameter

aus Wikipedia, der freien Enzyklopädie

Kapselung

Nachdem ich in alten Zeiten "call by name" durchaus benutzt habe, habe ich mich beim Paradigmenwechsel zum Objektorientierten Programmieren immer 'mal wieder gefragt, ob der "call by name" von Algol-60 nicht etwas ähnliches wie Objektorientierung schon vorausgesehen hatte. Wer hat dazu eine Idee/Kommentar (Bernhard, 21-Feb-2005, 16:26).

Mit Namensparametern kann man sicher - ähnlich wie etwa mit Funktionszeigern in C - recht viel anstellen. Objektorientierung enthält aber Kapselung von Daten und Methoden, Vererbung, Überladen von Namen etc. Inwieweit das in Algol-60 so implementierbar ist, ist mehr als fraglich. Von Vorraussicht kann meiner bescheidenen Meinung nach hier keine Rede sein, obwohl Algol-60 natürlich Klasse ist. --Hubi 17:25, 21. Feb 2005 (CET)

Hmm, da hast Du vollkommen Recht, die Apsekte der Kapselung sind nicht vorhanden. Meine Frage bezog sich auf den Aspekt der dynamischen Bindung. (Bernhard, 23-Jan-2007, 12:10)

Referenzparameter

Weil das vielfach falsch verstanden wird, hier nochmal ausführlich:

Pascal hat Referenzparameter und Wertparameter (Standard Wert, mit VAR Referenz).

C hat nur Wertparameter. Der Aktualparameter bleibt IMMER unverändert. Felder existieren in C strenggenommen nicht, es gibt lediglich Pointer. Auch diese Pointer werden nicht verändert. Natürlich kann sich der Wert ändern, auf den ein Pointer zeigt. Man kann sich natürlich vorstellen, es gebe Felder, weil das in schöneren Sprachen so ist. Es bleibt aber dabei, dass lvalues nur pointer sind (zu empfangen als z.B. int *x , int* x ist nicht korrekt geschrieben, int[] x gibt es nicht und int x[] ist in Standard-C nicht erlaubt).

In C++ gibt es Referenzparameter und Wertparameter (Standard Wert, mit & Referenz). Das ist neben der Objektorientierung eine der wesentlichen Neuerungen in C++ gegenüber C, macht es doch die Übergabe von structs (also Klassen) ohne Bitkopie möglich.

In Fortran gibt es nur Referenzparameter. Wenn kein lvalue, sondern z.B. eine Konstante übergeben wird, kann es sein, dass die Konstante geändert wird, wenn der Formalparameter verändert wird. WRITE (*,*) 0 ergibt dann z.B. 1 (!)

In Java gibt es _keine_ Referenzparameter, wie im Text angegeben! Java kennt auch, wie C nur call-by-value. Ein Referenzvariable - also z.B. eine Referenz auf ein Objekt einer Klasse A wird auch als _Wert_ an eine Methode übergeben. Dass dies call-by-value geschieht erkennt man, wenn man versucht dieser übergebenen Referenz innerhalb der Methode einen anderen Wert (eine Referenz auf ein anderes Objekt der selben Klasse A oder Subklassen von A) zuweisst. Diese Wertänderung müsste, wenn die Übergabe call-by-reference geschieht, nach der Rückkehr der Methode wieder sichtbar sein - ist aber nicht der Fall! Deshalb werden in Java auch Referenzen nur call-by-value übergeben - das wird sehr sehr häufig falsch gesehen! Ein Beispiel:

class A 
{
    public int v;
    public A(int v) {
         this.v = v;
    }    
    int getV() {
        return v;
    } 
}

class Main 
{
    private static void method(A a) {
        a = new A(3);
    }
    public static void main(String[] args) {
        a = new A(5);
        method(a);
        System.out.println(a.getValue());  // gibt 5 und nicht 3 aus - also call-by-value!!!
    }
}

--Voc 12:59, 19. Dez 2006 (CEST)

Name-Parameter sind, weil meines Erachtens nach total abstrus, nur in alten Sprachen enthalten. Selbst Fortran, eine der ältesten Sprachen, hat das nicht.

Gerade diese Einzigartigkeit des Nameparameters ist doch das entscheidend enzyklopädische.

Falls du die Existenz von Feldern in C verneinst, hast du recht. Allerdings hat C Feldkonstanten, denn
          int x[]={0, 1, 2, 3, 4 };
ist kein Pointer, sondern ein Feld, wenn auch x die Semantik eines Zeigers besitzt. Bei einem Feld ist der Aktualparameter der
Inhalt des Feldes und der wird verändert. Hubi 16:35, 9. Aug 2005 (CEST)
Zur Illustration vielleicht ein Beispiel in C (das angeblich nur Wertparameter hat) und Pascal mit Wert- und Referenzparametern:
(ohne Übersetzung)
        int x[3];
        f(y) int y[];
        {  y[1]=815; 
        }
        main()
        { x[1]=10; x[2]=100;
          f(x);
          printf("%d",x[1]);
       }
       program p;
       type x_type is array [0..2] of integer;
       var x: x_type;
       procedure f(y: x_type); 
         begin
            y[1]:=815;
         end;
       begin
           x[1]:=10; x[2]:=100;
           f(x);
           writeln(x[1]);
        end.
C müsste hier 815, Pascal jedoch wegen des Wertparameter-Feldes 10 ausgeben. Erst wenn ich
            procedure f(var y: x_type)
also einen Referenzparameter verwende, erreiche ich das Verhalten von C. So ist die Aussage C hat Felder als Referenzparameter gemeint: --Hubi 16:55, 9. Aug 2005 (CEST)


Man kann auch in C auf Variablen schreibend zugreifen, die an Funktionen übergeben werden. Das stimmt. In Deinem Beispiel ist y der Parameter. y wird nicht verändert. Eine Variable, die über y referenziert wird, wird verändert. In Pascal gibt es wirklich Felder, die als Parameter übergeben werden können. Dieses Feld kann verändert werden.

Damit der Unterschied zwischen echten Feldern und Pointer-Pseudo-Feldern klar wird, hier ein kleines Beispiel:

int x[3];
int z[3];
f(y) int y[];
{  y[3]=815; 
}
main()
 { x[1]=10; x[2]=100;
  f(x);
  printf("%d %d",x[1], z[i]);
 }

So steht es nämlich mit der Referenz in C... Mvb 10.8.2005 13:40

Abgesehen davon, das dies nicht läuft (i muss wohl 0 heissen), beweist das gar nichts. Dass Feldüberlauf nicht geprüft wird, heisst nicht, dass keine Felder existieren. Warum behandeln alle C-Tutorials und Lehrbücher wohl Felder? Natürlich weil C keine Felder hat. Murksprogramme zeigen gar nix. --Hubi 16:27, 10. Aug 2005 (CEST)

Klar, muss 0 heißen. Feldüberläufe kann es bei Arrays eigentlich nicht geben, wenn der Compiler gut ist. Aber, naja, in der Praxis prüft das keiner, weil es zuviel Zeit kostest, weiß ich auch.

Aber anderes Beispiel

int x[4];
f(y) int y[];
{  y[0]=815; 
}
main()
 { x[0]=10; x[1]=100; x[2]=200; x[3] = 0;
  f(x+1);
  f(x+2);
  printf("%d",x[1]);
 }

Was ist y? Ein Feld kann es ja nicht sein, es gibt nur eins, das ist x und x ist ungleich x. Ist y vielleicht ein Unterfeld? Wie groß ist y dann? Ist y eim zweiten Aufruf auch ein Unterfeld, welches Element gehört zum ersten, welches zum zweiten? Alles ganz ungünstige Fragen für die Autoren, die behaupten, C habe Felder. Man kann C wesentlich besser verstehen, wenn man sich nur an Pointern orientiert. Achja, was ist mit

freimachen (y) int y[];
{
  free(y);
}


int *x = malloc (100 * sizeof(int));
int meinx = x;
i := 100;
while (i>0) {
  *x = i;
  i--;
  x++;
}
/* 200 Zeilen später, immer meinx benutzen */
freimachen (x);

Da freut sich der Fehlersucher so, dass er postwendend eine Voodoopuppe vom Programmierer bastelt. mvb 10.8.2005 16:56

Wie schon oben erwähnt, wenn man die Existenz von Feldern ablehnt (Zitat: C hat keine Felder), hast du recht. C hat aber Felder, wie die zahlreichen Lehrbücher und Tutorials zeigen. Dass Felder letztendlich nur als Feldkonstanten auftauchen und in Ausdrücken exakt äquivalent zu Zeigern auf den Elementtyp behandelt werden, ändert an der Existenz von Feldern nichts. Letztendlich komnmt es auf die Semantik an, und die ist bei Parameterübergaben von Feldkonstanten nunmal die eines Referenzparameters. Daran ändern auch weiterführende Beispiele, (x+2) etc. mit Zeigerarithmetik nichts. --Hubi 14:01, 11. Aug 2005 (CEST)

Jensen's device

Ich habe am Anfang meines Informatikstudium den Namensparameter als Jensen's device kennengelernt. Im Laufe der Algol 60 Entwicklung muß ein dänischer Mathematiker ?. Jensen vorkommen, der die Implementierung mit Prozeduraufruf einer Parameterbeschaffungsprozedur hinter dem Aufruf der parametrisierten Prozedur entworfen hat. --SonniWP2 11:39, 19. Aug. 2007 (CEST)