Sprachkonzepte Preprozessor Operatoren Kontrollstrukturen Typen OOP Bibliotheken |
Operator und OperandIn C und C++ wird die eigentliche Programmausführung mittels Operatoren beschrieben. Nebst mathematischen Verknüpfungen wie beispielsweise +, -, * und / sind selbst Funktionsaufrufe und Speicheralloziierungen als Operatoren zu verstehen. Die Strukturen, die durch Operatoren ausgelesen oder verändert werden, sind als
Hierbei sind zunächst die Variablen DetailsDas Verständnis von Operatoren und Operanden ist im Allgemeinen wenig problematisch, da es an die gebräuchliche Mathematik angelehnt ist, wo auch von Operatoren gesprochen wird und Resultate einer Operation als Operand für eine andere dienen können. In der Programmierung gibt es jedoch einige Besonderheiten, die beachtet werden müssen.Operanden: lvalue und rvalueAlle Operatoren lesen Werte und geben Werte zurück, doch nur einige Operatoren weisen Werte zu. Dabei unterscheidet man bei den verschiedenen Werten zwischen L-Werten und R-Werten, im Englischen bekannt als lvalue und rvalue. Die Bedeutung dieser beiden Buchstaben L und R ist niemals standartisiert worden, weswegen bis heute einige Unklarheit darüber herrscht. Die einfachste, jedoch nicht korrekte Erklärung dieser beiden Buchstaben L und R ist, dass L für Links steht und R für Rechts. Diese Erklärung leitet sich ab aus der Betrachtung des Zuweisungsoperators, welcher rechts stets einen R-Wert erwartet, den er einem L-Wert auf der linken Seite zuweist:
Tatsächlich jedoch ist es angebrachter, von Localizable (L) und Readable (R) zu sprechen: Adressierbar und Lesbar. Dies aus folgendem Grund: Um einen Wert zu lesen, muss er insbesondere eines sein: Lesbar. Um jedoch einen Wert zuweisen zu können, braucht man Platz, zu dem man ihn zuweisen kann. Ein Makro oder ein konstanter Wert beispielsweise braucht keinen Platz, er ist fest im Programm eingebunden. Eine Variable jedoch hat einen Platz reserviert, sei es im Speicher oder als Register des Prozessors, an eine solche Stelle kann der Compiler einen Wert schreiben, er kann zugewiesen werden, er hat eine Adresse, er ist lokalisierbar. Für die Definition des Zuweisungsoperators bedeutet dies folgendes: Der Ausdruck auf der rechten Seite muss einen lesbaren Wert darstellen. Links des Operators jedoch muss ein Ausdruck stehen, dessen Auswertung einen adressierbaren Wert ergibt. Es gibt jedoch auch Operatoren, bei denen diese Position nicht stimmt. Beispielsweise gibt es die beiden Varianten des Inkrements: Post-Inkrement-Operator und Pre-Inkrement-Operator. Die Post-Variante steht nach dem Operanden, die Pre-Variante davor, jedoch erwarten beide Operatoren einen L-Wert. Dies deswegen, da die Operatoren diesen Wert selbst verändern, ihn somit also auch adressieren können müssen. Dies kann man leicht überprüfen, indem man versucht, folgende zwei fehlerhafte Zeilen zu kompilieren, beide Varianten erwarten einen L-Wert, obschon der Wert bei der zweiten Zeile rechts steht:
Anders herum gibt es Operatoren, welche überhaupt keinen L-Wert erwarten, sondern zwei R-Werte. Beispielsweise der Additions-Operator:
Am besten sieht man die Bedeutung
Man beachte, dass der Compiler den Fehler address of register variable ... requested meldet, wenn versucht wird, mittels des Adress-Operators die Adresse eines Prozessorregisters anzusprechen. Operatoren: Unary, binaryOperatoren erwarten entweder einen oder zwei Operanden, was im Englischen mit unary und binary bezeichnet wird. Unäre Operatoren besitzen immer nur einen Operanden, der entweder links oder rechts von dem Operator steht. Ein Beispiel für einen unären Operator ist der Negativ-Operator, der auch oft mit
Binäre Operatoren hingegen haben zwei Operanden, wie beispielsweise der Multiplikations-Operator, der zwei Werte miteinander multipliziert.
Operatoren: AbarbeitungsrichtungZu jedem Operator ist zudem definiert, in welcher Reichenfolge die Operanden abgearbeitet werden müssen. Diese sogenannte
Auch für unäre Operatoren ist eine Abarbeitungsrichtung definiert, was die Position des Operanden relativ zum Operator definiert. Der unäre Negativ-Operator - ist definiert als
Operatoren: RangordnungZusätzlich zur Abarbeitungsrichtung ist zu jedem Operator eine Priorität definiert. Diese Rangordnung stellt die Assoziativität verschiedenartiger Operatortypen aufgrund deren Priorität sicher. Beispielsweise werden mathematische Operatoren prioritärer behandelt als Zuweisungsoperatoren, man möchte ja zuerst eine Rechnung ausführen und erst dann das Resultat einer Variablen zuweisen. Die Rangordnung beinhaltet beispielsweise auch das bekannte Assoziativgesetzt (Punkt-vor-Strich-Regel) der Mathematik:
Sowohl der Additions-Operator +, als auch der Multiplikations-Operator * werden von links nach rechts abgearbeitet, jedoch hat der Multiplikations-Operator eine höhere Priorität wie der Additions-Operator. Somit wird ohne Klammerung die Multiplikation vor der Addition ausgeführt, genauso, wie es in der Mathematik üblich ist. Die Prioritäten werden üblicherweise festgelegt, indem jedem Operator ein
Man beachte, dass die Quellen sich teilweise auch widersprechen. Erst ab der Multiplikations-Gruppe mit den Operatoren *, / und % sind sich sämtliche Quellen einig. Bei den niederen Rängen ist beispielsweise der Unterschied der Rangordnung des Klammer-Operators aufzuführen, welcher bei manchen Quellen die absolute Priorität 1 erhält, bei anderen jedoch mit dem Type-Cast gleichgestellt wird. Allerdings wird man beim wirklichen Programmieren äusserst selten auf Probleme stossen, da viele Operatoren gar nicht erst gemeinsam auftreten und somit eine Rangfolge hinfällig ist.
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||