Menu
Coddy logo textTech

Rigueur du mot-clé const

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

Lors de l'écriture de fonctions qui agissent comme des méthodes, certaines devraient modifier l'objet (comme player_take_damage), tandis que d'autres devraient seulement lire les données sans rien changer. Le mot-clé const vous permet d'imposer cette distinction au niveau du compilateur.

En marquant un paramètre de pointeur comme const, vous promettez que la fonction ne modifiera pas les données vers lesquelles il pointe. Si vous essayez accidentellement de modifier un membre, le compilateur produira une erreur :

typedef struct {
    int x;
    int y;
} Point;

// Cette fonction peut seulement LIRE le point
void point_print(const Point *self) {
    printf("(%d, %d)\n", self->x, self->y);
    // self->x = 10;  // ERREUR : impossible de modifier via un pointeur const
}

// Cette fonction peut MODIFIER le point
void point_move(Point *self, int dx, int dy) {
    self->x += dx;
    self->y += dy;
}

Le paramètre const Point *self indique à la fois au compilateur et aux autres programmeurs que point_print est un « getter » ou une opération en lecture seule. C'est ce qu'on appelle la const-correctness — utiliser const partout où une modification n'est pas nécessaire.

Cette pratique permet de détecter les bogues tôt. Si vous écrivez une fonction d'affichage et que vous modifiez accidentellement un champ, le compilateur vous arrête immédiatement au lieu de laisser le bogue s'introduire dans votre programme.

challenge icon

Défi

Facile

Construisons un module Temperature qui stocke une valeur de température et fournit à la fois des opérations de lecture seule et de modification. Cela vous aidera à vous entraîner à utiliser des pointeurs const pour distinguer clairement les fonctions qui lisent simplement les données de celles qui les modifient.

Vous allez créer trois fichiers :

  • temperature.h : Déclarez une structure Temperature avec un seul membre double celsius. Déclarez également trois fonctions :
    • temp_display — prend un pointeur const vers Temperature et affiche la température actuelle (lecture seule)
    • temp_adjust — prend un pointeur classique vers Temperature et un montant double, puis ajoute le montant à celsius (modification)
    • temp_to_fahrenheit — prend un pointeur const vers Temperature et renvoie la valeur convertie en Fahrenheit (lecture seule)
    Utilisez des gardes d'inclusion avec le symbole TEMPERATURE_H.
  • temperature.c : Implémentez les trois fonctions. La fonction temp_display doit afficher au format "Current: %.1fC\n". La fonction temp_to_fahrenheit doit renvoyer celsius * 9.0 / 5.0 + 32.0. Rappelez-vous que les fonctions utilisant des pointeurs const ne peuvent pas modifier les données de la structure.
  • main.c : Créez une Temperature, effectuez des opérations et affichez les résultats.

Vous recevrez deux entrées : la valeur celsius initiale (sous forme de double) et le montant de l'ajustement (sous forme de double).

Dans votre fichier principal :

  1. Initialisez une Temperature avec la valeur celsius initiale
  2. Appelez temp_display pour afficher la température de départ
  3. Appelez temp_adjust pour modifier la température du montant de l'ajustement
  4. Appelez temp_display à nouveau pour afficher la température mise à jour
  5. Affichez la conversion en Fahrenheit en utilisant temp_to_fahrenheit

Affichez les résultats dans ce format :

Current: {celsius}C
Current: {celsius}C
Fahrenheit: {fahrenheit}F

Utilisez %.1f pour toutes les valeurs de température afin d'afficher une décimale.

Par exemple, avec une valeur initiale de 20.0 et un ajustement de 5.0, la sortie serait :

Current: 20.0C
Current: 25.0C
Fahrenheit: 77.0F

Aide-mémoire

Le mot-clé const peut être utilisé avec des paramètres de pointeur pour indiquer qu'une fonction ne modifiera pas les données pointées. C'est ce qu'on appelle la const correctness.

Lorsqu'un paramètre de pointeur est marqué comme const, le compilateur empêchera toute modification des données via ce pointeur :

typedef struct {
    int x;
    int y;
} Point;

// Fonction en lecture seule - ne peut pas modifier le point
void point_print(const Point *self) {
    printf("(%d, %d)\n", self->x, self->y);
    // self->x = 10;  // ERREUR : impossible de modifier via un pointeur const
}

// Fonction de modification - peut changer le point
void point_move(Point *self, int dx, int dy) {
    self->x += dx;
    self->y += dy;
}

L'utilisation de const Point *self communique à la fois au compilateur et aux autres programmeurs que la fonction est une opération en lecture seule. Cela aide à détecter les bogues tôt — si vous essayez accidentellement de modifier des données dans une fonction qui ne devrait rien changer, le compilateur produira immédiatement une erreur.

Bonne pratique : Utilisez const pour les paramètres de pointeur chaque fois que la fonction n'a pas besoin de modifier les données. Cela rend l'intention de votre code plus claire et empêche les modifications accidentelles.

Essayez vous-même

#include <stdio.h>
#include "temperature.h"

int main() {
    double initial_celsius, adjustment;
    scanf("%lf", &initial_celsius);
    scanf("%lf", &adjustment);
    
    // TODO: Créer une structure Temperature et l'initialiser avec initial_celsius
    
    // TODO: Appeler temp_display pour afficher la température de départ
    
    // TODO: Appeler temp_adjust pour modifier la température par le montant de l'ajustement
    
    // TODO: Appeler à nouveau temp_display pour afficher la température mise à jour
    
    // TODO: Afficher la conversion en Fahrenheit en utilisant temp_to_fahrenheit
    // Format: "Fahrenheit: %.1fF\n"
    
    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