Files
programming-concepts-universal/docs/programming-concepts-universal.md

16 KiB
Raw Permalink Blame History

🎓 Interaktiver Programmierkurs: Von C zu universellen Konzepten

Ein Kurs für C/C++-Einsteiger mit Fokus auf übertragbare Programmierkonzepte


📋 Kursübersicht

Zielgruppe: Student mit C-Grundlagen, geplantem C++-Umstieg
Kursdauer: 8 Wochen (selbstgewähltem Tempo)
Lernziel: Sprachunabhängige Programmierkonzepte verstehen und auf beliebige Sprachen anwenden


🗺️ Modul-Struktur

Woche 1-2: Grundlagen & Denkweisen
├── Modul 1: Das Memory-Modell (Stack vs Heap)
├── Modul 2: Datentypen als Konzepte (nicht Syntax)
└── Checkpoint A: Selbsteinschätzung

Woche 3-4: Kontrollstrukturen & Logik
├── Modul 3: Flusskontrolle universell
├── Modul 4: Funktionen als Abstraktion
└── Checkpoint B: Mini-Projekt #1

Woche 5-6: Datenstrukturen
├── Modul 5: Arrays, Listen, Strukturen
├── Modul 6: Pointer & Referenzen verstehen
└── Checkpoint C: Datenstruktur-Implementierung

Woche 7-8: OOP & Fortgeschrittenes
├── Modul 7: Von structs zu Objekten (C → C++ → Konzept)
├── Modul 8: Modularisierung & Design Patterns
└── Final-Projekt: Sprachunabhängige Anwendung

🧠 Modul 1: Das Memory-Modell

Konzept: Speicher ist universell

In C:

int stack_var = 42;           // Stack - automatisch verwaltet
int* heap_var = malloc(4);    // Heap - manuell verwaltet
*heap_var = 42;
free(heap_var);               // Nicht vergessen!

Das universelle Konzept:

Stack = Kurzlebig, automatisch, schnell
Heap = Langfristig, manuell/verwaltet, flexibel

🎯 Interaktive Übung 1.1: Memory-Map

Zeichne ein Diagramm:

┌─────────────────┐  High Address
│     Stack       │ ← Wachst nach unten (lokal vars)
│       ↓         │
│                 │
│       ↑         │
│     Heap        │ ← Wachst nach oben (malloc/new)
│   (freier       │
│    Speicher)    │
│                 │
│   Static/Data   │ ← Globale Variablen, Strings
│   (Programm)    │
└─────────────────┘  Low Address

Frage: Was passiert bei dieser C-Code Sequenz?

void foo() {
    int a = 10;        // Wo landet das?
    int *b = malloc(sizeof(int));  // Und das?
    *b = 20;
    // b vergessen zu free()
}
Antwort anzeigen
  • aStack (automatisch gelöscht nach foo())
  • bStack (nur der Pointer!)
  • *b (der Wert 20) → Heap
  • ⚠️ Memory Leak: *b bleibt im Heap, weil free() vergessen wurde

Universelles Konzept: Jede Sprache hat Stack/Heap. Python/Java haben Garbage Collection, C/C++ nicht, Rust hat Ownership.


🔢 Modul 2: Datentypen als Konzepte

Konzept: Typen sind Speicher + Operationen

Nicht lernen: "int ist 4 Bytes"
Lernen: "int ist ein ganzzahliger Typ mit begrenztem Bereich"

🎯 Interaktive Übung 2.1: Typ-Universum

Ordne diese Konzepte zu:

Konzept C C++ Python Java JavaScript
Ganzzahl (fix) int int - int Number
Ganzzahl (beliebig) long long long long int BigInteger BigInt
Fließkomma float float float float Number
Hochpräzision double double float double -
Wahrheitswert bool (C99) bool bool boolean boolean
Text char[] string str String string

Erkenntnis: Konzepte sind gleich, Syntax variiert!

🧪 Praxis 2.2: Typische Fehler

// C-Fehler
int a = 2147483647;
int b = a + 1;  // Was ist b nun?

Antwort: Überlauf (Overflow). b wird -2147483648 (Integer Overflow)

Universelles Konzept: Alle Typen haben Grenzen. Kenne deine Grenzen!


🔄 Modul 3: Flusskontrolle universell

Konzept: Programme = Sequenz + Auswahl + Wiederholung

