不完全类型和复杂声明

不完全类型是暂时没有完全定义好的类型,编译器不知道这种类型该占几个字节的存储空间,例如:

struct s;
union u;
char str[];

具有不完全类型的变量可以通过多次声明组合成一个完全类型,比如数组str声明两次:

char str[];
char str[10];

当编译器碰到第一个声明时,认为str是一个不完全类型,碰到第二个声明时str就组合成完全类型了,如果编译器处理到程序文件的末尾仍然无法把str组合成一个完全类型,就会报错。

有些情况下这么做有一定的理由,比如第一个声明是写在头文件里的,第二个声明写在.c文件里,这样如果要改数组长度,只改.c文件就行了,头文件可以不用改。

不完全的结构体类型有重要作用:

struct s {
struct t *pt;
};
struct t {
struct s *ps;
};

struct s和struct t各有一个指针成员指向另一种类型。编译器从前到后依次处理,当看到strucs { struct t* pt; };时,认为struct t是一个不完全类型, pt是一个指向不完全类型的指针,尽管如此,这个指针却是完全类型,因为不管什么指针都占4个字节存储空间,这一点很明确。然后编译器又看到struct t { struct s *ps; };,这时struct t有了完整的定义,就组合成一个完全型了, pt的类型就组合成一个指向完全类型的指针。由于struct s在前面有完整的定义,所以struct s *ps;也定义了一个指向完全类型的指针。

这样的类型定义是错误的:

struct s {
struct t ot;
};
struct t {
struct s os;
};

编译器看到struct s { struct t ot; };时,认为struct t是一个不完全类型,无法定义成员ot,因为不知道它该占几个字节。所以结构体中可以递归地定义指针成员,但不能递归地定义变量成员,你可以设想一下,假如允许递归地定义变量成员, struct s中有一个struct t, struct t中又有一个struct s, struct s又中有一个struct t,这就成了一个无穷递归的定义。

以上是两个结构体构成的递归定义,一个结构体也可以递归定义:

struct s {
char data[6];
struct s* next;
};

当编译器处理到第一行struct s {时,认为struct s是一个不完全类型,当处理到第三行struct s*next;时,认为next是一个指向不完全类型的指针,当处理到第四行};时, struct s成了一个完全类型, next也成了一个指向完全类型的指针。

转载于:https://www.cnblogs.com/xiaojianliu/articles/8735663.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值