In diesem Kapitel erfahren Sie, wie in C bestimmte Datentypen in andere konvertiert werden und wie Sie dies selbst beeinflussen können.
7 Typumwandlung
Wenn Sie in C einen Datentyp in einen anderen konvertieren (umwandeln), vollziehen Sie ein Type-Casting. Es gibt zwei Möglichkeiten, den Datentyp zu ändern:
- Der Compiler nimmt eine automatische Konvertierung von einem zum anderen Datentyp vor. Dies geschieht, wenn Sie z. B. einem int-Wert einen float-Wert zuweisen. Man spricht dabei von einer impliziten Datentypumwandlung.
- Der Programmierer kann die Konvertierung des Datentyps durch eine explizite Typumwandlung erzwingen.
Bei beiden Vorgehensweisen wird vorausgesetzt, dass der Compiler eine Typumwandlung auch wirklich unterstützt.
7.1 Implizite Datentypumwandlung 

Wenn man in Ausdrücken Operanden unterschiedlicher Datentypen miteinander über Operanden verknüpft, sind implizite Datentypumwandlungen nötig. Wie diese implizite (automatische) Umwandlung vor sich geht und worauf Sie gegebenenfalls achten müssen, soll in den folgenden Abschnitten näher erläutert werden.
7.1.1 Implizites »char« nach »int« 

Ein char wird bei Bewertungen und Berechnungen immer in ein int umgewandelt. Es wird mit nichts Kleinerem gerechnet als mit int. Nehmen wir beispielsweise folgende Berechnung:
char val1 = 10, val2 = 20, val3; val3 = val1 + val2;
Zwar haben Sie hier char-Datentypen verwendet, aber der Compiler führt hier trotzdem eine implizite Datentypumwandlung nach int durch. Daraus kann man ableiten, dass int und char beliebig mischbar sind. Diese »char nach int«-Umwandlung ist auch von Bedeutung beim Einlesen einzelner Zeichen und beim Überprüfen auf EOF.
Hinweis |
Die »char nach int«-Umwandlung ist allerdings auch rechnerabhängig, weil char mit dem Zahlenwert –128 bis +127 oder 0 bis +255 abgebildet sein kann. Ob char vorzeichenbehaftet ist oder nicht, wird vom ANSI-C-Standard nicht vorgeschrieben. Gleiches wie für »char nach int« gilt auch analog für »short nach int«. |
7.1.2 Implizites »float« nach »double« 

Dasselbe, was ich schon zuvor über »char nach int« geschrieben habe, gilt für implizite Umwandlungen von float nach double. Auch hierbei wird bei Berechnungen ein float automatisch in ein double konvertiert. Daher erfolgen alle Berechnungen immer mit derselben Genauigkeit.
7.1.3 Implizite Umwandlung in einen komplexen Gleitpunkttyp 

Bei einer Umwandlung einer reellen Gleitpunktzahl oder ganzen Zahl in einen komplexen Gleitpunkttyp (C99) erhält der Realteil den Wert der reellen Gleitpunktzahl bzw. ganzen Zahl. Der Imaginärteil hingegen ist 0. Bei der Umwandlung von komplexen Gleitpunkttypen in einen anderen komplexen Typ wird der Typ wie bei den reellen Gegenstücken umgewandelt.
7.1.4 Übliche arithmetische Datentypumwandlung 

