Add module6_pointers.c
This commit is contained in:
173
src/c_examples/module6_pointers.c
Normal file
173
src/c_examples/module6_pointers.c
Normal file
@@ -0,0 +1,173 @@
|
|||||||
|
// ============================================
|
||||||
|
// Modul 6: Pointer
|
||||||
|
// Beispiele in C
|
||||||
|
// ============================================
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user