Array of Pointers in C (auf Deutsch)

Hallo dort, zukünftige Programmier-Zauberer! Heute werden wir auf eine aufregende Reise in die Welt der C-Programmierung gehen, insbesondere werden wir das faszinierende Konzept des Arrays von Zeigern erkunden. Keine Sorge, wenn das erstmal überwältigend klingt – ich verspreche Ihnen, dass Sie am Ende dieser Anleitung diese mächtige Werkzeug wie ein Profi handhaben werden!

C - Array of Pointers

Was ist ein Array von Zeigern?

Bevor wir in die Tiefe springen, beginnen wir mit den Grundlagen. Stellen Sie sich vor, Sie haben eine Reihe von magischen Stäben (Zeigern), die jede in der Lage sind, verschiedene Zauber (Daten) herbeizurufen. Was wäre, wenn Sie diese Stäbe in einer ordentlichen Reihe (Array) organisieren könnten? Das ist im Grunde genommen, was ein Array von Zeigern ist – eine Sammlung von Speicheradressen, alle in einer Reihe und bereit für die Aktion!

In den Begriffen der C-Programmierung ist ein Array von Zeigern einfach ein Array, bei dem jedes Element ein Zeiger ist. Diese Zeiger können auf verschiedene Datentypen wie Ganzzahlen, Zeichen oder sogar komplexe Strukturen zeigen.

Ein Array von Zeigern erstellen

Lassen Sie uns damit beginnen, unser erstes Array von Zeigern zu erstellen. Die Syntax ist bastante ähnlich wie die Erstellung eines regulären Arrays, aber mit einer kleinen Wendung:

data_type *array_name[size];

Hierbei ist data_type der Typ der Daten, auf die die Zeiger verweisen sollen, array_name der Name, den Sie Ihrem Array geben möchten, und size die Anzahl der Zeiger, die Sie in Ihrem Array haben möchten.

Sehen wir uns ein einfaches Beispiel an:

#include <stdio.h>

int main() {
int *number_pointers[5];  // Deklaration eines Arrays von 5 Ganzzahl-Zeigern

int a = 10, b = 20, c = 30, d = 40, e = 50;

// Zuweisen von Adressen zu den Zeigern
number_pointers[0] = &a;
number_pointers[1] = &b;
number_pointers[2] = &c;
number_pointers[3] = &d;
number_pointers[4] = &e;

// Ausgabe der Werte, auf die jeder Zeiger zeigt
for(int i = 0; i < 5; i++) {
printf("Wert bei number_pointers[%d] = %d\n", i, *number_pointers[i]);
}

return 0;
}

In diesem Beispiel haben wir ein Array von 5 Ganzzahl-Zeigern erstellt. Wir weisen dann die Adressen von fünf Ganzzahlvariablen diesen Zeigern zu. Schließlich geben wir die Werte aus, auf die jeder Zeiger zeigt.

Wenn Sie diesen Code ausführen, sehen Sie:

Wert bei number_pointers[0] = 10
Wert bei number_pointers[1] = 20
Wert bei number_pointers[2] = 30
Wert bei number_pointers[3] = 40
Wert bei number_pointers[4] = 50

Ist das nicht magisch? Wir haben just unser erstes Array von Zeigern erstellt!

Ein Array von Zeigern auf Ganzzahlen

Nun, da wir unseren Füßen gewässert haben, tauchen wir ein wenig tiefer in Arrays von Zeigern auf Ganzzahlen ein. Dies ist besonders nützlich, wenn Sie mit mehreren Arrays arbeiten oder wenn Sie ein Array sortieren möchten, ohne die tatsächlichen Daten zu bewegen.

Hier ist ein Beispiel, das zeigt, wie wir ein Array von Zeigern auf Ganzzahlen verwenden können, um Zahlen zu sortieren, ohne die tatsächlichen Werte zu verschieben:

#include <stdio.h>

void swap(int **a, int **b) {
int *temp = *a;
*a = *b;
*b = temp;
}

int main() {
int numbers[] = {50, 30, 20, 10, 40};
int *ptr[5];

// Initialisieren der Zeiger
for(int i = 0; i < 5; i++) {
ptr[i] = &numbers[i];
}

// Sortieren der Zeiger basierend auf den Werten, auf die sie zeigen
for(int i = 0; i < 5; i++) {
for(int j = i + 1; j < 5; j++) {
if(*ptr[i] > *ptr[j]) {
swap(&ptr[i], &ptr[j]);
}
}
}

// Ausgabe der sortierten Werte
printf("Sortierte Werte: ");
for(int i = 0; i < 5; i++) {
printf("%d ", *ptr[i]);
}

// Das ursprüngliche Array bleibt unverändert
printf("\nUrsprüngliches Array: ");
for(int i = 0; i < 5; i++) {
printf("%d ", numbers[i]);
}

return 0;
}

Dieser Code zeigt eine mächtige Verwendung eines Arrays von Zeigern. Wir sortieren die Zeiger basierend auf den Werten, auf die sie zeigen, was effektiv eine Sortierung der Daten ohne Verschiebung der ursprünglichen Werte bedeutet. Es ist, als würden wir die magischen Stäbe neu anordnen, ohne die Zauber, die sie herbeirufen, zu stören!