Die Operanden eines binären Operators dürfen in C einen unterschiedlichen skalaren Datentyp besitzen. Durch die übliche arithmetische Datentypumwandlung wird dabei implizit ein gemeinsamer Datentyp gebildet. Dazu wird die ganzzahlige Erweiterung ausgeführt. Treten danach noch Operanden mit verschieden Typen auf, wird in den Typ desjenigen Operanden umgewandelt, der in der nebenstehenden Hierarchie am weitesten oben steht. Das Ergebnis ist ebenfalls von diesem Typ.
Für die Hierarchie von ganzzahligen Typen gelten folgende Regeln:
- Bei ganzzahligen Standardtypen gilt folgende Rangfolge:
char < short < int < long < long long
- Die Rangfolge bei ganzzahligen Typen ist unabhängig vom Vorzeichen. Der Typ int hat beispielsweise denselben Rang wie signed int und unsigned int.
- Der Rang eines Standardtyps ist immer größer als der Rang eines erweiterten ganzzahligen Typs in <stdint.h> (C99) mit gleicher Breite. So ist der Rang von int höher als der von int_least32_t, obwohl beide die gleiche Breite besitzen.
Bei der Hierarchie von Gleitpunkttypen gelten folgende Regeln:
- Die Rangfolge der Gleitpunkttypen sieht folgendermaßen aus:
float < double < long double
-
- bzw. für die komplexen Gegenstücke:
float _Complex < double _Complex < long double _Complex
- Gleitpunkttypen haben immer einen höheren Rang als ganzzahlige Typen.
Bei der Zuweisung wird der rechte Operand immer in den Typ des linken Operanden umgewandelt. Dabei werden überzählige (Nachkomma-)Stellen oder höherwertige Bits, die nicht mehr Platz haben, einfach abgeschnitten: Es wird nicht gerundet. Wenn der Originalwert im neuen Typ nicht mehr darstellbar ist, findet ein Überlauf statt, und das Ergebnis hat mit dem Originalwert meist nicht mehr viel gemein.
Hinweis |
Die automatische Typumwandlung (implizit) funktioniert nicht bei den Zuweisungsoperatoren und den logischen Operatoren && und ||. |
Bezogen auf diese Aussage, finden Sie in der folgenden Tabelle eine Zusammenfassung, was passiert, wenn Sie einem Datentyp (linker Operand) einen anderen Datentyp (rechter Operand) zuweisen (Operator).
Typ | Operand | Typ | Umwandlung |
int |
= |
float |
Der Nachkommateil wird weggelassen. |
int |
= |
double |
|
int |
= |
long |
Die höherwertigen Bits werden weggelassen. |
char |
= |
int |
|
char |
= |
short |
|
float |
= |
double |
Der Wert wird entweder gerundet oder abgeschnitten (hängt von der Implementierung ab). |
float |
= |
long, int, short, char |
Sollte hier keine genaue Darstellung möglich sein, wird der Wert entweder gerundet oder abgeschnitten (ebenfalls abhängig von der Implementierung). |
double |
= |
Bei der üblichen arithmetischen Datentypumwandlung gibt es folgende Punkte, die Sie unbedingt beachten sollten:
- Bei der Umwandlung von höherwertigen Datentypen in niederwertigere Datentypen kann es zu Informationsverlust kommen.
- Der Verleich von signed- und unsigned-Typen kann falsch sein. So kann beispielsweise -1 > 1U wahr sein.
- Die Division zweiter int-Werte gibt immer nur einen Ganzzahlanteil zurück. Hier findet keine automatische Konvertierung in eine Gleitpunktzahl statt.
- die Umwandlung eines negativen Wertes in einen Typ ohne Vorzeichen
- Bei der Umwandlung von ganz großen Zahlen (beispielsweise long long) in einen Gleitpunkttyp kann es passieren, dass die Genauigkeit nicht mehr ausreicht, um die Zahl genau darzustellen.
Hierzu noch ein einfaches Listing mit solchen üblichen arithmetischen Datentypumwandlungen:
/* implizitCasts.c */ #include <stdio.h> int main(void) { // Nachkommateil wird weggelassen. int float2int = 3.8; // Höherwertige Bits werden abgeschnitten. char int2char = 1000; float char2float = 'A'; float long2float = 444444444; printf("float2int : %d\n", float2int ); printf("int2char : %c\n", int2char ); printf("char2float: %f\n", char2float ); printf("long2float: %f\n", long2float ); return 0; }
Bei mir gibt das Programm beispielsweise Folgendes aus:
float2int : 3 int2char : Þ char2float: 65.000000 long2float: 444444448.000000
Ihre Meinung
Wie hat Ihnen das Openbook gefallen? Wir freuen uns immer über Ihre Rückmeldung. Schreiben Sie uns gerne Ihr Feedback als E-Mail an kommunikation@rheinwerk-verlag.de.