C Arrays & Zeiger

6 Kernkonzepte
Die wichtigsten Konzepte zu Arrays und Zeigern in C: Arrays · Pointer · Speicher · Zeigerarithmetik · Strings · Mehrdim. Arrays Arrays und Zeiger sind zentrale Konzepte in C. Sie ermöglichen effiziente Speicherverwaltung und direkten Zugriff auf den Arbeitsspeicher – die Grundlage für systemnahe Programmierung.

Arrays – Zusammenhängende Daten

typ name[größe] · Index · sizeof
int zahlen[5] = {1, 2, 3, 4, 5}; zahlen[0] = 10; // erstes Element printf("%d", zahlen[2]); // 3

Arrays speichern mehrere Werte des gleichen Typs in zusammenhängendem Speicher. Der Zugriff erfolgt über den Index (0-basiert). Die Größe muss zur Compile-Zeit bekannt sein.

Wichtige Array-Konzepte

Konzept Beschreibung
int arr[10] Array mit 10 Elementen
int arr[] = {1, 2, 3} Initialisierung ohne Größenangabe
arr[0] Erstes Element (Index 0)
sizeof(arr) Gesamtgröße in Bytes
sizeof(arr) / sizeof(arr[0]) Anzahl der Elemente
arr Name des Arrays = Zeiger auf erstes Element
Beispiele
// Array-Deklaration und Initialisierung
int zahlen[3] = {10, 20, 30};
int namen[] = {'A', 'B', 'C'}; // Größe automatisch 3
// Zugriff und Änderung
zahlen[1] = 25; // zweites Element wird 25
printf("%d", zahlen[0]); // 10
// Array-Länge berechnen
int len = sizeof(zahlen) / sizeof(zahlen[0]);
printf("Länge: %d", len); // 3
Tipp: Der Array-Name ist ein konstanter Zeiger auf das erste Element. arr und &arr[0] sind äquivalent.

Pointer – Adressen verwalten

* · & · NULL · void*
int x = 42; int *p = &x; // p zeigt auf x printf("%d", *p); // 42 (Dereferenzierung) *p = 99; // x wird 99

Pointer (Zeiger) speichern die Speicheradresse einer Variable. Sie ermöglichen direkten Zugriff auf den Speicher, dynamische Allokation und effiziente Parameterübergabe.

Wichtige Pointer-Konzepte

Konzept Beschreibung
&variable Adressoperator – liefert die Adresse einer Variable
*pointer Dereferenzierungsoperator – Zugriff auf den Wert an der Adresse
int *p Pointer auf int
NULL Nullzeiger (zeigt auf nichts)
void * Typenloser Pointer (für beliebige Datentypen)
int **p Pointer auf Pointer (mehrfache Indirektion)
Beispiele
// Pointer-Deklaration und Nutzung
int a = 5;
int *p = &a;
printf("Adresse: %p, Wert: %d", p, *p);
// Pointer auf Pointer
int **pp = &p;
printf("%d", **pp); // 5
// NULL-Pointer
int *null_ptr = NULL;
if (null_ptr == NULL) {
printf("Zeiger ist NULL");
}
⚠️ Achtung: Dereferenzieren Sie niemals einen NULL-Pointer oder einen uninitialisierten Pointer – das führt zu einem Segmentation Fault (Programmabsturz).

Speicher – malloc, calloc, free

malloc · calloc · realloc · free
int *arr = (int*)malloc(5 * sizeof(int)); if (arr == NULL) { /* Fehler */ } free(arr); // Speicher freigeben

Dynamische Speicherallokation ermöglicht die Reservierung von Speicher zur Laufzeit. malloc, calloc und realloc reservieren Speicher auf dem Heap, free gibt ihn frei.

Speicherfunktionen