Ein Array von Zeigern auf Zeichen

Als nächstes erkunden wir Arrays von Zeigern auf Zeichen. Dies ist unglaublich nützlich, wenn man mit Zeichenketten (Strings) in C arbeitet. Tatsächlich erstellt man, wenn man ein Array von Zeichenketten in C deklariert, ein Array von Zeigern auf Zeichen!

Hier ist ein Beispiel, um dies zu veranschaulichen:

#include <stdio.h>

int main() {
char *fruits[] = {
"Apfel",
"Banane",
"Kirsche",
"Dattel",
"Holunderbeere"
};

int num_fruits = sizeof(fruits) / sizeof(fruits[0]);

printf("Unsere Früchteschale enthält:\n");
for(int i = 0; i < num_fruits; i++) {
printf("%s\n", fruits[i]);
}

// Versuchen wir, eine Frucht zu ändern
fruits[1] = "Blaubeere";

printf("\nNach ein wenig Magie enthält unsere Früchteschale jetzt:\n");
for(int i = 0; i < num_fruits; i++) {
printf("%s\n", fruits[i]);
}

return 0;
}

In diesem fruchtigen Beispiel haben wir ein Array von Zeigern auf Zeichen (Zeichenketten) erstellt. Jedes Element des Arrays fruits ist ein Zeiger auf das erste Zeichen jeder Fruchtbezeichnung.

Die Magie hier ist, dass wir ganz einfach ganze Zeichenketten ändern können, indem wir nur den Zeiger ändern, so wie wir es mit "Banane" zu "Blaubeere" getan haben. Es ist, als würden wir ganze Zauberbücher mit einem Wisch unserer Stab ändern!

Ein Array von Zeigern auf Strukturen

Letztlich, aber nicht zuletzt, erkunden wir die komplexeste (und aufregendste) Verwendung von Arrays von Zeigern – Zeigern auf Strukturen. Dies ist unglaublich kraftvoll, wenn man mit komplexen Datentypen umgehen muss und die Flexibilität möchte, sie effizient zu manipulieren.

Hier ist ein Beispiel, das dieses Konzept demonstriert:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct Zauberer {
char name[50];
char zauber[50];
int kraft;
};

int main() {
struct Zauberer *zauberer_pointers[3];

// Erstellen und initialisieren von Zauberern
for(int i = 0; i < 3; i++) {
zauberer_pointers[i] = (struct Zauberer*)malloc(sizeof(struct Zauberer));

printf("Geben Sie den Namen des Zauberers ein: ");
scanf("%s", zauberer_pointers[i]->name);

printf("Geben Sie den Lieblingszauber des Zauberers ein: ");
scanf("%s", zauberer_pointers[i]->zauber);

printf("Geben Sie die Kraftstufe des Zauberers ein: ");
scanf("%d", &zauberer_pointers[i]->kraft);

printf("\n");
}

// Ausgabe der Zauberer-Informationen
printf("Unsere mächtigen Zauberer:\n");
for(int i = 0; i < 3; i++) {
printf("Zauberer: %s, Lieblingszauber: %s, Kraftstufe: %d\n",
zauberer_pointers[i]->name,
zauberer_pointers[i]->zauber,
zauberer_pointers[i]->kraft);
}

// Vergessen Sie nicht, den reservierten Speicher freizugeben!
for(int i = 0; i < 3; i++) {
free(zauberer_pointers[i]);
}

return 0;
}

In diesem magischen Beispiel haben wir ein Array von Zeigern auf Zauberer-Strukturen erstellt. Dies ermöglicht es uns, dynamisch Speicher für jeden Zauberer zuzuweisen und auf ihre Eigenschaften mit dem Pfeiloperator (->) zuzugreifen.

Diese Herangehensweise gibt uns die Flexibilität, komplexe Datenstrukturen zu erstellen und zu manipulieren. Es ist, als hätte man ein Zauberbuch, das dynamisch neue Zauber hinzufügen kann, während wir sie lernen!

Und so haben wir es, junge Programmierer! Wir haben durch die Welt der Arrays von Zeigern in C gereist, von den Grundlagen zu den fortgeschrittenen Konzepten. Denken Sie daran, dass wie jeder mächtige Zauber, Arrays von Zeigern Übung erfordern, um sie zu meistern. Also zögern Sie nicht, experimentieren und Ihre eigenen magischen Programme zu erstellen!

Hier ist eine schnelle Referenztabelle der Methoden, die wir abgedeckt haben:

Methode Beschreibung
data_type *array_name[size]; Deklaration eines Arrays von Zeigern
array_name[index] = &variable; Zuweisen einer Adresse zu einem Zeiger im Array
*array_name[index] Zugriff auf den Wert, auf den der Zeiger im Array zeigt
array_name[index]->member Zugriff auf einen Member einer Struktur, auf die der Zeiger im Array zeigt

Üben Sie weiter, bleiben Sie neugierig, und bald werden Sie komplexe Programme mit der Leichtigkeit eines erfahrenen Zauberers erstellen können. Happy Coding!

Credits: Image by storyset