Menu
Coddy logo textTech

Accès aux membres parents

Fait partie de la section Object Oriented Programming du Journey C de Coddy — leçon 30 sur 61.

Maintenant que nous comprenons l'imbrication de structures (struct embedding) et la règle du premier membre, concentrons-nous sur l'aspect pratique : comment lire et modifier les données du parent imbriqué à l'intérieur d'une fonction.

Lorsqu'une fonction reçoit une structure Child (ou un pointeur vers celle-ci), l'accès aux membres du parent nécessite de naviguer à travers la structure imbriquée. La syntaxe dépend du fait que vous travaillez avec une valeur ou un pointeur.

typedef struct {
    int id;
    int score;
} Parent;

typedef struct {
    Parent parent;
    char grade;
} Child;

Avec un pointeur vers Child, utilisez l'opérateur flèche pour atteindre le parent, puis le point pour accéder à ses membres :

void update_score(Child* c, int new_score) {
    c->parent.score = new_score;  // Flèche puis point
}

void print_info(Child* c) {
    printf("ID: %d, Score: %d\n", c->parent.id, c->parent.score);
}

Avec une valeur (passée par copie), utilisez des points partout :

void show_id(Child c) {
    printf("ID: %d\n", c.parent.id);  // Point puis point
}

Ce modèle d'accès chaîné — child->parent.member ou child.parent.member — est la manière dont vous interagissez avec les données héritées dans le modèle de composition du C. C'est légèrement plus verbeux qu'un véritable héritage, mais c'est explicite et clair quant à la relation entre les types.

challenge icon

Défi

Facile

Construisons un système de notation des étudiants qui démontre comment accéder et modifier des données à l'intérieur d'une structure imbriquée. Vous allez créer une hiérarchie où un Student contient un Person imbriqué, puis écrire des fonctions qui travaillent avec les données du parent à travers l'enfant.

Vous organiserez votre code sur trois fichiers :

  • student.h : Définissez votre hiérarchie de structures avec des gardes d'inclusion. Créez une structure Person avec name (un tableau de caractères de 50 caractères) et age (un entier). Définissez ensuite une structure Student qui imbrique Person comme premier membre et ajoute un champ grade (un entier représentant leur score). Déclarez deux fonctions : set_person_age qui prend un Student* et une nouvelle valeur d'âge, et print_student qui prend un Student* et affiche toutes les informations.
  • student.c : Implémentez les deux fonctions. Votre fonction set_person_age doit modifier l'âge à l'intérieur de la structure Person imbriquée — c'est ici que vous pratiquerez la syntaxe flèche-puis-point (s->person.age). Votre fonction print_student doit accéder et afficher tous les champs de la personne imbriquée et de l'étudiant lui-même.
  • main.c : Créez une variable Student et initialisez tous ses champs. Utilisez ensuite set_person_age pour mettre à jour l'âge de la personne imbriquée, et appelez print_student pour afficher le résultat.

Vous recevrez quatre entrées : le nom de l'étudiant (une chaîne de caractères), son âge initial (un entier), sa note (un entier), et un nouvel âge (un entier à mettre à jour via votre fonction).

Dans votre fichier principal, créez l'étudiant avec les valeurs initiales, puis appelez set_person_age pour changer l'âge par la nouvelle valeur, et enfin appelez print_student pour afficher les informations mises à jour.

Votre sortie devrait ressembler à ceci :

Name: Emma
Age: 21
Grade: 85

Emma est le nom, 21 est l'âge mis à jour (pas l'âge initial), et 85 est la note. L'apprentissage clé ici est de naviguer à travers la structure imbriquée pour lire et écrire les membres du parent.

Aide-mémoire

Pour accéder aux membres d'une structure parente imbriquée à partir d'une fonction, utilisez une syntaxe d'accès chaînée qui dépend du fait que vous travaillez avec un pointeur ou une valeur.

Avec un pointeur vers la structure enfant, utilisez l'opérateur flèche pour atteindre le parent imbriqué, puis la notation par point pour accéder à ses membres :

void update_score(Child* c, int new_score) {
    c->parent.score = new_score;  // Flèche puis point
}

void print_info(Child* c) {
    printf("ID: %d, Score: %d\n", c->parent.id, c->parent.score);
}

Avec une valeur (passée par copie), utilisez la notation par point partout :

void show_id(Child c) {
    printf("ID: %d\n", c.parent.id);  // Point puis point
}

Ce modèle — child->parent.member ou child.parent.member — permet un accès explicite aux données héritées dans le modèle de composition du C.

Essayez vous-même

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

int main() {
    char name[50];
    int initial_age, grade, new_age;
    
    // Lire les entrées
    fgets(name, 50, stdin);
    name[strcspn(name, "\n")] = '\0';  // Supprimer le saut de ligne
    scanf("%d", &initial_age);
    scanf("%d", &grade);
    scanf("%d", &new_age);
    
    // TODO: Créer une variable Student
    
    // TODO: Initialiser tous les champs de l'étudiant
    // - Copier name vers le name de la person imbriquée en utilisant strcpy
    // - Définir l'age de la person imbriquée à initial_age
    // - Définir le grade de l'étudiant
    
    // TODO: Appeler set_person_age pour mettre à jour l'age à new_age
    
    // TODO: Appeler print_student pour afficher le résultat
    
    return 0;
}
quiz iconTestez-vous

Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.

Toutes les leçons de Object Oriented Programming