1. Grundbegriffe der Informatik
Grundlagen
Algorithmus
Ein Algorithmus ist eine eindeutige, schrittweise Handlungsvorschrift zur Lösung eines Problems. Er besteht aus einer endlichen Anzahl von Schritten, die in einer bestimmten Reihenfolge ausgeführt werden.
Eigenschaften eines Algorithmus:
- Eindeutigkeit: Jeder Schritt ist genau definiert
- Ausführbarkeit: Jeder Schritt kann ausgeführt werden
- Endlichkeit: Der Algorithmus endet nach endlich vielen Schritten
- Determiniertheit: Gleiche Eingaben liefern gleiche Ergebnisse
Beispiel: Rezept zum Kuchenbacken, Wegbeschreibung, Sortieralgorithmus
Grundlagen
Programm
Ein Programm ist die konkrete Umsetzung eines Algorithmus in einer Programmiersprache. Es besteht aus einer Folge von Anweisungen, die von einem Computer ausgeführt werden können.
Ein einfaches C-Programm:
#include <stdio.h>
int main() {
printf("Hallo Welt!");
return 0;
}
Grundlagen
Compiler
Ein Compiler ist ein Programm, das Quellcode (von Menschen geschriebener Code) in Maschinencode (vom Computer ausführbare Anweisungen) übersetzt.
Ablauf: Quellcode → Compiler → Ausführbare Datei
gcc -o programm programm.c
Grundlagen
Syntax
Die Syntax definiert die grammatikalischen Regeln einer Programmiersprache. Sie legt fest, wie Code geschrieben werden muss, damit er vom Compiler verstanden wird.
int zahl = 42; // Korrekte Syntax
int 42 = zahl; // Falsche Syntax
Grundlagen
Semantik
Die Semantik beschreibt die Bedeutung von Code. Sie definiert, was der Code tatsächlich macht, wenn er ausgeführt wird.
x = x + 1; // Syntax korrekt, Semantik: "Erhöhe x um 1"
2. Programmierung & Algorithmen
Konzepte
Programmierparadigma
Ein Programmierparadigma ist ein grundlegender Programmierstil oder eine Denkweise, wie Programme strukturiert werden.
Beispiele:
- Imperativ: Beschreibt WIE etwas gemacht wird (C, Java)
- Deklarativ: Beschreibt WAS gemacht werden soll (SQL, HTML)
- Objektorientiert: Programme als Objekte mit Eigenschaften (Java, C++)
- Funktional: Programme als mathematische Funktionen (Haskell, Lisp)
Konzepte
Debugging
Debugging ist der Prozess des Findens und Behebens von Fehlern (Bugs) in einem Programm.
Arten von Fehlern:
- Syntax-Fehler: Verstöße gegen die Grammatik (werden vom Compiler erkannt)
- Laufzeit-Fehler: Fehler während der Ausführung (z.B. Division durch Null)
- Logische Fehler: Programm läuft, macht aber nicht das Richtige
Konzepte
Kommentar
Kommentare sind erklärende Texte im Code, die vom Compiler ignoriert werden. Sie dienen der Dokumentation und Verständlichkeit.
// Einzeiliger Kommentar
/* Mehrzeiliger
Kommentar */
int x = 5; // Variable für das Alter
3. Datentypen & Variablen
Datentypen
Variable
Eine Variable ist ein benannter Speicherplatz, in dem ein Wert gespeichert wird. Der Wert kann während der Programmausführung verändert werden.
Bestandteile:
- Name: Bezeichner der Variable (z.B. "alter")
- Typ: Art der Daten (z.B. int, double)
- Wert: Gespeicherte Daten (z.B. 25)
int alter = 25; // Variable "alter" vom Typ int mit Wert 25
Datentypen
Konstante
Eine Konstante ist ein Wert, der nach der Initialisierung nicht mehr verändert werden kann.
const double PI = 3.14159;
#define MAX_WERT 100
Datentypen
Datentyp
Ein Datentyp definiert, welche Art von Werten eine Variable speichern kann und welche Operationen damit möglich sind.
Grundlegende Datentypen in C:
- int: Ganzzahlen (z.B. 42, -17, 0)
- float: Fließkommazahlen einfacher Genauigkeit (z.B. 3.14)
- double: Fließkommazahlen doppelter Genauigkeit (z.B. 3.14159265)
- char: Einzelne Zeichen (z.B. 'A', 'x', '5')
- void: Kein Wert (für Funktionen ohne Rückgabewert)
Datentypen
Deklaration
Bei der Deklaration wird eine Variable angelegt und ihr Typ festgelegt. Speicherplatz wird reserviert.
int zahl; // Deklaration ohne Initialisierung
Datentypen
Initialisierung
Bei der Initialisierung wird einer Variablen bei der Deklaration ein Anfangswert zugewiesen.
int zahl = 42; // Deklaration + Initialisierung
Datentypen
Type Casting
Type Casting ist die explizite Umwandlung eines Datentyps in einen anderen.
int x = 10;
int y = 3;
double ergebnis = (double)x / y; // 3.333... statt 3
4. Operatoren
Operatoren
Arithmetische Operatoren
Operatoren für mathematische Berechnungen:
- + Addition: 5 + 3 = 8
- - Subtraktion: 5 - 3 = 2
- * Multiplikation: 5 * 3 = 15
- / Division: 6 / 3 = 2
- % Modulo (Rest): 7 % 3 = 1
Operatoren
Vergleichsoperatoren
Operatoren zum Vergleichen von Werten (Ergebnis: wahr oder falsch):
- == Gleich: 5 == 5 ist wahr
- != Ungleich: 5 != 3 ist wahr
- < Kleiner als: 3 < 5 ist wahr
- > Größer als: 5 > 3 ist wahr
- <= Kleiner oder gleich
- >= Größer oder gleich
Operatoren
Logische Operatoren
Operatoren zur Verknüpfung von Bedingungen:
- && UND: Beide Bedingungen müssen wahr sein
- || ODER: Mindestens eine Bedingung muss wahr sein
- ! NICHT: Negiert eine Bedingung
if (alter >= 18 && hatFuehrerschein) { // Beide müssen wahr sein
printf("Darf Auto fahren");
}
Operatoren
Inkrement & Dekrement
Operatoren zum Erhöhen oder Verringern um 1:
- ++ Inkrement: x++ oder ++x (erhöht x um 1)
- -- Dekrement: x-- oder --x (verringert x um 1)
int x = 5;
x++; // x ist jetzt 6
x--; // x ist jetzt wieder 5
Operatoren
Zuweisungsoperator
Der Operator = weist einer Variablen einen Wert zu.
Wichtig: = ist KEINE Gleichheit, sondern eine Zuweisung!
int x = 5; // x bekommt den Wert 5
x = x + 1; // x bekommt den neuen Wert 6
x += 3; // Kurzform für x = x + 3
5. Kontrollstrukturen
Verzweigungen
if-Anweisung
Eine Verzweigung, die Code nur ausführt, wenn eine Bedingung wahr ist.
if (alter >= 18) {
printf("Volljährig");
}
Verzweigungen
if-else-Anweisung
Eine Verzweigung mit zwei Pfaden: einer für den wahren Fall, einer für den falschen Fall.
if (alter >= 18) {
printf("Volljährig");
} else {
printf("Minderjährig");
}
Verzweigungen
switch-case-Anweisung
Mehrfachverzweigung basierend auf dem Wert einer Variablen.
switch(tag) {
case 1: printf("Montag"); break;
case 2: printf("Dienstag"); break;
default: printf("Anderer Tag");
}
Schleifen
for-Schleife
Eine Schleife mit fester Anzahl von Durchläufen. Ideal für bekannte Wiederholungszahlen.
Bestandteile:
- Initialisierung: Startwert
- Bedingung: Wann die Schleife weiterläuft
- Inkrement: Was nach jedem Durchlauf passiert
for(int i = 0; i < 10; i++) {
printf("%d ", i); // Gibt 0 bis 9 aus
}
Schleifen
while-Schleife
Eine Schleife, die läuft, SOLANGE eine Bedingung wahr ist. Bedingung wird VOR jedem Durchlauf geprüft.
int i = 0;
while(i < 5) {
printf("%d ", i);
i++;
}
Schleifen
do-while-Schleife
Eine Schleife, die mindestens einmal ausgeführt wird. Bedingung wird NACH jedem Durchlauf geprüft.
int i = 0;
do {
printf("%d ", i);
i++;
} while(i < 5);
Schleifen
break
Das Schlüsselwort break beendet eine Schleife sofort.
for(int i = 0; i < 10; i++) {
if(i == 5) break; // Stoppt bei i=5
printf("%d ", i);
}
Schleifen
continue
Das Schlüsselwort continue überspringt den Rest des aktuellen Schleifendurchlaufs.
for(int i = 0; i < 10; i++) {
if(i % 2 == 0) continue; // Überspringt gerade Zahlen
printf("%d ", i); // Gibt nur ungerade Zahlen aus
}
6. Funktionen
Funktionen
Funktion
Eine Funktion ist ein benannter Codeblock, der eine bestimmte Aufgabe erfüllt und wiederverwendet werden kann.
Vorteile:
- Wiederverwendbarkeit: Code einmal schreiben, mehrfach nutzen
- Modularität: Große Programme in kleine Teile zerlegen
- Lesbarkeit: Bessere Struktur und Verständlichkeit
int addiere(int a, int b) {
return a + b;
}
int summe = addiere(5, 3); // summe = 8
Funktionen
Parameter
Parameter sind Werte, die an eine Funktion übergeben werden. Sie stehen in den Klammern bei der Funktionsdefinition.
void begruessung(char name[]) { // name ist ein Parameter
printf("Hallo, %s!", name);
}
Funktionen
Argument
Argumente sind die konkreten Werte, die beim Funktionsaufruf übergeben werden.
begruessung("Anna"); // "Anna" ist das Argument
Funktionen
Rückgabewert
Der Wert, den eine Funktion zurückgibt. Der Rückgabetyp steht vor dem Funktionsnamen.
int quadrat(int x) {
return x * x; // Gibt das Quadrat zurück
}
Funktionen
void
Eine Funktion mit Rückgabetyp void gibt keinen Wert zurück.
void druckeText() {
printf("Hallo!");
// Kein return nötig
}
Funktionen
Funktionsprototyp
Ein Funktionsprototyp (Deklaration) informiert den Compiler über die Existenz einer Funktion, bevor sie definiert wird.
// Prototyp (oben im Code)
int addiere(int a, int b);
// Definition (später im Code)
int addiere(int a, int b) {
return a + b;
}
7. Arrays & Strings
Arrays
Array (Feld)
Ein Array ist eine Sammlung von Elementen des gleichen Datentyps, die unter einem gemeinsamen Namen gespeichert werden.
Wichtig: Array-Indizes beginnen bei 0!
int zahlen[5]; // Array mit 5 int-Werten
int werte[3] = {10, 20, 30}; // Initialisiertes Array
zahlen[0] = 5; // Erstes Element
zahlen[4] = 9; // Letztes Element (Index 4, nicht 5!)
Arrays
Index
Der Index gibt die Position eines Elements im Array an. Der erste Index ist immer 0.
int zahlen[5] = {10, 20, 30, 40, 50};
// zahlen[0] = 10
// zahlen[1] = 20
// zahlen[4] = 50
Strings
String (Zeichenkette)
Ein String ist ein Array von Zeichen (char), das mit dem Nullzeichen '\0' endet.
Wichtig: Jeder String benötigt ein Zeichen mehr für '\0'!
char name[6] = "Hallo"; // 5 Zeichen + '\0' = 6
char text[] = "HTW"; // Größe automatisch (4 Zeichen)
Strings
Nullzeichen ('\0')
Das Nullzeichen markiert das Ende eines Strings. Es wird automatisch hinzugefügt, wenn Sie Strings mit "" initialisieren.
char text[] = "Hi"; // Speichert: 'H', 'i', '\0'
Strings
String-Funktionen (string.h)
Wichtige Funktionen aus der Bibliothek string.h:
- strlen(s): Gibt die Länge eines Strings zurück
- strcpy(ziel, quelle): Kopiert einen String
- strcat(ziel, quelle): Hängt einen String an
- strcmp(s1, s2): Vergleicht zwei Strings
char text1[20] = "Hallo";
int laenge = strlen(text1); // 5
strcpy(text1, "Welt"); // text1 = "Welt"
Arrays
Mehrdimensionale Arrays
Arrays können mehrere Dimensionen haben. Ein 2D-Array ist wie eine Tabelle mit Zeilen und Spalten.
int matrix[3][4]; // 3 Zeilen, 4 Spalten
char namen[5][20]; // 5 Namen, jeder max. 19 Zeichen
8. Zeiger (Pointers)
Zeiger
Zeiger (Pointer)
Ein Zeiger ist eine Variable, die eine Speicheradresse enthält. Zeiger "zeigen" auf andere Variablen im Speicher.
int zahl = 42;
int *zeiger = &zahl; // zeiger speichert die Adresse von zahl
Zeiger
Adressoperator (&)
Der Operator & gibt die Speicheradresse einer Variablen zurück.
int x = 5;
int *ptr = &x; // ptr speichert die Adresse von x
Zeiger
Dereferenzierungsoperator (*)
Der Operator * greift auf den Wert zu, auf den ein Zeiger zeigt.
int x = 5;
int *ptr = &x;
printf("%d", *ptr); // Gibt 5 aus (Wert von x)
Zeiger
NULL-Zeiger
Ein NULL-Zeiger zeigt auf keine gültige Adresse. Er wird verwendet, um zu kennzeichnen, dass ein Zeiger noch nicht initialisiert ist.
int *ptr = NULL; // Zeiger zeigt auf nichts
Zeiger
Call-by-Value
Bei Call-by-Value wird eine Kopie des Werts an die Funktion übergeben. Änderungen in der Funktion beeinflussen das Original nicht.
void aendere(int x) {
x = 10; // Ändert nur die Kopie
}
Zeiger
Call-by-Reference
Bei Call-by-Reference wird die Adresse einer Variablen übergeben. Änderungen in der Funktion beeinflussen das Original.
void aendere(int *x) {
*x = 10; // Ändert das Original
}
9. Speicherverwaltung
Speicher
Stack
Der Stack ist ein Speicherbereich für lokale Variablen und Funktionsparameter. Speicher wird automatisch verwaltet.
Eigenschaften:
- Schneller Zugriff
- Begrenzte Größe
- Automatische Verwaltung (LIFO - Last In, First Out)
Speicher
Heap
Der Heap ist ein Speicherbereich für dynamisch allokierten Speicher. Der Programmierer muss Speicher manuell verwalten.
Eigenschaften:
- Größerer Speicher verfügbar
- Langsamerer Zugriff
- Manuelle Verwaltung (malloc, free)
Speicher
Speicheradresse
Eine Speicheradresse ist eine eindeutige Nummer, die eine Position im Arbeitsspeicher identifiziert.
int x = 5;
printf("%p", &x); // Gibt Adresse aus, z.B. 0x7ffd5e3c4a1c
Speicher
Scope (Gültigkeitsbereich)
Der Scope definiert, wo im Code eine Variable sichtbar und verwendbar ist.
- Lokale Variablen: Nur innerhalb einer Funktion/Block sichtbar
- Globale Variablen: Im gesamten Programm sichtbar
int global = 10; // Globale Variable
void funktion() {
int lokal = 5; // Lokale Variable
}
10. Git & Versionskontrolle
Git
Versionskontrolle
Ein System zur Verwaltung von Änderungen an Dateien über die Zeit. Ermöglicht das Nachverfolgen, Wiederherstellen und Zusammenarbeiten.
Git
Repository (Repo)
Ein Verzeichnis, das von Git verwaltet wird und alle Dateien sowie deren Versionsgeschichte enthält.
git init // Erstellt ein neues Repository
Git
Commit
Ein Commit ist ein Schnappschuss des Projekts zu einem bestimmten Zeitpunkt. Jeder Commit hat eine eindeutige ID.
git add .
git commit -m "Erste Version"
Git
Branch
Ein Branch ist ein unabhängiger Entwicklungszweig. Der Hauptbranch heißt meist "main" oder "master".
git branch feature // Erstellt Branch "feature"
git checkout feature // Wechselt zu "feature"
Git
Remote Repository
Ein Repository auf einem Server (z.B. GitHub), das zur Zusammenarbeit und Sicherung genutzt wird.
git remote add origin https://github.com/user/repo.git
git push origin main
Git
Clone
Erstellt eine lokale Kopie eines Remote-Repositories.
git clone https://github.com/user/repo.git
Git
Pull & Push
Pull: Lädt Änderungen vom Remote-Repo herunter
Push: Lädt lokale Commits zum Remote-Repo hoch
git pull origin main // Änderungen holen
git push origin main // Änderungen hochladen