C++字节基础

一、字节序

bool am_little_endian ()
{
unsigned short i=1;
return (int)*((char *)(&i)) ? true : false;
}
int main()
{
if(am_little_endian())
{
printf("本机字节序为小段序!\n");
}else
{
printf("本机字节序为大段序!\n");
}
return 0;
}

二、字节对齐

VS默认8,Linux默认4。

结构体字节对齐规则
先介绍三个概念:自身对齐值、指定对齐值、有效对齐值。

a: 自身对齐值:数据类型本身的对齐值,例如char类型的自身对齐值是1,short类型是2;

b: 指定对齐值:编译器或程序员指定的对齐值,32位单片机的指定对齐值默认是4;

c: 有效对齐值:自身对齐值和指定对齐值较小的那个。

对齐有两个规则:

d: 不但结构体的成员有有效对齐值,结构体本身也有对齐值,这主要是考虑结构体的数组,对于结构体或者类,要将其补齐为其有效对齐值的整数倍。结构体的有效对齐值是其最大数据成员的自身对齐值

e: 存放成员的起始地址必须是该成员有效对齐值的整数倍。

例子一:

#pragma pack (2)
	typedef struct head {
		char f
	} _head;
#pragma pack ()
	int a = sizeof(_head);//a = 1

假如结构体起始地址是0x0000,

成员f的自身对齐值1,指定对齐值2,所以有效对齐值是1,根据规则e地址0x0000是1的整数倍,故a存放起始地址是0x0000,占一个字节;

根据规则d,体结构体本身也有对齐值,是其最大数据成员的自身对齐值。所以这里是成员f,体结构体本身对齐值是1。再根据e,1是1的整数倍,所以结构体大小为1。

例子二:

#pragma pack (2)
	typedef struct head {
		char f
		int b;
		char c;
	} _head;
#pragma pack ()
	int a = sizeof(_head);//a = 8

假如结构体起始地址是0x0000

成员f的自身对齐值1,指定对齐值2,所以有效对齐值是1,根据规则e,地址0x0000是1的整数倍,故a存放起始地址是0x0000,占一个字节;

成员b的自身对齐值4,指定对齐值2,所以有效对齐值是2,根据规则e,地址0x0002是2的整数倍,故a存放起始地址是0x0002,占4个字节;

成员c的自身对齐值1,指定对齐值2,所以有效对齐值是1,根据规则e,地址0x0006是1的整数倍,故a存放起始地址是0x0006,占一个字节;

此时共用了7个字节,但是根据规则d,体结构体本身也有对齐值,是其最大数据成员的自身对齐值。所以这里是成员b,体结构体本身对齐值是4。再根据e,7不是4的整数倍,所以要+1,,即为8。

例子三:

#pragma pack (16)
	typedef struct head {
		char f
		int b;
		char e;
	} _head;
#pragma pack ()
	_head h;
	int a = sizeof(h);  //a = 12

假如结构体起始地址是0x0000

成员f的自身对齐值1,指定对齐值16,所以有效对齐值是1,根据 规则e 地址0x0000是1的整数倍,故a存放起始地址是0x0000,占一个字节;

成员b的自身对齐值4,指定对齐值16,所以有效对齐值是4,规则e 地址0x0004是4的整数倍,故a存放起始地址是0x0004,占4个字节;

成员c的自身对齐值1,指定对齐值16,所以有效对齐值是1,规则e 地址0x0008是1的整数倍,故a存放起始地址是0x0008,占一个字节;

此时共用了9个字节,但是根据规则d,体结构体本身也有对齐值,是其最大数据成员的自身对齐值。所以这里是成员b,体结构体本身对齐值是4。再根据e,9不是4的整数倍,所以要+3,,即为12。


版权声明:本文为asdasfdgdhh原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。