结构与联合

107 阅读2分钟
1.结构声明

在声明结构时,必须列出它包含的所有成员,这个列表包括每个成员的类型与名字。

struct tag {member-list}variable-list;

其中tag,member-list,variable-list至少需要出现两个,举几个例子。

struct {
	int a;
	char c;
	float f;
}x;

这里声明创建了一个名叫x的变量,它包括三个成员:一个整数,一个字符和一个浮点数

struct simple{
	int a;
	char b;
	float c;
};

这里的声明把标签simple和这个成员列表类型在一起,该声明并没有提供变量列表,所以它们并没有创建任何变量。那么怎么创建结构体变量呢?

struct simple x;
struct simple y[20],*z;

声明结构时可以使用另一种良好技巧是用typedef创建一种新的类型,如下面的例子所示。

typedef struct {
	int a;
	char b;
	float c;
}Simple;
```c
这个技巧和声明一个结构体标签的效果是几乎相同的,区别在于simple现在是个类型名而不是一个结构标签,所以后续声明可能像下面这个样子。
```c
Simple x;
Simple y[20],*z;

如果你想在多个源文件中使用同一种类型的结构,应该把标签声明或者typedef的形式放在一个头文件中,当源文件需要这个声明的时候可以使用#include指令把那个头文件包含起来。

结构体的自引用

在一个结构体中内部包含一个类型的结构是否是合法的呢?这里举一个例子,可以说明这一点。

struct simple{
	int a;
	struct simple b;
	int c;
};

其实这种类型的自引用是违法的,因为成员b是另一个完整的结构,其内部还包含着自己的成员b,这两个成员都是完整的结构,他还包含自己的成员b,这样子会无休止的重复下去,就像一个永远不会停止的递归程序。但是下面的声明确实合法的。

struct simple{
	int a;
	struct simple*b;
	int c;
};

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

警示:

typedef struct {
	int a;
	simple3 *b;
	int c
}simple3;

这里创建失败了,类型名是直到声明的末尾才定义的,所以在结构声明内部他没有定义。 解决方法是定义一个结构标签来声明b,如下图所示:

typedef struct simple3{
	int a;
	struct simple3 *b;
	int c;
}simple4;