结构和联合
结构体基础
聚合类型
聚合类型:能够同时存储超过一个单独的数据,C语言提供两种聚合数据类型数组和结构。
数组和结构的区别:
- 数组是相同类型的数据的聚合,结构是不同类型数据的聚合。
- 因为数组的元素长度相同可以采用下标方式访问,结构成员的长度不同,只能通过名字访问,不能通过下标来访问。
- 数组名在表达式中使用时被当做一个指针,而结构体变量在表达式中使用时不能被当做一个指针。
结构体的声明
结构的通常形式
struct tag(可选)
{
member-list
}variable-list(可选);
基于以上形式,结构可以有如下几种声明:
//形式1
struct
{
int age;
char name[10];
} Person1, Person2;
//形式2
struct PersonT
{
int age;
char name[10];
} Person1;
struct PersonT Person2;
//形式3
struct PersonT
{
int age;
char name[10];
};
struct PersonT Person1, Person2;
- 在形式2和形式3种,使用结构标签可以在将来的声明中用struct tag 作为struct {内容...}的简写形式。
- 在第2种形式中,结构的声明和变量的定义混合在一起,使得代码可能不易阅读。
- 将结构的声明和变量的定义分开来写是一个更好的选择,如第3种形式所示。
注意:
struct
{
int a;
char b;
float c;
}x;
struct
{
int a;
char b;
float c;
}*y;
第一个声明创建了一个x变量,它包含了三个成员,一个整数,一个字符和一个浮点数。
第二个声明创建了指向一个结构类型的指针。
需要注意的是虽然两者结构体的成员是一致的,但是编译器将它们认为是不同的变量类型,所以下面的表达式是不合法的:
y = &x
typedef 创建新的结构类型
声明结构时可以使用的另一种良好技巧是用typedef创建一种新的类型,如:
typedef struct
{
int age;
char name[10];
}PersonT;
PersonT Person1, Person2;
此时,PersonT 是一种typedef定义的新的类型,而不再是结构标签。
注意:
struct
{
}NewVarT;
typedef struct
{
}NewTypeT;
二者表达的意思截然不同。前者声明了一个结构变量,而后者则声明了一种新的类型。
结构的成员
间接访问与直接访问
struct PersonT
{
int age;
char name[10];
};
struct PersonT Person1;
struct PersonT *pPerson;
直接访问
Person1.age; Person1.name[0]; //.和[]的优先级相同,结合顺序为从左到右,因此可以省略括号
间接访问
pPerson->age; pPerson->name[0]; //->和[]的优先级也相同
结构的自引用
结构的成员变量的类型不能是结构本身,但可以是指向自身结构的指针类型。例如:
struct SelfT
{
int a;
struct SelfT b;
}
struct SelfT
{
int a;
struct SelfT *b;
}
前者是非法的,结构体中包含自己的成员,这样一直重复永无止境。
而后者则是合法的。实际上,更加高级的数据结构,如链表和树,都是用这种技巧实现的。










