Dieser Artikel oder nachfolgende Abschnitt ist nicht hinreichend mit
Belegen (beispielsweise
Einzelnachweisen) ausgestattet. Angaben ohne ausreichenden Beleg könnten demnächst entfernt werden. Bitte hilf Wikipedia, indem du die Angaben recherchierst und
gute Belege einfügst.
In der Programmierung wird innerhalb von Anweisungen zwischen L-Wert- und R-Wert-Ausdrücken unterschieden. Das L bedeutet, dass ein L-Wert-Ausdruck auf der linken Seite einer Zuweisung stehen kann. R-Wert-Ausdrücke dürfen nur auf der rechten Seite von Zuweisungen vorkommen. Ein Ausdruck innerhalb einer Anweisung besitzt einen L-Wert, wenn der Ausdruck auf einen Speicherort verweist. Ein L-Wert zeigt somit auf adressierbaren Speicher. Ausdrücke, die keinen L-Wert besitzen, sind R-Wert-Ausdrücke. Alle Zuweisungen mit L-Wert-Ausdrücken haben zugleich R-Wert-Ausdrücke, aber nicht jeder R-Wert-Ausdruck ist Teil einer Zuweisung.
L-Wert-Ausdrücke sind häufig Bezeichner von Datentypen, können jedoch auch als Funktionsaufrufe oder als Dereferenzierung (dt. Rückverweisung) von Zeigern oder Feldern vorkommen.
In der objektorientierten Programmierung
L-Wert-Ausdrücke können auch auf Objekte verweisen, die Daten und Code enthalten können: Daten in Form von Feldern (oft als Attribute oder Eigenschaften bezeichnet) und Code in Form von Prozeduren (oft als Methoden bezeichnet).
Temporär auftretende Objekte, sogenannte Temporaries zählen zu den R-Werten. Betrachten wir als Beispiel folgende Anweisung: x = a + (b * c);
Hier entsteht als Zwischenwert das Ergebnis von b * c
. Wenn x, a, b, und c Objekte einer Klasse sind, kann es sein, dass mit b * c
ein temporäres Objekt (engl. a temporary) entsteht, das bei der Zuweisung an x wieder zerstört wird. Um unnötiges Kopieren von Objektmembern zu vermeiden, bietet C++ den Move Constructor und den Move Assignment Operator an.
- Beispiele
// C++ Quellcode
#include <iostream>
typedef unsigned long long ull;
int x; // benannter Speicherort, der als L-Wert-Ausdruck verwendet werden kann
int& f(int& variable) { return variable; } // benötigt L-Wert-Argument, gibt L-Wert zurück
int g(int wert) { return wert; } // gibt einen R-Wert zurück
int main()
{
x = 3; // x ist ein L-Wert-Ausdruck, 3 ein R-Wert-Ausdruck
f(x) = 5; // f(x) ist (hier) ein L-Wert-Ausdruck, 5 ein R-Wert-Ausdruck
// g(x) = 0; // funktioniert nicht, da g(x) kein L-Wert-Ausdruck ist
// x = f(100); // funktioniert nicht, da 100 kein L-Wert-Ausdruck ist
std::cout << "Der L-Wert von x ist " << reinterpret_cast<ull>(&x) << std::endl;
std::cout << "Der L-Wert von f(x) ist " << reinterpret_cast<ull>(&f(x)) << std::endl;
std::cout << "Der R-Wert von f(x) ist " << f(x) << std::endl;
// std::cout << "Der L-Wert von g(x) ist " << reinterpret_cast<ull>(&g(x)) << std::endl; // funktioniert nicht
std::cout << "Der R-Wert von g(x) ist " << g(x) << std::endl;
// -----------------------------------------------------------------
int feld[3] = { 11, 22, 33 };
int * zeiger = feld;
feld[2] = 1; // Arrayindexierung als L-Wert-Ausdruck
*(zeiger+2) = 0; // Zeigerdereferenzierung als L-Wert-Ausdruck
std::cout << "Der L-Wert von *(zeiger+2) ist " << reinterpret_cast<ull>(zeiger+2) << std::endl;
std::cout << "Der L-Wert von feld[2] ist " << reinterpret_cast<ull>(&feld[2]) << std::endl;
//------------------------------------------------
// Hier wird ein temporaeres std::string -Objekt benutzt. 'Temporaries' besitzen R-Werte
std::cout << "Das Wort \"Container\" besteht aus " << std::string("Container").length() << " Zeichen.\n";
}
Mögliche Ausgabe:
Der L-Wert von x ist 0x602194
Der L-Wert von f(x) ist 0x602194
Der R-Wert von f(x) ist 5
Der R-Wert von g(x) ist 5
Der L-Wert von *(zeiger+2) ist 0x7ffdf9ec0808
Der L-Wert von feld[2] ist 0x7ffdf9ec0808
Das Wort "Container" besteht aus 9 Zeichen.
Anhand der Ausgabe ist ersichtlich, dass die L-Werte die Speicheradressen der L-Wert-Ausdrücke sind.
Weblinks