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;
}10 30 0 4 10 99 30 0 0 6 2 3
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;
}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;
}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>
| 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;
}Hallo-Welt (10) 1 0 1 Welt 6 HALLO-WELT 9
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;
}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;
}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
strcmpvergleichen, mitsnprintfsicher zusammensetzen strcpy/strcat/getskönnen Puffer überlaufen lassen- Zahlen aus Text:
strtol/strtodstattatoi/atof
Aufgabe
Schreibe eine Funktion, die einen String umkehrt ("Hallo" wird "ollaH") und eine, die zählt, wie oft ein Zeichen vorkommt.