Add Checkpoint solution: checkpoint_a.c
This commit is contained in:
181
exercises/checkpoint_a.c
Normal file
181
exercises/checkpoint_a.c
Normal file
@@ -0,0 +1,181 @@
|
||||
// ============================================
|
||||
// Checkpoint A: Memory & Datentypen
|
||||
// Lösung für Selbsttest nach Modul 1-2
|
||||
// ============================================
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
// ============================================
|
||||
// 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;
|
||||
}
|
||||
Reference in New Issue
Block a user