Salta al contenuto
Note per Studenti Strutture (struct) in C

Strutture (struct) in C

In questa pagina 6

Definizione

Una struct raggruppa in un unico tipo più campi di tipo anche diverso (come una tupla con nomi o un semplice oggetto Python con soli attributi).

c
struct punto {
    double x;
    double y;
};

struct punto p = {1.0, 2.0};
struct punto q = {.y = 5.0, .x = 3.0};   /* inizializzatori con nome */
p.x = 4.0;                                /* accesso ai campi con . */

Con typedef si dà un nome più corto al tipo:

c
typedef struct {
    char nome[32];
    int matricola;
    double media;
} Studente;

Studente s = {"Ada", 123456, 28.5};
  • Una struct si può assegnare (q = p; copia tutti i campi, anche gli array interni) ma non confrontare con ==.
  • sizeof(Studente) può essere maggiore della somma dei campi per l'allineamento in memoria (padding).

Struct e funzioni

Una struct passata per valore viene copiata per intero; per modificarla o per evitare la copia di strutture grandi si passa un puntatore. Con un puntatore i campi si raggiungono con ->: ps->media equivale a (*ps).media.

c
double distanza(struct punto a, struct punto b) {         /* per valore */
    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}

void aggiorna_media(Studente *ps, double nuovo_voto, int n_esami) {
    ps->media = (ps->media * (n_esami - 1) + nuovo_voto) / n_esami;
}

struct punto medio(struct punto a, struct punto b) {      /* struct come valore di ritorno */
    struct punto m = {(a.x + b.x) / 2, (a.y + b.y) / 2};
    return m;
}

Restituire una struct è il modo pulito di restituire più valori insieme (alternativa ai parametri puntatore di Puntatori in CUn puntatore contiene un indirizzo di memoria; operatori & e *, NULL, puntatori come parametri per modificare variabili del chiamante, aritmetica dei puntatori, legame tra array e puntatori, const, puntatori a puntatori.Puntatori in C →).

Array di struct

c
Studente classe[3] = {
    {"Ada", 1, 29.0},
    {"Alan", 2, 27.5},
    {"Grace", 3, 30.0},
};

int migliore = 0;
for (int i = 1; i < 3; i++)
    if (classe[i].media > classe[migliore].media)
        migliore = i;
printf("%s\n", classe[migliore].nome);

Struct dinamiche

c
Studente *ps = malloc(sizeof *ps);
if (ps != NULL) {
    strcpy(ps->nome, "Ada");
    ps->matricola = 1;
    free(ps);
}

Vedi Gestione della memoria in CSegmenti di memoria di un processo (codice, dati statici, stack, heap); durata delle variabili; allocazione dinamica con malloc, calloc, realloc e free; errori classici: memory leak, dangling pointer, double free, buffer overflow; strumenti di controllo.Gestione della memoria in C →.

Struct autoreferenziali

Una struct non può contenere se stessa, ma può contenere un puntatore al proprio tipo. È la base delle strutture collegate:

c
typedef struct nodo {
    int valore;
    struct nodo *succ;     /* serve il nome "struct nodo": il typedef non è ancora completo */
} Nodo;

Uso in Liste concatenateLista concatenata semplice: nodi allocati dinamicamente collegati da puntatori; inserimento e rimozione in testa, scorrimento, ricerca, inserimento ordinato, deallocazione; confronto dei costi con l'array; versione in Python.Liste concatenate → e, come tipo che nasconde la rappresentazione, in Tipi di dato astrattiUn ADT è definito dalle operazioni e dal loro comportamento, non dalla rappresentazione; interfaccia e implementazione; realizzazione in Python con le classi e in C con header e tipo opaco; esempio di un ADT Frazione.Tipi di dato astratti →.

Errori tipici

Teoria collegata