Dopo aver imparato come funzionano i puntatori e come si dichiarano le struct, è il momento di unire i due concetti: i puntatori a struct permettono di gestire interi oggetti passando solo il loro indirizzo, senza copiarli interamente.
1️⃣ Dichiarare un puntatore a struct
Partiamo da una struct semplice:
struct Studente {
string nome;
int eta;
float media;
};
Possiamo creare una variabile di tipo Studente e un puntatore che la punta:
Studente s1 = {"Marco", 17, 8.2};
Studente* p = &s1; // p contiene l indirizzo di s1
Ora p non è uno Studente, ma un puntatore a uno Studente.
2️⃣ Accesso ai campi: * e ->
Ci sono due modi per accedere ai campi della struct tramite puntatore:
| Forma | Descrizione | Esempio |
|---|---|---|
(*p).campo | Derefenzia il puntatore, poi accede al campo | (*p).nome = "Luca"; |
p->campo | Forma abbreviata molto usata | p->nome = "Luca"; |
Entrambe le forme sono equivalenti, ma la seconda (->) è più leggibile e comune.
3️⃣ Esempio completo
#include <iostream>
using namespace std;
struct Studente {
string nome;
int eta;
float media;
};
int main() {
Studente s1 = {"Marco", 17, 8.2};
Studente* p = &s1; // puntatore a struct
cout << "Dati originali:" << endl;
cout << "Nome: " << p->nome << endl;
cout << "Età: " << p->eta << endl;
cout << "Media: " << p->media << endl;
// Modifica tramite puntatore
p->media = 9.0;
cout << "\nDopo modifica:" << endl;
cout << "Nuova media: " << s1.media << endl;
}
✅ Output:
Dati originali:
Nome: Marco
Età: 17
Media: 8.2
Dopo modifica:
Nuova media: 9
4️⃣ Puntatori a struct e array
Se abbiamo un vettore di struct, possiamo usare un puntatore per scorrere gli elementi:
Studente classe[3] = {
{"Anna", 16, 8.0},
{"Luca", 17, 7.5},
{"Sara", 16, 9.1}
};
Studente* p = classe; // punta al primo elemento
for (int i = 0; i < 3; i++) {
cout << (p + i)->nome << " - Media: " << (p + i)->media << endl;
}
👉 Qui p + i si comporta come &classe[i].
Quindi (p + i)->media equivale a classe[i].media.
5️⃣ Funzioni con puntatori a struct
Puoi passare un puntatore a struct a una funzione per modificare direttamente l oggetto originale:
void aggiornaMedia(Studente* ps, float nuovaMedia) {
ps->media = nuovaMedia;
}
int main() {
Studente s = {"Chiara", 18, 7.4};
aggiornaMedia(&s, 8.5);
cout << "Nuova media: " << s.media;
}
✅ Output:
Nuova media: 8.5
💡 Passando un puntatore, la funzione non lavora su una copia ma sullo stesso oggetto.
6️⃣ Puntatore a struct e memoria dinamica (anticipazione)
In preparazione alla prossima lezione, ecco un esempio di creazione dinamica di una struct con new:
Studente* p = new Studente;
p->nome = "Giulia";
p->eta = 19;
p->media = 9.3;
cout << p->nome << " - Media: " << p->media;
delete p; // libera la memoria allocata
Questa tecnica sarà approfondita nella lezione successiva sui puntatori e memoria dinamica.
LABORATORIO
Gestione di Studenti con Puntatori a Struct
In questo laboratorio imparerai a utilizzare puntatori a struct per accedere e modificare i campi di una struttura. Creerai un piccolo sistema per gestire un gruppo di studenti.
- Compilatore C++ (Code::Blocks, Dev-C++ o Visual Studio Code)
- Console per visualizzare i risultati
1 Dichiarazione di una struct
Crea una struct Studente con i campi: nome, eta e media.
2 Puntatore a struct
Crea un oggetto Studente e un puntatore che lo punti, poi stampa i dati.
Studente s = {"Marco", 17, 8.2};
Studente* p = &s;
cout << p->nome << " - " << p->eta << " anni - media " << p->media;
3 Modifica tramite funzione
Scrivi una funzione che riceve un puntatore a struct e aggiorna la media.
void aggiorna(Studente* ps, float nuovaMedia) {
ps->media = nuovaMedia;
}
4 Array e scorrimento con puntatore
Crea un array di 3 studenti e visualizzali con un puntatore.
Studente classe[3] = {
{"Anna", 16, 8.0},
{"Luca", 17, 7.5},
{"Sara", 16, 9.1}
};
Studente* p = classe;
for (int i = 0; i < 3; i++)
cout << (p + i)->nome << " - " << (p + i)->media << endl;
5 Esercizi aggiuntivi
- Scrivi una funzione che restituisce un puntatore allo studente con la media più alta.
- Scrivi una funzione che incrementa di 1 l età di tutti gli studenti usando un puntatore.
- Estendi la struct aggiungendo un campo
classe(es. "3A") e stampalo.