Strukturdiagramm:

SEQUENZ
   │
   ▼
┌──────┐
│Aktion│
└──────┘
   │
   ▼
┌──────┐
│Aktion│
└──────┘

AUSWAHL (if/else)
   │
   ▼
┌────────┐
│Bedingung?│
└────────┘
   │Ja    │Nein
   ▼      ▼
┌────┐  ┌────┐
│Dann│  │Sonst│
└────┘  └────┘

WIEDERHOLUNG (loops)
   │
   ▼
┌──────────┐
│Bedingung?│←────┐
└──────────┘     │
   │Ja           │Nein
   ▼             │
┌──────┐         │
│Body  │─────────┘
└──────┘

🎯 Interaktive Übung 3.1: Struktur erkennen

Welche Struktur hat dieser Code?

// Code A
for (int i = 0; i < 10; i++) {
    if (i % 2 == 0) continue;
    printf("%d ", i);
}

// Code B
int x = 5;
if (x > 0) {
    if (x < 10) {
        printf("Im Bereich");
    }
}

// Code C
while (1) {
    char c = getchar();
    if (c == 'q') break;
    process(c);
}
Lösungen
  • Code A: Wiederholung (for) + Auswahl (if) + Sprung (continue)
  • Code B: Verschachtelte Auswahl (nested if)
  • Code C: Endlosschleife (while(1)) + Abbruchbedingung (break)

Universell: for, while, if, break, continue existieren in fast allen Sprachen mit ähnlicher Semantik.


🔧 Modul 4: Funktionen als Abstraktion

Konzept: Funktionen kapseln Komplexität

Analogie: Funktion = Rezept

  • Eingabe: Zutaten (Parameter)
  • Prozess: Anleitung (Funktionskörper)
  • Ausgabe: Gericht (Return-Wert)

🎯 Interaktive Übung 4.1: Black-Box-Denken

Betrachte diese Funktion:

int mystery(int a, int b) {
    int result = 0;
    while (b != 0) {
        if (b & 1) result += a;
        a <<= 1;
        b >>= 1;
    }
    return result;
}

Ohne Code zu analysieren: Was könnte diese Funktion tun?

Tipp + Lösung

Tipp: Teste mit Werten:

  • mystery(3, 4) → ?
  • mystery(5, 5) → ?

Lösung: Es ist die ägyptische Multiplikation (schnelle Multiplikation ohne *).

Konzept: Funktionen sind Black Boxes. Verstehe Input/Output, nicht unbedingt Implementation.

🧪 Praxis 4.2: Design by Contract

/**
 * Berechnet den Durchschnitt eines Arrays.
 * 
 * PRECONDITION: array != NULL, size > 0
 * POSTCONDITION: Rückgabe = Summe(array) / size
 * 
 * @param array Nicht-leeres Array von double
 * @param size Anzahl der Elemente (> 0)
 * @return Durchschnittswert
 */
double average(const double* array, size_t size);

Universelles Konzept: Design by Contract (Eiffel, aber überall anwendbar)


📦 Modul 5: Datenstrukturen

Konzept: Strukturen organisieren Daten

Evolution:

// 1. Primitive
int score = 100;

// 2. Array (Sammlung gleicher Typen)
int scores[5] = {100, 95, 87, 92, 88};

// 3. Struct (Zusammengesetzter Typ)
typedef struct {
    char name[50];
    int scores[5];
    float average;
} Student;

// 4. Dynamische Struktur (Linked List)
typedef struct Node {
    Student data;
    struct Node* next;
} Node;

Universelle Datenstrukturen:

Struktur Verwendung Sprachen
Array Indexierter Zugriff Alle
Linked List Einfügen/Löschen C, C++, Java
Stack LIFO (Undo, Parsing) Alle (meist builtin)
Queue FIFO (Scheduling) Alle
Hash Map Schlüssel-Wert Lookup Python, JS, Java, C++
Tree Hierarchien Alle

🎯 Interaktive Übung 5.1: Struktur wählen

Szenarien: Welche Datenstruktur?

  1. Browser-History (Back/Forward) → ?
  2. Druck-Warteschlange → ?
  3. Wörterbuch (Wort → Definition) → ?
  4. DOM-Elemente einer Webseite → ?
