Vai al contenuto

Le struct

Raggruppa dati correlati in un'unica entità organizzata.

Le struct in C++ sono uno strumento fondamentale per raggruppare dati correlati in un'unica entità.

📌 Differenza chiave tra Struct e Classi: Struct: membri pubblici per default | Classi: membri privati per default

1. Definizione e Dichiarazione

📌 Cos'è una Struct? Un tipo di dato composto che aggrega variabili di tipi diversi in un unico insieme logico.

1.1 Sintassi Base

struct NomeStruct {
    // dichiarazione dei membri
    tipo membro1;
    tipo membro2;
    // ...
};

1.2 Esempi Pratici

// Esempio: Struct Persona
struct Persona {
    string nome;
    int eta;
    string indirizzo;
};

// Esempio: Struct Punto 2D
struct Punto {
    int x;
    int y;
};

// Esempio: Struct Studente
struct Studente {
    string nome;
    string cognome;
    int matricola;
    double mediaVoti;
};

2. Inizializzazione e Accesso ai Membri

Operatore Punto

Per accedere ai membri di variabili struct normali

persona.nome

Operatore Freccia

Per accedere ai membri tramite puntatori

ptr->nome

2.1 Inizializzazione Aggregata

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

struct Persona {
    string nome;
    int eta;
    string indirizzo;
};

int main() {
    // Inizializzazione aggregata con {}
    Persona p = {"Mario Rossi", 30, "Via Roma 1"};

    // Accesso ai membri usando l'operatore punto
    cout << "Nome: " << p.nome << endl;
    cout << "Età: " << p.eta << endl;
    cout << "Indirizzo: " << p.indirizzo << endl;

    return 0;
}

2.2 Accesso tramite Puntatore

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

struct Persona {
    string nome;
    int eta;
};

int main() {
    Persona p = {"Luca Bianchi", 25};
    Persona* ptr = &p;  // Puntatore alla struct

    // Utilizzo dell'operatore '->' per accedere ai membri
    cout << "Nome: " << ptr->nome << endl;
    cout << "Età: " << ptr->eta << endl;

    // Equivalente a: (*ptr).nome
    cout << "Nome (alternativo): " << (*ptr).nome << endl;

    return 0;
}

3. Struct e Funzioni

📌 Tipi di Passaggio: Per Valore: Copia della struct | Per Riferimento: Modifica l'originale

3.1 Passaggio per Valore

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

struct Punto {
    int x;
    int y;
};

// Passaggio per valore - crea una copia
void stampaPunto(Punto p) {
    cout << "Punto(" << p.x << ", " << p.y << ")" << endl;
}

int main() {
    Punto p = {3, 4};
    stampaPunto(p);  // p originale non viene modificato
    return 0;
}

3.2 Passaggio per Riferimento

#include <iostream>
using namespace std;

struct Punto {
    int x;
    int y;
};

// Passaggio per riferimento - modifica l'originale
void spostaPunto(Punto &p, int dx, int dy) {
    p.x += dx;
    p.y += dy;
}

int main() {
    Punto p = {3, 4};
    cout << "Punto originale: (" << p.x << ", " << p.y << ")" << endl;

    spostaPunto(p, 2, -1);  // Modifica p direttamente

    cout << "Punto dopo spostamento: (" << p.x << ", " << p.y << ")" << endl;
    return 0;
}

4. Uso Avanzato delle Struct

4.1 Struct Nidificate

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

struct Data {
    int giorno;
    int mese;
    int anno;
};

struct Studente {
    string nome;
    int matricola;
    Data dataDiNascita; // Struct nidificata
};

int main() {
    // Inizializzazione con struct nidificata
    Studente s = {"Anna Verdi", 12345, {15, 6, 2000}};

    cout << "Studente: " << s.nome << endl;
    cout << "Matricola: " << s.matricola << endl;
    cout << "Data di nascita: " << s.dataDiNascita.giorno << "/"
        << s.dataDiNascita.mese << "/" << s.dataDiNascita.anno << endl;

    return 0;
}

