C语言结构体中函数指针调用后未修改成员值的问题
问题分析与解决方案
你遇到的这个问题,核心原因是C语言的结构体传值调用机制。咱们来拆解一下:
当你调用start.incrementValue(start)时,你把整个start结构体作为参数传递给了函数incrementNodeValue。在C语言里,这种传参方式会创建一个原结构体的副本——函数内部操作的this只是原start的克隆体,不是同一个对象。所以你在函数里把this.value加1,修改的只是副本的值,原结构体start的value完全没被碰过,这就导致了函数内打印11,但外部输出还是10的矛盾结果。
修正方案:改用指针传递结构体
要解决这个问题,我们需要让函数直接操作原结构体的内存,而不是副本。具体要改这几个地方:
- 修改函数的参数类型:把函数参数从结构体值改成结构体指针,这样传递的是原结构体的地址
- 调整函数内的成员访问方式:用
->替代.来访问指针指向的结构体成员 - 更新结构体里的函数指针类型:让它匹配接受指针的函数签名
- 调用函数时传递结构体的地址:用
&取原结构体的地址传进去
下面是修正后的完整代码:
#include <stdio.h> struct node { int value; struct node * left; struct node * right; // 函数指针改为接受struct node*类型参数 void (*incrementValue)(struct node*); }; // 参数改为结构体指针 void incrementNodeValue(struct node *this){ // 用->访问指针指向的成员 this->value ++; printf("the value is now %d\n", this->value); } int main(){ struct node firstLeft = { 5, NULL, NULL, incrementNodeValue }; struct node firstRight = { 15, NULL, NULL, incrementNodeValue }; struct node start = { 10, &firstLeft, &firstRight, incrementNodeValue }; // 传递start的地址 start.incrementValue(&start); printf("%d\n", start.value); return 0; }
现在编译运行这段代码,输出就会变成:
the value is now 11 11
完全符合你的预期了。
补充说明
C语言里,除了指针和数组(数组会退化为指针),所有参数传递都是值传递——包括结构体、基本数据类型等。如果想在函数里修改原对象的内容,必须传递它的地址(指针),让函数直接操作原内存空间。
内容的提问来源于stack exchange,提问作者hexidian
相关产品推荐
相关产品推荐

