Teil 1: Grundlagen


Operationen

Zuweisung

Zuweisung von numerischen Daten

Die Zuweisung von Konstanten, Variablen oder eines Ausdrucks an eine Variable erfolgt mit dem Zuweisungsoperator =. Dabei können folgende Fälle auftreten:

  • Datentypen links und rechts des Operators = sind gleich
    In diesem Fall erfolgt die Zuweisung 1:1 ohne Informationsverlust.
  • Linker Operand besitzt größeren Wertebereich als rechter Operand und beide Datentypen besitzen den gleichen Vorzeichentyp (signed/unsigned)
    Der rechte Operand wird vorzeichenrichtig auf den Datentyp des linken Operanden erweitert und es geht somit keine Information verloren.
  • Linker Operand besitzt kleineren Wertebereich als rechter Operand und beide Datentypen besitzen den gleiche Vorzeichentyp (signed/unsigned)
    Es werden nur die niederwertigen Bytes der rechten Operanden in den linken Operanden übernommen, d.h. es geht eventuell Information verloren.
  • Beiden Operanden besitzen unterschiedliche 'Vorzeichen-Datentypen' (unsigned nach signed oder umgekehrt)
    Auch hier werden nur die niederwertigen Bytes der rechten Operanden in den linken Operanden übernommen, d.h. es geht eventuell Information verloren.
  • Linker Operand ist ein Ganzzahl-Datentyp und rechter Operand ist ein Gleitkomma-Datentyp
    Bei der Konvertierung einer Gleitkommazahl in eine Ganzzahl werden die Nachkommastellen abgeschnitten, d.h. es erfolgt keine automatische Rundung

Soll sichergestellt werden, dass bei der Zuweisung keine Information verloren geht, dann ist der Ausdruck rechts vom Zuweisungsoperator in eine geschweifte Klammer einzuschließen. In diesem Fall versucht der Compiler zu überprüfen, ob der Ausdruck ohne Informationsverlust zugewiesen werden. Diese Überprüfung zur Compilezeit wird als Preventing narrowing bezeichnet.

#include <iostream>
using std::cout;
using std::endl;

// main() Funktion
int main()
{
    // Zuweisung einer unsigned Variable an eine signed Variable
    // wenn gilt: sizeof(leftOper) gleich sizeof(rightOper)
    unsigned short uShort = 40000;
    short sShort = uShort;
    cout << "Zuweisung 'unsigned short' an 'short' als Dezimalzahl:\n";
    cout << "uShort: " << uShort << ", sShort: " << sShort << endl;
    cout << "Und nun als Hex-Zahl\n" << std::hex;
    cout << "uShort: " << uShort << ", sShort: " << sShort << endl;
    // Zuweisung eines groesseren Datentyps an einen kleineren
    long sLong = 80000L;
    sShort = sLong;
    cout << "Zuweisung 'long' an 'short' als Dezimalzahl:\n" << std:dec;
    cout << "sLong: " << sLong << ", sShort " << sShort << endl;
    cout << "Und nun als Hex-Zahl\n" << std::hex;
    cout << "sLong: " << sLong << ", sShort " << sShort << endl;
    // Wenn der Kommentar in nachfolgender Anweisung entfernt wird
    // gibt es einen Übersetzungsfehler, da die Zuweisung einer long
    // Variable an eine short Variable zum Informationsverlust fuehrt
    // sShort = { sLong };
}

Zuweisung von Zeichen- und String-Literalen

Wird ein Zeichen-Literal einer Variable zugewiesen, so sollte die Variable vom Datentyp char sein. Entsprechendes gilt auch für wide-character Zeichen. Der Datentyp der Variable sollte hier wchar_t sein.

Bei der Zuweisung eines String-Literals an eine Variable muss die Variable den Datentyp Zeiger auf const char besitzen. Um einen const char-Zeiger zu definieren, wird nach dem Datentyp const char und vor dem Variablennamen ein * (Sternchen) gestellt.

#include <iostream>
using std::cout;
using std::endl;

// main() Funktion
int main()
{
    // Zeichen einer Variablen zuweisen
    char letter = 'A';
    // String-Literal einer Variablen (Zeiger) zuweisen
    const char* pText = "Dies ist ein String";
    // Beide Variablen ausgeben
    cout << "Zeichen: " << letter << endl; cout << "String : " << pText << endl;
}

Mehrfach-Zuweisung

Bei der Mehrfach-Zuweisung wird mehreren Variablen in einer Anweisung der gleiche Wert zugewiesen. Die einzelnen Variablen werden mit dem Zuweisungsoperator verkettet und ganz rechts wird der zuzuweisende Ausdruck angegeben. Die Zuweisungen erfolgen dann in der Reihenfolge von rechts nach links.

