Wertzuweisung

Aus SELFHTML-Wiki
Wechseln zu: Navigation, Suche

Übersicht

In Programmier- und anderen Sprachen können Variablen oder Konstanten Werte zugewiesen bekommen.

HTML
<a href="https://selfhtml.org">SELFHTML</a>
dem Attribut href wird der Wert https://selfhtml.org zugewiesen
CSS
body { color: #888 }
der Wert der Textfarbe (color) des body-Elements wird auf #888 festgelegt
HTTP
127.0.0.1/index.html?title=test
der URL-Parameter title bekommt den Wert test zugewiesen
JavaScript
var sinnDesLebens = 42;
der Variablen sinnDesLebens wird der Wert 42 zugewiesen
PHP
$Sinn_des_Lebens = 42;
die Variable Sinn_des_Lebens erhält den Wert 42

Solcherart Zuweisungen sind keine mathematischen Gleichungen, sondern erfolgen immer von rechts nach links. Auf der linken Seite steht der Akzeptor (von lat. annehmen), der eine Zuweisung akzeptiert; rechts vom Zuweisungsoperator steht der Donator (von lat. schenken, geben), der seinen Wert übergibt.

Beispiel
$a = 42;
$b = $a;
42 = $b;

In der ersten Zeile bekommt die Variable a den Wert 42 zugewiesen, in der zweiten Zeile bekommt die Variable b den Wert der Variablen a (derzeit 42) zugewiesen. Die dritte Zeile ist ungültig, weil 42 kein Akzeptor ist.

Vergleich von Zuweisungs- und Vergleichsoperatoren

Je nach Programmiersprache sind die Zuweisungsoperatoren unterschiedlich, auf jeden Fall muss man sie von dem Vergleichsoperator unterscheiden, der auf Gleichheit prüft.

Sprache Zuweisungsoperator Vergleichsoperator
HTML = gibt es nicht, keine Programmiersprache
CSS : gibt es nicht, keine Programmiersprache
Pascal und andere := =
C, PHP, JavaScript und andere = == / ===
BASIC = = 1
Tcl set 2 ==

1 BASIC unterscheidet an Hand des Kontextes zwischen Zuweisung und Vergleich
2 In Tcl ist das Schema [Zuweisungsoperator] [Akzeptor] [Donator]

Die Wertzuweisung als Ausdruck

In den von C abgeleiteten Programmiersprachen wie JavaScript oder PHP ist die Wertzuweisung kein Statement, sondern ein Ausdruck. Das bedeutet, dass eine Zeile wie

   a = b + 7;

einen Ausdruck mit einem Seiteneffekt (die Variable a wird verändert) darstellt. Der Ausdruck verwendet die Operatoren + zur Addition und = zur Wertzuweisung, und das Ergebnis des =-Operators ist der zugewiesene Wert. Dieser könnte nun weiterverwendet werden:

Weitergabe an eine Funktion
    myfunction(a = b + 7);

b+7 wird an a zugewiesen und danach wird der zugewiesene Wert wird an myfunction als Argument übergeben.

Mehrfachzuweisung
    x = a = b + c + 7;

Hier zeigt sich eine Besonderheit des Zuweisungsoperators. Damit sie einen Sinn ergibt, muss zuerst b+c+7 bestimmt werden, danach die Zuweisung an a erfolgen und erst dann die Zuweisung an x. Das könnte man mit Klammern erreichen, aber es funktioniert auch ohne Klammern. Der Effekt, der hier wirksam wird, ist die Assoziativität, die angibt, ob Operatoren mit gleicher Rangstufe von links nach rechts oder von rechts nach links ausgeführt werden. Der + Operator ist linksassoziativ, deshalb wird zuerst b+c berechnet und auf diese Summe 7 addiert. Der = Operator ist dagegen rechtsassoziativ, weshalb die Zuweisung an a zuerst ausgeführt wird.

Zuweisung statt Vergleich
    if (a = 7) { ... }                      /* Zuweisung von 7, 7 entspricht true */
    if (a == 7) { ... }                     /* Vergleich von a mit 7 */
    while ($row = $db->fetch_row()) { ... }    /* Korrekt! */

Hier zeigt sich ein häufiger Programmierfehler in JavaScript und PHP. Den Zuweisungsoperator = wird an Stelle des Vergleichsoperators == verwendet, so dass a den Wert 7 erhält. Weil JavaScript und PHP einen numerischen Wert, der nicht gleich 0 ist, wie true auffassen, ist die if-Abfrage immer wahr. In der folgenden Zeile finden Sie die korrekte Formulierung.

Es gibt aber auch Fälle, wo die Zuweisung bewusst in einer Bedingung steht. Die dritte Beispielzeile zeigt eine typische Datenbank-Einleseschleife in PHP. Die fetch_row Methode liefert entweder eine Datenzeile, null wenn keine Daten mehr folgen oder false wenn ein Fehler auftrat. Die so formulierte Schleife endet also, wenn keine Daten mehr kommen oder ein Fehler auftritt.

Zuweisung statt Vergleich
    if (a = b + 7 > 10) { ... }   
    if ((a = b + 7) > 10) { ... }

In der ersten Zeile dieses Beispiels fehlen Klammern. Hier muss auf die Rangfolge der Operatoren geachtet werden. Vergleiche haben einen höheren Rang als Berechnungen, und diese einen höheren Rang als Zuweisungen, deshalb wird zunächst b+7 berechnet, die Summe mit 10 verglichen und das Vergleichsergebnis, also true oder false, in a gespeichert. Danach erst erfolgt die Auswertung durch das if-Statement. Die sechste Zeile dagegen berechnet auf Grund der Klammerung b+7, speichert den Wert in a, vergleicht diesen Wert mit 10 und verzweigt dann je nach Ergebnis.

Arten von Akzeptoren

Als Akzeptor können nicht nur einfache Variablen dienen. Es können auch Array-Elemente sein oder Eigenschaften von Objekten. In Sprachen wie C++ ist es sogar möglich, dass eine Funktion eine Referenz auf eine Variable zurückgibt, die dann in einer Zuweisung als Akzeptor dienen kann.

Akzeptoren aller Art
// Beispiele in JavaScript
var tab = [ 1, 2, 3 ];
var obj = { name: 'Müller' };

tab[2] = 4711;       // Akzeptor ist ein Array-Element
obj.name = 'Meier';  // Akzeptor ist ein Objekt-Property
Beispiel
// C++ Beispiel
int someValue = 123;
int& getStorage() {         // Funktion getStorage liefert eine Referenz auf someValue
   return someValue;
}
getStorage() = 15;         // überschreibt den Wert von someValue


Property-Setter

Einige Programmiersprachen bieten spezielle Syntax an, mit der man eine Zuweisung an eine Objekteigenschaft auf einen Funktionsaufruf abbilden kann. Eine solche Funktion nennt man einen Property-Setter. Der Nutzer dieses Objekts bemerkt normalerweise nichts davon. Um den Anschein eines normalen Property zu wahren, wird üblicherweise auch noch ein getter hinzugefügt.

Property-Setter in Javascript
var myObject = {
   get name() { return this._name; }
   set name(neuerName) { this._name = neuerName.toUpperCase(); }
};

myObject.name = "Schmidt";  // Sieht aus wie eine Zuweisung, ist aber ein Funktionsaufruf
alert(myObject.name);       // Zeigt "SCHMIDT" an.

Normalerweise würde man die „interne“ Ablage des Namens vor dem Nutzer verbergen, z.B. mittels eines Moduls