Funktion Beschreibung
malloc(bytes) Reserviert bytes Bytes (nicht initialisiert)
calloc(n, size) Reserviert n Elemente à size Bytes (initialisiert mit 0)
realloc(ptr, bytes) Ändert die Größe des reservierten Speichers
free(ptr) Gibt reservierten Speicher frei
Beispiele
// malloc – Speicher reservieren
int *arr = (int*)malloc(10 * sizeof(int));
if (arr == NULL) { // Fehlerbehandlung }
// calloc – Speicher mit Null-Initialisierung
int *arr2 = (int*)calloc(5, sizeof(int)); // alle 0
// realloc – Speicher vergrößern
arr = (int*)realloc(arr, 20 * sizeof(int));
// Speicher freigeben
free(arr);
free(arr2);
⚠️ Achtung: Jeder malloc/calloc/realloc muss mit free freigegeben werden – sonst entsteht ein Speicherleck (memory leak).

Zeigerarithmetik – p++, p--, p + n

++ · -- · + · - · Unterschied
int arr[] = {10, 20, 30}; int *p = arr; printf("%d", *p); // 10 p++; // p zeigt jetzt auf arr[1] printf("%d", *p); // 20

Zeigerarithmetik ermöglicht das Navigieren durch Arrays durch Addition/Subtraktion von Ganzzahlen. Die Schrittweite entspricht der Größe des Zeigertyps (sizeof(T)).

Operationen

Operation Beschreibung
p++ / ++p Inkrementiert den Zeiger (nächstes Element)
p-- / --p Dekrementiert den Zeiger (vorheriges Element)
p + n Zeiger + n Elemente
p - q Differenz zweier Zeiger (Anzahl Elemente)
p < q Vergleich von Zeigeradressen
Beispiele
// Zeigerarithmetik mit Array
int arr[] = {100, 200, 300, 400};
int *p = arr;
// Iteration mit Zeiger
for (int i = 0; i < 4; i++) {
printf("%d ", *(p + i));
}
// while-Schleife mit Inkrement
int *q = arr;
while (q < arr + 4) {
printf("%d ", *q);
q++;
}
Tipp: Zeigerarithmetik ist die Grundlage für das effiziente Durchlaufen von Arrays. *(p + i) ist äquivalent zu p[i].

Strings – char-Arrays & String-Funktionen

char[] · char* · strlen · strcpy · strcmp
char str1[] = "Hallo"; char *str2 = "Welt"; printf("%s", str1); // Hallo printf("%lu", strlen(str1)); // 5

Strings in C sind Arrays vom Typ char, die mit einem Nullzeichen '\0' abgeschlossen werden. Die string.h-Bibliothek bietet viele Hilfsfunktionen.

Wichtige String-Funktionen

Funktion Beschreibung
strlen(s) Länge des Strings (ohne '\0')
strcpy(dest, src) Kopiert src nach dest
strncpy(dest, src, n) Kopiert max. n Zeichen
strcat(dest, src) Hängt src an dest an
strcmp(s1, s2) Vergleicht zwei Strings (0 = gleich)
strncmp(s1, s2, n) Vergleicht max. n Zeichen
strchr(s, c) Sucht erstes Vorkommen von c
strstr(s, sub) Sucht Teilstring sub
Beispiele
// String-Deklarationen
char s1[] = "Hallo"; // Array auf Stack
char *s2 = "Welt"; // Zeiger auf String-Literal
// String-Funktionen
char puffer[20];
strcpy(puffer, "Hallo");
strcat(puffer, " Welt"); // "Hallo Welt"
// Vergleich
if (strcmp(s1, s2) == 0) {
printf("Strings sind gleich");
}
⚠️ Achtung: String-Funktionen prüfen nicht die Puffergröße. strcpy und strcat können zu Pufferüberläufen führen – verwenden Sie strncpy und strncat für mehr Sicherheit.

Mehrdim. Arrays – Matrix & Pointer

int arr[2][3] · Pointer zu Arrays
int matrix[2][3] = {{1,2,3}, {4,5,6}}; matrix[0][1] = 99; // 2 → 99 printf("%d", matrix[1][2]); // 6

Mehrdimensionale Arrays speichern Daten in Tabellenform. Sie werden als "Array von Arrays" realisiert und sind im Speicher zeilenweise angeordnet.

Beispiele
// 2D-Array (3x3)
int matrix[3][3] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// Zugriff mit Schleifen
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
printf("%d ", matrix[i][j]);
}
printf("\n");
}
// Pointer auf 2D-Array (Zeilen-Arrays)
int (*ptr)[3] = matrix; // ptr zeigt auf erste Zeile
printf("%d", ptr[1][2]); // 6
Tipp: Ein 2D-Array int arr[M][N] kann als int (*ptr)[N] übergeben werden – der Zeiger zeigt auf ein Array von N ints.

C Arrays & Zeiger im Überblick

arr[i] Array-Zugriff
*(arr + i) äquivalent
& Adressoperator
&var → Adresse
* Dereferenzierung
*ptr → Wert
malloc Speicher reservieren
Heap-Allokation
free Speicher freigeben
Vermeidet Leaks
\0 String-Terminierung
Nullzeichen

Quick Summary

int a[5]
Array-Deklaration
int *p
Pointer-Deklaration
malloc()
Speicher allokieren
p++
Zeigerarithmetik
char s[]
Strings
int m[2][3]
Mehrdim. Arrays
int arr[] = {1,2,3}; int *p = arr; p++; printf("%d", *p);