C语言指针参数赋值无效?为何结构体深拷贝可正常工作?
没错,你精准命中了问题的核心——C语言里所有参数传递都是值传递,哪怕是指针参数也不例外,这直接导致了两种赋值方式的天差地别。咱们掰开揉碎了说:
1. 为什么newPosition = oldPosition没用?
当你把指针作为参数传给函数时,函数拿到的是这个指针的副本——相当于复制了一份指针里存的地址值,和原指针是完全独立的两个变量。
你在函数里执行newPosition = oldPosition,只是把这个副本指针的指向改成了和oldPosition一样,但函数外面的那个原newPosition指针(也就是你定义的未初始化的那个)根本没被碰过。等函数执行完,副本被销毁,外面的newPosition还是原来那个未初始化的状态,指向的是随机内存地址,自然没法正常打印结构体内容。
2. 为什么*newPosition = *oldPosition能正常工作?
这时候你操作的是指针指向的内存区域:虽然newPosition是副本,但它存的地址和外面原指针是一样的(因为副本复制了原指针的地址值)。当你执行*newPosition = *oldPosition,本质是把oldPosition指向的结构体里的所有成员值,逐字节拷贝到newPosition指向的内存块里。
等函数结束后,外面的原指针指向的内存已经被正确填充了结构体数据,自然就能正常打印了。
补充:如果想修改指针本身的指向怎么办?
要是你的需求是让外面的指针直接指向oldPosition的内存(而不是拷贝内容),那你需要传递指针的指针(也就是Position **类型的参数)。比如:
void change_pointer(Position *oldPos, Position **newPosPtr) { // 修改的是原指针的指向,因为newPosPtr是原指针的地址 *newPosPtr = oldPos; }
调用的时候传&newPosition,这样函数里的修改才会影响到外面的原指针。不过你的场景是拷贝结构体内容,所以用解引用赋值的方式就足够了(这里要提一句:如果结构体里包含指针成员,这种赋值是浅拷贝,需要手动深拷贝;但如果是像Position这种纯值类型的结构体,这种赋值就是完整的内容拷贝)。
内容的提问来源于stack exchange,提问作者Marvin