4.2 Funzioni Membro nelle Struct

#include <iostream>
using namespace std;

struct Rettangolo {
    int larghezza;
    int altezza;

    // Funzione membro per calcolare l'area
    int area() const {
        return larghezza * altezza;
    }

    // Funzione membro per calcolare il perimetro
    int perimetro() const {
        return 2 * (larghezza + altezza);
    }

    // Funzione per ridimensionare
    void ridimensiona(int nuova_larghezza, int nuova_altezza) {
        larghezza = nuova_larghezza;
        altezza = nuova_altezza;
    }
};

int main() {
    Rettangolo r = {5, 3};

    cout << "Rettangolo: " << r.larghezza << "x" << r.altezza << endl;
    cout << "Area: " << r.area() << endl;
    cout << "Perimetro: " << r.perimetro() << endl;

    r.ridimensiona(8, 4);
    cout << "Dopo ridimensionamento:" << endl;
    cout << "Area: " << r.area() << endl;

    return 0;
}

Esercizi Pratici

Metti in pratica ciò che hai imparato sulle struct

Esercizio 1: Gestione Rubrica

Obiettivo: Creare una rubrica di contatti usando le struct.

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

struct Contatto {
    string nome;
    string cognome;
    string telefono;
};

int main() {
    int n;
    cout << "Quanti contatti vuoi inserire? ";
    cin >> n;
    cin.ignore(); // Pulisce il buffer dopo cin

    // Array dinamico di contatti
    Contatto* rubrica = new Contatto[n];

    // Inserimento contatti
    for (int i = 0; i < n; i++) {
        cout << "\\n--- Contatto " << i + 1 << " ---" << endl;
        cout << "Nome: ";
        getline(cin, rubrica[i].nome);
        cout << "Cognome: ";
        getline(cin, rubrica[i].cognome);
        cout << "Telefono: ";
        getline(cin, rubrica[i].telefono);
    }

    // Visualizzazione rubrica
    cout << "\\n=== RUBRICA ===" << endl;
    for (int i = 0; i < n; i++) {
        cout << i + 1 << ". " << rubrica[i].nome << " "
            << rubrica[i].cognome << " - " << rubrica[i].telefono << endl;
    }

    // IMPORTANTE: Deallocare la memoria
    delete[] rubrica;

    return 0;
}

Esercizio 2: Ordinamento Prodotti

Obiettivo: Ordinare un array di prodotti per prezzo.

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

struct Prodotto {
    string nome;
    double prezzo;
};

void scambia(Prodotto &a, Prodotto &b) {
    Prodotto temp = a;
    a = b;
    b = temp;
}

void ordinaProdotti(Prodotto prodotti[], int n) {
    // Bubble Sort per prezzo
    for (int i = 0; i < n - 1; i++) {
        for (int j = 0; j < n - i - 1; j++) {
            if (prodotti[j].prezzo > prodotti[j + 1].prezzo) {
                scambia(prodotti[j], prodotti[j + 1]);
            }
        }
    }
}

int main() {
    int n;
    cout << "Numero di prodotti: ";
    cin >> n;
    cin.ignore();

    Prodotto* prodotti = new Prodotto[n];

    // Input prodotti
    for (int i = 0; i < n; i++) {
        cout << "\\nProdotto " << i + 1 << ":" << endl;
        cout << "Nome: ";
        getline(cin, prodotti[i].nome);
        cout << "Prezzo: ";
        cin >> prodotti[i].prezzo;
        cin.ignore();
    }

    // Ordinamento
    ordinaProdotti(prodotti, n);

    // Output ordinato
    cout << "\\n=== PRODOTTI ORDINATI ===" << endl;
    for (int i = 0; i < n; i++) {
        cout << prodotti[i].nome << " - " << prodotti[i].prezzo << " €" << endl;
    }

    delete[] prodotti;
    return 0;
}

6. Esercizi Avanzati

Esercizio 3: Sistema di Gestione Biblioteca

Obiettivo: Gestire libri con struct complesse.

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