Grundrechenoperationen

Für Berechnungen stehen die bekannten Rechenoperationen zur Verfügung.

Operator
Operation
+
Addition
-
Subtraktion
*
Multiplikation
/
Division
%
Modulo

Bis auf den Modulo-Operator sind alle Operationen auf Ganzzahlen wie auch auf Gleitkommazahlen anwendbar. Der Modulo-Operator berechnet den Rest einer Ganzzahl-Division.

Zusätzlich stellt C++ eine Reihe von Kurzschreibweisen für häufig benötigte Rechenoperationen bereit, die in der nachfolgenden Tabelle aufgeführt sind.

Operator
Operation
x++
Erhöht x um 1 nach dessen Auswertung
++x
Erhöht x um 1 vor dessen Auswertung
x--
Vermindert x um 1 nach dessen Auswertung
--x
Vermindert x um 1 vor dessen Auswertung
x *= y
x = x*y
x /= y
x = x/y
x %= y
x = x%y

// Datei iostream einbinden
#include <iostream>
using std::cout;
using std::endl;

int main ()
{
    short sVar1 = 10, sVar2 = 4;
    float fVar1 = 1.1f;
    // Division von zwei Ganzzahlen
    auto res1 = sVar1 / 3;
    cout << "10 / 3 = " << res1 << endl;
    // Modulo-Berechnung
    res1 = sVar1 % 3;
    cout << "10 % 3 = " << res1 << endl;
    // Division von zwei Gleitkommazahlen
    auto res2 = fVar1 / -0.3f;
    cout << "1.1f / -0.3f = " << res2 << endl;
    // Kurzschreibweise fuer Division durch 2
    sVar1 /= 2;
    cout << "10 /= 2 " << sVar1 << endl;
    // Erhoehe sVar2 um 1 und weise Ergebnis res1 zu
    res1 = ++sVar2;
    cout << "sVar2+1 nach res1: " << res1 << endl;
    // Weise sVar2 res zu und erhoehe danach sVar2
    res1 = sVar2++;
    cout << "sVar2 nach res1, danach sVar2+1: " << res1 << endl;
    cout << "sVar2 jetzt: " << sVar2 << endl;
}

Bit- und Schiebeoperationen

Bit- und Schiebeoperationen sind nur auf Ganzzahlen zugelassen. Mit ihnen können 8, 16, 32 oder 64 Bits gleichzeitig beeinflusst werden, abhängig davon, ob die Bitoperation auf einen char, short, int, long oder long long Datentyp angewandt wird. Bis auf den Bitoperator 'rechts schieben' arbeiten alle Bit- und Schiebeoperatoren vorzeichenunabhängig. Bei all diesen Operationen wird die Ganzzahl als eine Kombination aus '0' und '1' Bits betrachtet

Operator
Syntax
Ergebnis
&
OP1 & OP2
AND: Liefert als Ergebnis nur an den Stellen ein 1-Bit, an denen beiden Operanden ein 1-Bit besitzen.
|
OP1 | OP2
OR: Liefert als Ergebnis an den Stellen ein 1-Bit, an denen einer der Operanden ein 1-Bit besitzen.
^
OP1 ^ OP2
EXOR: Liefert als Ergebnis an den Stellen ein 1-Bit, an denen beide Operanden unterschiedliche Bits besitzen
~
~OP1
NOT: Liefert an den Stellen ein 1-Bit, an denen der Operand ein 0-Bit besitzt und umgekehrt.
<<
OP1 << OP2
SHIFT LEFT: Schiebt die Bits des Operanden OP1 um OP2 Positionen nach links.
>>
OP1 >> OP2
SHIFT RIGHT: Schiebt die Bits des Operanden OP1 um OP2 Positionen nach rechts.

.Genauso wie bei den Grundrechenoperationen, stehen auch für die Bit- und Schiebeoperationen entsprechende Kurzschreibweisen zur Verfügung:

Operator
Operation
x &= y
x = x & y
x |= y
x = x | y
x ^= y
x = x ^ y
x <<= y
x = x << y
x >>= y
x = x >> y

#include <iostream>
using std::cout;
using std::endl;

