在实际编程中,常常会遇到这样的问题:定义一个数据类型,而这个数据类型又包含此数据类型的变量。面对这个问题,通常的解决方法是把数据类型的变量定义为指针形式。例如二叉树结点的定义:
struct Node{//二叉树节点
int data;//节点数据
struct Node* leftChild;//节点左孩子
struct Node* rightChild;//节点右孩子
}
上面的二叉树节点定义是正确的,可以编译通过。但是如果定义为如下对象形式,则无法编译通过:
struct Node{//二叉树节点
int data;//节点数据
struct Node leftChild;//节点左孩子
struct Node rightChild;//节点右孩子
}
为什么采用指针形式可以通过编译,而采用上述的对象形式却不能编译通过呢?
原因在于C/C++采用的是静态编译模型。程序要正确地编译,编译器需要知道一个结构占用的空间有多大,除此之外,这类错误也成为结构的递归定义错误。
那为什么使用指针形式就可以了呢?
我们知道,指针的大小跟机器的字长有关,不管是什么类型,编译后指针的大小总是能够确定的,所以如果在32位机器上,指针的大小为4字节,则采用指针的形式,struct Node的大小在编译后就可以确定,为sizeof(int) + 4 + 4。而对于对象形式的struct Node定义,其长度在编译后是没有办法确定的。
所以,在编译过程中,要禁止类和结构的递归定义,以防产生奇怪的编译错误。