繁体   English   中英

为什么前向声明结构不起作用?

[英]Why does forward declaration of struct not work?

我用C语言编写了一个小代码,其中定义了两个结构类型,两个结构类型在其定义中具有彼此的成员。 情况1:如果在struct bar之前定义了struct foo,则代码将按预期进行编译。 情况2:如果在struct bar之后定义了struct foo,它将无法编译,这也是预期的,因为无法知道struct foo变量的内存要求。 但是我期望如果在情况2中使用struct foo的前向声明,它将编译。但是它不起作用。 我想念什么?

#include<stdio.h>
#include<stdlib.h>

struct foo; // forward declaration

struct bar
{
  int a;
  struct bar *next;
  struct foo ch;
};

struct foo
{
  struct bar *n;
  struct foo *nx;
};


int main()
{
  struct bar p;
  return(0);
}

前向声明仅通知编译器有一个称为foo它对大小没有任何说明。 您可以使用foo*因为这是一个已知大小的指针,但不能使用foo本身,因为它的大小为unknwon,因此编译器不知道bar的内存布局应如何。

而且编译器只对您的文档进行一次遍历。 因此它不知道前面定义的结构。

如果结构类型X仅在结构声明或其函数中作为指针类型出现,并且头文件中的代码未尝试访问X的任何成员变量,则不应#include Xh,而应使其不完整在首次使用X之前先声明X(也称为“转发”声明)。以下是一个示例,其中结构类型Thing通过指针引用X:

struct X;  /* incomplete ("forward") declaration */

struct Thing {
  int i;
  struct X* x_ptr;
};

编译器很乐意接受包含指向不完全已知的结构类型的指针的代码,这基本上是因为指针始终具有相同的大小和特征,无论它们指向什么。 通常,只有.c文件中的代码需要访问X的成员(或大小),因此.c文件将#include“ Xh”。 这是封装模块并将其与其他模块解耦的强大技术。

也就是说,如果您的代码类似于:

#include<stdio.h>
#include<stdlib.h>

struct foo; // forward declaration

struct bar
{
  int a;
  struct bar *next;
  struct foo *ch;       /* MODIFIED LINE */
};

struct foo
{
  struct bar *n;
  struct foo *nx;
};


int main()
{
  struct bar p;
  return(0);
}

但是在您的情况下,struct bar具有类型为foo的“ element”。 因此,它将给错误字段具有不完整的类型。

另外,您也可以参考以下代码段(可以正常使用):

#include<stdio.h>
#include<stdlib.h>

struct bar
{
  int a;
  struct aabar *next;  /* MODIFIED LINE - aabar never declared */
  struct foo *ch;
};

struct foo
{
  struct bar *n;
  struct foo *nx;
};

int main()
{
  struct bar p;
  return(0);
}

声明也不能让编译器知道如何分配内存。

在您的struct foo ,元素nx是一个指针,因此定义struct foo不需要内存大小。 但是,在struct bar ,元素ch不是指针,因此定义struct bar需要知道struct foo的大小。 前向声明不指定内存大小,而是定义。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM