Arithmetische Typen
(Siehe auch Typ für eine Übersicht des Typsystems und die Liste der typbezogenen Dienstprogramme, die von der C-Bibliothek bereitgestellt werden.)
Boolescher TypBeachten Sie, dass die Konvertierung zu _Bool(bis C23)bool(seit C23) nicht dasselbe ist wie die Konvertierung zu anderen Ganzzahl-Typen: (bool)0.5 ergibt true, während (int)0.5 ergibt 0. |
(seit C99) |
[bearbeiten] Zeichen-Typen
- signed char — Typ für die Darstellung von vorzeichenbehafteten Zeichen.
- unsigned char — Typ für die Darstellung von vorzeichenlosen Zeichen. Wird auch verwendet, um Objektrepräsentationen (roher Speicher) zu inspizieren.
- char — Typ für die Zeichenrepräsentation. Entspricht entweder signed char oder unsigned char (welcher einer von beiden implementierungsabhängig ist und durch einen Compiler-Schalter gesteuert werden kann), aber char ist ein eigenständiger Typ, der sich von sowohl signed char als auch unsigned char unterscheidet.
Beachten Sie, dass die Standardbibliothek auch typedef-Namen wchar_t, char16_t und char32_t(seit C11) zur Darstellung von weiten Zeichen und char8_t für UTF-8-Zeichen(seit C23) definiert.
[bearbeiten] Ganzzahl-Typen
- short int (auch zugänglich als short, kann das Schlüsselwort signed verwenden)
- unsigned short int (auch zugänglich als unsigned short)
- int (auch zugänglich als signed int)
- Dies ist der optimalste Ganzzahl-Typ für die Plattform und garantiert mindestens 16 Bit. Die meisten aktuellen Systeme verwenden 32 Bit (siehe Datenmodelle unten).
- unsigned int (auch zugänglich als unsigned), das vorzeichenlose Gegenstück von int, das Modulo-Arithmetik implementiert. Geeignet für Bit-Manipulationen.
- long int (auch zugänglich als long)
- unsigned long int (auch zugänglich als unsigned long)
|
(seit C99) |
|
(seit C23) |
Hinweis: Wie bei allen Typspezifizierern ist jede Reihenfolge zulässig: unsigned long long int und long int unsigned long bezeichnen denselben Typ.
Die folgende Tabelle fasst alle verfügbaren Ganzzahl-Typen und ihre Eigenschaften zusammen
| Typspezifizierer | Entsprechender Typ | Breite in Bits nach Datenmodell | ||||
|---|---|---|---|---|---|---|
| C-Standard | LP32 | ILP32 | LLP64 | LP64 | ||
char
|
char | mindestens 8 |
8 | 8 | 8 | 8 |
signed char
|
signed char | |||||
unsigned char
|
unsigned char | |||||
short
|
short int | mindestens 16 |
16 | 16 | 16 | 16 |
short int
| ||||||
signed short
| ||||||
signed short int
| ||||||
unsigned short
|
unsigned short int | |||||
unsigned short int
| ||||||
int
|
int | mindestens 16 |
16 | 32 | 32 | 32 |
signed
| ||||||
signed int
| ||||||
unsigned
|
unsigned int | |||||
unsigned int
| ||||||
long
|
long int | mindestens 32 |
32 | 32 | 32 | 64 |
long int
| ||||||
signed long
| ||||||
signed long int
| ||||||
unsigned long
|
unsigned long int | |||||
unsigned long int
| ||||||
long long
|
long long int (C99) |
mindestens 64 |
64 | 64 | 64 | 64 |
long long int
| ||||||
signed long long
| ||||||
signed long long int
| ||||||
unsigned long long
|
unsigned long long int (C99) | |||||
unsigned long long int
| ||||||
Neben den minimalen Bit-Anzahlen garantiert der C-Standard, dass
- 1 == sizeof(char)
≤sizeof(short)≤sizeof(int)≤sizeof(long)≤sizeof(long long).
Hinweis: Dies erlaubt den Extremfall, bei dem Bytes 64 Bit groß sind, alle Typen (einschließlich char) 64 Bit breit sind und sizeof für jeden Typ 1 zurückgibt.
Hinweis: Die Ganzzahl-Arithmetik ist für vorzeichenbehaftete und vorzeichenlose Ganzzahl-Typen unterschiedlich definiert. Siehe arithmetische Operatoren, insbesondere Ganzzahl-Überläufe.
[bearbeiten] Datenmodelle
Die von jeder Implementierung getroffenen Entscheidungen über die Größen der fundamentalen Typen werden kollektiv als Datenmodell bezeichnet. Vier Datenmodelle fanden weite Akzeptanz
32-Bit-Systeme
- LP32 oder 2/4/4 (int ist 16-Bit, long und Zeiger sind 32-Bit)
- Win16 API
- ILP32 oder 4/4/4 (int, long und Zeiger sind 32-Bit);
- Win32 API
- Unix und Unix-ähnliche Systeme (Linux, Mac OS X)
64-Bit-Systeme
- LLP64 oder 4/4/8 (int und long sind 32-Bit, Zeiger ist 64-Bit)
- Win64 API
- LP64 oder 4/8/8 (int ist 32-Bit, long und Zeiger sind 64-Bit)
- Unix und Unix-ähnliche Systeme (Linux, Mac OS X)
Andere Modelle sind sehr selten. Zum Beispiel erschien ILP64 (8/8/8: int, long und Zeiger sind 64-Bit) nur in einigen frühen 64-Bit-Unix-Systemen (z.B. Unicos auf Cray).
Beachten Sie, dass exakte Ganzzahl-Typen seit C99 in <stdint.h> verfügbar sind.
[bearbeiten] Reelle Gleitkomma-Typen
C hat drei oder sechs(seit C23) Typen zur Darstellung reeller Gleitkommawerte
- float — Gleitkommatyp mit einfacher Genauigkeit. Entspricht dem IEEE-754 binary32 Format, falls unterstützt.
- double — Gleitkommatyp mit doppelter Genauigkeit. Entspricht dem IEEE-754 binary64 Format, falls unterstützt.
- long double — Gleitkommatyp mit erweiterter Genauigkeit. Entspricht dem IEEE-754 binary128 Format, falls unterstützt, andernfalls dem IEEE-754 binary64-extended Format, falls unterstützt, andernfalls einem nicht-IEEE-754 erweiterten Gleitkommaformat, solange seine Genauigkeit besser ist als binary64 und sein Bereich mindestens so gut ist wie binary64, andernfalls entspricht es dem IEEE-754 binary64 Format.
- Das binary128 Format wird von einigen HP-UX, SPARC, MIPS, ARM64 und z/OS-Implementierungen verwendet.
- Das bekannteste IEEE-754 binary64-extended Format ist das 80-Bit x87-Format mit erweiterter Genauigkeit. Es wird von vielen x86- und x86-64-Implementierungen verwendet (eine bemerkenswerte Ausnahme ist MSVC, das long double im selben Format wie double, d.h. binary64, implementiert).
|
(seit C23) |
Gleitkomma-Typen können spezielle Werte unterstützen
- Unendlich (positiv und negativ), siehe INFINITY
- das negative Null, -0.0. Es vergleicht sich gleich mit der positiven Null, ist aber in einigen arithmetischen Operationen bedeutsam, z. B. 1.0 / 0.0 == INFINITY, aber 1.0 / -0.0 == -INFINITY)
- nicht-eine-Zahl (NaN), die sich mit nichts (einschließlich sich selbst) vergleicht. Mehrere Bit-Muster stellen NaNs dar, siehe nan, NAN. Beachten Sie, dass C keine besondere Beachtung für Signalisierungs-NaNs (gemäß IEEE-754) hat und alle NaNs als leise behandelt.
Reelle Gleitkommazahlen können mit arithmetischen Operatoren + - / * und verschiedenen mathematischen Funktionen aus <math.h> verwendet werden. Sowohl eingebaute Operatoren als auch Bibliotheksfunktionen können Gleitkomma-Ausnahmen auslösen und errno setzen, wie in math_errhandling beschrieben.
Gleitkomma-Ausdrücke können einen größeren Bereich und eine höhere Genauigkeit aufweisen, als ihre Typen anzeigen, siehe FLT_EVAL_METHOD. Zuweisung, Rückgabe und Cast erzwingen den Bereich und die Genauigkeit auf diejenige, die mit dem deklarierten Typ verbunden ist.
Gleitkomma-Ausdrücke können auch kontrahiert werden, das heißt, sie werden so berechnet, als hätten alle Zwischenwerte einen unendlichen Bereich und eine unendliche Genauigkeit, siehe #pragma STDC FP_CONTRACT.
Einige Operationen mit Gleitkommazahlen werden durch den Zustand der Gleitkomma-Umgebung beeinflusst und ändern diesen (am bemerkenswertesten die Rundungsrichtung).
Implizite Konvertierungen sind zwischen reellen Gleitkomma-Typen und Ganzzahl-, komplexen und imaginären Typen definiert.
Siehe Grenzen von Gleitkomma-Typen und die <math.h> Bibliothek für zusätzliche Details, Grenzen und Eigenschaften der Gleitkomma-Typen.
Komplexe Gleitkomma-TypenKomplexe Gleitkomma-Typen modellieren die mathematische komplexe Zahl, d.h. die Zahlen, die als Summe einer reellen Zahl und einer reellen Zahl multipliziert mit der imaginären Einheit geschrieben werden können: a + bi Die drei komplexen Typen sind
Hinweis: Wie bei allen Typspezifizierern ist jede Reihenfolge zulässig: long double complex, complex long double und sogar double complex long bezeichnen denselben Typ. Führen Sie diesen Code aus Ausgabe 1/(1.0+2.0i) = 0.2-0.4i
Jeder komplexe Typ hat dieselbe Objektrepräsentation und Ausrichtungsanforderungen wie ein Array aus zwei Elementen des entsprechenden reellen Typs (float für float complex, double für double complex, long double für long double complex). Das erste Element des Arrays enthält den Realteil und das zweite Element des Arrays den Imaginärteil. Komplexe Zahlen können mit arithmetischen Operatoren Inkrement- und Dekrementoperatoren sind für komplexe Typen nicht definiert. Relationale Operatoren sind für komplexe Typen nicht definiert (es gibt keine Vorstellung von "kleiner als").
Um das Ein-Unendlich-Modell der komplexen Zahlenarithmetik zu unterstützen, betrachtet C jeden komplexen Wert mit mindestens einem unendlichen Teil als unendlich, auch wenn sein anderer Teil eine NaN ist, garantiert, dass alle Operatoren und Funktionen grundlegende Eigenschaften von Unendlichkeiten beachten und stellt cproj bereit, um alle Unendlichkeiten auf die kanonische zu mappen (siehe arithmetische Operatoren für die genauen Regeln). Führen Sie diesen Code aus #include <complex.h> #include <math.h> #include <stdio.h> int main(void) { double complex z = (1 + 0*I) * (INFINITY + I*INFINITY); // textbook formula would give // (1+i0)(∞+i∞) ⇒ (1×∞ – 0×∞) + i(0×∞+1×∞) ⇒ NaN + I*NaN // but C gives a complex infinity printf("%f%+f*i\n", creal(z), cimag(z)); // textbook formula would give // cexp(∞+iNaN) ⇒ exp(∞)×(cis(NaN)) ⇒ NaN + I*NaN // but C gives ±∞+i*nan double complex y = cexp(INFINITY + I*NAN); printf("%f%+f*i\n", creal(y), cimag(y)); } Mögliche Ausgabe inf+inf*i inf+nan*i C behandelt auch mehrere Unendlichkeiten so, dass sie, trotz der inhärenten Einschränkungen der kartesischen Darstellung, die Richtungsinformationen nach Möglichkeit beibehalten. die Multiplikation der imaginären Einheit mit unendlicher Realität ergibt die korrekt-vorzeichenbehaftete imaginäre Unendlichkeit: i × ∞ = i∞. Außerdem ergibt i × (∞ – i∞) = ∞ + i∞ die vernünftige Quadrante.
Imaginäre Gleitkomma-TypenImaginäre Gleitkomma-Typen modellieren die mathematischen imaginären Zahlen, d.h. Zahlen, die als reelle Zahl multipliziert mit der imaginären Einheit geschrieben werden können: bi Die drei imaginären Typen sind
Hinweis: Wie bei allen Typspezifizierern ist jede Reihenfolge zulässig: long double imaginary, imaginary long double und sogar double imaginary long bezeichnen denselben Typ. Führen Sie diesen Code aus Ausgabe 1/(3.0i) = -0.3i
Jeder der drei imaginären Typen hat dieselbe Objektrepräsentation und Ausrichtungsanforderung wie sein entsprechender reeller Typ (float für float imaginary, double für double imaginary, long double für long double imaginary). Hinweis: Trotzdem sind imaginäre Typen eigenständig und nicht kompatibel mit ihren entsprechenden reellen Typen, was Aliasing verbietet. Imaginäre Zahlen können mit arithmetischen Operatoren Inkrement- und Dekrementoperatoren sind für imaginäre Typen nicht definiert.
Die imaginären Zahlen ermöglichen es, alle komplexen Zahlen mit der natürlichen Notation x + I*y auszudrücken (wobei I als _Imaginary_I definiert ist). Ohne imaginäre Typen können bestimmte spezielle komplexe Werte nicht natürlich erzeugt werden. Zum Beispiel, wenn I als _Complex_I definiert ist, ergibt die Schreibweise 0.0 + I*INFINITY NaN als Realteil, und CMPLX(0.0, INFINITY) muss stattdessen verwendet werden. Dasselbe gilt für Zahlen mit einer negativen Null im Imaginärteil, die bei der Arbeit mit Bibliotheksfunktionen mit Zweigfunktionen wie csqrt bedeutsam sind: 1.0 - 0.0*I ergibt den positiven Null-Imaginärteil, wenn I als _Complex_I definiert ist, und der negative Null-Imaginärteil erfordert die Verwendung von CMPLX oder conj. Imaginäre Typen vereinfachen auch die Implementierungen; die Multiplikation einer imaginären Zahl mit einer komplexen Zahl kann bei Unterstützung von imaginären Typen geradlinig mit zwei Multiplikationen implementiert werden, anstatt mit vier Multiplikationen und zwei Additionen. |
(seit C99) |
[bearbeiten] Schlüsselwörter
- bool, true, false, char, int, short, long, signed, unsigned, float, double.
- _Bool, _BitInt, _Complex, _Imaginary, _Decimal32, _Decimal64, _Decimal128.
[bearbeiten] Wertebereich
Die folgende Tabelle bietet eine Referenz für die Grenzen gängiger numerischer Darstellungen.
Vor C23 erlaubte der C-Standard jede vorzeichenbehaftete Ganzzahldarstellung, und der minimal garantierte Bereich von N-Bit-Ganzzahlen mit Vorzeichen war von -(2N-1
-1) bis +2N-1
-1 (z. B. -127 bis 127 für einen vorzeichenbehafteten 8-Bit-Typ), was den Grenzen von Einerkomplement oder Vorzeichen und Betrag entspricht.
Alle gängigen Datenmodelle (einschließlich aller ILP32, LP32, LP64, LLP64) und fast alle C-Compiler verwenden jedoch die Zweierkomplementdarstellung (die einzigen bekannten Ausnahmen sind einige Compiler für UNISYS), und ab C23 ist dies die einzige vom Standard zugelassene Darstellung mit dem garantierten Bereich von -2N-1
bis +2N-1
-1 (z. B. -128 bis 127 für einen vorzeichenbehafteten 8-Bit-Typ).
| Typ | Größe in Bits | Format | Wertebereich | |
|---|---|---|---|---|
| Ungefähr | Exakt | |||
| Zeichen | 8 | signed | −128 bis 127 | |
| unsigned | 0 bis 255 | |||
| 16 | UTF-16 | 0 bis 65535 | ||
| 32 | UTF-32 | 0 bis 1114111 (0x10ffff) | ||
| Ganzzahl | 16 | signed | ± 3,27 · 104 | −32768 bis 32767 |
| unsigned | 0 bis 6,55 · 104 | 0 bis 65535 | ||
| 32 | signed | ± 2,14 · 109 | −2.147.483.648 bis 2.147.483.647 | |
| unsigned | 0 bis 4,29 · 109 | 0 bis 4.294.967.295 | ||
| 64 | signed | ± 9,22 · 1018 | −9.223.372.036.854.775.808 bis 9.223.372.036.854.775.807 | |
| unsigned | 0 bis 1,84 · 1019 | 0 bis 18.446.744.073.709.551.615 | ||
| binary Gleitkomma- zahl |
32 | IEEE-754 |
|
|
| 64 | IEEE-754 |
|
| |
| 80[Anmerkung 1] | x86 |
|
| |
| 128 | IEEE-754 |
|
| |
| dezimal Gleitkomma- zahl |
32 | IEEE-754 |
| |
| 64 | IEEE-754 |
| ||
| 128 | IEEE-754 |
| ||
- ↑ Die Objekt-Repräsentation belegt normalerweise 96/128 Bits auf 32/64-Bit-Plattformen.
Hinweis: Die tatsächlichen (im Gegensatz zu den garantierten minimalen) Bereiche sind in den Header-Dateien <limits.h> und <float.h> verfügbar.
[bearbeiten] Siehe auch
| C++ Dokumentation für Fundamentale Typen
|