EMZETT.
Login

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

Kapitel 8 von 15 im Kurs C. Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.

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 3

Achtung

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:

20

const 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
abc

Vergisst du das abschließende '\0', laufen String-Funktionen über das Ende hinaus.

Die Funktionen aus <string.h>

FunktionZweck
strlen(s)Länge ohne '\0'
strcpy(ziel, quelle)kopieren (unsicher bei zu kleinem Ziel)
strncpy, snprintfkopieren 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, memcmpSpeicherblö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
9

Achtung

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:

Dieser

Zeichen 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
7

Merke

  • 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 strcmp vergleichen, mit snprintf sicher zusammensetzen
  • strcpy/strcat/gets können Puffer überlaufen lassen
  • Zahlen aus Text: strtol/strtod statt atoi/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

Weiter im Kurs

Zurück: Funktionen

Weiter: Zeiger

Alle Kapitel: C im Überblick