struct Autore {
    string nome;
    string cognome;
    int annoNascita;
};

struct Libro {
    string titolo;
    Autore autore;  // Struct nidificata
    int annoPubblicazione;
    string isbn;
    bool disponibile;

    void stampaDettagli() const {
        cout << "Titolo: " << titolo << endl;
        cout << "Autore: " << autore.nome << " " << autore.cognome << endl;
        cout << "Anno: " << annoPubblicazione << endl;
        cout << "ISBN: " << isbn << endl;
        cout << "Disponibile: " << (disponibile ? "Sì" : "No") << endl;
    }

    void prestito() {
        if (disponibile) {
            disponibile = false;
            cout << "Libro prestato con successo!" << endl;
        } else {
            cout << "Libro non disponibile!" << endl;
        }
    }

    void restituzione() {
        disponibile = true;
        cout << "Libro restituito!" << endl;
    }
};

int main() {
    Libro libro1 = {
        "Il Nome della Rosa",
        {"Umberto", "Eco", 1932},
        1980,
        "978-88-452-0000-0",
        true
    };

    libro1.stampaDettagli();
    cout << endl;

    libro1.prestito();
    libro1.stampaDettagli();

    return 0;
}

Esercizio 4: Calcolatrice Geometria

Obiettivo: Usare struct per forme geometriche.

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

struct Cerchio {
    double raggio;
    double x, y;  // Coordinate centro

    double area() const {
        return M_PI * raggio * raggio;
    }

    double circonferenza() const {
        return 2 * M_PI * raggio;
    }
};

struct Rettangolo {
    double base;
    double altezza;
    double x, y;  // Coordinate angolo in basso a sinistra

    double area() const {
        return base * altezza;
    }

    double perimetro() const {
        return 2 * (base + altezza);
    }

    double diagonale() const {
        return sqrt(base * base + altezza * altezza);
    }
};

int main() {
    Cerchio c = {5.0, 0.0, 0.0};
    Rettangolo r = {4.0, 3.0, 0.0, 0.0};

    cout << "=== CERCHIO ===" << endl;
    cout << "Area: " << c.area() << endl;
    cout << "Circonferenza: " << c.circonferenza() << endl;

    cout << "\\n=== RETTANGOLO ===" << endl;
    cout << "Area: " << r.area() << endl;
    cout << "Perimetro: " << r.perimetro() << endl;
    cout << "Diagonale: " << r.diagonale() << endl;

    return 0;
}

7. Best Practices

Linee guida per un uso efficace:

Nomi Descritivi

Usa nomi chiari per struct e membri (es: Persona invece di P)

Inizializzazione

Usa sempre l'inizializzazione per evitare valori indefiniti

Commenti

Commenta struct complesse per migliorare la leggibilità

Gestione Memoria

Dealloca sempre la memoria con delete[] per array dinamici

C++ Moderno

Usa inizializzatori uniformi e costruttori per codice più robusto

Conclusioni

Le struct in C++ sono uno strumento semplice ma potentissimo per organizzare e gestire gruppi di dati correlati. Grazie alla loro semplicità (con membri pubblici per default) e alla possibilità di essere estese con funzioni membro, esse rappresentano un primo passo verso la programmazione orientata agli oggetti. Utilizzando le struct, è possibile creare strutture dati chiare e facilmente manutenibili, fondamentali per lo sviluppo di applicazioni complesse. 🚀

Esercitazioni Pratiche C++

Metti in pratica ciò che hai imparato con queste esercitazioni complete

Tutte le Esercitazioni

📊 Variabili e Tipi di Dato

➕ Operatori Matematici e Logici in C++

🔀 Strutture di controllo condizionali

🔄 I cicli in C++

🗃️ C++ gli array

⚙️ Le funzioni in C++

📈 Ordinamento dei Dati

🏗️ Le struct in C++

🎯 I puntatori

🧩 La Programmazione Orientata agli Oggetti (OOP)

📁 La gestione dei file in C++

💪 Esercizi C++ Raccolta Completa

12 esercitazioni complete per padroneggiare il C++