?????? little endian和big endian是表示計算機字節順序的兩種格式,所謂的字節順序指的是長度跨越多個字節的數據的存放形式.
??????? 假設從地址0x00000000開始的一個字中保存有數據0x1234abcd,那么在兩種不同的內存順序的機器上從字節的角度去看的話分別表示為:
?????? 1)little endian:在內存中的順序是0x00000000-0xcd,0x00000001-0xab,0x00000002-0x34,0x00000003-0x12
?????? 2)big? endian:在內存中的順序是0x00000000-0x12,0x00000001-0x34,0x00000002-0xab,0x00000003-0xcd
?????? 需要特別說明的是,以上假設機器是每個內存單元以8位即一個字節為單位的.
?????? 簡單的說,little endian把低位存放到高位,而big endian把低位存放到低位.
?????? 現在主流的CPU,intel系列的是采用的little endian的格式存放數據,而motorola系列的CPU采用的是big endian.
??????
?????? 以下是判斷字節存儲順序的可移植的C語言代碼:
??????
/**/
/*
*******************************************************************
????created:????2006-9-5
????filename:?????test.cpp
????author:????????李創
????
????purpose:????可移植的用于判斷存儲格式是
????????????????little?endian還是big?ednian的C代碼
????????????????取自<<C:?A?Reference?Manual>>
********************************************************************
*/
#include?
<
stdio.h
>
union

{
????
long
?Long;
????
char
?Char[
sizeof
(
long
)];
}
u;

int
?main()

{????
????u.Long?
=
?
1
;
????
????
if
?(u.Char[
0
]?
==
?
1
)????

????
{
????????printf(
"
Little?Endian!\n
"
);
????}
????
else
?
if
?(u.Char[
sizeof
(
long
)?
-
?
1
]?
==
?
1
)

????
{
????????printf(
"
Big?Endian!\n
"
);
????}
????
else
????
{
????????printf(
"
Unknown?Addressing!\n
"
);
????}
????printf(
"
Now,?Let's?look?at?every?byte?in?the?memory!\n
"
);
????
for
?(
int
?i?
=
?
0
;?i?
<
?
sizeof
(
long
);?
++
i)

????
{
????????printf(
"
[%x]?=?%x\n
"
,?
&
u.Char[i],?u.Char[i]);
????}
????
return
?
0
;
}
?
?????? 很多人認為掌握這個知識是不必要,其實不然.在網絡編程中,TCP/IP統一采用big endian方式傳送數據,也就是說,假設現在是在一個字節順序是little endian的機器上傳送數據,要求傳送的數據是0XCEFABOBO,那么你就要以0XBOBOFACE的順序在unsigned int中存放這個數據,只有這樣才能保證存放的順序滿足TCP/IP的字節順序要求.很多時候,需要自己編寫應用層的協議,字節順序的概念在這個時候就顯得及其的重要了.
?????? 下面給出的是在big endian和little endian中相互轉換的代碼,C語言強大的位操作的能力在這里顯示了出來:
????????
/**/
/*
*******************************************************************
????created:????2006-9-5
????filename:?????get32put32.cpp
????author:????????李創
????
????purpose:????在little?endian和big?ednian之間相互轉化數據的演示代碼

********************************************************************
*/
#include?
<
stdio.h
>
const
?unsigned?
char
?SIZE_OF_UNSIGNEDINT??
=
?
sizeof
(unsigned?
int
);
const
?unsigned?
char
?SIZE_OF_UNSIGNEDCHAR?
=
?
sizeof
(unsigned?
char
);

void
?put_32(unsigned?
char
?
*
cmd,?unsigned?
int
?data)

{
????
int
?i;
????
for
?(i?
=
?SIZE_OF_UNSIGNEDINT?
-
?
1
;?i?
>=
?
0
;?
--
i)

????
{
????????cmd[i]?
=
?data?
%
?
256
;
????????
//
?或者可以:
????????
//
cmd[i]?=?data?&?0xFF;
????????data?
=
?data?
>>
?
8
;
????}
}
unsigned?
int
?get_32(unsigned?
char
?
*
cmd)

{
????unsigned?
int
??ret;
????
int
?i;

????
for
?(ret?
=
?
0
,?i?
=
?SIZE_OF_UNSIGNEDINT?
-
?
1
;?i?
>=
?
0
;?
--
i)

????
{
????????ret??
=
?ret?
<<
?
8
;
????????ret?
|=
?cmd[i];????????
????}
????
????
return
?ret;
}
int
?main(
void
)

{
????unsigned?
char
?cmd[SIZE_OF_UNSIGNEDINT];
????unsigned?
int
?data,?ret;
????unsigned?
char
?
*
p;
????
int
?i;

????data?
=
?
0x12345678
;
????printf(
"
data?=?%x\n
"
,?data);
????
//
?以字節為單位打印出數據
????p?
=
?(unsigned?
char
*
)(
&
data);
????
for
?(i?
=
?
0
;?i?
<
?SIZE_OF_UNSIGNEDINT;?
++
i)

????
{
????????printf(
"
%x
"
,?
*
p
++
);
????}
????printf(
"
\n
"
);

????
//
?以相反的順序存放到cmd之中
????put_32(cmd,?data);
????
for
?(i?
=
?
0
;?i?
<
?SIZE_OF_UNSIGNEDINT;?
++
i)

????
{
????????printf(
"
cmd[%d]?=?%x\n
"
,?i,?cmd[i]);
????}
????
//
?再以相反的順序保存數據到ret中
????
//
?保存之后的ret數值應該與data相同
????ret?
=
?get_32(cmd);
????printf(
"
ret?=?%x\n
"
,?ret);
????p?
=
?(unsigned?
char
*
)(
&
ret);
????
for
?(i?
=
?
0
;?i?
<
?SIZE_OF_UNSIGNEDINT;?
++
i)

????
{
????????printf(
"
%x
"
,?
*
p
++
);
????}
????printf(
"
\n
"
);

????
return
?
0
;
}
參考資料:<<C: A Reference Manual>>