Kurz: Ein Array speichert mehrere Werte gleichen Typs direkt nacheinander im Speicher. Die Größe ist beim Anlegen fest. Der Index beginnt bei 0.
Teil des Kurses C
Arrays
Ein Array speichert mehrere Werte gleichen Typs direkt nacheinander im Speicher. Die Größe ist beim Anlegen fest. Der Index beginnt bei 0.
#include <stdio.h>
int main(void) {
int z[5] = {10, 20, 30}; // Rest wird 0
int auto_groesse[] = {1, 2, 3, 4}; // Größe 4 erkannt
int n = sizeof auto_groesse / sizeof auto_groesse[0];
printf("%d %d %d %d\n", z[0], z[2], z[4], n);
z[1] = 99;
for (int i = 0; i < 5; i++) printf("%d ", z[i]);
printf("\n");
int matrix[2][3] = { {1, 2, 3}, {4, 5, 6} };
printf("%d %zu %zu\n", matrix[1][2], sizeof matrix / sizeof matrix[0], sizeof matrix[0] / sizeof matrix[0][0]);
return 0;
}Ausgabe:
10 30 0 4
10 99 30 0 0
6 2 3Achtung
C prüft Indizes nicht.
z[10]bei 5 Elementen ist ein Zugriff außerhalb des Speichers: undefiniertes Verhalten (Absturz, falsche Werte oder Sicherheitslücke). Halte Grenzen selbst ein.
Arrays an Funktionen übergeben
Ein Array “zerfällt” beim Übergeben zu einem Zeiger auf das erste Element. Die Länge geht verloren, also gib sie mit:
#include <stdio.h>
int summe(const int *a, int n) {
int s = 0;
for (int i = 0; i < n; i++) s += a[i];
return s;
}
void verdopple(int a[], int n) { // a[] ist dasselbe wie int *a
for (int i = 0; i < n; i++) a[i] *= 2;
}
int main(void) {
int z[] = {1, 2, 3, 4};
int n = (int)(sizeof z / sizeof z[0]);
verdopple(z, n);
printf("%d\n", summe(z, n));
return 0;
}Ausgabe:
20const int * verspricht, dass die Funktion die Daten nicht ändert.
Strings sind char-Arrays
C hat keinen eigenen String-Typ. Ein String ist ein char-Array, das mit dem Zeichen '\0' (Wert 0) endet:
#include <stdio.h>
#include <string.h>
int main(void) {
char a[] = "Hallo"; // 6 Bytes: H a l l o \0
char b[20] = "Welt";
const char *c = "Konstante"; // Zeiger auf feste Zeichen (nicht änderbar!)
printf("%s %zu %zu\n", a, strlen(a), sizeof a);
printf("%s %zu %zu\n", b, strlen(b), sizeof b);
a[0] = 'J'; // erlaubt: a ist ein Array
printf("%s %c\n", a, c[0]);
char manuell[4] = {'a', 'b', 'c', '\0'};
printf("%s\n", manuell);
return 0;
}Ausgabe:
Hallo 5 6
Welt 4 20
Jallo K
abcVergisst du das abschließende '\0', laufen String-Funktionen über das Ende hinaus.
Die Funktionen aus <string.h>
| Funktion | Zweck |
|---|---|
strlen(s) | Länge ohne '\0' |
strcpy(ziel, quelle) | kopieren (unsicher bei zu kleinem Ziel) |
strncpy, snprintf | kopieren mit Längenbegrenzung |
strcat(ziel, quelle) | anhängen (unsicher) |
strcmp(a, b) | vergleichen: 0 = gleich, <0 / >0 |
strchr(s, c), strstr(s, teil) | Zeichen / Teilstring suchen |
memcpy, memmove, memset, memcmp | Speicherblöcke |
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main(void) {
char text[64];
snprintf(text, sizeof text, "%s-%s", "Hallo", "Welt"); // sicher
printf("%s (%zu)\n", text, strlen(text));
printf("%d %d %d\n", strcmp("a", "b") < 0, strcmp("b", "b"), strcmp("c", "b") > 0);
char *p = strstr(text, "Welt");
printf("%s %ld\n", p ? p : "nicht gefunden", p ? (long)(p - text) : -1L);
for (char *q = text; *q; q++) *q = (char) toupper((unsigned char) *q);
printf("%s\n", text);
int buchstaben = 0;
for (const char *q = text; *q; q++) if (isalpha((unsigned char) *q)) buchstaben++;
printf("%d\n", buchstaben);
return 0;
}Ausgabe:
Hallo-Welt (10)
1 0 1
Welt 6
HALLO-WELT
9Achtung
Strings vergleicht man mit
strcmp, nie mit==.==vergleicht nur Adressen.
Pufferüberlauf: der Klassiker
char ziel[8];
strcpy(ziel, "Dieser Text ist viel zu lang"); // schreibt über das Ende hinaus!Das Überschreiben angrenzenden Speichers (buffer overflow) ist eine der häufigsten Ursachen von Sicherheitslücken. Verwende snprintf oder prüfe strlen(quelle) < sizeof ziel.
#include <stdio.h>
#include <string.h>
// Sichere Kopie: schneidet ab, endet immer mit '\0'
size_t kopiere(char *ziel, size_t groesse, const char *quelle) {
if (groesse == 0) return 0;
size_t n = strlen(quelle);
if (n >= groesse) n = groesse - 1;
memcpy(ziel, quelle, n);
ziel[n] = '\0';
return n;
}
int main(void) {
char klein[8];
kopiere(klein, sizeof klein, "Dieser Text ist viel zu lang");
printf("%s\n", klein);
return 0;
}Ausgabe:
DieserZeichen und Zahlen umwandeln
#include <stdio.h>
#include <stdlib.h>
int main(void) {
printf("%d %d\n", atoi("42"), atoi("abc")); // atoi erkennt Fehler nicht!
char *ende;
long l = strtol("123xyz", &ende, 10); // besser: Rest und Fehler prüfbar
printf("%ld \"%s\"\n", l, ende);
printf("%.2f\n", strtod("3.14159", NULL));
char buf[16];
snprintf(buf, sizeof buf, "%d", 2025);
printf("%s\n", buf);
printf("%d\n", '7' - '0'); // Ziffer als Zahl
return 0;
}Ausgabe:
42 0
123 "xyz"
3.14
2025
7Merke
- Arrays: feste Größe, Index ab 0, keine Grenzprüfung
- Beim Übergeben wird ein Array zum Zeiger; die Länge übergibst du extra
- Ein String ist ein
char-Array mit abschließendem'\0' - Strings mit
strcmpvergleichen, mitsnprintfsicher zusammensetzen strcpy/strcat/getskönnen Puffer überlaufen lassen- Zahlen aus Text:
strtol/strtodstattatoi/atof
Übungsaufgabe
Schreibe eine Funktion, die einen String umkehrt ("Hallo" wird "ollaH") und eine, die zählt, wie oft ein Zeichen vorkommt.
Quiz zur Selbstkontrolle
Womit endet ein C-String?
- Mit dem Zeichen ‘\0’ (richtig)
- Mit einem Zeilenumbruch
- Mit EOF
- Mit einem Leerzeichen
Wie vergleicht man zwei Strings?
- strcmp(a, b) (richtig)
- a == b
- a = b
- a.equals(b)
Was ist ein Pufferüberlauf?
- Schreiben über das Ende eines Arrays hinaus (richtig)
- Ein voller Drucker
- Ein zu langer Dateiname
- Eine Endlosschleife
Weiter im Kurs
Zurück: Funktionen
Weiter: Zeiger
Alle Kapitel: C im Überblick