Variablen und einfache Datentypen
Arrays, Zeiger, Strings
Bedingte Ausführung
Schleifen
Funktionen
C ist eine streng typisierte Sprache
Variablen sollten “sprechende” Namen haben
Gut: begruessung, automarke, nenner, …
Schlecht: var1, str2, laufen, …
Es gibt verschiedene Standards für Variablenbenennung
isRunning, feindAnzahl, …Underscore: is_running, feind_anzahl, …
Sucht euch einen aus, benutzt sie konsequent!
Jedes Variable muss mit ihrem Typ deklariert bzw. definiert werden:
int a, b;
float c;Vor der ersten Verwendung sollte jede Variable initialisiert werden
a = 15;Deklaration und Initialisierung passiert oft gleichzeitig
int anzahl_der_studierenden = 56;Einfachster Datentyp: Ganzzahlen
Gibt Datentypen für verschieden große Zahlen
Vermutlich schon mal gehört: short, int, long
Problem: Genaue Größe einer int-Variable variiert systemabhängig
int gespeichert werden kann, da er auch nur 16 Bit haben könnteinttypes.hWollen wissen / festlegen, wie viele Bit / Byte die verwendeten Variablen haben
Daher verwenden wir Datentypen aus inttypes.h:
int8_t, uint8_t, int16_t, uint16_t, int32_t, uint32_t, int64_t, uint64_t
Die Zahl steht für die Anzahl der Bits in der Zahl
intX_t sind Zahlen mit, uintX_t Zahlen ohne Vorzeichen
#include <inttypes.h> // Datentypen einbinden
uint8_t guests; // 0 <= Anzahl Gäste <= 255
uint64_t file_size; // 64bit für Dateien >= 4,3 GB
int16_t geburtsjahr; // im Bereich etwa -32768 bis 32767Kommazahlen: float
// Wichtig: Punkt statt Komma
float percentage = 0.345; // 34,5%Kommazahlen mit doppelter Genauigkeit: double
double pi = 3.141592653589793;CPU kann nur mit einzelnen Zahlen rechnen
Es gibt dafür CPU-Register für Ganzzahlen (z.B. bis 64 Bit) und Kommazahlen
Teilweise liegen Variablenwerte im Speicher
Müssen zuerst in die Register geladen werden
Wollen mehrere gleichartige Dinge speichern
Beipiel: Eine Liste von 5 Geburtsjahren
// 5 Plätze, je -32768 <= jahr <= 32767
int16_t geburtsjahr[5];Zugriff über die Indizes 0 bis 4
geburtsjahr[0] = 1985;
geburtsjahr[1] = 1973;
// ...
geburtsjahr[4] = 1996;uint8_t x = 5; int32_t y = 9; int16_t arr[5];
uint8_t x = 5; int32_t y = 9; int16_t arr[5];
xuint8_t x = 5; int32_t y = 9; int16_t arr[5];
x und yuint8_t x = 5; int32_t y = 9; int16_t arr[5];
x, y und arrprintf("%"PRId8"; %"PRId32"; %d", x, y, arr);
=> "5; 9; 18"uint8_t x = 5; int32_t y = 9; int16_t arr[5];
x, y und arrprintf("%"PRId8"; %"PRId32"; %d", x, y, arr);
=> "5; 9; 18"arr enthält keine Daten, nur die Adresse, wo diese liegen
arr ist ein Zeiger auf Daten vom Typ int16_t, der Typ der Variablen ist int16_t*
Wie kann ich auf Daten zugreifen, von denen nur die Adresse bekannt ist?
printf("arr[0] = %"PRId16" \n", *arr);
printf("arr[1] = %"PRId16" \n", *(arr+1));
printf("arr[2] = %"PRId16" \n", *(arr+2));
// ...*(arr+2) = 17; // arr[2] = 17int8_t x = 5;
int8_t *pX;
x und pXint8_t x = 5;
int8_t *pX = &x;
pX zeigt jetzt auf xint8_t x = 5;
int8_t *pX = &x;
pX = 6;
pX zeigt auf Speicherstelle 6int8_t x = 5;
int8_t *pX = &x;
*pX = 6;
pX zeigt, ist jetzt 6Text wird als Array von Zeichen (char) dargestellt
char text[10] = "Hallo!";
Text wird als Array von Zeichen (char) dargestellt
char text[10] = "Hallo!";
Können daher einzelne Zeichen verändern
char text[10] = "Hallo!"; text[1] = 'e';
Ein char enthält Zahlen von 0 bis 255, entspricht also 256 verschiedenen Zeichen (siehe auch ASCII-Tabelle)
Wissen, wo String anfängt, aber nicht, wo er aufhört
Strings hören auf, wenn der erste Array-Eintrag die Zahl 0 ist
if, else if, elseProgrammausführung ist im Allgemeinen abhängig von Variablenwerten, Benutzereingaben, etc.
if (x == y) {
// Mache etwas, wenn x und y gleich sind
// ACHTUNG: Vergleich ist ==, nicht =
} else if (5 < a) {
// Mache etwas, wenn x != y und a > 5
} else {
// Mache etwas, wenn x != y und a <= 5
}if, else if, else IIVergleichsoperatoren: <, >, <=, >=, ==, !=
Logische Operatoren: &&, ||, !
Achtung: Folgendes :
char text1[10] = "Hallo!";
char text2[10] = "Hallo!";
if (text1 == text2) {
// Texte sind gleich
} else {
// Texte sind nicht gleich
}siehe man 3 strncmp / man 3 strncasecmp
switchuint8_t z = // Irgendwo kommt die Zahl her
switch (z) {
case 0:
printf("Das ist sehr wenig!");
break; // <- Wichtig, sonst bei "case 1" weiter
case 1:
printf("Besser, als nichts...");
break;
case 2: case 3: case 4: case 5:
printf("Geht noch mit einer Hand.");
break;
default:
printf("Zu viel!");
}whileProgrammcode mehrfach ausführen, solange eine Bedingung zutrifft
int32_t a = 34;
uint32_t b = 5;
int64_t r = 1;
while (b > 0) {
r = r * a;
b--; // b = b - 1
}forAuch Zählschleife genannt
for (int16_t i = 0; i < 100; i++) {
// Hier ist i = 0, 1, ..., 99
}(semantisch) äquivalent zu folgendem Code
int16_t i = 0;
while (i < 100) {
// Hier ist i = 0, 1, ..., 99
i++;
}do whileWie die while-Schleife, Bedingung wird jedoch erst nach der ersten Ausführung getestet
int32_t a = 34;
uint32_t b = 5;
int64_t r = 1;
do {
r = r * a;
b--; // b = b - 1
} while (b > 0);
// Nur korrekt, wenn b initial nicht 0 istRückgabetyp Name(Parametertyp Parametername, ...) {
// Funktionskörper
}Beispielsweise
int64_t hoch(int32_t a, uint32_t b) {
int64_t r = 1;
while (b > 0) {
r = r * a;
b--;
}
return r;
}Variablen und einfache Datentypen
Arrays, Zeiger, Strings
Bedingte Ausführung
Schleifen
Funktionen