Operatoren und Sequenzpunkte in C
Operatoren ohne Sequenzpunkte
Die meisten Operatoren, wie etwa der Additionsoperator "+" haben gar keine Sequenzpunkte. Ausnahmen hiervon bilden einzelne spezielle C -Operatoren und überladene Operatoren, die in anderen Lektionen behandelt werden.
Für das folgenden Programms "sumprint.c" ist also unspezifiziert, ob die Ausgabe mit dem Text "AB" oder dem Text "BA" beginnt.
sumprint.c#include <stdio.h>
int main()
{ printf( "A" )+ printf( "B" ); printf( "\n" ); }printf( "A" )+ printf( "B" ); [Kompassdiagramm].--------------.
| printf("A") | Wert
"A" -->|S0A S1A|------.
| | |
'--------------' |
| Wirkung | .--------------.
V '--->| | Wert
Ausgabe von "A" | + |------>S2 ;
.--->| |
| '--------------'
.--------------. |
| printf("B") | Wert |
"B" -->|S0B S1B|------'
| |
'--------------'
| Wirkung
V
Ausgabe von "B"
Operatoren mit Sequenzpunkten
Der Typ und Wert eines Ausdrucks mit dem Kommaoperator "," ist der Typ und Wert des rechten Operands. So ist der Wert des Ausdrucks "3 , 4" beispielsweise der Wert "4". Dieser binäre linksassoziative Operator hat die niedrigste Priorität aller Operatoren, daher ist ein Ausdruck der aus zwei Operanden besteht, die mit dem Kommaoperator "," verknüpft sind, fast immer einzuklammern, wenn er als Teil eines größeren Ausdrucks vorkommen soll.
- 〈expression 〉 ::=
- 〈assignment-expr 〉 |
- 〈expression 〉 "," 〈assignment-expr 〉.
(Einige in dieser Produktion vorkommende Nichtterminalsymbole werden erst in späteren Lektionen behandelt, man kann der Produktion aber schon jetzt entnehmen, daß der Komma-Operator zwei Ausdrücke zu einem Ausdruck verbindet.)
Der Kommaoperator "," definiert einen Sequenzpunkt : Alle Wirkungen des linken Operanden sind abgeschlossen, bevor die Auswertung des rechten Operanden beginnt. Während für "printf( "A" )+ printf( "B" ); printf( "\n" );" nicht spezifiziert ist, ob die Ausgabe mit dem Text "AB" oder dem Text "BA" beginnt, ist die Ausgabe von "printf( "A" ), printf( "B" ); printf( "\n" );" die Zeile "AB".
commaprint.c#include <stdio.h>
int main()
{ printf( "A" ), printf( "B" ); printf( "\n" ); }stdoutAB
Der Kommaoperator kann verwendet werden, wenn an einer Stelle, an der Anweisungen nicht erlaubt sind, Ausdrücke in bestimmter zeitlicher Reihenfolge ausgewertet werden sollen, weil die Verbindung zweier Ausdrücke mit einem Kommaoperator wieder einen Ausdruck ergibt. Da der Wert des linken Operanden verworfen wird, ähnelt die Art der Behandlung des linken Operanden aber sehr der Behandlung des Ausdrucks einer Ausdruckanweisung. Der Kommaoperator ist neben der Verbundanweisung eine Möglichkeit zur Formulierung einer Sequenz, allerdings einer Sequenz aus Ausdrücken und nicht aus Anweisungen.
In einer Funktionsanwendung, wie der Anwendung "printf( "A", "B" )", gilt das Komma, wenn es direkt in den runden Klammern des Aufrufoperators steht, nicht als Kommaoperator, sondern wird als Argument-Trenner interpretiert. (Die Funktion "printf" kann auf mehrere Argumente angewendet werden, aber im allgemeinen wird nur das erste Argument direkt ausgegeben.) Soll der Wert eines Kommaausdrucks als Argument verwendet werden, kann er eingeklammert werden, wie in der Anwendung "printf(( "C", "D" ))".
argumentcomma.cpp#include <stdio.h>
int main()
{ printf( "A", "B" ); printf(( "C", "D" )); printf( "\n" ); }stdoutAD
Übungsfrage Welchen Wert hat der Ausdruck "0, 1"? Welchen Wert hat der Ausdruck "0, 1, 2"?
Übungsfrage Welchen Wert hat der Ausdruck "printf( "A" ), printf( "B" )"?
Übungsfrage Ist der Text "0, 1;" eine Anweisung, zwei Anweisungen oder gar keine Anweisung?
Übungsfrage Welchen Typ und Wert haben die folgenden Ausdrücke (ohne die Anführungszeichen): "3,0 - 3.0" und "3.0 - 3,0"?
Übungsaufgabe Schreiben Sie ein C -Programm, das den Wert des Ausdrucks "3,0" ausgibt.