C语言 结构声明不充分?

sczxawaw  于 2023-02-21  发布在  其他
关注(0)|答案(3)|浏览(122)

具有以下C代码:

struct Point2_s;
struct Point1_s{
  int x;
  int y;
  Point2_s P2;
} Point1;

struct Point2_s{
  int x;
  int y;
} ;

int main() {
    ...
    return 0;
}

我收到一个错误:
未知类型名称"Point2_s"
谁能解释一下为什么它不起作用?为什么在定义Point1_s成员P2时,结构Point2_s声明不充分?

rkue9o1l

rkue9o1l1#

在这条线上

struct Point2_s;

声明了不完整的结构说明符struct Point2_s
在本声明中

struct Point1_s{
  int x;
  int y;
  Point2_s P2;
} Point1;

使用了未知名称Point2_s。它与struct Point2_s不同。
但即使你会写

struct Point1_s{
  int x;
  int y;
  struct Point2_s P2;
} Point1;

然而,你不能在数据成员声明中使用不完整的类型。
来自C标准(6.7.2.1结构和联合说明符)
3结构或联合体不应包含不完整或函数类型的成员(因此,结构不应包含自身的示例,但可以包含指向自身示例的指针),除非具有多个命名成员的结构的最后一个成员可能具有不完整数组类型;这样的结构(以及可能递归地包含是这样的结构的成员的任何并集)不应当是结构的成员或数组的元素。
相反你需要写

struct Point2_s{
  int x;
  int y;
} ;

struct Point1_s{
  int x;
  int y;
  struct Point2_s P2;
} Point1;

或者你可以写

typedef struct Point2_s{
  int x;
  int y;
} Point2_s;

struct Point1_s{
  int x;
  int y;
  Point2_s P2;
} Point1;

在本例中,名称Point2_s是类型说明符struct Point2_s的别名。
另一方面,正如在其他答案中指出的,你可以使用指向不完整类型的指针,因为指针本身总是完整类型。

struct Point2_s;
struct Point1_s{
  int x;
  int y;
  struct Point2_s *P2;
} Point1;
eqoofvh9

eqoofvh92#

forward声明只能用于声明指向forward声明的结构体的指针,但它不知道该结构体有多大,所以不能直接使用该类型(它怎么知道要为P2成员保留多少空间?)
只需颠倒声明的顺序:

struct Point2_s{
  int x;
  int y;
};

struct Point1_s{
  int x;
  int y;
  struct Point2_s P2;  // You didn't typedef, so by the C standard, you need struct to declare the member
} Point1;

或者你需要使用指针

struct Point2_s;
struct Point1_s{
  int x;
  int y;
  struct Point2_s *P2; // Pointer, again adding struct; P2 will need to be allocated separately, e.g. by malloc
} Point1;

struct Point2_s{
  int x;
  int y;
};
brqmpdu1

brqmpdu13#

正向声明在这种情况下不起作用(从缺失的struct中抽象),因为编译器需要知道成员P2的大小。您需要在使用它的声明之前**声明它。

struct Point2_s{
  int x;
  int y;
} ;

struct Point1_s{
  int x;
  int y;
  struct Point2_s P2;
} Point1;

前向声明仅对指针有效:

struct Point2_s;

struct Point1_s{
  int x;
  int y;
  struct Point2_s *P2;
} Point1;

struct Point2_s{
  int x;
  int y;
} ;

相关问题