结构体指针地址比较失效,findset中if条件始终不相等求错因
问题分析与解决
你的问题核心是函数参数的传值机制导致的,下面一步步拆解问题:
为什么地址比较不生效?
- 值传递创建了独立副本:
makeset(struct node x)和findset(struct node x)都是以值传递的方式接收结构体参数。这意味着每次调用函数时,都会生成一个原结构体的局部副本,函数内的所有修改都只作用于这个副本,和main里的原结构体完全无关。- 比如在
makeset里,你写x.p = &x,这里的&x是函数内局部副本的地址,不是main里那个struct node i的地址。当makeset执行完毕,这个副本就会被销毁,main里的i.p根本没被初始化,还是个垃圾值。
- 比如在
- findset里的比较逻辑无效:调用
findset(i)时,又会创建一个新的副本,此时副本的p是未初始化的随机值,和副本自身的地址&x自然不相等,所以永远不会打印成功提示。
修正方案:改用指针传递
要让函数直接操作原结构体而非副本,我们需要把函数参数改成结构体指针,直接操作原对象的内存地址:
#include<stdio.h> struct node { struct node *p; int rank; }; // 接收结构体指针,直接操作原对象 void makeset(struct node *x) { x->p = x; // 让p指向结构体自身(指针x就是原结构体的地址) x->rank = 0; } // 用指针访问成员,比较p和结构体自身的地址 void findset(struct node *x) { if (x->p == x) { printf("It worked bro\n"); } } int main() { int nv, ne; nv = 4; ne = 5; for (int i = 0; i < nv; ++i) { struct node node_i; // 变量名避免和循环变量i重名,提升可读性 makeset(&node_i); // 传入原结构体的内存地址 findset(&node_i); // 同样传入地址操作原对象 } }
关键修改点说明
- 将函数参数从
struct node x改为struct node *x,让函数直接拿到原结构体的内存地址,操作的是原对象而非副本。 - 在
makeset里,用x->p = x代替x.p = &x:指针x本身就是原结构体的地址,直接赋值给p即可让结构体指向自身。 - main里的变量名改为
node_i,避免和循环变量i重名(语法允许但可读性差),调用函数时传入&node_i获取原结构体的地址。
修改后,每次循环的结构体都会被正确初始化,findset里的条件判断能正常生效,会打印4次"It worked bro"。
内容的提问来源于stack exchange,提问作者p gokul
相关产品推荐
相关产品推荐

