为何play函数中对结构体的修改在main函数中仍有效?
为什么play函数对结构体的修改在main函数中依然有效?
核心原因是你传递给play函数的是结构体的地址(指针),而非结构体的副本,所以函数内的修改直接作用在原结构体的内存空间上。
在C语言里,函数参数默认是「值传递」:如果直接传递变量(比如结构体本身),函数会创建一个该变量的临时副本,你在函数里修改的只是这个副本,原变量不会受到影响。但你这里的写法不一样:
- 在
main中调用play(&Test, hello, &data1)时,&Test是取结构体Test的内存地址,把这个地址传给了play函数的Data参数(struct Alpha *Data是指针类型)。 Data指针指向的就是main里Test结构体所在的那块内存,所以当你在play里执行Data->ptr_f = func_ptr和Data->a = test时,本质是直接通过地址访问并修改了Test结构体的成员,而非修改某个临时副本。
举个反例对比:如果play函数的参数写成struct Alpha Data(去掉指针),那此时传递的是Test的副本,你在play里修改Data的成员,main里的Test不会有任何变化——这才是你原本以为的「修改局限在函数作用域内」的情况。
你的代码运行结果也验证了这一点:play修改后的Test.ptr_f()能正常打印Hello,*(Test.a)也能输出4,说明原结构体的成员确实被修改了。
#include <stdio.h> #include <stdlib.h> struct Alpha{ void (*ptr_f)(void); int *a; }; void hello(void){ printf("Hello\n"); } void play(struct Alpha *Data, void (*func_ptr)(void), int *test){ Data->ptr_f = func_ptr; Data->a = test; } int main(void){ int data1 = 4; struct Alpha Test; play(&Test, hello, &data1); Test.ptr_f(); printf("*(Test.a) = %d\n", *(Test.a)); return 0; }
内容的提问来源于stack exchange,提问作者jey001
相关产品推荐
相关产品推荐

