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.h
Wollen 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 32767
Kommazahlen: 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];
uint8_t x = 5; int32_t y = 9; int16_t arr[5];
uint8_t x = 5; int32_t y = 9; int16_t arr[5];
printf("%"PRId8"; %"PRId32"; %d", x, y, arr);
=> "5; 9; 18"
uint8_t x = 5; int32_t y = 9; int16_t arr[5];
printf("%"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] = 17
int8_t x = 5;
int8_t *pX;
int8_t x = 5;
int8_t *pX = &x;
int8_t x = 5;
int8_t *pX = &x;
pX = 6;
int8_t x = 5;
int8_t *pX = &x;
*pX = 6;
Text 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
, else
Programmausfü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
switch
uint8_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!");
}
while
Programmcode 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
}
for
Auch 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 while
Wie 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 ist
Rü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