C++ Kurs

Zuweisungen

Die Themen:

Zuweisungen von numerischen Daten

Die Zuweisung von Konstanten, Variablen oder eines Ausdrucks an eine Variable erfolgt mit dem Zuweisungsoperator =.

HinweisIm weiteren Verlauf dieses Kapitels wird davon ausgegangen, dass eine short Variablen 2 Bytes und eine long Variable 4 Bytes belegen. Wie bereits erwähnt, kann dies je nach System/Compiler durchaus auch abweichen. Jedoch ändert sich dadurch nichts am grundsätzlichen Verhalten der nachfolgend beschriebenen Konvertierungen (Anpassungen) von unterschiedlichen Datentypen.
Zudem wird explizit auf den Einsatz von auto-Variablen verzichtet, da wir uns ja ansehen wollen was passiert, wenn Variablen mit unterschiedlichen Datentypen einander zugewiesen werden.

Bei der Zuweisung eines Ausdrucks an eine Variable müssen drei Fälle unterschieden werden:

1. Datentypen links und rechts des Operators = sind gleich

In diesem Fall muss bei der Zuweisung keine Anpassung vorgenommen werden und die Zuweisung erfolgt ohne Informationsverlust.

2. Linker Operand besitzt größeren Wertebereich als rechter Operand und beide Datentypen sind mit oder ohne Vorzeichen (signed bzw. unsigned).

In diesem Fall wird der rechte Operand durch den Compiler automatisch vorzeichenrichtig auf den Datentyp des linken Operanden erweitert und es geht somit keine Information verloren. Dies wird besonders deutlich bei der ersten Zuweisung im Beispiel, bei der eine short Variable einer long Variable zugewiesen wird.

PgmHeader
// Zuweisung short Variable an eine long Variable
short sVal = -10;    // = 0xFFF6
long  lVal = sVal;   // = 0xFFFFFFF6

//Zuweisung unsigned char Variable an eine unsigned long Variable
unsigned char bVal  = 128;    // = 0x80
unsigned long dwVal = bVal;   // = 0x00000080

3. Linker Operand besitzt kleineren Wertebereich als rechter Operand oder beiden Datentypen besitzen unterschiedliche 'Vorzeichen-Datentypen' (unsigned nach signed oder umgekehrt).

Dieses ist der kritische Fall! Hier werden die Bytes des rechten Operanden einfach in den linken Operanden kopiert und zwar beginnend mit dem niederwertigsten Byte. Die Anzahl der kopierten Bytes richtet sich dabei selbstverständlich nach der Größe des linken Operanden. D.h. wenn einer char-Variable einen long Wert zugewiesen wird, so wird nur das niederwertigste Byte des long Werts übernommen. Ein guter Compiler gibt aber in diesem Fall eine Warnung aus, die selbstverständlich auch ernst genommen werden sollte. Sonst kann es, wie im Beispiel bei der letzten Zuweisung, zu recht seltsamen Ergebnissen führen.

PgmHeader
// Zuweisung long Variable an eine short Variable
long  lVal = -186L;   // = 0xFFFFFF46
short wVal = lVal;    // = 0xFF46 = -186

// Zuweisung unsigned long Variable an eine unsigned char Variable
unsigned long dwVal = 128UL;   // = 0x00000080
unsigned char bVal  = dwVal;   // = 0x80

// Achtung! Zuweisung unsigned long Variable an eine char Variable
unsigned long dwVal = 128UL;  // 0x00000080
char          cVal  = dwVal;  // 0x80 = -128 (Vorzeichen!)
HinweisBei der Konvertierung einer Gleitkommazahl in eine Ganzzahl werden zusätzlich noch 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 Klammern einzuschließen. In diesem Fall versucht der Compiler beim Übersetzen des Programms zu überprüfen, ob der Ausdruck ohne Informationsverlust zugewiesen werden kann und gibt ansonsten eine Warnung aus. Diese Überprüfung zur Compilezeit wird auch als Preventing narrowing bezeichnet.

PgmHeader
// Zuweisung einer long Variable an eine short Variable
long  lVal = -186L;     // = 0xFFFFFF46
short wVal = {lVal};    // = 0xFF46 = -186, erzeugt eine Warnung
// Zuweisung eines Ausdrucks

short sVal = {wVal + 40000}; // Erzeugt ebenfalls eine Warnung, da 40000 kein short-Wert

