C Language
Datentypen
Suche…
Bemerkungen
- Während
char
1 Byte lang sein muss, muss 1 Byte nicht 8 Bit sein (oft auch als Oktett bezeichnet ), obwohl die meisten modernen Computerplattformen es als 8 Bit definieren. Die Implementierung der Anzahl von Bits prochar
wird durch die vorgesehenenCHAR_BIT
Makro, definiert in<limits.h>
. POSIX erfordert, dass 1 Byte aus 8 Bit besteht. - Typen mit fester Breite sollten nur spärlich verwendet werden. Die integrierten Typen von C sind so konzipiert, dass sie in jeder Architektur selbstverständlich sind. Die Typen mit fester Breite sollten nur verwendet werden, wenn Sie explizit eine ganzzahlige Größe benötigen (zum Beispiel für Netzwerke).
Integer-Typen und Konstanten
Signed Integer kann dieser Typen sein (der int
nach short
oder long
ist optional):
signed char c = 127; /* required to be 1 byte, see remarks for further information. */
signed short int si = 32767; /* required to be at least 16 bits. */
signed int i = 32767; /* required to be at least 16 bits */
signed long int li = 2147483647; /* required to be at least 32 bits. */
signed long long int li = 2147483647; /* required to be at least 64 bits */
Jeder dieser vorzeichenbehafteten Integer-Typen hat eine vorzeichenlose Version.
unsigned int i = 65535;
unsigned short = 2767;
unsigned char = 255;
Bei allen Typen außer char
die signed
Version angenommen, wenn der signed
oder unsigned
Teil ausgelassen wird. Der Typ char
stellt einen dritten Zeichentyp dar, der sich von signed char
und unsigned char
und die Signiertheit (oder nicht) hängt von der Plattform ab.
Verschiedene Typen von Integer-Konstanten (im C-Jargon als Literale bezeichnet) können auf der Grundlage ihres Präfixes oder Suffixes mit unterschiedlichen Basen und unterschiedlicher Breite geschrieben werden.
/* the following variables are initialized to the same value: */
int d = 42; /* decimal constant (base10) */
int o = 052; /* octal constant (base8) */
int x = 0xaf; /* hexadecimal constants (base16) */
int X = 0XAf; /* (letters 'a' through 'f' (case insensitive) represent 10 through 15) */
Dezimalkonstanten sind immer signed
. Hexadezimale Konstanten beginnen mit 0x
oder 0X
und 0X
beginnen nur mit einer 0
. Die beiden letzteren sind signed
oder unsigned
abhängig davon, ob der Wert in den signierten Typ passt oder nicht.
/* suffixes to describe width and signedness : */
long int i = 0x32; /* no suffix represent int, or long int */
unsigned int ui = 65535u; /* u or U represent unsigned int, or long int */
long int li = 65536l; /* l or L represent long int */
Ohne Suffix hat die Konstante den ersten Typ, der zu ihrem Wert passt, d. INT_MAX
Eine Dezimalkonstante, die größer ist als INT_MAX
wenn möglich vom Typ long
oder ansonsten long long
.
Die Header-Datei <limits.h>
beschreibt die Grenzen von Ganzzahlen wie folgt. Ihre implementierungsdefinierten Werte müssen gleich oder größer sein als die unten gezeigten, mit demselben Vorzeichen.
Makro | Art | Wert |
---|---|---|
CHAR_BIT | kleinstes Objekt, das kein Bitfeld (Byte) ist | 8 |
SCHAR_MIN | signed char | -127 / - (2 7 - 1) |
SCHAR_MAX | signed char | +127 / 2 7 - 1 |
UCHAR_MAX | unsigned char | 255/2 8 - 1 |
CHAR_MIN | char | siehe unten |
CHAR_MAX | char | siehe unten |
SHRT_MIN | short int | -32767 / - (2 15 - 1) |
SHRT_MAX | short int | +32767 / 2 15 - 1 |
USHRT_MAX | unsigned short int | 65535/2 16 - 1 |
INT_MIN | int | -32767 / - (2 15 - 1) |
INT_MAX | int | +32767 / 2 15 - 1 |
UINT_MAX | unsigned int | 65535/2 16 - 1 |
LONG_MIN | long int | -2147483647 / - (2 31 - 1) |
LONG_MAX | long int | +2147483647 / 2 31 - 1 |
ULONG_MAX | unsigned long int | 4294967295/2 32 - 1 |
Makro | Art | Wert |
---|---|---|
LLONG_MIN | long long int | -9223372036854775807 / - (2 63 - 1) |
LLONG_MAX | long long int | +9223372036854775807 / 2 63 - 1 |
ULLONG_MAX | unsigned long long int | 18446744073709551615/2 64 - 1 |
Wenn der Wert von einem Objekt vom Typ char
Zeichen erstreckt , wenn in einem Ausdruck verwendet, der Wert von CHAR_MIN
soll das gleiche sein wie die der SCHAR_MIN
und der Wert von CHAR_MAX
ist die gleich wie das sein SCHAR_MAX
. Wenn der Wert eines Objekt vom Typ char
nicht Vorzeichen erweitern , wenn in einem Ausdruck verwendet, der Wert von CHAR_MIN
sein soll 0 und der Wert von CHAR_MAX
ist die gleich wie das sein UCHAR_MAX
.
Der C99-Standard fügte einen neuen Header <stdint.h>
, der Definitionen für Ganzzahlen mit fester Breite enthält. Eine ausführlichere Erklärung finden Sie im Beispiel für die Ganzzahl mit fester Breite.
String Literals
Ein String-Literal in C ist eine Folge von Zeichen, die durch eine Literal-Null abgeschlossen wird.
char* str = "hello, world"; /* string literal */
/* string literals can be used to initialize arrays */
char a1[] = "abc"; /* a1 is char[4] holding {'a','b','c','\0'} */
char a2[4] = "abc"; /* same as a1 */
char a3[3] = "abc"; /* a1 is char[3] holding {'a','b','c'}, missing the '\0' */
String-Literale sind nicht modifizierbar (und können tatsächlich in einen Nur-Lese-Speicher gestellt werden, z. B. .rodata). Der Versuch, ihre Werte zu ändern, führt zu undefiniertem Verhalten.
char* s = "foobar";
s[0] = 'F'; /* undefined behaviour */
/* it's good practice to denote string literals as such, by using `const` */
char const* s1 = "foobar";
s1[0] = 'F'; /* compiler error! */
Mehrere String-Literale werden zur Kompilierzeit verkettet, sodass Sie Konstrukte wie diese schreiben können.
/* only two narrow or two wide string literals may be concatenated */
char* s = "Hello, " "World";
/* since C99, more than two can be concatenated */
/* concatenation is implementation defined */
char* s1 = "Hello" ", " "World";
/* common usages are concatenations of format strings */
char* fmt = "%" PRId16; /* PRId16 macro since C99 */
Zeichenkettenliterale unterstützen wie Zeichenkonstanten verschiedene Zeichensätze.
/* normal string literal, of type char[] */
char* s1 = "abc";
/* wide character string literal, of type wchar_t[] */
wchar_t* s2 = L"abc";
/* UTF-8 string literal, of type char[] */
char* s3 = u8"abc";
/* 16-bit wide string literal, of type char16_t[] */
char16_t* s4 = u"abc";
/* 32-bit wide string literal, of type char32_t[] */
char32_t* s5 = U"abc";
Integer-Typen mit fester Breite (seit C99)
Der Header <stdint.h>
enthält mehrere Integer-Typdefinitionen mit fester Breite. Diese Typen sind optional und werden nur bereitgestellt, wenn die Plattform über einen ganzzahligen Typ mit der entsprechenden Breite verfügt und der entsprechende vorzeichenbehaftete Typ eine Zweierkomplement-Darstellung mit negativen Werten hat.
In den Anmerkungen finden Sie Verwendungshinweise für Typen mit fester Breite.
/* commonly used types include */
uint32_t u32 = 32; /* exactly 32-bits wide */
uint8_t u8 = 255; /* exactly 8-bits wide */
int64_t i64 = -65 /* exactly 64 bit in two's complement representation */
Fließkommakonstanten
Die C-Sprache hat drei obligatorische reelle Fließkommatypen: float
, double
und long double
.
float f = 0.314f; /* suffix f or F denotes type float */
double d = 0.314; /* no suffix denotes double */
long double ld = 0.314l; /* suffix l or L denotes long double */
/* the different parts of a floating point definition are optional */
double x = 1.; /* valid, fractional part is optional */
double y = .1; /* valid, whole-number part is optional */
/* they can also defined in scientific notation */
double sd = 1.2e3; /* decimal fraction 1.2 is scaled by 10^3, that is 1200.0 */
Der Header <float.h>
definiert verschiedene Grenzwerte für Gleitkommaoperationen.
Gleitkomma-Arithmetik ist implementierungsdefiniert. Die meisten modernen Plattformen (Arm, x86, x86_64, MIPS) verwenden jedoch Fließkommaoperationen nach IEEE 754 .
C verfügt außerdem über drei optionale komplexe Fließkommatypen, die von den oben genannten abgeleitet werden.
Erklärungen interpretieren
Eine charakteristische syntaktische Besonderheit von C besteht darin, dass Deklarationen die Verwendung des deklarierten Objekts wie in einem normalen Ausdruck widerspiegeln.
Die folgenden Operatoren mit identischer Priorität und Assoziativität werden in Deklaratoren wiederverwendet, nämlich:
- der unäre
*
"Dereferenzierungs" -Operator, der einen Zeiger bezeichnet; - der binäre
[]
"Array Subscription" -Operator, der ein Array bezeichnet; - der (1 + n) -ary
()
"Funktionsaufruf" -Operator, der eine Funktion bezeichnet; - die
()
Gruppierung Klammern, die den Vorrang und die Assoziativität der übrigen aufgelisteten Operatoren überschreiben.
Die obigen drei Operatoren haben die folgende Priorität und Assoziativität:
Operator | Relativer Vorrang | Assoziativität |
---|---|---|
[] (Array-Abonnement) | 1 | Links nach rechts |
() (Funktionsaufruf) | 1 | Links nach rechts |
* (Dereferenzierung) | 2 | Rechts nach links |
Bei der Interpretation von Deklarationen muss man vom Bezeichner nach außen gehen und die benachbarten Operatoren in der richtigen Reihenfolge gemäß der obigen Tabelle anwenden. Jede Anwendung eines Operators kann durch die folgenden englischen Wörter ersetzt werden:
Ausdruck | Deutung |
---|---|
thing[X] | ein Array von Größe X von ... |
thing(t1, t2, t3) | eine Funktion, die t1 , t2 , t3 und zurückgibt ... |
*thing | ein Zeiger auf ... |
Daraus folgt, dass der Beginn der englischen Interpretation immer mit dem Bezeichner beginnt und mit dem Typ endet, der auf der linken Seite der Deklaration steht.
Beispiele
char *names[20];
[]
hat Vorrang vor *
, die Interpretation lautet also: names
ist ein Array der Größe 20 eines Zeigers auf char
.
char (*place)[10];
Im Falle der Verwendung von Klammern zum Überschreiben der Rangfolge wird das *
zuerst angewendet: place
ist ein Zeiger auf ein Array der Größe 10 von char
.
int fn(long, short);
Es gibt keinen Vorrang, über den Sie sich Gedanken machen müssen: fn
ist eine Funktion, die long
, short
und int
.
int *fn(void);
()
Wird zuerst angewendet: fn
ist eine Funktion, die void
und einen Zeiger auf int
.
int (*fp)(void);
Überschreiben der Priorität von ()
: fp
ist ein Zeiger auf eine Funktion, die void
und int
.
int arr[5][8];
Mehrdimensionale Arrays bilden keine Ausnahme von der Regel. Die Operatoren []
werden in der Reihenfolge von links nach rechts entsprechend der Assoziativität in der Tabelle angewendet: arr
ist ein Array der Größe 5 eines Arrays der Größe 8 von int
.
int **ptr;
Die beiden Dereferenzierungsoperatoren haben gleiche Priorität, sodass die Assoziativität wirksam wird. Die Operatoren werden in einer Reihenfolge von rechts nach links angewendet: ptr
ist ein Zeiger auf einen Zeiger auf ein int
.
Mehrere Erklärungen
Das Komma kann als Trennzeichen verwendet werden (* nicht * wie der Komma-Operator), um mehrere Deklarationen innerhalb einer einzelnen Anweisung zu begrenzen. Die folgende Anweisung enthält fünf Deklarationen:int fn(void), *ptr, (*fp)(int), arr[10][20], num;
Die deklarierten Objekte im obigen Beispiel sind:
-
fn
: eine Funktion, dievoid
undint
; -
ptr
: ein Zeiger auf einint
; -
fp
: ein Zeiger auf eine Funktion, dieint
undint
; -
arr
: ein Array der Größe 10 eines Arrays der Größe 20 vonint
; -
num
:int
.
Alternative Interpretation
Da Deklarationen gespiegelt werden, kann eine Deklaration auch in Bezug auf die Operatoren, die auf das Objekt angewendet werden könnten, und den endgültigen resultierenden Typ dieses Ausdrucks interpretiert werden. Der Typ, der auf der linken Seite steht, ist das Endergebnis, das sich nach Anwendung aller Operatoren ergibt.
/*
* Subscripting "arr" and dereferencing it yields a "char" result.
* Particularly: *arr[5] is of type "char".
*/
char *arr[20];
/*
* Calling "fn" yields an "int" result.
* Particularly: fn('b') is of type "int".
*/
int fn(char);
/*
* Dereferencing "fp" and then calling it yields an "int" result.
* Particularly: (*fp)() is of type "int".
*/
int (*fp)(void);
/*
* Subscripting "strings" twice and dereferencing it yields a "char" result.
* Particularly: *strings[5][15] is of type "char"
*/
char *strings[10][20];