1、C提供两种类型的聚合数据类型,数组和结构,数组是相同类型元素的集合,而使用结构能够把不同类型的值存储在一起;数组是通过下标引用或指针间接访问元素的,而结构可以通过成员名字来访问的,当然结构也可以通过指针来进行间接访问的;
2、不同的结构声明即使它们的成员列表相同也被认为是不同的类型;
struct {
int a;
char b;
float c;
}x;
struct{
int a;
char b;
float c;
}y[20], *z;
对于以上的描述,这两个声明被编译器当作两种截然不同的类型,即使它们的成员列表完全相同,因此变量y和z的类型和x的类型不同,因此下面这条语句不成立:
z = &x;
3、如果采用以下的声明方式,那么将不一样
struct SIMPLE
{
int a;
char b;
float c;
} ;
struct SIMPLE x;
struct SIMPLE y[20], z;
这样x,y,z都是同一类型的结构变量;
标签允许多个声明使用同一个成员列表,并且创建同一种类型的结构;
4、采用typedef也可以声明同一种类型的变量,如下
typedef struct
{
int a;
char b;
float c;
} Simple;
Simple x;
Simple y[20], z;
同样 x,y,z都是同一类型的结构变量;
5、下标引用与点操作符具有相同的优先级,它们的结合性都是从左到右的,但是点操作符的优先级高于间接访问操作符;
6、结构自引用的陷阱:
typedef struct{
int a;
SELF_REF3 *b;
int c;
}SELF_REF3;
这个声明的目的是为这个结构创建类型名SELF_REF3,但是类型名直到声明的末尾才定义,因此在结构声明的内部它尚未定义;
以下是解决方案:
typedef struct SELF_REF3_TAG{
int a;
struct SELF_REF3_TAG *b;
int c;
}SELF_REF3;
7、作为函数参数的结构,如果采用传递结构,则需要复制整个结构的长度到堆栈中,再丢弃,这样的效率比较低,而传递结构指针比结构小得多,因此能够提高效率,但是向函数传递结构指针也有不足之处,就是可以对调用的变量进行修改(可以用const声明结构指针来防止);
8、联合的声明与结构类似,联合的所有成员引用的是内存中相同的位置,可用于某一时刻,只有一个字段被使用,提高效率;
9、如果联合的各个成员具有不同的长度,联合的长度就是它最长成员的长度;
10、联合变量可以被初始化,但是这个初始值必须是联合第一个成员的类型,而且它必须位于一对花括号里面;
例如:(把x.a初始化为5)
union{
int a;
float b;
char c[4];
}x = {5};
我们不能把这个类量初始化为一个浮点值或字符值,如果给出的初始值是任何其他类型,它就会转换为一个整数赋给x.a