Array, vettori e stringhe in C++
Fino a questo punto abbiamo lavorato con variabili che contengono un singolo valore. Tuttavia, nella maggior parte dei programmi reali è necessario gestire collezioni di dati: elenchi di numeri, sequenze di nomi, insiemi di misure. Il C++ offre diversi strumenti per memorizzare e manipolare gruppi di valori dello stesso tipo. In questo articolo esamineremo gli array tradizionali, il contenitore std::vector e la classe std::string per il testo.
Gli array in stile C
Un array è una sequenza di elementi dello stesso tipo, disposti in modo contiguo in memoria e accessibili tramite un indice numerico. Gli indici partono sempre da zero: il primo elemento ha indice zero, il secondo indice uno, e così via. La dimensione di un array tradizionale è fissa e deve essere nota al momento della dichiarazione.
#include <iostream>
int main() {
int values[5] = {10, 20, 30, 40, 50};
std::cout << values[0] << std::endl; // Primo elemento: 10
values[2] = 99; // Modifica del terzo elemento
return 0;
}
Bisogna prestare grande attenzione a non accedere a indici fuori dai limiti dell'array: il C++ non controlla automaticamente questi accessi, e leggere o scrivere oltre la fine dell'array produce comportamenti indefiniti, una delle cause più insidiose di errori difficili da diagnosticare.
Il contenitore std::array
Il C++ moderno mette a disposizione std::array, un contenitore a dimensione fissa che racchiude un array tradizionale offrendo un'interfaccia più sicura e comoda. Conosce la propria dimensione, può essere copiato e passato alle funzioni con maggiore facilità, e fornisce metodi utili come size.
#include <array>
#include <iostream>
int main() {
std::array<int, 3> scores = {7, 8, 9};
std::cout << "Dimensione: " << scores.size() << std::endl;
return 0;
}
Il contenitore std::vector
Quando il numero di elementi non è noto in anticipo o deve poter cambiare durante l'esecuzione, lo strumento più adatto è std::vector. Si tratta di un array dinamico che cresce e si riduce automaticamente secondo necessità, gestendo la memoria in modo trasparente. È uno dei contenitori più usati in assoluto nel C++ moderno.
#include <vector>
#include <iostream>
int main() {
std::vector<int> temperatures = {18, 21, 19};
temperatures.push_back(22); // Aggiunge un elemento in coda
// Scorre tutti gli elementi con il ciclo basato su intervallo
for (int temp : temperatures) {
std::cout << temp << std::endl;
}
return 0;
}
Il metodo push_back aggiunge un elemento alla fine del vettore, mentre size ne restituisce il numero di elementi. L'accesso ai singoli elementi avviene con la stessa sintassi degli array, usando le parentesi quadre e un indice.
Le stringhe con std::string
Il testo viene gestito in modo idiomatico tramite la classe std::string, che rappresenta una sequenza di caratteri di lunghezza variabile. Rispetto agli array di caratteri in stile C, std::string è molto più sicura e comoda: gestisce automaticamente la memoria, conosce la propria lunghezza e fornisce numerose operazioni di alto livello.
#include <string>
#include <iostream>
int main() {
std::string firstName = "Mario";
std::string lastName = "Rossi";
// L'operatore + concatena due stringhe
std::string fullName = firstName + " " + lastName;
std::cout << fullName << std::endl;
std::cout << "Lunghezza: " << fullName.length() << std::endl;
return 0;
}
L'operatore + concatena le stringhe, mentre metodi come length restituiscono il numero di caratteri. È anche possibile accedere ai singoli caratteri tramite indice, esattamente come con gli array, e scorrerli con un ciclo.
Leggere e scorrere una collezione
Combinando i contenitori con i cicli si possono elaborare insiemi di dati in modo elegante. Vediamo un esempio che calcola la somma degli elementi di un vettore, una delle operazioni più comuni nella pratica.
#include <vector>
#include <iostream>
int main() {
std::vector<int> sales = {120, 85, 200, 45};
int total = 0;
for (int amount : sales) {
total += amount; // Accumula la somma
}
std::cout << "Totale: " << total << std::endl;
return 0;
}
Saper gestire collezioni di dati è una competenza indispensabile. Nel C++ moderno si tende a preferire std::vector e std::string rispetto agli array e alle stringhe in stile C, proprio per la sicurezza e la comodità che offrono. Nel prossimo e ultimo articolo introdurremo la programmazione orientata agli oggetti, che permette di definire tipi di dato personalizzati.