结构
1.结构声明
struct tag{ member-list } variable-list;
struct {
int a;
char b;
} x;
struct {
int a;
char b;
} y[20], *x;
/*x为变量, y为数组,含有20个结构, z为指针*/
/*使用标签来创建变量,xyz为同一类型的变量*/
struct SIMPLE {
int a;
char b;
};
struct SIMPLE x;
struct SIMPLE y[20], *z;
typedef struct {
int a;
char b;
} Simple;
Simple x;
Simple y[20], *z;
2.结构成员的访问
通过结构操作符.来访问
3.结构成员的间接访问
.和->操作符的区别
(*cp).a;
cp->a;
点操作符优先级高于间接访问操作符,需对间接访问操作符加括号
箭头操作符不需要显式调用间接访问操作符
4.结构自引用
struct SELF_REF {
int a;
struct SELF_REF b;
int c;
}
/*这个声明是非法的,其中结构中包含自己的成员b,将重复下去无止境*/
struct SELF_REF {
int a;
struct SELF_REF *b;
int c;
}
/*合法,b为指针,编译器在结构长度确定之前就知道指针长度。*/
typedef struct {
int a;
SELF_REF3 *b;
int c;
}SELF_REF3;
/*错误,类型名直到声明的末尾才定义,在结构的声明内部它尚未定义*/
struct B;
/*不完整声明,作为结构标签的标识符*/
struct INIT {
int a;
short b[5];
}x = {
10,
{1,2,3,4,5fc }
};
5.结构的存储分配
int a;
char b;
char c;
系统禁止编译器在一个结构的起始位置跳过几个字节来满足边界对齐要求,所以结构的起始位置必须是结构中边界要求最严格的数据类型所要求的位置,否则声明的变量会跳过几个字节才能存储,利用率低。
函数 offsetof (type, member)
type是结构的类型,member是成员名,返回一个size_t值,表示指定的成员开始存储的位置距离结构开始存储的位置偏移几个字节。
6.作为函数参数的结构
void print_receipt( Transaction trans);
void print_receipt( Transaction *trans);
void print_receipt( register Transaction const *trans);
/*使用寄存器进一步提高效率,const不可以修改指针的数据*/
传入结构,但效率很低,C语言参数传值调用方式将参数的一份拷贝传给参数,将许多字节复制到堆栈中;传入指向结构的指针,效率会提升很多。
7.位段
struct CHAR {
unsigned ch : 7;
unsigned font : 6;
unsigned size : 19;
};
/*类型 成员名 冒号 整数(用于指定该位段所占用的位的数目)*/
struct CHAR ch1;
使用位段,能够把长度为奇数的数据包装在一起,节省存储空间;很方便的访问一个整型值的内容。
联合
union {
float f;
int i;
} fi;
联合的所有成员引用的是内存中的相同位置。
联合的各个成员有不同的长度,联合的长度为它最长成员的长度。