大端小端区别、Union和Struct的内存分配
嵌入式系統開發者應該對Little-endian和Big-endian模式非常了解。采用Little-endian模式的CPU對操作數的存放方式是從低字節到高字節,而Big-endian模式對操作數的存放方式是從高字節到低字節。也就是說Big-endian模式符合人的習慣,而Little-endian更加方便計算機操作。
例如,16bit寬的數0x1234在Little-endian模式CPU內存中的存放方式(假設從地址0x4000開始存放)為:
內存地址 0x4000 0x4001
存放內容 0x34 0x12
而在Big-endian模式CPU內存中的存放方式則為:
內存地址 0x4000 0x4001
存放內容 0x12 0x34
32bit寬的數0x12345678在Little-endian模式CPU內存中的存放方式(假設從地址0x4000開始存放)為:
內存地址 0x4000 0x4001 0x4002 0x4003
存放內容 0x78 0x56 0x34 0x12
而在Big-endian模式CPU內存中的存放方式則為:
內存地址 0x4000 0x4001 0x4002 0x4003
存放內容 0x12 0x34 0x56 0x78
若判斷處理器是Big還是Little模式,有兩種方法。
1、
int i=1;??
??? char *p=(char *)&i;??
??? if(*p==1)????
?????????? printf("1");?
??? else
?????????? printf("2");
????????? 大小端存儲問題,如果小端方式(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
{
char c[10];
char cc1;
}u11;首先按照char c[10]分配10個字節,然后按照char的1個字節對齊,最終sizeof(u11)=10;
typedef union
{
char c[10];
int i;
}u22;首先按照char c[10]分配10個字節,然后按照int的4個字節對齊,最終sizeof(u22)=12;
typedef union
{
char c[10];
double d;
}u33;首先按照char c[10]分配10個字節,然后按照double的4個自己對齊,最終sizeof=16;
union U1 {
5 char? c;
6 int? i;
7 double? d;
8 ??? } ;按照double的8個字節分配,最終為8;
9 union U2 {
10 char? c;
13 ???? } ;按照char c的一個字節分配,最終sizeof為1;
14
15 union U3 {
16 char? c;
17 int? i;
18 // double d;
19 ???? } ;按照int的4個字節分配,最終sizeof為4;
因此,舉例中union分配的內存按照int分配4個字節,如果是小端模式則存放的方式為???????????????????????????????????????????????????????????????????????????????????????????????????????
地址A
------------------------------------
|A?????? |A+1?? |A+2??? |A+3 | int a;
|0x01 |0x00?? |0x00?? |0x00 |
-------------------------------------
|A????? |char b;
|????????? |
---------?????????
如果是大端如何存儲c.a的呢?????
地址A
------------------------------------------
|A????????? |A+1??? |A+2????? |A+3????? |int a;
|0x00?? |0x00?? |0x00??? |0x01??? |
------------------------------------------
|A?????? |char b;
|??????????? |
---------??????
因此我們就可以通過查看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
轉載于:https://www.cnblogs.com/chenglei/archive/2009/11/10/1599992.html
總結
以上是生活随笔為你收集整理的大端小端区别、Union和Struct的内存分配的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: noi99钉子和小球 解题报告
- 下一篇: Spring.NET学习笔记11——自定