Inicialización en Stack
Parte de la sección Programación Orientada a Objetos del Journey de C de Coddy. Lección 14 de 61.
No todos los objetos necesitan vivir en el heap. Cuando un struct es pequeño y tiene una vida útil corta, asignarlo en la pila es más sencillo y rápido: no hay malloc, no hay free ni riesgo de fugas de memoria.
En lugar de devolver un puntero, una función de fábrica puede devolver la estructura por valor. La estructura completa se copia al código que realiza la llamada:
typedef struct {
int x;
int y;
} Point;
Point create_point(int x, int y) {
Point p;
p.x = x;
p.y = y;
return p;
}
El llamador recibe una copia completamente inicializada:
Point origin = create_point(0, 0);
Point cursor = create_point(100, 50);
printf("Cursor: (%d, %d)\n", cursor.x, cursor.y);
Sin punteros, no se requiere limpieza. Cuando origin y cursor salen del ámbito, se destruyen automáticamente.
Este enfoque funciona mejor para structs pequeños sin miembros asignados dinámicamente. Para objetos más grandes o aquellos que contienen punteros a memoria del montón, el patrón de constructor con malloc sigue siendo la mejor opción.
Desafío
FácilConstruyamos un módulo Temperature que cree lecturas de temperatura en la pila mediante una función de fábrica. A diferencia de los constructores basados en el montón de lecciones anteriores, este enfoque devuelve la estructura por valor: sin malloc, sin free, solo una asignación sencilla y eficiente en la pila.
Crearás tres archivos:
temperature.h: Declara una estructuraTemperaturecon dos miembros:double celsiusychar scale(para almacenar 'C' en Celsius). También declara dos funciones:create_temperature: recibe un valor double y devuelve una estructuraTemperaturepor valor (¡no un puntero!)temperature_to_fahrenheit: recibe unconst Temperature *y devuelve la temperatura equivalente en Fahrenheit como un double
TEMPERATURE_H.temperature.c: Implementa ambas funciones. Tu función de fábrica debe crear una variable localTemperature, inicializar sus campos (establecerscaleen'C') y devolverla. La fórmula de conversión es:fahrenheit = celsius * 9.0 / 5.0 + 32.0main.c: Usa tu función de fábrica para crear una lectura de temperatura y mostrar los valores tanto en Celsius como en Fahrenheit.
Recibirás una entrada: la temperatura en Celsius (como un double).
En tu archivo principal, usa create_temperature para crear una estructura Temperature con el valor proporcionado. Después imprime el valor original en Celsius y su equivalente en Fahrenheit.
Imprime la salida con este formato:
Celsius: {celsius}
Fahrenheit: {fahrenheit}Usa %.2f para ambos valores para mostrar dos decimales.
Por ejemplo, con una entrada de 25.0, la salida sería:
Celsius: 25.00
Fahrenheit: 77.00Observa lo limpio que es este enfoque. Recibes una estructura completamente inicializada sin preocuparte por la gestión de memoria. Cuando tu variable Temperature sale de ámbito, se limpia automáticamente.
Pruébalo tú mismo
#include <stdio.h>
#include "temperature.h"
int main() {
double celsius_input;
scanf("%lf", &celsius_input);
// TODO: Usa create_temperature para crear un struct Temperature
// TODO: Imprime el valor en Celsius usando el formato %.2f
// TODO: Usa temperature_to_fahrenheit para convertir e imprimir el valor en Fahrenheit
return 0;
}
Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.
Todas las lecciones de Programación Orientada a Objetos
1Fundamentos de programación modular
Archivos de cabeceraGuardas de inclusiónArchivos fuenteFunciones estáticasRepaso: Calculadora modular4Encapsulamiento
Concepto de punteros opacosDefinición de structs opacosGetters y SettersValidación en settersResumen: Caja secreta7Punteros a funciones
Declaración de punteros a funcionesLlamada a punteros a funcionesTypedef para punteros a funcionesPasar funciones como argumentosRepaso: Dispatch de calculadora10Contenedores genéricos
Repaso de punteros voidWrapper genéricoSwap genéricoComparación genéricaRepaso: Array genérico2Objetos y métodos
Structs como objetosEl puntero 'Self'Const CorrectnessPuntero vs. ValorMétodos auxiliaresResumen: Point Manager5Proyecto: Cuenta bancaria simple
Configuración del proyectoImplementación de la cuenta3Ciclo de vida de los objetos
Patrón ConstructorPatrón DestructorInicialización en StackCopia profundaResumen: String Wrapper6Herencia mediante composición
Incrustación de StructsLa regla del primer miembroAcceso a miembros padreUpcastingResumen: Jerarquía de formas9Proyecto: Dibujador de figuras
Descripción general del proyectoImplementación del círculoImplementación del rectánguloUso polimórficoContenedor de figurasPractica por tu cuenta: Compilador de C online