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