Pointers on C——10 Structures and Unions.5

来源:互联网 发布:我知主掌握明天歌谱 编辑:程序博客网 时间:2024/05/17 22:04

10.1.5 Self-Referential Structures

结构的自引用

Is it legal for a structure to contain a member that is the same type as the structure?Here is an example to illustrate this idea.

在一个结构内部包含一个类型为该结构本身的成员是否合法呢?这里有一个例子,可以说明这个想法。


struct SELF_REF1 {

int a;

struct SELF_REF1 b;

int c;

};


This type of self reference is not legal, because the member b is another complete structure that will contain its own member b. This second member is yet another complete structure and contains its own member b, and so forth, forever. The problem is somewhat like a recursive program that never stops recursing. But the following declaration is legal. Can you see the difference?

这种类型的自引用是非法的,因为成员b 是另一个完整的结构,其内部还将包含它自己的成员b 。这第2 个成员又是另一个完整的结构,它还将包括它自己的成员b 。这样重复下去永无止境。这有点像永远不会终止的递归程序。但下面这个声明却是合法的,你能看出其中的区别吗?


struct SELF_REF2 {

int a;

struct SELF_REF2 *b;

int c;

};


The difference between this declaration and the previous one is that b is now a pointer rather than a structure. The compiler knows the size of a pointer to a structure even before the size of the structure has been determined, so this self reference is legal.

这个声明和前面那个声明的区别在于b 现在是一个指针而不是结构。编译器在结构的长度确定之前就已经知道指针的长度,所以这种类型的自引用是合法的。


If the idea of a structure containing a pointer to itself seems strange, keep in mind that it will actually be pointing to a different structure of the same type. More advanced data structures, such as linked lists and trees, are implemented with this technique. Each structure points to the next element on the list or down this branch of a tree.

如果你觉得一个结构内部包含一个指向该结构本身的指针有些奇怪,请记住它事实上所指向的是同一种类型的不同结构。更加高级的数据结构,如链表和树,都是用这种技巧实现的。每个结构指向链表的下一个元素或树的下一个分枝。


Watch out for this trap:

警惕下面这个陷阱:


typedef struct {

int a;

SELF_REF3 *b;

int c;

} SELF_REF3;


The intent of this declaration is to create SELF_REF3 as the type name for this structure. It fails, however. The type name SELFT_REF3 only becomes defined at the end of the declaration, so it is undefined inside of the declaration.

这个声明的目的是为这个结构创建类型名SELF_REF3。但是,它失败了。类型名直到声明的末尾才定义,所以在结构声明的内部它尚未定义。


The solution is to define a structure tag to use in declaring b, as shown next.

解决方案是定义一个结构标签来声明b ,如下所示:


typedef struct SELF_REF3_TAG {

int a;

struct SELF_REF3_TAG *b;

int c;

} SELF_REF3;


10.1.6 Incomplete Declarations

Occasionally you will have to declare structures that are mutually dependent, that is,each contains one or more members of the other type. As with self referential structures, at least one of the structures must refer to the other only through pointers.

The problem is in the declaration: if each structure refers to the otherʹs structure tag,which one is declared first?

偶尔,你必须声明一些相互之间存在依赖的结构。也就是说,其中一个结构包含了另一个结构的一个或多个成员。和自引用结构一样,至少有一个结构必须在另一个结构内部以指针的形式存在。

问题在于声明部分:如果每个结构都引用了其他结构的标签,哪个结构应该首先声明呢?


The solution to this problem is the incomplete declaration, which declares an identifier to be a structure tag. We can then use the tag in declarations where the size of the structure is not needed, such as declaring pointers to it. A subsequent declaration associates a member list with the tag.

这个问题的解决方案是使用不完整声明(incomplete declaration),它声明一个作为结构标签的标识符。然后,我们可以把这个标签用在不需要知道这个结构的长度的声明中,如声明指向这个结构的指针。接下来的声明把这个标签与成员列表联系在一起。


Consider this example, in which two different structure types each contain a pointer to the other.

考虑下面这个例子,两个不同类型的结构内部都有一个指向另一个结构的指针。


struct B;

struct A {

struct B *partner;

/* other declarations */

};

struct B{

struct A *partner;

/* other declarations */

};


The incomplete declaration of the tag is needed in die member list of A. Once has been declared, the member list for can be declared.

在A 的成员列表中需要标签B 的不完整的声明。一旦A 被声明之后, B 的成员列表也可以被声明。


10.1.7 Initializing Structures

Structures can be initialized in much the same way as arrays. A comma‐separated initializer list enclosed in braces is used to specify the values for the structure members. The values are written in the order given in the member list. Missing values cause the remaining members to get default initialization.

结构的初始化方式和数组的初始化很相似。一个位于一对花括号内部、由逗号分隔的初始值列表可用于结构各个成员的初始化。这些值根据结构成员列表的顺序写出。如果初始列表的值不够,剩余的结构成员将使用缺省值进行初始化。


Structures containing array or structure members are initialized similar to multidimensional arrays. A complete initializer list for the aggregate member is nested within the initializer list for the structure. Here is an example:

结构中如果包含数组或结构成员,其初始化方式类似于多维数组的初始化。一个完整的聚合类型成员的初始值列表可以嵌套于结构的初始值列表内部。这里有一个例子:


struct INIT_EX {

int a;

short b[10];

Simple c;

} x = {

10,

{ 1, 2, 3, 4, 5 },

{ 25, 'x', 1.9 }

};

上一章 Pointers on C——10 Structures and Unions.4