Menu
Coddy logo textTech

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.

challenge icon

Desafio

Fácil

Vamos 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 struct Temperature com dois membros: double celsius e char scale (para armazenar 'C' para Celsius). Também declare duas funções:
    • create_temperature — recebe um valor double e retorna uma struct Temperature por valor (não um ponteiro!)
    • temperature_to_fahrenheit — recebe um const Temperature * e retorna a temperatura equivalente em Fahrenheit como um double
    Use guards de inclusão com o símbolo TEMPERATURE_H.
  • temperature.c: Implemente ambas as funções. Sua função de fábrica deve criar uma variável Temperature local, inicializar seus campos (definir scale como 'C') e retorná-la. A fórmula de conversão é: fahrenheit = celsius * 9.0 / 5.0 + 32.0
  • main.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.00

Observe 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;
}
quiz iconTeste seus conhecimentos

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