Inicialização na Stack
Parte da seção Object Oriented Programming do Journey de C da Coddy — lição 14 de 61.
Nem todo objeto precisa residir na heap. Quando uma struct é pequena e tem um tempo de vida curto, alocá-la na stack é mais simples e rápido — sem malloc, sem free, sem risco de vazamentos de memória.
Em vez de retornar um ponteiro, uma função factory pode retornar a struct por valor. A struct inteira é copiada para o chamador:
typedef struct {
int x;
int y;
} Point;
Point create_point(int x, int y) {
Point p;
p.x = x;
p.y = y;
return p;
}
O chamador recebe uma cópia totalmente inicializada:
Point origin = create_point(0, 0);
Point cursor = create_point(100, 50);
printf("Cursor: (%d, %d)\n", cursor.x, cursor.y);
Sem ponteiros, nenhuma limpeza necessária. Quando origin e cursor saem de escopo, eles são destruídos automaticamente.
Esta abordagem funciona melhor para structs pequenas sem membros alocados dinamicamente. Para objetos maiores ou aqueles que contêm ponteiros para a memória heap, o padrão de construtor com malloc continua sendo a melhor escolha.
Desafio
FácilVamos construir um módulo Temperature que cria leituras de temperatura na pilha (stack) usando uma função de fábrica. Ao contrário dos construtores baseados em heap das lições anteriores, essa abordagem retorna a struct por valor — sem malloc, sem free, apenas uma alocação de pilha simples e eficiente.
Você criará três arquivos:
temperature.h: Declare uma structTemperaturecom dois membros:double celsiusechar scale(para armazenar 'C' para Celsius). Também declare duas funções:create_temperature— recebe um valor double e retorna uma structTemperaturepor valor (não um ponteiro!)temperature_to_fahrenheit— recebe umconst Temperature *e retorna a temperatura equivalente em Fahrenheit como um double
TEMPERATURE_H.temperature.c: Implemente ambas as funções. Sua função de fábrica deve criar uma variávelTemperaturelocal, inicializar seus campos (definirscalecomo'C') e retorná-la. A fórmula de conversão é:fahrenheit = celsius * 9.0 / 5.0 + 32.0main.c: Use sua função de fábrica para criar uma leitura de temperatura e exibir os valores em Celsius e Fahrenheit.
Você receberá uma entrada: a temperatura em Celsius (como um double).
No seu arquivo principal, use create_temperature para criar uma struct Temperature com o valor fornecido. Em seguida, imprima o valor original em Celsius e seu equivalente em Fahrenheit.
Imprima a saída neste formato:
Celsius: {celsius}
Fahrenheit: {fahrenheit}Use %.2f para ambos os valores para exibir duas casas decimais.
Por exemplo, com uma entrada de 25.0, a saída seria:
Celsius: 25.00
Fahrenheit: 77.00Observe como essa abordagem é limpa — você recebe uma struct totalmente inicializada sem preocupações com o gerenciamento de memória. Quando sua variável Temperature sai de escopo, ela é limpa automaticamente.
Folha de consulta
Funções de fábrica (factory functions) podem retornar structs por valor em vez de ponteiros. Isso aloca a struct na pilha (stack) — sem malloc, sem free e sem vazamentos de memória.
Exemplo de uma função de fábrica retornando por valor:
typedef struct {
int x;
int y;
} Point;
Point create_point(int x, int y) {
Point p;
p.x = x;
p.y = y;
return p;
}
Usando a função de fábrica:
Point origin = create_point(0, 0);
Point cursor = create_point(100, 50);
printf("Cursor: (%d, %d)\n", cursor.x, cursor.y);
A struct é copiada para quem a chamou e destruída automaticamente quando sai de escopo. Essa abordagem funciona melhor para structs pequenas sem membros alocados dinamicamente.
Experimente você mesmo
#include <stdio.h>
#include "temperature.h"
int main() {
double celsius_input;
scanf("%lf", &celsius_input);
// TODO: Use create_temperature para criar uma struct Temperature
// TODO: Imprima o valor Celsius usando o formato %.2f
// TODO: Use temperature_to_fahrenheit para converter e imprimir o valor Fahrenheit
return 0;
}
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Object Oriented Programming
1Fundamentos da Programação Modular
Arquivos de CabeçalhoInclude GuardsArquivos-FonteFunções EstáticasRecapitulação: Calculadora Modular4Encapsulamento
Conceito de Ponteiros OpacosDefinindo Structs OpacasGetters e SettersValidação em SettersRecapitulação: Caixa Secreta2Objetos e Métodos
Structs como ObjetosO Ponteiro 'Self'Const CorrectnessPonteiro vs ValorMétodos AuxiliaresRecapitulação: Point Manager5Projeto: Conta Bancária Simples
Configuração do ProjetoImplementação da Conta3Ciclo de Vida de Objetos
Padrão de ConstrutorPadrão de DestrutorInicialização na StackCópia ProfundaRecapitulação: String Wrapper6Herança via Composição
Incorporação de StructsA Regra do Primeiro MembroAcessando Membros PaiUpcastingRecapitulação: Hierarquia de Formas9Projeto: Desenhador de Formas
Visão Geral do ProjetoImplementação do Círculo