版权归原作者所有,如有侵权,请联系我们

[科普中国]-不完全类型

科学百科
原创
科学百科为用户提供权威科普内容,打造知识科普阵地
收藏

不完整类型是尚未指定其成员的结构或联合类型,尚未指定其维度的数组类型,或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]后面就没事了。

本词条内容贡献者为:

方正 - 副教授 - 江南大学