C语言如何正确更新结构体副本?按钮hovered成员更新失效问题
解决思路
你的判断完全正确:scgui_draw_button采用传值调用,函数内的self是原结构体的副本,所有对self的修改(包括hovered)都只会作用在副本上,原结构体不会有任何变化。以下是几种不用大规模重写代码的解决方案:
方案一:返回修改后的结构体(侵入性最小)
这个方案几乎不用改动函数内部代码,只需要调整函数返回值和调用方式:
- 修改头文件函数声明:把返回类型从
void改为struct SCGUI_Button
// button.h struct SCGUI_Button scgui_draw_button(struct SCGUI_Button button);
- 修改函数实现:在函数末尾返回修改后的副本
// button.c struct SCGUI_Button scgui_draw_button(struct SCGUI_Button self) { // 原有的样式判断、绘制代码完全不动 return self; // 最后返回修改后的结构体 }
- 调用时重新赋值:每次调用后把返回值覆盖原变量
// 原调用:scgui_draw_button(button); button = scgui_draw_button(button);
这种方式的优势是完全保留原有逻辑,仅需3处小改动,就能让hovered的修改生效。
方案二:改用指针参数(一劳永逸,改动量极小)
你担心改指针会破坏现有代码,但实际改动远没有想象中麻烦——编辑器的全局替换功能可以一键完成大部分修改:
- 修改头文件函数声明:参数改为指针类型
// button.h void scgui_draw_button(struct SCGUI_Button *self);
函数内批量替换:把所有
self.替换成self->(比如VS Code里用Ctrl+Shift+F全局替换)- 示例:
self.hovered = true;→self->hovered = true; - 示例:
self.style.background_color.red→self->style.background_color.red
- 示例:
调整依赖函数的调用:如果
scgui_set_style/set_default_styles接收的是结构体副本,传*self即可,不用修改这些函数的实现
// 原调用:scgui_set_style(self); scgui_set_style(*self);
- 调用时传地址:
scgui_draw_button(&button);
这个方案彻底解决了传值导致的修改无效问题,后续扩展按钮功能也更方便,实际改动仅需几分钟就能完成。
内容的提问来源于stack exchange,提问作者Scollier
相关产品推荐
相关产品推荐

