Mehrdimensionale Arrays in C und C++
In dieser Lektion durchläufst du eine zweidimensionale Matrix und berechnest die Summe der Elemente jeder Zeile.
Einführung
Ein zweidimensionales Array kann man sich als Tabelle aus Zeilen und Spalten vorstellen. In C und C++ wird es zeilenweise (row-major) zusammenhängend im Speicher abgelegt: zuerst die ganze erste Zeile, danach die zweite und so weiter.
Wichtige Punkte
- Ein Zeiger darf nur auf ein noch existierendes Objekt des richtigen Typs zeigen oder null sein.
- Jeder reservierte Speicherbereich muss genau einmal freigegeben werden.
- Mache deutlich, welche Funktion den Speicher besitzt (ownership) und welche Daten nur gelesen werden (const).
So funktioniert es
Zeige auf eine Zelle, um Zeile, Spalte und ihre Position im Speicher zu sehen, wo alle Zeilen hintereinander liegen.
Codebeispiele in C und C++
#include <stdio.h>
int main(void) {
int matrix[2][3] = {{1, 2, 3}, {4, 5, 6}};
for (int row = 0; row < 2; ++row) {
int total = 0;
for (int column = 0; column < 3; ++column) total += matrix[row][column];
printf("row %d=%d\n", row, total);
}
return 0;
}
row 0=6
row 1=15
#include <array>
#include <iostream>
int main() {
std::array<std::array<int, 3>, 2> matrix{{{{1, 2, 3}}, {{4, 5, 6}}}};
for (std::size_t row = 0; row < matrix.size(); ++row) {
int total = 0;
for (int value : matrix[row]) total += value;
std::cout << "row " << row << '=' << total << '\n';
}
}
row 0=6
row 1=15
C und C++ im Vergleich
Zwei verschachtelte Schleifen durchlaufen die Matrix: Die äußere geht durch die Zeilen, die innere addiert die Elemente der jeweiligen Zeile zur Variablen total. In C musst du beim Übergeben eines zweidimensionalen Arrays an eine Funktion die Größe aller Dimensionen außer der ersten angeben. In C++ speichert std::array die Größe im Typ selbst und bietet die Methode at(), die prüft, ob ein Index gültig ist.
Besitz und Freigabe von Speicher muss der Programmierer vollständig selbst sicherstellen.
Container und RAII geben Ressourcen automatisch frei, wenn die Lebensdauer des Objekts endet.
Übungen zur Vertiefung
Führe beide Versionen aus und ändere dann den Code, um zu beobachten, welche Sicherheit jede Sprache bietet.
- Teste mit Nullzeigern und fehlgeschlagener Speicherreservierung.
- Führe das Programm mit AddressSanitizer und UndefinedBehaviorSanitizer aus, um Speicherfehler zu finden.
- Notiere klar, welcher Zeiger den Speicher besitzt und welcher nur zum Lesen dient.
Mit einer Challenge üben
Nutze den Inhalt dieser Lektion, um ein echtes Problem zu lösen. Jede Challenge läuft im Browser, mit sofortigen Tests und einem KI-Review.
- Row Sums Add up every row of a grid. Einfach
- Minesweeper Neighbor Counts Annotate a rectangular board. Mittel