diff --git a/src/c_examples/module6_pointers.c b/src/c_examples/module6_pointers.c new file mode 100644 index 0000000..fc4db1d --- /dev/null +++ b/src/c_examples/module6_pointers.c @@ -0,0 +1,173 @@ +// ============================================ +// Modul 6: Pointer +// Beispiele in C +// ============================================ + +#include +#include + +// Beispiel 6.1: Pointer-Grundlagen +void demo_basic_pointers() { + printf("=== Pointer-Grundlagen ===\n\n"); + + int value = 42; + int* ptr = &value; // Pointer zeigt auf value + + printf("value = %d\n", value); + printf("&value = %p (Adresse von value)\n", (void*)&value); + printf("ptr = %p (Wert des Pointers = Adresse)\n", (void*)ptr); + printf("*ptr = %d (Dereferenzierung)\n", *ptr); + + // Modifikation via Pointer + *ptr = 100; + printf("\nNach *ptr = 100:\n"); + printf("value = %d (geändert!)\n", value); +} + +// Beispiel 6.2: Pointer-Arithmetik +void demo_pointer_arithmetic() { + printf("\n=== Pointer-Arithmetik ===\n\n"); + + int arr[] = {10, 20, 30, 40, 50}; + int* p = arr; // = &arr[0] + + printf("arr[0] = %d, *p = %d\n", arr[0], *p); + printf("arr[1] = %d, *(p+1) = %d\n", arr[1], *(p + 1)); + + // Äquivalenzen + printf("\nÄquivalenzen:\n"); + printf("arr[2] == *(arr + 2) == *(p + 2) == %d\n", arr[2]); + printf("&arr[2] == arr + 2 == p + 2 == %p\n", (void*)(arr + 2)); + + // Pointer-Inkrement + p++; // Verschiebt um sizeof(int)! + printf("\nNach p++: *p = %d\n", *p); +} + +// Beispiel 6.3: Double Pointer (Pointer zu Pointer) +void demo_double_pointer() { + printf("\n=== Double Pointer ===\n\n"); + + int value = 42; + int* ptr = &value; // Pointer auf int + int** dptr = &ptr; // Pointer auf Pointer + + printf("value = %d\n", value); + printf("*ptr = %d\n", *ptr); + printf("**dptr = %d\n", **dptr); // Doppelte Dereferenzierung + + printf("\nAdressen:\n"); + printf("&value = %p\n", (void*)&value); + printf("ptr = %p, &ptr = %p\n", (void*)ptr, (void*)&ptr); + printf("dptr = %p\n", (void*)dptr); +} + +// Beispiel 6.4: Pointer und Arrays +void demo_pointer_arrays() { + printf("\n=== Pointer und Arrays ===\n\n"); + + int arr[3] = {10, 20, 30}; + int* p = arr; + + // Array-Notation vs Pointer-Notation + printf("Array-Notation:\n"); + for (int i = 0; i < 3; i++) { + printf("arr[%d] = %d\n", i, arr[i]); + } + + printf("\nPointer-Notation:\n"); + for (int i = 0; i < 3; i++) { + printf("*(p + %d) = %d\n", i, *(p + i)); + } + + // ABER: sizeof unterscheidet sich! + printf("\nsizeof(arr) = %zu (gesamtes Array)\n", sizeof(arr)); + printf("sizeof(p) = %zu (nur Pointer)\n", sizeof(p)); +} + +// Beispiel 6.5: Pointer zu Funktionen +int add(int a, int b) { return a + b; } +int sub(int a, int b) { return a - b; } + +void demo_function_pointers() { + printf("\n=== Pointer zu Funktionen ===\n\n"); + + int (*operation)(int, int); // Funktionspointer-Typ + + operation = add; + printf("add(5, 3) = %d\n", operation(5, 3)); + + operation = sub; + printf("sub(5, 3) = %d\n", operation(5, 3)); +} + +// Beispiel 6.6: Void Pointer (Generisch) +void demo_void_pointer() { + printf("\n=== Void Pointer ===\n\n"); + + int i = 42; + float f = 3.14; + char c = 'A'; + + void* generic; + + // Kann auf jeden Typ zeigen + generic = &i; + printf("int: %d\n", *(int*)generic); + + generic = &f; + printf("float: %f\n", *(float*)generic); + + generic = &c; + printf("char: %c\n", *(char*)generic); +} + +// Beispiel 6.7: Dangling Pointer (Gefahr!) +void demo_dangling_pointer() { + printf("\n=== Dangling Pointer (Gefährlich!) ===\n\n"); + + int* dangling; + + { + int local = 42; // Stack-Variable + dangling = &local; + printf("Innerhalb Block: *dangling = %d\n", *dangling); + } // local wird hier FREIGEGEBEN! + + // ⚠️ dangling zeigt jetzt auf ungültigen Speicher! + // printf("Außerhalb: *dangling = %d\n", *dangling); // UNDEFINED! + printf("⚠️ dangling ist jetzt ungültig (Dangling Pointer)!\n"); + + // ✅ Lösung: dangling auf NULL setzen + dangling = NULL; + if (dangling != NULL) { + printf("%d\n", *dangling); + } else { + printf("✅ Pointer ist NULL, Zugriff verhindert\n"); + } +} + +// ============================================ +// Hauptprogramm +// ============================================ +int main() { + demo_basic_pointers(); + demo_pointer_arithmetic(); + demo_double_pointer(); + demo_pointer_arrays(); + demo_function_pointers(); + demo_void_pointer(); + demo_dangling_pointer(); + + printf("\n=== Wichtige Konzepte ===\n"); + printf("1. Pointer = Adresse einer Variable\n"); + printf("2. * = Dereferenzierung (Wert holen)\n"); + printf("3. & = Adresse holen\n"); + printf("4. Pointer-Arithmetik: p+1 = p + sizeof(type)\n"); + printf("5. arr[i] == *(arr + i)\n"); + printf("6. Double Pointer: **pp für Pointer zu Pointer\n"); + printf("7. Dangling Pointer: Zeigt auf freigegebenen Speicher\n"); + printf("8. NULL-Check ist Pflicht!\n"); + + return 0; +}