From d1fc3fdb2cfd83dda99552e5865eb6b004e8caeb Mon Sep 17 00:00:00 2001 From: b0rbor4d Date: Wed, 15 Apr 2026 00:26:04 +0200 Subject: [PATCH] Add Checkpoint solution: checkpoint_a.c --- exercises/checkpoint_a.c | 181 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 exercises/checkpoint_a.c diff --git a/exercises/checkpoint_a.c b/exercises/checkpoint_a.c new file mode 100644 index 0000000..97dc106 --- /dev/null +++ b/exercises/checkpoint_a.c @@ -0,0 +1,181 @@ +// ============================================ +// Checkpoint A: Memory & Datentypen +// Lösung für Selbsttest nach Modul 1-2 +// ============================================ + +#include +#include +#include +#include + +// ============================================ +// AUFGABE 1: Stack vs Heap Analyse +// ============================================ +void aufgabe1_memory_analyse() { + printf("=== AUFGABE 1: Memory-Analyse ===\n\n"); + + // Gegeben: Was passiert hier? + printf("Code:\n"); + printf("void test() {\n"); + printf(" int x = 42; // Stack\n"); + printf(" int *p = &x; // Stack (Pointer)\n"); + printf(" int *heap = malloc(4); // Heap\n"); + printf(" *heap = 100;\n"); + printf("} // <- Was wird freigegeben?\n\n"); + + // Lösung: + printf("LÖSUNG:\n"); + printf("1. x (int, Wert 42) -> Stack -> AUTOMATISCH freigegeben\n"); + printf("2. p (Pointer auf x) -> Stack -> AUTOMATISCH freigegeben\n"); + printf("3. heap (Pointer-Wert) -> Stack -> AUTOMATISCH freigegeben\n"); + printf("4. *heap (int, Wert 100) -> Heap -> NICHT freigegeben! MEMORY LEAK!\n\n"); + printf("Fehler: Kein free(heap) vorhanden!\n\n"); +} + +// ============================================ +// AUFGABE 2: Typ-Grenzen und Overflow +// ============================================ +void aufgabe2_typ_grenzen() { + printf("=== AUFGABE 2: Typ-Grenzen ===\n\n"); + + printf("Frage: Was ist der Output?\n"); + printf("short s = 32767;\n"); + printf("s = s + 1;\n"); + printf("printf(\"%%d\\n\", s);\n\n"); + + // Demonstrieren + short s = 32767; + printf("Vor: s = %d\n", s); + s = s + 1; + printf("Nach: s = %d\n\n", s); + + printf("LÖSUNG: -32768 (Overflow bei signed short!)\n"); + printf("32767 ist SHRT_MAX, +1 ergibt -32768 (SHRT_MIN)\n"); + printf("Bei signed integer overflow ist Verhalten undefiniert!\n\n"); +} + +// ============================================ +// AUFGABE 3: Pointer-Dereferenzierung +// ============================================ +void aufgabe3_pointer() { + printf("=== AUFGABE 3: Pointer ===\n\n"); + + printf("Frage: Was ist der Output?\n"); + printf("int a = 5, b = 10;\n"); + printf("int *p1 = &a, *p2 = &b;\n"); + printf("p1 = p2;\n"); + printf("*p1 = 20;\n"); + printf("printf(\"%%d %%d\\n\", a, b);\n\n"); + + // Demonstrieren + int a = 5, b = 10; + int *p1 = &a, *p2 = &b; + p1 = p2; // p1 zeigt jetzt auch auf b! + *p1 = 20; // b wird 20! + + printf("Output: %d %d\n\n", a, b); + + printf("LÖSUNG: 5 20\n"); + printf("- a bleibt 5 (unverändert)\n"); + printf("- p1 zeigt nach p1=p2 auf b\n"); + printf("- *p1 = 20 ändert b auf 20\n"); + printf("- a wurde nie verändert!\n\n"); +} + +// ============================================ +// AUFGABE 4: Memory-Layout Visualisierung +// ============================================ +void aufgabe4_memory_layout() { + printf("=== AUFGABE 4: Memory-Layout ===\n\n"); + + printf("Aufgabe: Zeichne das Memory-Layout für:\n"); + printf("void foo() {\n"); + printf(" int x = 10; // Line 1\n"); + printf(" int *p = malloc(4); // Line 2\n"); + printf(" *p = 20; // Line 3\n"); + printf(" int arr[3] = {1,2,3}; // Line 4\n"); + printf("}\n\n"); + + printf("LÖSUNG (nach Line 4):\n"); + printf("┌─────────────────┐\n"); + printf("│ Stack │\n"); + printf("│ ┌───────────┐ │\n"); + printf("│ │ x = 10 │ │ <- int (4 Bytes)\n"); + printf("│ ├───────────┤ │\n"); + printf("│ │ p = 0x... │ │ <- Pointer (8 Bytes auf 64-bit)\n"); + printf("│ │ (zeigt │ │\n"); + printf("│ │ auf Heap)│ │\n"); + printf("│ ├───────────┤ │\n"); + printf("│ │ arr[0]=1 │ │ <- Array (12 Bytes = 3*4)\n"); + printf("│ │ arr[1]=2 │ │\n"); + printf("│ │ arr[2]=3 │ │\n"); + printf("│ └───────────┘ │\n"); + printf("└─────────────────┘\n"); + printf(" │\n"); + printf(" ▼\n"); + printf("┌─────────────────┐\n"); + printf("│ Heap │\n"); + printf("│ ┌───────────┐ │\n"); + printf("│ │ *p = 20 │ │ <- malloc(4)\n"); + printf("│ └───────────┘ │\n"); + printf("└─────────────────┘\n\n"); + + printf("Nach foo() Ende:\n"); + printf("- Stack: Alles freigegeben (x, p, arr)\n"); + printf("- Heap: *p BLEIBT (Memory Leak ohne free!)\n\n"); +} + +// ============================================ +// BONUS: Typ-Sicherheit mit Fixed-Width +// ============================================ +void bonus_fixed_width() { + printf("=== BONUS: Fixed-Width Typen ===\n\n"); + + printf("Vorteile von stdint.h:\n\n"); + + printf("Statt 'int' (Größe variiert):\n"); + printf(" int32_t x; // Garantiert 32-bit\n"); + printf(" int64_t y; // Garantiert 64-bit\n"); + printf(" uint8_t z; // Garantiert 8-bit, unsigned\n\n"); + + printf("Präfixe:\n"); + printf(" int = signed\n"); + printf(" uint = unsigned\n"); + printf(" 8/16/32/64 = Bits\n\n"); + + printf("Beispiel Portabilität:\n"); + int32_t portabel = 100; // Überall 32-bit + printf(" int32_t: %zu Bytes (immer 4)\n", sizeof(portabel)); + printf(" int: %zu Bytes (kann 2, 4 oder 8 sein)\n\n", sizeof(int)); +} + +// ============================================ +// HAUPTPROGRAMM +// ============================================ +int main() { + printf("╔══════════════════════════════════════════════════════════╗\n"); + printf("║ CHECKPOINT A: LÖSUNGEN (Memory & Datentypen) ║\n"); + printf("╚══════════════════════════════════════════════════════════╝\n\n"); + + printf("Diese Datei enthält die Lösungen für Checkpoint A.\n"); + printf("Vergleiche mit deinen Antworten!\n\n"); + + aufgabe1_memory_analyse(); + aufgabe2_typ_grenzen(); + aufgabe3_pointer(); + aufgabe4_memory_layout(); + bonus_fixed_width(); + + printf("╔══════════════════════════════════════════════════════════╗\n"); + printf("║ ZUSAMMENFASSUNG ║\n"); + printf("╠══════════════════════════════════════════════════════════╣\n"); + printf("║ ✓ Stack: Automatisch, schnell, begrenzt ║\n"); + printf("║ ✓ Heap: Manuell, flexibel, persistent ║\n"); + printf("║ ✓ malloc/free immer paaren! ║\n"); + printf("║ ✓ Pointer = Adresse, * = Wert an Adresse ║\n"); + printf("║ ✓ Integer-Overflow = undefiniertes Verhalten ║\n"); + printf("║ ✓ Fixed-Width Typen (stdint.h) für Portabilität ║\n"); + printf("╚══════════════════════════════════════════════════════════╝\n"); + + return 0; +}