1.这里先讲一讲enum枚举类型吧之前忘记掉了,声明方式:
enum Jar_type { CUP=9(可以赋特定的整型值,如果后边不赋值的话就是+1, PINT, QUART, HALF, GALLON };
变量声明方式:
enum Jar_type milk, gas, medicine;
10.1some基础知识
1. 结构体是根据成员名字来访问结构体成员的,而且结构体是一个标量
10.1.1结构声明
struct tag { member_list } variable-list;//声明结构是必须列出它包含的所有成员,tag字段准许为成员列表提供名,这样就可以准许多个生命使用同一个成员列表,并且创建同一种类型的结构。
struct SIMPLE {
int a;
char b;
float c;
};
struct SIMPLE x;
struct SIMPLE y[20], *z;
这里使用标签创建变量,所以x y z是同一种类型的结构变量
倘若不加SIMPLE,就是直接struct {xxxx}x ,struct {xxxx}y,这样的话,即使xy成员一样,却不是一种类型的
另外一种
typedef struct {
int a;
char b;
float c;
} Simple;
它和上边的标签声明区别在于Simple现在是一个类型名,而不是结构标签,后续的声明是
Simple x;
Simple y[20], *z;
10.1.2 结构成员
10.1.3结构成员的直接访问
这里要注意的就是(.)操作符和[】下标引用具有相同优先级,结合性都是从左往右
comp.sa[4].c //comp是一个结构体;变量,sa是他的一个成员,sa是一个数组,然后数组元素是另外一个结构,c是这个结构的成员
10.1.4结构成员的间接访问
(.)操作符优先级高于间接访问操作符
举个例子
void func( struct COMPLEX *cp);
(*cp).f//这样可以访问这个变量所指向的结构的成员f
另外一个方便很多的操作符(-> ) 他的左操作数必须是一个指向结构的指针,箭头操作符对左操作数执行间接访问取得指针所指向的结构,然后和点操作符一样,根据右操作数选择一个指定的结构成员,间接访问操作符建于箭头操作符中,所以左边不需要放*和()
cp->f
10.1.5结构体的自引用
在一个结构体内部包含一个指向该结构本身的指针是可以的,他指向的是同一种类型的不同结构,像链表和树都是用这种技巧实现的,每个结果指向链表的下一个元素或者树的下一个分支
一个合法的声明:
struct self_ref2{
int a;
struct self_ref2 *b;
int c;
}//在这里编译器是可以知道指针的长度的
如果使用typedef的话,需要定义一个结构标签来声明b
typedef struct self_ref3_tag {
int a;
struct self_ref3_tag *b;
int c;
} self_ref3;
10.1.6 不完整声明
主要就是用于声明一些相互之间存在依赖的结构
struct B;
struct A {
struct B *partner;
};
struct B{
struct A *partner;
};
10.1.7 结构的初始化
比如上边的那个x={10,'z',5}如果结构体里边有数组或者结构体就需要加个括号大括号
10.2结构,指针和成员
px->b//px是一个指向结构体的指针,b是一个数组,所以这个表达式得到的值是一个指针常量
*(px->b)得到的则是数组的第一个元素
一个以前经常晕菜的东西就是【】(.)(->)这几个的优先级,看了这本书发现就从左往右好像就可以了嘎嘎嘎
10.3结构的存储分配
编译器按照成员列表的顺序一个接一个地给每个成员分配内存,只有当存储成员需要满足正确的边界需求时成员之间才可能出现用于填充的额外内存空间
sizeof 可以得到一个结构的整体长度,
如果需要确定某一个结构成员的实际位置,应该考虑边界对齐因素,可以使用offset( type(结构类型), member(成员名) );
10.4作为函数参数的结构
这里就是说传递结构指针比传递结构整体效率来得高,结构体实际上是一种标量,就当成int一类的来使用
10.5 位段
和结构体声明类似,举个例子
struct CHAR {
unsigned ch :7;//ch一共占17位
unsigned font :6;
unsigned size :19;
};//位段成员必须是声明为int, signed int, unsigned int 类型,后边是一个冒号和一个整数,这个整数指定该位段所占用的位的数目
struct CHAR ch1;
另外一个理由是可以很方便访问一个整型值的部分内容,比如磁盘控制器
10.6 联合
联合的声明和结构类似,但是联合中所有成员中引用的的内存中的相同位置
例子:
union {
float f;
int i;
} fi;
可以这样子使用
fi.f=3.14159
printf( "%d\n", fi.i);
也可以用在结构体里
struct variable {
enum { INT, FLOAT, STRING } type;
union {
int i;
float f;
char *s;
} value;
}
这个主要用在解释器里,对于整型变量,type字段设置为INT,整型值存储与value.i字段
联合变量的初始化
union {
int a;
float b;
char c[4];
} x= { 5 };
把x.a的变量初始化为5;不能初始化为一个浮点值或者字符值,如果赋值了,那么有可能转化为一个整数并赋值给x.a