不完整类型是尚未指定其成员的结构或联合类型,尚未指定其维度的数组类型,或void类型(无法完成void类型)。 这种类型可能无法实例化(其大小未知),也不能访问其成员(它们也是未知的); 但是,可以使用派生的指针类型(但不能解除引用)。
介绍不完全类型指“函数之外、类型的大小不能被确定的类型”,只能以有限方式使用。不能定义该类型的对象。不完全类型只能用于定义指向该类型的指针及引用1,或者用于声明使用该类型作为形参类型或者返回值类型。
C的类型分为:
对象类型(char、int、数组、指针、结构体等)
函数类型
不完全类型
结构体的声明就是一个不完全类型的典型例子。
struct Woman_tag;struct Man_tag {....struct Woman_tag *wife;....};struct Woman_tag {....int age;....};代码释例它们通常用作指针,作为前向或外部声明。 例如,代码可以声明一个不完整的类型,如下所示:
struct thing *pt;这将pt声明为指向struct thing和不完整类型struct的指针。 数据指针始终具有相同的字节宽度,无论它们指向什么,因此该语句本身有效(只要pt未被解除引用)。 不完整类型可以在稍后的同一范围内通过重新声明来完成:
struct thing { int num;}; /* thing struct type is now completed */不完整的类型用于实现递归结构; 类型声明的正文可以推迟到翻译单位的后面:
typedef struct Bert Bert;typedef struct Wilma Wilma;struct Bert { Wilma *wilma;};struct Wilma { Bert *bert;};不完整类型也用于数据隐藏; 不完整类型在头文件中定义,而主体仅在相关源文件中定义。
C语言不完全类型不完全类型也就是不知道变量的所有的类型信息。比如可以声明一个数组,但是不给出该数组的长度;声明一个指针,但是不给出该指针的类型;声明一个结构体类型,但是不给出完整的结构体定义,只说它是一个结构体。但是最终你必须得给出完整的类型信息。要不然编译会报错的。编译器在编译某个单元时,如果遇到一个不完全类型的定义的类型或变量(假设它叫p),它会把这当作正常现象,然后继续编译该单元,如果在本单元内找不到p完整的类型信息,它就去其它编译单元找。如果把整个编译过程分为编译、链接两个过程。在编译阶段遇到不完全类型是正常的,但是在链接过程中,所有的不完全类型必须存在对应的完整类型信息,否则报错。
举个例子,下面的代码先声明了一个不完全类型的变量字符数组str,没有给出它的长度信息。然后再定义了一次str数组,这次给出的长度信息。
char str[];//不完全类型定义char str[10];//终于遇到了str数组的完整类型信息,编译器松了一口气注意:不完全类型定义不适合局部变量,如果把上面两行代码放在一个函数体中,会出现符号重定义错误。
不完全类型由于不包含具体的类型信息,所以不能通过sizeof来获得其大小。(编译器君的旁边:我连它的完整类型都不知道,我怎么告诉你它的大小。)下面的代码不能编译通过。它会报错 error: invalid application of `sizeof' to an incomplete type 不能对不完全类型使用sizeof。
#include char str[];int n =sizeof(str);char str[10]; int main(){ printf("%d ",n); return 0;}如果把int n = sizeof(str)放到charstr[10]后面就没事了。
本词条内容贡献者为:
方正 - 副教授 - 江南大学