大端小端差别、Union和Struct的内存分配
嵌入式系统开发者应该对Little-endian和Big-endian模式非常了解。采用Little-endian模式的CPU对操作数的存放方式是从低字节到高字节,而Big-endian模式对操作数的存放方式是从高字节到低字节。也就是说Big-endian模式符合人的习惯,而Little-endian更加方便计算机操作。 例如,16bit宽的数0x1234在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为: 而在Big-endian模式CPU内存中的存放方式则为: 32bit宽的数0x12345678在Little-endian模式CPU内存中的存放方式(假设从地址0x4000开始存放)为: 而在Big-endian模式CPU内存中的存放方式则为: 若判断处理器是Big还是Little模式,有两种方法。 1、 int i=1; 大小端存储问题,如果小端方式(i占至少两个字节的长度)则i所分配的内存最小地址那个字节中就存着1,其他字节是0.大端的话则1在i的最高地址字节处存放,char是一个字节,所以强制将char型量p指向i则p指向的一定是i的最低地址,那么就可以判断p中的值是不是1来确定是不是小端 2、 int checkCPU( ) { { union w { int a; char b; } c; c.a = 1; return(c.b ==1); } } 这个解法涉及到Union的内存分配模式。 Union的大小为其内部所有变量的最大值,并且按照类型最大值的整数倍进行内存对齐。 例如: typedef Union typedef union typedef union union U1 因此,举例中union分配的内存按照int分配4个字节,如果是小端模式则存放的方式为 地址A 如果是大端如何存储c.a的呢? 地址A ------------------------------------------ 因此我们就可以通过查看char b==1?来判断大小端了。 顺便说明一下struct的内存分配方式。 struct的内存大小为每个数据内存的加和,首先按照最大的数据类型进行单个分配,如果前一个数据占用不了所有的内存,而剩下的内存可以放下下一个数据,则第二个数据不另外分配内存,否则重新分配一个最大类型的内存单元。 struct{ char c; double d; };16 struct{ char c; char c1; double d; };16 struct{ char c; double d; char c2; };24 |