【问题标题】:Why a structure is allowed to have "pointer to its own type" as member but not "(an array of the) structure type" itself?为什么允许结构具有“指向其自身类型的指针”作为成员而不是“(结构类型的数组)”本身?
【发布时间】:2016-09-20 23:02:03
【问题描述】:

当我尝试声明以下函数时

typedef struct TRIE_NODE
{
    char* word;
    struct TRIE_NODE node[26];
}TRIE_NODE;

我收到以下错误:

'struct TRIE_NODE'的定义直到结束'}'才完成

然而,如果我用一个指向 26 个节点的指针声明这个函数,它编译得很好。

typedef struct TRIE_NODE
{
    char* word;
    struct TRIE_NODE* node[26];
}TRIE_NODE;

我想,因为这不是一个实例,所以我不可能获得指向这 26 个数组中的第一个的指针,但如果这是问题所在,TRIE_NODE* node[26] 怎么不是问题?这个声明不是等同于TRIE_NODE node[1][26]吗?

【问题讨论】:

  • 您正在尝试定义的结构的结构内声明一个结构...说快 10 倍 ;)
  • 即使它确实有效,它不会是无限大的。由于每个 TRIE_NODE 包含 26 个 TRIE_NODES,每个 TRIE_NODES 包含 26 个 TRIE_NODE,依此类推...
  • “这个声明不等于TRIE_NODE node[1][26]吗?” - 不,不是。为什么?
  • “当我尝试声明以下函数时” - 哪个函数?没有功能!而且数组不是指针也不是数组!
  • 为什么投反对票?感觉这是一个很好的问题,它有一个很好的答案

标签: c struct declaration definition


【解决方案1】:

当我尝试声明以下函数时

等等!!那不是函数,那是typedef-ing 一个结构,一个用户定义的类型。


也就是说,在第一种情况下,

typedef struct TRIE_NODE
{
    char* word;
    struct TRIE_NODE node[26];  //array of type struct TRIE_NODE
}TRIE_NODE;

如果必须这样做,编译器需要知道struct TRIE_NODE 在定义之前的大小,这是不可能的。所以无效。

另一方面,

typedef struct TRIE_NODE
{
    char* word;
    struct TRIE_NODE* node[26];  //array of pointers (of type struct TRIE_NODE)
}TRIE_NODE; 

很好,因为您正在为结构分配(数组)指针,此时编译器不需要知道结构的实际大小。因此,编译器愉快地分配了指针,并且定义(构造)完全有效。

【讨论】:

  • 非常感谢,我现在看到了第一个声明的问题。但是,指针和数组不是几乎可以互换的吗? struct TRIE_NODE* node[26] 不应该等同于 struct TRIE_NODE[1][26]?我刚刚尝试过,我得到了与第一个声明相同的错误。我之所以这么说是因为我正在阅读“C prime plus”并且他经常提到两者对于编译器都是可以互换的,所以它们在编译时都变成了相同的指针声明。
  • @Selhar 不,一般来说,它们不一样,也不能互换。谷歌“数组不是指针”,阅读 C 常见问题。
  • 嗯,非常感谢,这有点令人沮丧,我刚刚花了很多时间阅读“C prime plus”,如果他错了,我想知道我还学错了什么。跨度>
  • @Selhar:永远不要认为数组是指针,也是数组!但是你关于“C prime plus”的结论是好的。遗憾的是,有很多关于 C 的废话。情况变得更糟,因为它实际上并没有那么复杂。但必须了解 Cs 的基本概念。
  • @Olaf 您一般会推荐哪些作者作为 CS 书籍?我打算在C之后学习C++,我的想法是阅读“C++ Primer plus”,因为我非常喜欢“C Primer plus”。
【解决方案2】:

要回答您自己的问题,请问:需要多少字节

struct TRIE_NODE node[26];

占用?事实上,您希望sizeof(struct TRIE_NODE) 是什么?

原因

struct TRIE_NODE *node[26];

有效的是我们知道sizeof(struct TRIE_NODE*) 的值。因为所有的结构体指针都具有相同的大小,我们可以分配一个由N个结构体指针组成的数组,无论它们的类型如何,即使没有完全定义。

指针和数组不是几乎可以互换的吗?

指针和数组的语法是相似的。您可以为指针下标,也可以添加到数组的地址。但他们定义不同的东西。基本上:数组保存数据,指针保存地址。

在 C 标准库的某些部分,您会发现这样定义的结构:

struct S {
    int len;
    char data[1];
};

您可能会问为什么不使用指针?

struct Z {
    int len;
    char *data;
};

答案:struct S 实际上比它似乎占用的 5 个左右字节大,并且数据部分紧随len 之后开始。在假定的 struct Z 示例中,data 不会开始数据;数据将在其他地方,无论data points

假设结构被适当地初始化,在这两种情况下data[0] 将寻址数组的第一个字节。它们在语法上相似。但是内存布局不同。在S 的情况下,该字节将非常接近(char*)&len + sizeof(len)。在Z 的情况下,它将位于data 指向的任何位置。

【讨论】:

  • 指针可能有不同的大小。 (但由于这个原因,所有指向结构类型的指针都具有相同的大小)。
  • 我的立场是正确的,谢谢。这一定是 指向其他类型的指针不需要具有相同的表示或对齐要求。 的意思。
【解决方案3】:

没有人提到这一点,但是如果允许结构具有自身的成员或数组(不是指针,而是常规成员或数组),那么结构将是递归的并且具有无限大小,因为该成员将具有更多成员在同一类型的内部,依此类推,直到无穷大。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-20
    • 1970-01-01
    • 2019-03-18
    • 1970-01-01
    • 2011-06-09
    • 1970-01-01
    相关资源
    最近更新 更多