结构指针地址比较不起作用

时间:2018-04-07 02:41:18

标签: c pointers struct

如果findset内的条件没有给出正确的比较。它始终显示不相等。

我在哪里弄错了?

#include<stdio.h>

struct node {
  struct node *p;
  int rank;
};

void makeset(struct node x) {
  x.p = &x;
  x.rank = 0;
}

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 i;
    makeset(i);
    findset(i);
  }
}

3 个答案:

答案 0 :(得分:2)

void findset(struct node x)
 {
    if (x.p == &x)
    {

x是传入的副本... x始终是全新的,而&x不会匹配之前的任何地址。

请注意,这不仅仅是结构,而是所有值......

int i = 3;

void f( int j)
{
    // &j != &i
    // j == i
    // j and I have the same value, but different address
}

int main()
{
   f(i);
}

答案 1 :(得分:0)

正如另一张海报所说,你传递的是价值而不是实际的变量。这里的解决方案是指针功能如此强大的原因之一,您可以只传递要更改的实际变量的指针。例如:

include_directories

这对你来说应该更好

答案 2 :(得分:0)

您的代码无法运行。您忽略了C使用pass by value这一事实 - 这意味着当您将stuct node作为参数传递给函数时(例如void makeset(struct node x)),该函数会收到副本> struct具有与main()中原始结构相同的地址(且非常不同)。

因此,当您将结构传递给void findset(struct node x)时,if (x.p == &x)无法测试为真 - 因为不要求x的副本的地址被接收存储在void findset(struct node x)中的p与传递给x的{​​{1}}副本的地址相同。

你的第二个问题是你在:

中声明相同的结构void makeset(struct node x) 4次
i

您已在 for (int i = 0; i < nv; ++i) { struct node i; makeset(i); findset(i); } 循环中声明了变量i。当您声明for时,您没有创建struct node i;,而只是创建了struct node 0;, struct node 1; ... 4次。 (没有变量可以命名为数字或以C中的数字开头)struct node i;声明中的i 阴影 struct node的循环计数器声明。将警告i添加到编译字符串中,作为编译器警告的标准部分。

如果您希望能够单独填充节点,则需要声明一个-Wshadow数组。出于此示例的目的,您可以声明具有相同名称的结构4次 - 但这仅限于在struct node循环中使用(因为您的结构在中声明了 for循环块,它被循环的每次迭代都被销毁(堆栈内存被释放以供重用)。为了防止这种情况发生,你可以在进入循环之前声明一个4 for的数组,例如< / p>

struct node

接下来,为了让#include <stdio.h> #define NNODES 4 /* if you need a constant, define one */ ... int main (void) { struct node nodes[NNODES] = {{ .p = NULL }}; 能够将您传递的findset的原始地址作为参数进行比较,您必须传递地址 struct,而不是struct本身。这样,即使函数接收到指向struct node的指针,包含的值也是调用函数的结构的原始地址(此处为struct node

所以你需要将两个函数声明都改为:

main()

void makeset (struct node *x)

您还需要使用void findset (struct node *x) 运算符来访问成员而不是->运算符。

将所有部分放在一起,你可以做类似以下的事情:

'.'

注意> 每个#include <stdio.h> #define NNODES 4 /* if you need a constant, define one */ struct node { struct node *p; int rank; }; void makeset (struct node *x) { x->p = x; x->rank = 0; } void findset (struct node *x) { if (x->p == x) printf ("It worked bro\n"); } int main (void) { struct node nodes[NNODES] = {{ .p = NULL }}; for (int i = 0; i < NNODES; i++) { makeset (&nodes[i]); findset (&nodes[i]); } } 地址如何传递给struct node中的每个函数,例如main())< / p>

示例使用/输出

makeset (&nodes[i]);

现在有效......

如果你确实打算在你的$ ./bin/struct_ptr_addr It worked bro It worked bro It worked bro It worked bro 循环中声明一个stuct node来创建和销毁每次迭代,那么它对于单个结构也是一样的 - 你仍然需要将结构的地址传递给每个函数,例如

for

(输出相同)

希望您现在明白,当您将变量作为参数传递时,被调用函数会接收包含原始值的变量的副本。并且,如果要传递变量的地址,则必须将地址作为指针传递,以确保在被调用函数中可以使用该原始地址(并且在调用者中可以看到任何更改)。