You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

结构体指针地址比较失效,findset中if条件始终不相等求错因

问题分析与解决

你的问题核心是函数参数的传值机制导致的,下面一步步拆解问题:

为什么地址比较不生效?

  1. 值传递创建了独立副本:makeset(struct node x) 和 findset(struct node x) 都是以值传递的方式接收结构体参数。这意味着每次调用函数时,都会生成一个原结构体的局部副本,函数内的所有修改都只作用于这个副本,和main里的原结构体完全无关。
    • 比如在makeset里,你写x.p = &x,这里的&x是函数内局部副本的地址,不是main里那个struct node i的地址。当makeset执行完毕,这个副本就会被销毁,main里的i.p根本没被初始化,还是个垃圾值。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 08:39:40