Struct in C++

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. 🚀

Torna in alto