Kurz: C ist statisch typisiert: Jede Variable hat einen festen Typ, der bestimmt, wie viel Speicher sie braucht.
Teil des Kurses C
C ist statisch typisiert: Jede Variable hat einen festen Typ, der bestimmt, wie viel Speicher sie braucht.
Ganzzahlen und Kommazahlen
| Typ | typische Größe | Bereich |
|---|---|---|
char | 1 Byte | ein Zeichen oder -128 bis 127 |
short | 2 Byte | ±32.767 |
int | 4 Byte | ±2,1 Milliarden |
long | 4 oder 8 Byte | systemabhängig |
long long | 8 Byte | ±9,2 · 10¹⁸ |
unsigned ... | wie oben | nur ≥ 0, doppelt so groß |
float | 4 Byte | ca. 7 Stellen |
double | 8 Byte | ca. 15 Stellen (Standard) |
_Bool / bool | 1 Byte | 0 oder 1 (<stdbool.h>) |
Die Größen hängen vom System ab. Für feste Größen gibt es <stdint.h>: int8_t, uint8_t, int16_t, int32_t, int64_t, uint64_t, sowie size_t für Größen und Indizes.
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <limits.h>
int main(void) {
int alter = 17;
unsigned int zaehler = 3000000000u;
long long gross = 9000000000LL;
double pi = 3.14159265358979;
char buchstabe = 'A';
bool fertig = true;
uint8_t byte = 255;
printf("%d %u %lld %.5f %c %d %d\n", alter, zaehler, gross, pi, buchstabe, fertig, byte);
printf("Größen: char %zu, short %zu, int %zu, long %zu, long long %zu, double %zu, Zeiger %zu\n",
sizeof(char), sizeof(short), sizeof(int), sizeof(long), sizeof(long long), sizeof(double), sizeof(void *));
printf("INT_MAX = %d, INT_MIN = %d\n", INT_MAX, INT_MIN);
return 0;
}Ausgabe:
17 3000000000 9000000000 3.14159 A 1 255
Größen: char 1, short 2, int 4, long 8, long long 8, double 8, Zeiger 8
INT_MAX = 2147483647, INT_MIN = -2147483648sizeof liefert die Größe in Bytes. Ein char ist technisch eine kleine Ganzzahl: 'A' ist 65.
Konstanten
#include <stdio.h>
#define MWST 0.19 /* Makro (Textersetzung, kein Typ) */
enum { MAX_LAENGE = 10 }; /* Aufzählungskonstante */
int main(void) {
const int ANZAHL = 5; /* typisierte Konstante */
double netto = 100.0;
printf("%.2f %d %d\n", netto * (1 + MWST), ANZAHL, MAX_LAENGE);
return 0;
}Ausgabe:
119.00 5 10Schreibe Konstanten meist als const oder enum. #define kennt keine Typen und kann zu Überraschungen führen.
Ganzzahldivision, Umwandlung und Überlauf
#include <stdio.h>
#include <limits.h>
int main(void) {
printf("%d %f %f\n", 7 / 2, 7 / 2.0, (double) 7 / 2); // 3, 3.5, 3.5
printf("%d %d\n", 7 % 3, -7 % 3); // Rest, Vorzeichen folgt dem Dividenden
int i = 3.99; // Nachkommastellen fallen weg
printf("%d\n", i);
unsigned char u = 255;
u++; // unsigned: definierter Überlauf (Wrap-around)
printf("%d\n", u);
char c = 'a' + 1;
printf("%c %d\n", c, c);
printf("%d\n", (int) 'A' + 1);
return 0;
}Ausgabe:
3 3.500000 3.500000
1 -1
3
0
b 98
66Achtung
Der Überlauf vorzeichenbehafteter Zahlen (
int) ist in C undefiniertes Verhalten: Der Compiler darf annehmen, dass er nie auftritt. Rechne bei großen Werten mitlong longoder prüfe vorher.
Initialisieren!
Lokale Variablen haben ohne Anfangswert einen zufälligen Inhalt (was gerade im Speicher stand). Initialisiere immer:
#include <stdio.h>
int main(void) {
int a = 0;
int b = 5, c = 7;
double d = 0.0;
int feld[3] = {0}; // alle Elemente 0
printf("%d %d %d %.1f %d\n", a, b, c, d, feld[2]);
return 0;
}Ausgabe:
0 5 7 0.0 0Gültigkeitsbereich und Lebensdauer
| Art | Gültig | Lebt |
|---|---|---|
| lokale Variable | im Block { } | bis zum Blockende (Stack) |
| globale Variable | im ganzen Programm | ganze Laufzeit (anfangs 0) |
static lokal | im Block | ganze Laufzeit, behält den Wert |
#include <stdio.h>
int zaehler_global = 0;
void zaehle(void) {
static int aufrufe = 0; // wird nur einmal initialisiert
int lokal = 0;
aufrufe++; lokal++; zaehler_global++;
printf("static %d, lokal %d, global %d\n", aufrufe, lokal, zaehler_global);
}
int main(void) {
zaehle(); zaehle(); zaehle();
return 0;
}Ausgabe:
static 1, lokal 1, global 1
static 2, lokal 1, global 2
static 3, lokal 1, global 3Globale Variablen vermeidest du am besten: Sie machen Programme schwer verständlich.
Merke
- Typen:
char,int,long long,float,double,bool,unsigned; feste Größen aus<stdint.h> sizeofliefert die Größe in Bytes- Ganzzahldivision schneidet ab;
7 / 2.0rechnet als Kommazahl - Vorzeichenbehafteter Überlauf ist undefiniertes Verhalten
- Variablen immer initialisieren;
conststatt Magic Numbers staticlokal behält den Wert zwischen Aufrufen
Übungsaufgabe
Gib die Größe und den Wertebereich der Typen int, unsigned int und long long auf deinem System aus.
Quiz zur Selbstkontrolle
Was ergibt 7 / 2 bei int?
- 3 (richtig)
- 3.5
- 4
- 2
Welchen Wert hat eine lokale int-Variable ohne Initialisierung?
- Einen unbestimmten Wert (richtig)
- 0
- -1
- NULL
Was liefert sizeof(int) typischerweise?
- 4 (richtig)
- 2
- 8
- 1
Weiter im Kurs
Zurück: Aufbau eines C-Programms
Weiter: Operatoren und Ausdrücke
Alle Kapitel: C im Überblick