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;