Initialisation sur la pile
Fait partie de la section Object Oriented Programming du Journey C de Coddy — leçon 14 sur 61.
Tous les objets n'ont pas besoin de résider sur le tas. Lorsqu'une structure est petite et a une durée de vie courte, l'allouer sur la pile est plus simple et plus rapide — pas de malloc, pas de free, aucun risque de fuite de mémoire.
Au lieu de retourner un pointeur, une fonction d'usine peut retourner la structure par valeur. La structure entière est copiée vers l'appelant :
typedef struct {
int x;
int y;
} Point;
Point create_point(int x, int y) {
Point p;
p.x = x;
p.y = y;
return p;
}
L'appelant reçoit une copie entièrement initialisée :
Point origin = create_point(0, 0);
Point cursor = create_point(100, 50);
printf("Cursor: (%d, %d)\n", cursor.x, cursor.y);
Pas de pointeurs, aucun nettoyage requis. Lorsque origin et cursor sortent de la portée, ils sont automatiquement détruits.
Cette approche fonctionne mieux pour les petites structures sans membres alloués dynamiquement. Pour les objets plus volumineux ou ceux contenant des pointeurs vers la mémoire du tas (heap), le modèle de constructeur avec malloc reste le meilleur choix.
Défi
FacileConstruisons un module Temperature qui crée des relevés de température sur la pile (stack) à l'aide d'une fonction d'usine (factory function). Contrairement aux constructeurs basés sur le tas (heap) des leçons précédentes, cette approche renvoie la structure par valeur — pas de malloc, pas de free, juste une allocation sur la pile simple et efficace.
Vous allez créer trois fichiers :
temperature.h: Déclarez une structureTemperatureavec deux membres :double celsiusetchar scale(pour stocker 'C' pour Celsius). Déclarez également deux fonctions :create_temperature— prend une valeur double et renvoie une structureTemperaturepar valeur (pas un pointeur !)temperature_to_fahrenheit— prend unconst Temperature *et renvoie la température équivalente en Fahrenheit sous forme de double
TEMPERATURE_H.temperature.c: Implémentez les deux fonctions. Votre fonction d'usine doit créer une variable localeTemperature, initialiser ses champs (définirscaleà'C'), et la renvoyer. La formule de conversion est :fahrenheit = celsius * 9.0 / 5.0 + 32.0main.c: Utilisez votre fonction d'usine pour créer un relevé de température et afficher les valeurs en Celsius et en Fahrenheit.
Vous recevrez une entrée : la température en Celsius (sous forme de double).
Dans votre fichier principal, utilisez create_temperature pour créer une structure Temperature avec la valeur donnée. Ensuite, affichez la valeur Celsius d'origine et son équivalent en Fahrenheit.
Affichez la sortie dans ce format :
Celsius: {celsius}
Fahrenheit: {fahrenheit}Utilisez %.2f pour les deux valeurs afin d'afficher deux décimales.
Par exemple, avec une entrée de 25.0, la sortie serait :
Celsius: 25.00
Fahrenheit: 77.00Remarquez à quel point cette approche est propre — vous recevez une structure entièrement initialisée sans aucun souci de gestion de la mémoire. Lorsque votre variable Temperature sort de la portée (scope), elle est automatiquement nettoyée.
Aide-mémoire
Les fonctions d'usine (factory functions) peuvent retourner des structures par valeur au lieu de pointeurs. Cela alloue la structure sur la pile — pas de malloc, pas de free, et pas de fuites de mémoire.
Exemple d'une fonction d'usine retournant par valeur :
typedef struct {
int x;
int y;
} Point;
Point create_point(int x, int y) {
Point p;
p.x = x;
p.y = y;
return p;
}
Utilisation de la fonction d'usine :
Point origin = create_point(0, 0);
Point cursor = create_point(100, 50);
printf("Cursor: (%d, %d)\n", cursor.x, cursor.y);
La structure est copiée vers l'appelant et automatiquement détruite lorsqu'elle sort de la portée. Cette approche fonctionne mieux pour les petites structures sans membres alloués dynamiquement.
Essayez vous-même
#include <stdio.h>
#include "temperature.h"
int main() {
double celsius_input;
scanf("%lf", &celsius_input);
// TODO: Utiliser create_temperature pour créer une struct Temperature
// TODO: Afficher la valeur Celsius en utilisant le format %.2f
// TODO: Utiliser temperature_to_fahrenheit pour convertir et afficher la valeur Fahrenheit
return 0;
}
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
1Bases de la programmation modulaire
Fichiers d'en-têteGardes d'inclusionFichiers sourcesFonctions statiquesRécapitulatif : Calculatrice modulaire4Encapsulation
Concept des pointeurs opaquesDéfinir des structures opaquesGetters et settersValidation dans les settersRécapitulatif : La boîte secrète2Objets et méthodes
Structs comme objetsLe pointeur 'Self'Rigueur du mot-clé constPointeur vs ValeurMéthodes utilitairesRécapitulatif : Point Manager5Projet : Compte bancaire simple
Configuration du projetImplémentation du compte8Polymorphisme
Pointeurs de fonctions dans les structuresSimulation de méthodesLe concept d'interfaceImplémentation d'interfacesItération polymorphiqueRécapitulatif : Greeter11Patrons de conception en C
Patron SingletonPatron FabriquePatron ItérateurRécapitulatif : Logger Factory3Cycle de vie des objets
Pattern de constructeurPattern de destructeurInitialisation sur la pileCopie profondeRécapitulatif : String Wrapper6Héritage par composition
Imbrication de structLa règle du premier membreAccès aux membres parentsUpcastingRécapitulatif : Hiérarchie des formes9Projet : Dessinateur de formes
Aperçu du projetImplémentation du cercle