解析C语言结构体及位段
1.结构的定义
在实际情况中,数据经常以成组的形式存在。如果这些值的类型各不相同,他们无法同时存储于同一个数组中,在C中,可以使用结构把不同类型的值存储在一起,所以结构也是一些值的集合,这些值称为它的成员,但是这些成员的类型可以不同。
拓展:
“结构”是一种构造数据类型,也叫做用户自定义数据类型,它是由若干“成员”组成的。 每一个成员可以是一个基本数据类型或者又是一个构造类型。 结构即是一种“构造”而成的数据类型, 那么在说明和使用之前必须先定义它,也就是构造它。如同在说明和调用函数之前要先定义一样。
2.结构的初始化
结构的初始化和数组相似,位于一对花括号内,由逗号分隔初始值,可用于结构各个成员的初始化。这些值将根据结构成员的顺序写出,如果初始值不够,剩余的结构成员将使用缺省值进行初始化。
struct S { int a; int b[10]; char c[20]; }s={ 10, {1,2,3,4,5}, "abc" };
typedef:在C中,定义一个结构体类型如果要用typedef:
typedef struct Student { int a; }Stu;
当需要声明变量时,就可以直接Stu.stu1;如果没有typedef则需用 struct Student stu1 来声明;(Stu==struct Student);
4.结构体的内存存储
结构在内存中的存储是按照成员列表顺序一个接一个的给每个成员分配内存。而在分配的时候则遵循结构体内存对齐规则:
- (1).第一个成员在与结构体变量偏移量为0的地址处;
- (2).其他成员变量要对齐到对齐数的整数倍的地址处; 对齐数:编译器的默认对齐数与该成员大小的较小值; (默认对齐数 vs:8,linux:4)
- (3).结构体的总大小为最大对齐数的整数倍。
- (4).如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整体大小就是所有最大对齐数的整数倍。
struct S { int a; char b; double c; }; //则此结构体大小为16
stuct A { doulbe d; char e; }; struct S { int a; char b; struct A C; double c; }; //结构体S的大小为32
内存对齐的原因:
- (1).平台原因:不是所有的硬件平台都能访问任意地址上的任意数据;某些硬件平台只能在某些地址处取某些特定类型的数据,否则将抛出硬件异常。
- (2).性能原因:数据结构应该尽可能的在自然边界上对齐。原因在于,为了访问未对齐的内存,处理器需要作两次内存访问,而对齐的内存访问仅需要一次访问。
5.结构体位段
位段的声明和结构类似,但位段的成员是一个或多个位的字段。位段成员必须声明位int,unsigned int或signed int类型。在成员的后面是一个冒号和一个整数,这个整数就是该位段所占用的位的大小。
struct S { int a : 7; signed int b : 6; unsigned int c : 12; };
位段的数据存储:
当一个声明指定了2个位段,第二个位段无法放在第一个位段剩余的位上,编译器有可能把第二个位段放在内存的下一个字节上,也可能直接放在第一个位段后面。
位段的大小:
位段的大小取决于编辑器对位段的数据存储:
struct S { int a : 1; }; //S的大小为4 struct S { int a : 1; int b : 5; int c : 6; };
总结