Antworten
  1. Stack (LIFO - letzter Besuch zuerst zurück)
  2. Queue (FIFO - erste Anfrage zuerst drucken)
  3. Hash Map/Dictionary (O(1) Lookup)
  4. Tree (hierarchische Struktur, Parent-Child)

Konzept: Datenstrukturen sind sprachunabhängige Muster!


🎯 Modul 6: Pointer & Referenzen

Konzept: Indirektion ist universell

Die 3 Ebenen:

Wert ──────→ Variable ──────→ Pointer
  │              │                │
  │              │                │
  ▼              ▼                ▼
 42           int x             int* p
              x = 42            p = &x
                                *p = 42

In verschiedenen Sprachen:

Sprache Konzept Syntax
C Pointer int* p = &x;
C++ Reference int& r = x;
Python Name/Referenz a = b (referenziert selbes Objekt)
Java Reference Object o = obj;
Rust Borrowing &x (immutable), &mut x (mutable)
Go Pointer p := &x

🎯 Interaktive Übung 6.1: Pointer-Diagramm

Zeichne für diesen Code:

int a = 5;
int b = 10;
int* p = &a;
int* q = &b;
p = q;
*p = 20;

Fragen:

  1. Was ist a?
  2. Was ist b?
  3. Was ist *p?
  4. Was ist *q?
Diagramm + Lösung
Initial:
┌─────┐      ┌─────┐
│  a  │ 5    │  b  │ 10
│(0x100)│     │(0x104)│
└─────┘      └─────┘

p = &a:
┌─────┐
│  p  │───→ ┌─────┐
│(0x200)│   │  a  │ 5
└─────┘   └─────┘

q = &b:
┌─────┐
│  q  │───→ ┌─────┐
│(0x204)│   │  b  │ 10
└─────┘   └─────┘

p = q:
┌─────┐
│  p  │──┐
│(0x200)│  │
└─────┘  │
┌─────┐  │
│  q  │─┼┘
│(0x204)│   ┌─────┐
└─────┘   └──→│  b  │ 10
              │(0x104)│
              └─────┘

*p = 20:
              ┌─────┐
              │  b  │ 20 ←── p und q zeigen hierhin!
              │(0x104)│
              └─────┘

Antworten:

  1. a = 5 (unverändert!)
  2. b = 20 (verändert via *p)
  3. *p = 20
  4. *q = 20

Konzept: Pointer sind Adressen. Mehrere Pointer können auf dieselbe Adresse zeigen (Aliasing).


🏗️ Modul 7: Von structs zu Objekten

Konzept: Daten + Verhalten = Objekt

Evolution in C → C++:

// C: Daten und Funktionen getrennt
typedef struct {
    float x, y;
} Point;

float point_distance(Point* a, Point* b) {
    return sqrt((a->x - b->x) ** 2 + ...);
}
// C++: Daten und Verhalten zusammen
class Point {
private:
    float x, y;
    
public:
    Point(float x, float y) : x(x), y(y) {}
    
    float distanceTo(const Point& other) const {
        return sqrt((x - other.x) ** 2 + ...);
    }
};

Universelles OOP-Konzept:

  • Kapselung: Daten schützen (private/public)
  • Abstraktion: Wie etwas funktioniert ist egal
  • Vererbung: "Ein Hund IST EIN Tier"
  • Polymorphie: Gleiche Schnittstelle, verschiedene Implementationen

🎯 Interaktive Übung 7.1: OOP-Konzepte zuordnen

class Animal {
public:
    virtual void speak() = 0;  // Was ist das?
};

class Dog : public Animal {    // Was ist das?
private:
    string name;               // Was ist das?
    
public:
    void speak() override {     // Was ist das?
        cout << "Wuff!" << endl;
    }
};
Lösungen
  • virtual ... = 0Abstrakte Methode (Polymorphie)
  • class Dog : public AnimalVererbung (Dog IST EIN Animal)
  • private: string nameKapselung (Daten geschützt)
  • void speak() overridePolymorphe Implementation

Konzept: Diese 4 Prinzipien existieren in Python, Java, C#, Ruby, Swift... nur Syntax variiert!


🎨 Modul 8: Modularisierung & Design

Konzept: Trennung von Belangen (Separation of Concerns)

Schichten-Architektur (universell):

