1:大端与小端?与寻常习惯的区别?
大端:高地址存储低位字节。
小端:低地址存储低位字节。
如对于数据0x1234,其32位为0x00001234。
对于大端来说:(地址由低到高存储)00 00 12 34
对于小端来说:(地址由低到高存储)34 12 00 00
由此可以得出结论:大端的存储方式与寻常习惯相一致,而小端的存储方式为按照字节倒排。
在一个64位的操作系统中定义如下结构体:
1
2
3
4
5
6
|
struct
st_task
{
uint16_t id;
uint32_t value;
uint64_t timestamp;
};
|
同时定义fool函数如下:
1
2
3
4
5
6
7
|
void
fool()
{
st_task task = {};
uint64_t a = 0x00010001;
memcpy
(&task, &a,
sizeof
(uint64_t));
printf
(
"%11u,%11u,%11u"
, task.id, task.value, task.timestamp);
}
|
上述fool()程序的执行结果为()
正确答案: 1,0,0
首先在内存中是小端存储方式存放字节。
uint16_t id;//两个字节,16位,
占2个 字节
uint32_t value;//4个字节,32位,
占4个字节
uint64_t timestamp;//8个字节,64位,
占8个字节
0x00010001十六进制,共32位
id(16bits)+16bits+value(32bits)=64位,
以8字节字节对齐需要
按照低位存储:
则id(16bits)+16bits会占据掉32bits的 0x00010001,id占据掉Ox0001,因此为1
id和value占第一行8字节,timestamp占第二行8个字节。 故
memcpy
复制8个字节的数据后,timestamp是没有值的。
uint64_t a = 0x00010001是8个字节,故在64位系统中是占了一行,只赋值给第一行数据。
按照小端存储原理,低字节存放在低地址:01 00 01 00 , 00 00 00 00;
所以id占用01 00; value 占用00 00 00 00;timestamp没有值 ;
union数据类型占用的空间
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
都知道union的大小取决于它所有的成员中,占用空间最大的一个成员的大小。所以对于u来说,大小就是最大的double类型成员a了,所以sizeof(u)=sizeof(double)=8。但是对于u2和u3,最大的空间都是char[13]类型的数组,为什么u3的大小是13,而u2是16呢?关键在于u2中的成员int b。由于int类型成员的存在,使u2的对齐方式变成4(4字节对齐),也就是说,u2的大小必须在4的对界上,所以占用的空间变成了16(最接近13的对界)。