Array multidimensionali in C e C++
In questa lezione scorrerai una matrice bidimensionale e calcolerai la somma degli elementi di ogni riga.
Introduzione
Un array bidimensionale si può immaginare come una tabella di righe e colonne. In C e C++ viene memorizzato in modo continuo, riga per riga (row-major): prima tutta la prima riga, poi la seconda, e così via.
Punti importanti
- Un puntatore deve puntare solo a un oggetto che esiste ancora, del tipo giusto, oppure essere nullo.
- Ogni area di memoria allocata va liberata esattamente una volta.
- Rendi chiaro quale funzione possiede la memoria (ownership) e quali dati sono solo letti (const).
Guarda come funziona
Punta una cella per vedere riga, colonna e posizione in memoria, dove tutte le righe sono salvate una dopo l'altra.
Esempi di codice C e 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
Confronto tra C e C++
Due cicli annidati scorrono la matrice: quello esterno passa per ogni riga, quello interno somma gli elementi di quella riga nella variabile total. In C, quando passi un array bidimensionale a una funzione, devi indicare la dimensione di tutti gli assi tranne il primo. In C++, std::array conserva la dimensione nel tipo stesso e ha il metodo at(), che controlla se l'indice è valido.
Il possesso e la liberazione della memoria sono interamente a carico del programmatore.
Contenitori e RAII liberano automaticamente le risorse quando l'oggetto arriva alla fine della sua vita.
Esercizi di approfondimento
Esegui entrambe le versioni e poi modifica il codice per osservare la differenza di sicurezza che offre ciascun linguaggio.
- Prova con puntatori nulli e allocazioni di memoria fallite.
- Esegui il programma con AddressSanitizer e UndefinedBehaviorSanitizer per trovare errori di memoria.
- Annota chiaramente quale puntatore possiede la memoria e quale serve solo per leggere.
Esercitati con una sfida
Usa ciò che questa lezione spiega per risolvere un problema reale. Ogni sfida gira nel browser, con test immediati e una revisione dell'IA.
- Row Sums Add up every row of a grid. Facile
- Minesweeper Neighbor Counts Annotate a rectangular board. Media