C: error: incompatible pointer types, remove & - a pointer to store its own address

C: error: incompatible pointer types, remove & - a pointer to store its own address

初学者问题:我想我有点理解指针(int *p,x = 1,p = &x),但显然不理解“->”和结构。

typedef struct node
{
    bool is_word;

    struct node* children[27];
}
node;

node* root = calloc(1, sizeof(node));

printf("address:%p\n", &root->children[1]);
printf("content%p\n", root->children[1]);

printf("\n");
root->children[1] = &root->children[1];

printf("address:%p\n", &root->children[1]);
printf("content%p\n", root->children[1]);

很简单,我有一个指针,我想让它存放自己的地址。但它给了我:

error: incompatible pointer types assigning to 'struct node *'
      from 'struct node **'; remove & [-Werror,-Wincompatible-pointer-types]
        root->children[1] = &root->children[1];
                          ^ ~~~~~~~~~~~~~~~~~~

我尝试了一些组合,none 目前有效。我错过了什么?

改变
root->children[1] = &root->children[1];

root->children[1] = root->children[1];

它不起作用的原因与错误消息中所述完全相同 -

root->children[i]是node*类型,也就是说root->children[i]本身就是一个内存地址,指向struct node.

类型的数据

话虽这么说,为什么要存储内存地址?
考虑以下示例:您是一个指向类型 int:
的指针 int *ptr
现在,如果你想要 ptr 的内存地址,你可以 printf("%p", ptr)
如果你想要数据,只需 printf("%d", *ptr)

根据您对 Ishay 的回答的评论,您想要实现 content == address...

很容易得到它,但我想警告你为什么不应该这样做。如果 node->children[1] 指向它自己的地址,取消引用指针是未定义的行为,因为那里是 而不是 一个 node 而是一个 node *。这意味着一旦你有了它,任何对 *(node->children[1]) 的访问,无论是读还是写,甚至使用 node->children[1]->... 语法,根据严格的别名规则(搜索 SO for C strict aliasing rule 以获得更多详细信息)。

一旦你被警告过,C语言对程序员是非常有信心的,甚至允许你做无意义的事情:

root->children[1] = (void *) &root->children[1]; /* or root->children[1] = (node *) &root->children[1]; */

printf("address:%p\n", &root->children[1]);
printf("content%p\n", root->children[1]);

会显示你想要的。这是因为总是允许将指针复制到 (void *),同样,void * 可以复制到任何其他指针。 C 标准要求(假设没有对齐问题,并且在您的示例中不应该存在)那些指针赋值是完美定义的,并且:

node ** p = (node **) root->children[1];

也已定义,p 必须指向 root->children[1]。换句话说,您可以将指向一种类型的指针转​​换为指向另一种类型的指针,然后将其转换回来将为您提供初始值,但您绝不能取消引用不正确指针。