Menu
Coddy logo textTech

La regola del primo membro

Fa parte della sezione Programmazione orientata agli oggetti del percorso C di Coddy. Lezione 29 di 61.

Quando incorpori una struct come primo membro di un'altra struct, accade qualcosa di potente: l'indirizzo di memoria della struct esterna è identico all'indirizzo di memoria del suo primo membro. Questo è garantito dallo standard C.

Considera il nostro esempio precedente:

typedef struct {
    int id;
} Parent;

typedef struct {
    Parent parent;  // Primo membro
    int grade;
} Child;

Quando crei una variabile Child, il membro Parent si trova proprio all’inizio della memoria di Child. Ciò significa che un puntatore a Child punta esattamente allo stesso indirizzo di un puntatore al suo membro Parent.

Child c;
Child* child_ptr = &c;
Parent* parent_ptr = (Parent*)child_ptr;  // Conversione sicura!

Entrambi i puntatori contengono lo stesso indirizzo. Questo ti permette di passare un Child* a qualsiasi funzione che si aspetta un Parent*:

void print_id(Parent* p) {
    printf("ID: %d\n", p->id);
}

// In main:
Child c;
c.parent.id = 42;
print_id((Parent*)&c);  // Works perfectly

Questa tecnica è il fondamento dell'ereditarietà in C. Una funzione scritta per il tipo base può operare su qualsiasi tipo derivato, purché il tipo base sia incorporato per primo. Il cast è sicuro perché le disposizioni della memoria corrispondono perfettamente.

challenge icon

Sfida

Facile

Esploriamo la regola del primo membro creando una semplice gerarchia di animali. Creerai una struct base Animal e una struct derivata Dog, poi mostrerai come un puntatore a Dog possa essere convertito in sicurezza in un puntatore a Animal.

L'idea chiave che applicherai: quando Animal è il primo membro di Dog, entrambe le struct condividono lo stesso indirizzo di memoria iniziale. Ciò significa che puoi passare un Dog* a qualsiasi funzione che si aspetta un Animal*, convertendo il puntatore.

Organizzerai il codice in tre file:

  • animal.h: Definisci entrambe le struct con le protezioni di inclusione. La struct Animal deve avere un solo campo: legs (un intero che rappresenta il numero di zampe). La struct Dog deve contenere Animal come primo membro e aggiungere un campo name (un array di caratteri di 50 caratteri). Dichiara anche una funzione print_animal che accetta un parametro Animal*.
  • animal.c: Implementa la funzione print_animal. Questa funzione opera sul tipo base. Conosce solo Animal e stampa quante zampe ha l'animale.
  • main.c: Crea una variabile Dog e valorizzane i campi (sia le zampe dell'animale incorporato sia il nome del cane). Poi mostra la regola del primo membro convertendo il tuo Dog* in un Animal* e passandolo a print_animal. Stampa anche separatamente il nome del cane per mostrare il quadro completo.

Riceverai due input: il nome del cane (una stringa) e il numero di zampe (un intero).

L'output dovrebbe essere così:

Dog: Buddy
Legs: 4

Dove Buddy è il nome del cane e 4 è il numero di zampe. Stampa prima il nome del cane da main.c, poi chiama print_animal con il puntatore convertito per visualizzare le zampe.

Questo dimostra come una funzione scritta per il tipo base (Animal) possa funzionare senza problemi con un tipo derivato (Dog) tramite la conversione dei puntatori: il fondamento dell'ereditarietà in C.

Provalo tu

#include <stdio.h>
#include <string.h>
#include "animal.h"

int main() {
    // Leggi l'input
    char name[50];
    int legs;
    scanf("%s", name);
    scanf("%d", &legs);
    
    // TODO: Crea una variabile Dog
    
    // TODO: Imposta il nome del cane usando strcpy
    
    // TODO: Imposta il numero di zampe (accedendo tramite Animal incorporato)
    
    // TODO: Stampa il nome del cane nel formato: "Dog: <name>"
    
    // TODO: Esegui il cast da Dog* ad Animal* e chiama print_animal
    // Questo dimostra la regola del primo membro!
    
    return 0;
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore C online