Salta al contenuto principale

Array e Vettori in C++: Come Memorizzare e Gestire Dati

Profile picture for user luca77king

In C++, array e vettori sono due strutture dati fondamentali per la gestione di collezioni di elementi dello stesso tipo. Tuttavia, differiscono significativamente in termini di flessibilità, sicurezza e gestione della memoria.

Un array in C++ è una sequenza di elementi dello stesso tipo, memorizzati in locazioni di memoria contigue. Ogni elemento è accessibile tramite un indice numerico che parte da zero. Ad esempio, dichiarando un array di interi con int numeri[5];, si riserva spazio per cinque interi consecutivi. Gli elementi possono essere referenziati come numeri[0], numeri[1], fino a numeri[4]. Tuttavia, la dimensione dell'array è fissa e deve essere specificata al momento della dichiarazione. Questo significa che non è possibile aggiungere o rimuovere elementi dinamicamente.

Questa rigidità può diventare un problema quando si ha a che fare con insiemi di dati di dimensione variabile. Ad esempio, se si volessero memorizzare i punteggi di una classe di studenti, un array sarebbe adatto solo se il numero di studenti fosse noto in anticipo e costante. Se il numero di studenti cambiasse, sarebbe necessario ridichiarare e ricopiare manualmente i dati in un nuovo array di dimensioni diverse.

Dichiarazione di un Array

int numeri[5];

Questa dichiarazione riserva spazio per cinque interi consecutivi in memoria. I valori possono essere assegnati in questo modo:

numeri[0] = 10; // Assegna 10 al primo elemento
numeri[1] = 20; // Assegna 20 al secondo elemento

Oppure direttamente in fase di dichiarazione:

int numeri[] = {10, 20, 30, 40, 50};

Un array in C++ ha una dimensione fissa, determinata al momento della dichiarazione, e non può essere modificata durante l'esecuzione del programma.

Iterare su un Array

#include <iostream>
using namespace std;

int main() {
    int punteggi[5] = {90, 85, 78, 92, 88};
    int somma = 0;
    
    for (int i = 0; i < 5; i++) {
        somma += punteggi[i];
    }
    
    cout << "Media: " << (somma / 5.0) << endl;
    return 0;
}

Vettori in C++

Un vettore, definito nella libreria <vector>, è una struttura dati dinamica che può crescere o ridursi durante l'esecuzione del programma.

Dichiarazione di un Vettore

#include <vector>
std::vector<int> punteggi;

Gli elementi possono essere aggiunti dinamicamente usando push_back():

punteggi.push_back(85);
punteggi.push_back(90);

L’accesso agli elementi è simile agli array:

cout << punteggi[1]; // Stampa il secondo elemento

Esempio di Uso dei Vettori

#include <iostream>
#include <vector>
using namespace std;

int main() {
    vector<int> punteggi;
    int valore;
    
    cout << "Inserisci i punteggi (-1 per terminare): ";
    while (true) {
        cin >> valore;
        if (valore == -1) break;
        punteggi.push_back(valore);
    }
    
    int somma = 0;
    for (int p : punteggi) {
        somma += p;
    }
    
    cout << "Media: " << (somma / (double)punteggi.size()) << endl;
    return 0;
}

Differenze tra Array e Vettori

  1. Dimensione: Gli array hanno dimensione fissa, i vettori possono crescere.
  2. Sicurezza: Con gli array, accedere a un indice fuori limite causa comportamento indefinito; i vettori offrono più sicurezza con at().
  3. Funzionalità: I vettori offrono metodi come push_back(), size(), erase() e insert().

Uso di Puntatori e Allocazione Dinamica

A volte, per avere una maggiore flessibilità, possiamo usare l’allocazione dinamica con new e gestire manualmente la memoria.

#include <iostream>
using namespace std;

void modificaArray(int*& arr, int& dim) {
    delete[] arr;  // Libera la memoria precedente
    dim *= 2;  // Raddoppia la dimensione
    arr = new int[dim];  // Alloca un nuovo array più grande
}

int main() {
    int dim = 5;
    int* array = new int[dim];
    modificaArray(array, dim);
    cout << "Nuova dimensione: " << dim << endl;
    delete[] array;  // Dealloca memoria
    return 0;
}

Spiegazione del Passaggio di Puntatori con *&

Nella funzione modificaArray, il parametro int*& arr è un riferimento a un puntatore. Questo permette di modificare direttamente il puntatore originale passato come argomento, evitando di creare una copia.

Se avessimo scritto:

void modificaArray(int* arr, int dim) {

all’interno della funzione arr sarebbe solo una copia del puntatore originale e la modifica non avrebbe effetto sul valore esterno.

Conclusione

  • Se la dimensione è nota e fissa, un array è sufficiente.
  • Se serve flessibilità, un vettore è la scelta migliore.
  • L’allocazione dinamica con puntatori è utile, ma va gestita con attenzione per evitare memory leak.