C++-Programmierung: Operatoren
Aus Wikibooks
[Bearbeiten] Vorzeichen
[Bearbeiten] -
Gibt einem numerischen Wert ein negatives Vorzeichen, bzw. kehrt das Vorzeichen um.
int i = -5; // i erhält den Wert -5 int n = -i; // n erhält den Wert 5
[Bearbeiten] +
Dient zur expliziten Angabe des Vorzeichen. Da aber Zahlen ohne explizites Vorzeichen positiv sind, kann dieser Operator immer weggelassen werden.
int i = 5; // i erhält den Wert 5 int n = +i; // n erhält den Wert 5
[Bearbeiten] Arithmetische Operatoren
Auf Operanden, die einen arithmetischen Typ tragen, werden die usual arithmetic conversions angewendet, um die Typen einander anzugleichen und den Typ des Resultats zu bestimmen.
[Bearbeiten] + (Addition)
Addiert die Werte seiner zwei Operanden und gibt das Ergebnis zurück.
int i = 3; int n = i + 5;
[Bearbeiten] - (Subtraktion)
Subtrahiert die Werte seiner zwei Operanden und gibt das Ergebnis zurück.
int i = 5; int n = i - 3;
[Bearbeiten] * (Multiplikation)
Multipliziert die Werte seiner zwei Operanden und gibt das Ergebnis zurück.
int i = 5; int n = 2 * i;
[Bearbeiten] / (Division)
Dividiert die Werte seiner zwei Operanden und gibt das Ergebnis zurück. Bei der Division von Ganzzahlen fällt ein eventueller Rest weg, wird also nicht gerundet.
int i = 10 / 3; // i erhält den Wert 3
[Bearbeiten] % (Modulo)
Dividiert die Werte seiner zwei Operanden und gibt den Divisionsrest zurück. Kann nur auf ganzzahlige Operanden angewendet werden. Ist mindestens ein Operand negativ, so ist das Vorzeichen des Resultats implementationsabhängig.
int i = 10 % 3; // i erhält den Wert 1
[Bearbeiten] Zuweisungen
[Bearbeiten] ++ (Inkrement)
Erhöht den Wert seines Operanden um 1.
i = 2; i++; // i hat den Wert 3
Bezüglich der Priorität unterscheidet man zwischen Postfix- und Präfix-Notation. Die Postfix-Notation (i++) hat eine höhere Priorität als die Präfix-Notation (++i).
[Bearbeiten] -- (Dekrement)
Vermindert den Wert seines Operanden um 1.
i = 2; i--; // i hat den Wert 1
Bezüglich der Priorität unterscheidet man zwischen Postfix- und Präfix-Notation. Die Postfix-Notation (i--) hat eine höhere Priorität als die Präfix-Notation (--i).
[Bearbeiten] = (Zuweisung)
Weist seinem linken Operanden den Wert des rechten Operanden zu
[Bearbeiten] Kombinierte Zuweisungsoperatoren
Die kombinierten Zuweisungsoperatoren kombinieren den Zuweisungsoperator mit einem anderen Operator:
- +=
- -=
- *=
- /=
- %=
- &=
- <<=
- >>=
- ^=
- |=
Dabei wird der linke Operator sowohl als linker Operator für die Zuweisung als auch für den anderen Operator verwendet.
a += b;
bedeutet also
a = a + (b);
Die Klammer um das b soll verdeutlichen, dass gesamte rechte Ausduck zuerst berechnet wird.
[Bearbeiten] Vergleiche
[Bearbeiten] == (Gleichheit)
Ergibt den boolschen Wert true, wenn die beiden Operanden gleich sind, sonst false.
[Bearbeiten] != (Ungleichheit)
Ergibt den boolschen Wert true, wenn die beiden Operanden ungleich sind, sonst false.
[Bearbeiten] <= (kleiner oder gleich)
Ergibt den boolschen Wert true, wenn der linke Operand kleiner oder gleich dem rechten ist, sonst false.
[Bearbeiten] >= (größer oder gleich)
Ergibt den boolschen Wert true, wenn der linke Operand größer oder gleich dem rechten ist, sonst false.
[Bearbeiten] < (kleiner)
Ergibt den boolschen Wert true, wenn der linke Operand kleiner als der rechte ist, sonst false.
[Bearbeiten] > (größer)
Ergibt den boolschen Wert true, wenn der linke Operand größer als der rechte ist, sonst false.
[Bearbeiten] Aussagenlogik
[Bearbeiten] && (Und-Verknüpfung)
Verknüpft die beiden Operanden und gibt true zurück, wenn beide Operanden den Wert true haben, sonst false.
true true ---- true
Kann das Ergebnis bereits vorhergesagt werden, nachdem der erste Operand ausgewertet wurde (dh, wenn dieser false ist, ist das Ergebnis sicher false), wird der zweite Operand nicht mehr ausgewertet.
[Bearbeiten] || (Oder-Verknüpfung)
Verknüpft die beiden Operanden und gibt true zurück, wenn einer der beiden Operanden den Wert true hat, sonst false.
true false ---- true
Kann das Ergebnis bereits vorhergesagt werden, nachdem der erste Operand ausgewertet wurde (dh, wenn dieser true ist, ist das Ergebnis sicher true), wird der zweite Operand nicht mehr ausgewertet.
[Bearbeiten] ! (Negierung)
Invertiert den Wert seiner Operanden. Aus true wird false - und umgekehrt.
true ---- false
[Bearbeiten] Bitmanipulation
[Bearbeiten] & (bitweise Und-Verknüpfung)
Verknüpft jedes Bit beider Operanden.
1100 1010 ---- 1000
[Bearbeiten] | (bitweise Oder-Verknüpfung)
Verknüpft jedes Bit beider Operanden.
1100 1010 ---- 1110
[Bearbeiten] ^ (exklusive Oder-Verknüpfung)
Verknüpft jedes Bit beider Operanden.
1100 1010 ---- 0110
[Bearbeiten] ~ (bitweise Negation)
Negiert den Wert jedes Bits.
10 -- 01
[Bearbeiten] << (Linksverschiebung)
Verschiebt die Bits des linken Operanden um die durch den rechten Operanden angegebene Anzahl von Stellen nach links.
int i = 1; // dual: 00000001 int n = i << 1; //dual: 00000010 = 2
[Bearbeiten] >> (Rechtsverschiebung)
Verschiebt die Bits des linken Operanden um die durch den rechten Operanden angegebene Anzahl von Stellen nach rechts.
int i = 5; //dual: 00000101 int n = i >> 1; //dual: 00000010 = 2
[Bearbeiten] Datenzugriff
[Bearbeiten] * (Zeigerdereferenzierung)
Dereferenziert einen Zeiger, damit nicht auf dessen wahren Inhalt (die Adresse), sondern auf den Speicherbereich, auf den dieser verweist, zugegriffen werden kann.
int variable = 5; int* zeiger = &variable; *zeiger = 3; //ändert den Wert von variable auf 3
[Bearbeiten] -> (Zugriff auf Member eines Objekts über einen Zeiger)
Dereferenziert einen Zeiger auf ein Objekt, der durch den linken Operanden angegeben wird, und greift auf den durch den rechten Operanden angegebenen Member zu.
obj_zeiger->member = wert; obj_zeiger->funktion();
[Bearbeiten] . (Zugriff auf Member)
Greift auf einen Member eines Objekts zu.
obj.member = wert; obj.funktion();
[Bearbeiten] :: (Qualifizierung)
Qualifizierung eines Bezeichners (Variable, Funktion, Klasse) mit seinem übergeordneten Element (Namespace, Klasse).
std::cout << "Hallo!" << std::endl;
[Bearbeiten] .* (Zugriff auf, und gleichzeitige Dereferenzierung eines Members)
Zugriff auf, und gleichzeitige Dereferenzierung eines Zeiger-Members eines Objekts.
objekt.*zeiger_member = 5;
[Bearbeiten] ->* (Zugriff auf, und gleichzeitige Dereferenzierung eines Members über einen Zeiger)
Zugriff auf, und gleichzeitige Dereferenzierung eines Zeiger-Member eines Objekt-Zeigers
obj_zeiger->*zeiger_member = wert;
[Bearbeiten] Typumwandlung
[Bearbeiten] () (explizites Casting)
Wandelt den Wert des Ausdrucks rechts der Klammer in den Typ innerhalb der Klammer.
float f = 3.3; int n = (int)f;
- Diese Art der Umwandlung stammt von C und sollte in C++ möglichst vermieden werden.
- Man kann nicht nur von/in eingebaute Datentypen casten.
- Konstruktorschreibweise (nur bei nicht mehrteiligen eingebauten Datentypen):
n = int(f);
- Zahlen wie 3.3 sind standardmäßig doubles. Möchte man aber ein float haben, genügt es, 3.3f zu schreiben.
[Bearbeiten] static_cast
Pendant zum C-Casting.
float f = 3.3; int n = static_cast<int>(f);
In den spitzen Klammern steht der Zieltyp. Wenn man Zeiger auf Objekte einer Hierarchie umwandeln möchte, sollte man eher dynamic_cast benutzen.
[Bearbeiten] const_cast
Ermöglicht den Schreibzugriff auf eine konstante Variable.
const int c = 42; int c = const_cast<int>(c);
[Bearbeiten] dynamic_cast
Korrekte Umwandlung eines Zeigers oder einer Referenz auf ein Objekt einer Basisklasse auf ein Objekt einer abgeleiteten Klasse.
class Base { /*...*/ }; class Derived : public Base { /*...*/ }; Base *bptr1 = new Derived; Base *bptr2 = new Base; Derived *dptr1 = dynamic_cast<Derived*>(bptr1); // i. o. Derived *dptr2 = dynamic_cast<Derived*>(bptr2); // Fehler: bptr2 zeigt auf eine Instanz von Base
class Base { /*...*/ }; class Derived : public Base { /*...*/ }; Derived dobj; Base bobj; Base &bref1 = dobj; Base &bref2 = bobj; Derived &dref1 = dynamic_cast<Derived&>(bref1); // i. o. Derived &dref2 = dynamic_cast<Derived&>(bref2); // Fehler: bref2 referenziert eine Instanz von Base
- Diese Art der Umwandlung funktioniert nur, wenn das umzuwandelnde Objekt wirklich eines des Zieltyps ist.
- Für die umgekehrte Richtung passiert die Umwandlung implizit, dynamic_cast wird nicht benötigt.
- Achtung: Schlägt die Umwandlung eines Zeigers fehl, gibt dynamic_cast einen Nullzeiger (0) zurück!
- Achtung: Schlägt die Umwandlung einer Referenz fehl, wirft dynamic_cast die Ausnahme std::bad_cast!
[Bearbeiten] reinterpret_cast
Gefährlichster und mächtigster Cast, der selten wirklich benötigt wird.
Mit ihm können u.a. Zeiger in Datentypen (und umgekehrt) „uminterpretiert“ werden.
int i = 25; float *fp = reinterpret_cast<float*>(i);
In diesem Beispiel zeigt fp auf eine höchstwahrscheinlich undefinierte Float-Variable an der Speicheradresse 25.
[Bearbeiten] typeid
Mit diesem Operator können während der Laufzeit Informationen über eine Variable, eine Referenz, einen (dereferenzierten) Zeiger oder eine Klasse abgefragt werden. Der Operator liefert eine Referenz vom Typ type_info& zurück, der in der Header-Datei typeinfo definiert ist.
#include <typeinfo> class Base { /*...*/ }; class Derived : public Base { /*...*/ }; Derived dobj; Base &bref = dobj; if ( typeid(bref) == typeid(Derived) ) std::cout << "bref referenziert Derived" << std::endl;
Achtung: Um diesen Operator verwenden zu können, muss aber bei den meisten Compilern RTTI explizit aktiviert werden (beim GNU-Compiler bspw. mit der Kommandozeilenoption -frtti), da die Introspektion sehr viel Aufwand vom Compiler erfordert.
[Bearbeiten] Speicherbehandlung
[Bearbeiten] & (Adressermittlung)
Ermittelt die Adresse des Operanden.
int i = 0; int* zeiger = &i;
[Bearbeiten] sizeof (Speicherbedarfsermittlung)
Ermittelt den Speicherbedarf eines Typs oder eines Ausdrucks.
int n = sizeof(int); int m = sizeof n;
Für einen Typ als Argument müssen Klammern gesetzt werden, für einen Ausdruck nicht.
[Bearbeiten] new (Objekterstellung)
Erstellt ein Objekt vom angegebenen Typ. Gibt einen Zeiger auf das neue Objekt zurück.
Object * p = new Object(parameter);
[Bearbeiten] new[] (Anlegen eines Objekt-Arrays)
Erstellt ein Objekt-Array.
Object * object_array = new Object[12];
[Bearbeiten] delete (Objektzerstörung)
Zerstört das angegebene Objekt.
Object * p = new Object; // Tu irgendetwas mit dem Objekt. delete p;
Verlangt einen Zeiger auf das Objekt als Argument. Das Objekt muss mit dem Operator new angelegt worden sein.
[Bearbeiten] delete[] (Zerstörung eines Objekt-Arrays)
Zerstört die Objekte im angegebenen Array.
delete [] objekt_array;
Die Objekte müssen mit dem Operator new[] angelegt worden sein.
[Bearbeiten] Sonstige
[Bearbeiten] () (Funktionsaufruf)
Aufruf einer Funktion und eventuelle Angabe von Parametern.
funktion(); objekt.funktion(1, "asdf");
[Bearbeiten] , (Aufzählung)
Das Komma hat in C++ eine doppelte Bedeutung. Zum einen hat es die (rein syntaktische) Aufgabe eines Trennzeichens bei Funktionsaufrufen und Initialisierungen:
int x = funktion(1, 2, 3); int y[] = { 4, 5, 6 };
Zum anderen bezeichnet es den Sequentialoperator. Die durch Komma getrennten Ausdrücke werden von links nach rechts bewertet. Im Beispiel
for (int n=0, m=0; n < 5; n++, m=2*n) { // ... }
wird bei der Reinitialisierung der Schleife zuerst n++ und dann m=2*n ausgeführt.
[Bearbeiten] * Zeigerdeklaration
Erstellt einen Zeiger auf einen bestimmten Datentypen.
int* int_zeiger; void* void_zeiger;
[Bearbeiten] ?: (Bedingung)
Der Bedingungsoperator (übrigens der einzige ternäre Operator, also ein Operator mit drei Operanden) ist eine Verkürzung für ein if-else-Konstrukt.
int max = (a>b) ? a : b;
Ergibt der erste Operand (in diesem Fall a>b) true, ergibt der gesamte Ausdruck den zweiten Operanden, sonst den dritten. Somit könnte die obige Zeile wie folgt geschrieben werden:
int max; if (a>b) { max = a; } else { max = b; }
Der Operand, der nicht das Ergebnis darstellt, wird nicht ausgewertet.
[Bearbeiten] [ ] (Indizierung)
Zugriff auf ein bestimmtes Element eines Arrays.
array[index] = 5;
[Bearbeiten] : (Vererbung)
Erben von Variablen und Funktionen einer Klasse
class Klasse : public Basisklasse, public AndereBasisklasse { ... };
[Bearbeiten] : (Initialisierung)
Initialisieren von Oberklassen und Membervariablen innerhalb der Konstruktor-Definition
Klasse::Klasse(int a, int b) // Konstruktor mit zwei Parametern : Oberklasse(a), // Weiterleitung des Parameters 'a' an den Oberklassen-Konstruktor _b(b) // Initialisierung der Membervariablen '_b' mit dem Wert von 'b' { ... }
[Bearbeiten] throw (Exception-Auslösung)
Wirft die als Operanden angegebene Exception.
throw exception;

