Menu
CoddyTech

栈上初始化

本课属于 Coddy C 学习旅程的“面向对象编程”单元。第 14 课,共 61 课。

并非每个对象都需要放在堆上。当结构体很小且生命周期很短时,在栈上分配它更简单、更快:不需要 malloc,不需要 free,也没有内存泄漏的风险。

工厂函数也可以按值返回结构体,而不是返回指针。整个结构体都会被复制到调用方:

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

Point create_point(int x, int y) {
    Point p;
    p.x = x;
    p.y = y;
    return p;
}

调用者会收到一个完全初始化的副本:

Point origin = create_point(0, 0);
Point cursor = create_point(100, 50);
printf("Cursor: (%d, %d)\n", cursor.x, cursor.y);

没有指针,也不需要清理。当 origin 和 cursor 超出作用域时,它们会自动销毁。

这种方法最适合不含动态分配成员的小型结构体。对于较大的对象或包含指向堆内存的指针的对象,使用 malloc 的构造函数模式仍然是更好的选择。

challenge icon

挑战

简单

让我们使用工厂函数构建一个 Temperature 模块,在栈上创建温度读数。与之前课程中基于堆的构造函数不同,这种方式按值返回结构体:不需要 malloc,不需要 free,只需简单高效地在栈上分配。

你需要创建三个文件:

  • temperature.h:声明一个 Temperature 结构体,包含两个成员:double celsius 和 char scale(用于存储摄氏温度标记 'C')。另外,还要声明两个函数:
    • create_temperature:接收一个 double 值,并按值返回一个 Temperature 结构体(不是指针!)
    • temperature_to_fahrenheit:接收一个 const Temperature *,并以 double 类型返回对应的华氏温度
    使用符号 TEMPERATURE_H 设置包含保护。
  • temperature.c:实现这两个函数。工厂函数应创建一个局部 Temperature 变量,初始化它的字段(将 scale 设置为 'C'),并返回该变量。转换公式为:fahrenheit = celsius * 9.0 / 5.0 + 32.0
  • main.c:使用工厂函数创建温度读数,并显示摄氏温度和华氏温度。

你会收到一个输入:摄氏温度(double 类型)。

在主文件中,使用 create_temperature,根据给定值创建一个 Temperature 结构体。然后打印原始摄氏温度值及其对应的华氏温度值。

请按以下格式输出:

Celsius: {celsius}
Fahrenheit: {fahrenheit}

两个值都使用 %.2f,显示两位小数。

例如,输入 25.0 时,输出为:

Celsius: 25.00
Fahrenheit: 77.00

请注意,这种方式非常简洁。你会得到一个完全初始化的结构体,无需担心内存管理。当 Temperature 变量超出作用域时,它会自动清理。

亲手试试

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

int main() {
    double celsius_input;
    scanf("%lf", &celsius_input);
    
    // TODO: 使用 create_temperature 创建一个 Temperature 结构体
    
    // TODO: 使用 %.2f 格式打印摄氏温度值
    
    // TODO: 使用 temperature_to_fahrenheit 转换并打印华氏温度值
    
    return 0;
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

面向对象编程中的所有课

自己练习: C 在线编译器