┌─────────────────────────────┐
│      Presentation           │ ← UI, Output
│      (View/Controller)      │
├─────────────────────────────┤
│       Business Logic        │ ← Verarbeitung
│       (Model/Services)      │
├─────────────────────────────┤
│       Data Access           │ ← Datenbank, Files
│       (Repository/DAO)      │
├─────────────────────────────┤
│       Infrastructure        │ ← Logging, Config
│       (Utils/Helpers)       │
└─────────────────────────────┘

In C:

src/
├── main.c          # Einstieg
├── ui/             # Presentation
│   ├── display.c
│   └── input.c
├── core/           # Business Logic
│   ├── calculator.c
│   └── validator.c
├── data/           # Data Access
│   ├── file_io.c
│   └── database.c
└── utils/          # Infrastructure
    ├── logger.c
    └── config.c

In C++:

src/
├── main.cpp
├── view/           # Presentation (MVC)
├── controller/     # Flow Control
├── model/          # Business Logic
├── repository/     # Data Access
└── utils/          # Infrastructure

🎯 Interaktive Übung 8.1: Design Patterns

Wähle das passende Pattern:

Problem Pattern Beschreibung
Genau eine DB-Verbindung Singleton Nur eine Instanz erlaubt
Verschiedene Zahlungsmethoden Strategy Austauschbare Algorithmen
Objekte ohne new erstellen Factory Zentralisierte Erstellung
Schritte A → B → C ausführen Template Method Algorithmus-Skelett

Konzept: Design Patterns sind sprachunabhängige Lösungen für wiederkehrende Probleme!


🚀 Final-Projekt: Sprachunabhängige Anwendung

Aufgabe: Todo-App mit mehreren Implementationen

Anforderungen (sprachunabhängig):

  1. CRUD-Operationen für Todos
  2. Speicherung (File oder Memory)
  3. CLI-Interface
  4. Modularer Aufbau

Implementiere in:

  • Version A: C (Structs, Function Pointers)
  • Version B: C++ (Klassen, STL)
  • (Optional) Version C: Python oder JavaScript

Der Test: Vergleiche die Implementationen. Welche Konzepte sind gleich? Was unterscheidet sich?


📝 Checkpoints & Selbsteinschätzung

Checkpoint A (nach Modul 2)

Fragen:

  • Ich kann Stack vs Heap erklären
  • Ich kenne die Grenzen primitiver Typen
  • Ich verstehe, warum Konzepte wichtiger sind als Syntax

Checkpoint B (nach Modul 4)

Mini-Projekt: Schreibe einen Taschenrechner mit:

  • Menü (Sequenz/Auswahl)
  • Mathematische Funktionen (Abstraktion)
  • Fehlerbehandlung

Checkpoint C (nach Modul 6)

Datenstruktur: Implementiere eine dynamische Liste (wie std::vector oder Python list) in C mit:

  • void list_append(List* list, int value)
  • int list_get(List* list, size_t index)
  • void list_remove(List* list, size_t index)

Final Check

  • Ich kann Konzepte auf neue Sprachen übertragen
  • Ich verstehe OOP-Prinzipien
  • Ich kann modularen Code strukturieren

📚 Ressourcen & Weiterführendes

Bücher

  • "The C Programming Language" (K&R) - Klassiker
  • "C++ Primer" (Lippman) - Umfassend
  • "Clean Code" (Martin) - Sprachunabhängig!
  • "Design Patterns" (Gang of Four) - Das Original

Online

  • exercism.org - Sprachübergreifende Übungen
  • leetcode.com - Algorithmen in beliebiger Sprache
  • codewars.com - Katas für verschiedene Sprachen

Praxis-Tipp

Lerne eine zweite Sprache parallel! Wenn du C lernst, schau dir Python-Äquivalente an. Die Kontraste machen die Konzepte klarer.


🎯 Abschluss

Die wichtigste Erkenntnis:

Programmieren ist nicht das Lernen von Syntax. Es ist das Verstehen von Konzepten, die in jeder Sprache wiederkehren nur mit anderem "Akzent".

Wenn du diesen Kurs durchgearbeitet hast, kannst du:

  • Jede neue Sprache schneller lernen (Konzepte bereits bekannt)
  • Bessere Architektur-Entscheidungen treffen
  • Sprachübergreifend als Entwickler arbeiten

Viel Erfolg! 🚀