大端小端区别、Union和Struct的内存分配
嵌入式系統(tǒng)開(kāi)發(fā)者應(yīng)該對(duì)Little-endian和Big-endian模式非常了解。采用Little-endian模式的CPU對(duì)操作數(shù)的存放方式是從低字節(jié)到高字節(jié),而B(niǎo)ig-endian模式對(duì)操作數(shù)的存放方式是從高字節(jié)到低字節(jié)。也就是說(shuō)Big-endian模式符合人的習(xí)慣,而Little-endian更加方便計(jì)算機(jī)操作。
例如,16bit寬的數(shù)0x1234在Little-endian模式CPU內(nèi)存中的存放方式(假設(shè)從地址0x4000開(kāi)始存放)為:
內(nèi)存地址 0x4000 0x4001
存放內(nèi)容 0x34 0x12
而在Big-endian模式CPU內(nèi)存中的存放方式則為:
內(nèi)存地址 0x4000 0x4001
存放內(nèi)容 0x12 0x34
32bit寬的數(shù)0x12345678在Little-endian模式CPU內(nèi)存中的存放方式(假設(shè)從地址0x4000開(kāi)始存放)為:
內(nèi)存地址 0x4000 0x4001 0x4002 0x4003
存放內(nèi)容 0x78 0x56 0x34 0x12
而在Big-endian模式CPU內(nèi)存中的存放方式則為:
內(nèi)存地址 0x4000 0x4001 0x4002 0x4003
存放內(nèi)容 0x12 0x34 0x56 0x78
若判斷處理器是Big還是Little模式,有兩種方法。
1、
int i=1;??
??? char *p=(char *)&i;??
??? if(*p==1)????
?????????? printf("1");?
??? else
?????????? printf("2");
????????? 大小端存儲(chǔ)問(wèn)題,如果小端方式(i占至少兩個(gè)字節(jié)的長(zhǎng)度)則i所分配的內(nèi)存最小地址那個(gè)字節(jié)中就存著1,其他字節(jié)是0.大端的話則1在i的最高地址字節(jié)處存放,char是一個(gè)字節(jié),所以強(qiáng)制將char型量p指向i則p指向的一定是i的最低地址,那么就可以判斷p中的值是不是1來(lái)確定是不是小端
2、
int checkCPU( )
{
??? {
?????????? union w
?????????? {??
????????????????? int a;
????????????????? char b;
?????????? } c;
?????????? c.a = 1;
?????????? return(c.b ==1);
??? }
}
這個(gè)解法涉及到Union的內(nèi)存分配模式。
Union的大小為其內(nèi)部所有變量的最大值,并且按照類型最大值的整數(shù)倍進(jìn)行內(nèi)存對(duì)齊。
例如:
typedef Union
{
char c[10];
char cc1;
}u11;首先按照char c[10]分配10個(gè)字節(jié),然后按照char的1個(gè)字節(jié)對(duì)齊,最終sizeof(u11)=10;
typedef union
{
char c[10];
int i;
}u22;首先按照char c[10]分配10個(gè)字節(jié),然后按照int的4個(gè)字節(jié)對(duì)齊,最終sizeof(u22)=12;
typedef union
{
char c[10];
double d;
}u33;首先按照char c[10]分配10個(gè)字節(jié),然后按照double的4個(gè)自己對(duì)齊,最終sizeof=16;
union U1 {
5 char? c;
6 int? i;
7 double? d;
8 ??? } ;按照double的8個(gè)字節(jié)分配,最終為8;
9 union U2 {
10 char? c;
13 ???? } ;按照char c的一個(gè)字節(jié)分配,最終sizeof為1;
14
15 union U3 {
16 char? c;
17 int? i;
18 // double d;
19 ???? } ;按照int的4個(gè)字節(jié)分配,最終sizeof為4;
因此,舉例中union分配的內(nèi)存按照int分配4個(gè)字節(jié),如果是小端模式則存放的方式為???????????????????????????????????????????????????????????????????????????????????????????????????????
地址A
------------------------------------
|A?????? |A+1?? |A+2??? |A+3 | int a;
|0x01 |0x00?? |0x00?? |0x00 |
-------------------------------------
|A????? |char b;
|????????? |
---------?????????
如果是大端如何存儲(chǔ)c.a的呢?????
地址A
------------------------------------------
|A????????? |A+1??? |A+2????? |A+3????? |int a;
|0x00?? |0x00?? |0x00??? |0x01??? |
------------------------------------------
|A?????? |char b;
|??????????? |
---------??????
因此我們就可以通過(guò)查看char b==1?來(lái)判斷大小端了。
順便說(shuō)明一下struct的內(nèi)存分配方式。
struct的內(nèi)存大小為每個(gè)數(shù)據(jù)內(nèi)存的加和,首先按照最大的數(shù)據(jù)類型進(jìn)行單個(gè)分配,如果前一個(gè)數(shù)據(jù)占用不了所有的內(nèi)存,而剩下的內(nèi)存可以放下下一個(gè)數(shù)據(jù),則第二個(gè)數(shù)據(jù)不另外分配內(nèi)存,否則重新分配一個(gè)最大類型的內(nèi)存單元。
struct{
char c;
double d;
};16
struct{
char c;
char c1;
double d;
};16
struct{
char c;
double d;
char c2;
};24
轉(zhuǎn)載于:https://www.cnblogs.com/chenglei/archive/2009/11/10/1599992.html
總結(jié)
以上是生活随笔為你收集整理的大端小端区别、Union和Struct的内存分配的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: noi99钉子和小球 解题报告
- 下一篇: 把光盘转化成镜像文件