Zuweisungen von Zeichen- und String-Literalen

Die Zuweisung von Zeichen- und String-Literalen erfolgt prinzipiell gleich wie die Zuweisung von numerischen Ausdrücken. Lediglich beim Datentyp des linken Operanden müssen Sie achtgeben.

Die nachfolgenden Ausführungen folgen der Richtlinie: die Datentypen bei Zuweisungen sollten links und rechts des Gleichheitszeichens stets identisch sein.

Wenn ein Zeichen-Literal einer Variable zugewiesen werden soll, so sollte die Variable vom Datentyp char sein. Das zuzuweisende Zeichen wird in einfachem Hochkomma eingeschlossen, so wie im Kapitel Konstanten dargestellt. Das Gleiche gilt auch für wide-character Zeichen. Der Datentyp der Variable sollte hier wchar_t sein und das zuzuweisende Zeichen wird ebenfalls in Hochkomma eingeschlossen und ist mit dem Präfix L zu versehen. Wenn ein Zeichen einem anderen Datentyp als char zugewiesen wird, so erfolgt, wie bei numerischen Daten, eine entsprechende Typkonvertierung vom Datentyp char aus.

HinweisBeachten Sie, dass hier der Datentyp char verwendet wird und nicht signed char bzw. unsigned char. Diese drei Datentypen sind nicht identisch. Nur wenn sizeof(char) gleich sizeof(signed char) bzw. sizeof(unsigned char) ist erfolgt die Zuweisung ohne Informationsverlust.

Bei der Zuweisung eines Standard String-Literals (ein String ohne Präfix) 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, so wie im nachfolgenden Beispiel dargestellt. Anschließend kann dann das in Anführungszeichen eingeschlossene String-Literal diesem Zeiger zugewiesen werden. Diesem Zeiger kann später im Programmverlauf durchaus ein weiteres String-Literal zugewiesen werden, da hier nicht der Zeiger konstant ist sondern das, worauf er zeigt, also das String-Literal. Mehr zu Zeigern später im Kurs.

PgmHeader
// Zuweisungen von Zeichen
char charA = 'A';    // = 0x41
char linef = '\n';   // = 0x0A

// Zuweisungen von wide character
wchar_t chA = L'A';   // = 0x0041
wchar_t lf  = L'\n';  // = 0x000A

// Zuweisungen von Strings
const char *pText;    // const char-Zeiger
pText = "Dies ist ein String!";
HinweisAus Gründen der Abwärtskompatibilität mit älteren Programmen ist es auch erlaubt, ein String-Literal einem char-Zeiger zuzuweisen.
char *pText = "String-Literal";
Bei neuen Programmen ist diese Zuweisung aber unbedingt zu vermeiden. Sie ist nur ein 'Tribut' des C++ Standards an bereits bestehende (alte C) Programme. Sollten Sie Programme für Microcontroller schreiben (sogenannte Embedded Systeme), dann kann dies unter Umständen zu ungewolltem Verhalten führen, da String-Literale in der Regel im ROM (read-only memory) abgelegt werden.

Mehrfach-Zuweisungen

Außer diesen einfachen Zuweisungen können auch Mehrfach-Zuweisungen eingesetzt werden. Hierbei wird dann mehreren Variablen in einer Anweisung der gleiche Wert zugewiesen. Die einzelnen Variablen werden mit dem Zuweisungsoperator verkettet und ganz rechts wird der zuzuweisende Ausdruck (Konstante oder weitere Variable) angegeben. Die Zuweisungen erfolgen dann in der Reihenfolge von rechts nach links.

PgmHeader
// Variablendefinitionen
short sVar1, sVar2;
char cVar;

// Zuweisungen
sVar1 = sVar2 = 0xFF;    // Ergebnis: sVar2=255, sVar1=255
sVar1 = cVar = 0xFF;     // Ergebnis: cVar=-1, sVar1=-1
cVar = sVar1 = 0xFF;     // Ergebnis: sVar1=255, cVar=-1!
AchtungVermeiden Sie bei Mehrfach-Zuweisungen unbedingt die Verwendung von unterschiedlichen Datentypen. Dies kann sonst, wie in der letzten Zuweisung oben dargestellt, zu unliebsamen Überraschungen führen.
Beispiel und ÜbungUnd hier geht's jetzt zum Beispiel und zur Übung.