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

Strutture (struct) in C

In questa pagina 6
In questa pagina 3

Definizione

Definizione (struct). 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).

Esempio. Con struct punto p = {1.0, 2.0}; p.x = 4.0; si ha p.x == 4.0 e p.y == 2.0.

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};

Proprietà (assegnazione e dimensione di una struct)

  • 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).

Esempio. Con Studente (char nome[32], int, double) sizeof(Studente) vale 48, più dei 32+4+8=4432+4+8=44 byte dei campi per il padding; q = p copia tutti i campi.

Struct e funzioni

Definizione (struct passate a 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.

Esempio. medio applicata ai punti (0,0)(0,0) e (4,2)(4,2) restituisce per valore la struct (2,1)(2,1).

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

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

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

Esempio. Con Nodo n1 = {1, NULL}; Nodo n2 = {2, &n1}; si ha n2.succ->valore == 1.

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

Versione ripasso

Definizione e uso

Una struct raggruppa più campi di tipo anche diverso; typedef dà un nome più corto al tipo.

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

Studente s = {"Ada", 123456, 28.5};   /* campo con ".": s.media */
  • Si possono assegnare (q = p; copia tutti i campi), ma non confrontare con ==.
  • sizeof può essere maggiore della somma dei campi per l'allineamento in memoria (padding).

Passaggio alle funzioni:

Array, allocazione dinamica e autoreferenzialità

c
typedef struct nodo {
    int valore;
    struct nodo *succ;     /* serve il nome "struct nodo" */
} Nodo;

Errori tipici

Esercizi su questo argomento

Teoria collegata