Spesso, nella realizzazione di un programma, risulta necessario o utile organizzare alcuni dati in forma di “tabella”. Ciรฒ consente infatti di raggruppare le informazioni in modo logico e facilmente interpretabile. Ma in che modo possiamo, attraverso le categorie messe a disposizione da un linguaggio di programmazione, rappresentare una tabella? I linguaggi piรน diffusi mettono a disposizione due famiglie di soluzioni. La prima (e piรน strutturata) รจ rappresentata dalle tabelle hash, utili in particolare quando i tipi di dato da memorizzare in ciascuna cella della tabella risultino numerosi, eterogenei e complessi. Nel presente articolo esamineremo invece casi piรน semplici, per i quali risulterร maggiormente adatta la seconda tipologia di soluzione, ovvero le matrici (o array multidimensionali). Il linguaggio di programmazione di riferimento sarร il C++.
Definizione di matrice
Per avere a disposizione una definizione efficace e operativa di matrice, partiamo dal concetto di array (di cui una matrice puรฒ essere considerata una sorta di estensione). Intendiamo con array un insieme ordinato di dati omogenei (cioรจ dello stesso tipo, ad esempio un insieme di numeri interi). Possiamo immaginare tali dati come ordinati in riga o in colonna. A questo punto possiamo intuire come una tabella non sia altro che un array a due dimensioni (righe e colonne), ovvero un caso particolare di array multidimensionale.
Ci rendiamo conto quindi di come il concetto di array risulti dotato di ampia generalitร : รจ possibile, anche se non comune nella pratica, costruire array a piรน di due dimensioni (una sorta di tabella cubica o “ipertabella”). Il grande potenziale di archiviazione e classificazione รจ purtroppo affievolito, in questi particolari casi, da una non trascurabile complessitร nella gestione del dato. Nel seguito quindi, con l’obiettivo di fornire in questo contesto indicazioni di immediata rilevanza pratica, ci concentreremo sulle caratteristiche degli array bidimensionali, fornendo anche alcuni esempi di utilizzo.
Sintassi delle matrici in C++
Anche per quanto riguarda l’aspetto sintattico, esamineremo la dichiarazione di una matrice facendo riferimento a quella di un array. Per dichiarare un array di nome a costituito da 10 interi possiamo usare l’istruzione:
int a[10];
La keyword int indica il tipo di dati contenuti all’interno dell’array (numeri interi), mentre a รจ il nome della variabile array appena dichiarata. Il numero 10, compreso tra parentesi quadre, indica quanti dati di tipo intero l’array a รจ in grado di contenere. Una volta eseguita questa istruzione quindi, in memoria viene riservato uno spazio contiguo che consente di archiviare 10 numeri interi. Per assegnare un valore al primo elemento dell’array a possiamo usare l’istruzione:
a[0] = 1;
Per riferirci a un elemento specifico ci serviamo ancora una volta delle parentesi quadre: indicando al loro interno la posizione a cui si desidera accedere. ร importante ricordare che la prima posizione non รจ indicata dall’indice “1”, ma dall’indice “0”. La dichiarazione di una matrice, intesa, come precedentemente illustrato, come un array bidimensionale, segue logicamente da quella di un array semplice:
int b[10][10];
La variabile b, cosรฌ dichiarata, indica una matrice 10×10, ovvero una tabella di interi costituita da 10 righe e 10 colonne. Per accedere all’elemento memorizzato nella prima colonna della prima riga, memorizzando all’interno di tale cella il valore 2, potremo usare invece, sempre in analogia con quanto visto per gli array unidimensionali, l’istruzione:
b[0][0] = 2;
Cerchiamo a questo punto di servirci degli elementi concettuali e sintattici sin qui esaminati per costruire un esempio semplice ma completo di utilizzo delle matrici.
Utilizzare le matrici in C++
Ipotizzeremo, nell’esempio proposto, di confrontarci con una matrice di numeri reali (ci serviremo quindi di variabili di tipo double). Tali numeri saranno organizzati in una matrice. Come spesso accade, tale matrice sarร rappresentativa di un particolare sistema fisico, ovvero conterrร al proprio interno particolari coefficienti associati alle equazioni che caratterizzano il comportamento del sistema stesso, consentendo di prevederlo e, in qualche misura, di regolarlo.
Per semplicitร , ipotizzeremo che tali coefficienti siano forniti in input dall’utente e che la matrice da essi costituita sia formata da 3 righe e 3 colonne. Compito del programma sarร calcolare la traccia della matrice, ovvero il prodotto dei termini sulla diagonale principale della tabella (da in alto a sinistra fino in basso a destra).
#include <iostream>
double prodotto(double m[3][3])
{
double prodotto = 1.0;
for (int i = 0; i < 3; i++) {
prodotto *= m[i][i];
}
return prodotto;
}
int main ()
{
double a[3][3];
std::cout << "Inserisci gli elementi della matrice, prima quelli della prima riga (da sinistra a destra), poi quelli della seconda, poi quelli della terza";
for(int i=0; i<3; i++)
{
for(int j=0; j<3; j++)
{
std::cin >> a[i][j];
}
}
std::cout << "Il prodotto degli elementi sulla diagonale della matrice" << std::endl;
for (int k = 0; k < 3; k++) {
for (int l = 0; l < 3; l++)
std::cout << " " << a[k][l];
std::cout << std::endl;
}
std::cout << std::endl;
std::cout << "e' " << prodotto(a) << std::endl;
return 0;
}
Come possiamo vedere, dopo aver incluso la libreria di sistema iostream (#include <iostream>), impostiamo il programma principale (main) in modo tale che chieda all’utente di inserire i 9 coefficienti da inserire all’interno della matrice a, dichiarata con double a[3][3]. Una volta letti i coefficienti tramite il comando std::cin, stampiamo la matrice (sempre all’interno del programma principale) e la traccia, ovvero il prodotto dei termini sulla diagonale principale, servendoci invece della funzione prodotto.
Tale funzione non fa che moltiplicare tra loro tutti gli elementi di tipo a[i][i], con i che va da 0 a 2, ovvero a[0][0], a[1][1] e a[2][2]. Si tratta proprio dei termini presenti sulla diagonale principale, contraddistinti dall’avere uguale indice di riga e di colonna. Sarร sufficiente eseguire il programma per verificarne il corretto funzionamento.
Considerazioni finali
Le matrici in C++ si rivelano uno strumento essenziale per la gestione efficace di dati strutturati. Attraverso l’uso delle matrici, gli sviluppatori possono rappresentare complessi set di dati in modo chiaro e organizzato. ร importante sottolineare che, nonostante la semplicitร della sintassi, le matrici possono diventare rapidamente complesse quando si lavora con applicazioni piรน avanzate, come l’algebra lineare, l’analisi dei dati o le simulazioni fisiche. Con l’ulteriore esplorazione delle librerie STL e delle funzioni avanzate, รจ possibile ampliare ulteriormente le capacitร del linguaggio C++, rendendolo ancora piรน potente per la programmazione scientifica e ingegneristica.