说明:
******不同的编译器和处理器,其结构体内部的成员有不同的对齐方式。
******使用sizeof()运算符计算结构体的长度。
###结构体中每个成员相对于结构首地址的偏移量都是成员大小的整数倍,如果有需要编译器会在成员之间加上填充字。
###结构体的总大小是结构体最宽基本类型成员大小的整数倍。如果需要编译器会在最后一个成员之后加上填充字。
struct A
{
<span style="white-space:pre"> </span>unsigned short a;<span style="white-space:pre"> </span>//4bytes
unsigned int b;<span style="white-space:pre"> </span>//4bytes
unsigned char c;<span style="white-space:pre"> </span>//4bytes
}aa;
按结构体成员对齐,应该给c分配一个字节的空间,但是还得按结构体的对齐方式,所以给c分配4个字节。sizeof(aa)==12
结构体成员对齐,应当按结构体中最大基本数据类型来分配存储空间,例如:当一个成员A分配的空间大于自己本身的大小时,若是下个成员B所需空间,A分配空间的剩下空间足以满足存储B的时候,那么就不会给B分配了,但是,若不能满足B的存储的话,会给B按结构体最大数据类型来分配。
###计算结构体某个成员相对于结构体首地址的偏移量,通过宏offsetof()可以获得。
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
//TYPE:结构体的类型
//MEMBER:结构体中某个成员
/*
*offsetof(,)宏解析:
*(TYPE *)0:将0强制转换成指向结构体首地址的指针(结构体首地址为0地址)
*((TYPE *)0)->MEMBER:结构体中某个变量
* &((TYPE *)0)->MEMBER:取成员变量MEMBER(都是在0地址的基础上增加的)的地址
* (size_t) &((TYPE *)0)->MEMBER:将取到的地址强制转换成size_t数据类型。
*/
结构体变量的初始化:
结构体:
struct A
{
unsigned short b;
unsigned int a;
unsigned short c;
unsigned short f;
unsigned short g;
unsigned short d;
unsigned char e;
};
第一种初始化方法:
struct A aa={
.b=2,
.a=1,
.c=3,
.d=4,
.e=5,
.f=6,
.g=7
};
第二种初始化方法:
struct A aa={1,2,3,4,5,6,7};
第三种初始化方法:
struct A aa;
aa.b=2;
aa.a=1;
aa.c=3;
aa.d=4;
aa.e=5;
aa.f=6;
aa.g=7;