// main() Funktion
int main()
{
    // Zwei Variablen definieren
    short val1 = 0xaa55, val2 = 0x00ff;
    // Inhalt der Variablen als Hex-Zahlen ausgeben
    cout << std::hex << "Als Hex-Zahlen val1: " << val1 << ", val2: " << val2 << endl;
    // Verunden der beiden Variablen
    short res = val1 & val2;
    cout << "val1 & val2: " << res << endl;
    // EXOR der beiden Variablen res = val1 ^ val2;
    cout << "val1 ^ val2: " << res << endl;
    // val1 um 4 Bits nach links
    val1 <<= 4;
    cout << "val1 <<= 4: " << val1 << endl;
    // val2 um 4 Bits nach rechts
    val2 >>= 4;
    cout << "val2 >>= 4: " << val2 << endl;
}

Vergleichs- und Logikoperationen

Die Vergleichs- und Logikoperatoren werden hauptsächlich in Verzweigungen und Programmschleifen eingesetzt, die später noch behandelt werden. Beide Operatorgruppen liefern als Ergebnis der Operation den bool-Wert true oder false zurück.

Operator
Syntax
Operation
<
EXP1 < EXP2
true, wenn Ergebnis von Ausdruck EXP1 kleiner als Ergebnis von Ausdruck EXP2
<=
EXP1 <= EXP2
true, wenn Ergebnis von Ausdruck EXP1 kleiner oder gleich Ergebnis von Ausdruck EXP2
==
EXP1 == EXP2
true, wenn Ergebnis von Ausdruck EXP1 gleich Ergebnis von Ausdruck EXP2
!=
EXP1 1= EXP2
true, wenn Ergebnis von Ausdruck EXP1 ungleich Ergebnis von Ausdruck EXP2
>= 
EXP1 >= EXP2
true, wenn Ergebnis von Ausdruck EXP1 größer oder gleich Ergebnis von Ausdruck EXP2
>
EXP1 > EXP2
true, wenn Ergebnis von Ausdruck EXP1 größer als Ergebnis von Ausdruck EXP2
&&
EXP1 && EXP2
true, wenn Ergebnis von Ausdruck EXP1 und EXP2 gleich true
||
EXP1 || EXP2
true, wenn Ergebnis von Ausdruck EXP1 oderEXP2 gleich true
!
! EXP
true, wenn Ergebnis von Ausdruck EXP false ist

#include <iostream>
using std::cout;
using std::endl;

// main() Funktion
int main()
{
    // Variablen definieren
    short var1 = 10, var2 = 5;
    cout << "var1, var2: " << var1 << ',' << var2 << endl;
    // Vergleichsoperationen
    // Klammern wegen der besseren Lesbarkeit
    auto res = (var1 < var2); cout << "var1 < var2: " << res << endl;
    // Ausgabe als bool Wert anstelle eines int-Wertes
    cout << std::boolalpha;
    cout << "Und als bool-Wert: " << res << endl;
    // Logikoperationen
    res = ((var1 == 10) && (var2 == 2));
    cout << "(var1 == 10) && (var2 == 2): " << res << endl;
    res = ((var1 > 5) || (var2 >= 10));
    cout << "(var1 > 5) || (var2 >= 10): " << res << endl;
}

Rangfolge der Operatoren

Nachfolgend in tabellarischer Form die Rangfolge aller Operatoren. In der Tabelle gilt: Operatoren in der Gruppe 1 werden vor den Operatoren der Gruppe 2 ausgeführt usw.

Gruppe
Operator
Operation
1
::
Gültigkeitsbereich
2
(...)
Klammerung
(...)
Funktionsaufruf
[...]
Indizierung

->
Indirekter Zugriff auf Member

.
Direkter Zugriff auf Member

++ und --
Post-Inkrement/Dekrement
3
! und ~
NOT und Negation
+ und -
Vorzeichen
++ und ++
Pre-Inkerement/Dekrement
&
Adressoperator
*
Dereferenzierungsoperator
sizeof(...)
Belegter Speicherplatz (Bytes)
new und delete
Dynamische Speicherverwaltung
(...)
Typkonvertierung
4
.* und ->*
Indirekter Zugriff auf Member
5
* und / und %
Arithmetische Operatoren
7
<< und >>
Scheibeoperatoren
8
<= und <
Vergleichsoperatoren
>= und >
Vergleichsoperatoren
9
== und !=
Vergleichsoperatoren
10
&
AND-Operator
11
^
EXOR-Operator
12
|
OR-Operator
13
&&
logischer AND-Operator
14
||
logischer OR-Operator
15
?..:
Bedingungsoperator
16
= und *=
/= und +=
%= und +=
-= und &=
^= und <<=
>>=
Zuweisungsoperatoren
17
throw
Ausnahme auslösen
18
,
Komma-Operator

<<< Daten

Zeiger  >>>


Copyright © cpp-tutor.de
Impressum &Datenschutz