日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

大端和小端的判断及转换

發(fā)布時(shí)間:2024/4/24 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 大端和小端的判断及转换 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

當(dāng)前的存儲器,多以byte為訪問的最小單元,當(dāng)一個(gè)邏輯上的地址必須分割為物理上的若干單元時(shí)就存在了先放誰后放誰的問題,于是端(endian)的問題應(yīng)運(yùn)而生了,對于不同的存儲方法,就有大端(big-endian)和小端(little- endian)兩個(gè)描述。

字節(jié)排序按分為大端和小端,概念如下

大端(big endian):低地址存放高有效字節(jié)

小端(little endian):低字節(jié)存放地有效字節(jié)

現(xiàn)在主流的CPU,intel系列的是采用的little endian的格式存放數(shù)據(jù),而motorola系列的CPU采用的是big endian,ARM則同時(shí)支持 big和little,網(wǎng)絡(luò)編程中,TCP/IP統(tǒng)一采用大端方式傳送數(shù)據(jù),所以有時(shí)我們也會把大端方式稱之為網(wǎng)絡(luò)字節(jié)序。

特別需要注意的是,C/C++語言編寫的程序里數(shù)據(jù)存儲順序是跟編譯平臺所在的CPU相關(guān)的,而 JAVA編寫的程序則唯一采用big endian方式來存儲數(shù)據(jù)。這里我就只討論C/C++語言的情況。

1.大端和小端的方式及判斷

舉個(gè)例子說明,我的機(jī)子是32位windows的系統(tǒng),處理器是AMD的。對于一個(gè)int型數(shù)0x12345678,為方便說明,這里采用16進(jìn)制表示。這個(gè)數(shù)在不同字節(jié)順序存儲的CPU中儲存順序如下:

0x12345678?? 16進(jìn)制,兩個(gè)數(shù)就是一字節(jié)

高有效字節(jié)——>低有效字節(jié): 12 34 56 78

????????? 低地址位???? 高低址位

大端:??12? 34??????? 56?? 78

小端:?78? 56??????? 34?? 12

下面驗(yàn)證下本機(jī)CPU屬于哪種字節(jié)存儲順序。代碼如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

#include <iostream>

?

using?namespace?std;

?

typedef?unsigned int?UINT;

typedef?unsigned char?UCHAR;

?

int?main()

{

????UINT?i=0x12345678;

????cout<<hex<<i<<endl;

????UCHAR?*p = (UCHAR*)&i;????????? //將i的地址傳給數(shù)組指針p,實(shí)際上p指向的地址是i在內(nèi)存中存儲的第一個(gè)字節(jié),大端就是0x12,小端就是0x78

????if((*p==0x78)&(*(p+1)==0x56))???????

????????cout<<"小端"<<endl;

????else?if((*p==0x12)&(*(p+1)==0x34))

????????cout<<"大端"<<endl;

????else

????????cout<<"這是神馬字節(jié)順序呢?";

????return?0;

}

調(diào)試顯示時(shí)小端,我用的機(jī)子字節(jié)存儲為小端方式。

2.大端和小端的字節(jié)轉(zhuǎn)換

當(dāng)兩臺采用不同字節(jié)序的主機(jī)通信時(shí),在發(fā)送數(shù)據(jù)之前都必須經(jīng)過字節(jié)序的轉(zhuǎn)換成為網(wǎng)絡(luò)字節(jié)序(即大端方式)后再進(jìn)行傳輸。此外用C/C++在小端方式的機(jī)器上編寫的程序與java程序互通時(shí)也要進(jìn)行大端和小端的轉(zhuǎn)換。

這里所謂轉(zhuǎn)換就是改變字節(jié)的排序,使交互時(shí)數(shù)據(jù)保持一致。舉一個(gè)例子,還是16進(jìn)制表示的數(shù)0x12345678,在小端機(jī)器上排序?yàn)?x78563412,當(dāng)內(nèi)存中這樣的數(shù)傳輸時(shí),在大端方式下就是0x78563412這個(gè)值,與原值不同,要想與原值相同,在傳輸前,在大端方式下就該是0x12345678,這時(shí)原數(shù)在內(nèi)存中為0x12345678,即將原數(shù)據(jù)0x12345678在內(nèi)存存儲序列為0x12345678,也就是要轉(zhuǎn)換成大端方式。

要傳輸值:12 34 56 78

不轉(zhuǎn)換時(shí),小端:78 56 34 12

轉(zhuǎn)換為大端:12 34 56 78

根據(jù)上面的大端和小端字節(jié)排序,可以方便的用移位運(yùn)算完成轉(zhuǎn)換功能。從小端轉(zhuǎn)到大端代碼如下:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

#include <iostream>

?

using?namespace?std;

?

typedef?unsigned int?UINT;

typedef?unsigned char?UCHAR;

?

int?main()

{

????UINT?i=0x12345678;

????cout<<hex<<i<<endl;

????UCHAR?*p = (UCHAR*)&i;

????UINT?num,num1,num2,num3,num4;

????num1=(UINT)(*p)<<24;

????num2=((UINT)*(p+1))<<16;

????num3=((UINT)*(p+2))<<8;

????num4=((UINT)*(p+3));

????num=num1+num2+num3+num4;

?

????cout<<"num1:"<<hex<<num1<<endl;???? //看num1的16進(jìn)制表示,下同

????cout<<"num2:"<<hex<<num2<<endl;

????cout<<"num3:"<<hex<<num3<<endl;

????cout<<"num4:"<<hex<<num4<<endl;

????cout<<"num:"<<hex<<num<<endl;

?

????unsigned char?*q = (unsigned char*)&num;

????if((*q==0x78)&(*(q+1)==0x56))?????????

????????cout<<"小端"<<endl;

????else?if((*q==0x12)&(*(q+1)==0x34))

????????cout<<"大端"<<endl;

????else

????????cout<<"這是神馬字節(jié)順序呢?";

????return?0;

}

至于說(UINT)(*p)為什么要移24位,其實(shí)是很好理解的,將0x00000012變成0x12000000,不就是向左移24位嗎。

當(dāng)然,向上面這樣寫時(shí)為了方便理解,可以更簡單的寫一個(gè)函數(shù)用于完成上面的轉(zhuǎn)換功能,函數(shù)如下:

1

2

3

4

5

UINT?EndianConvertLToB(UINT?InputNum) {

????UCHAR?*p = (UCHAR*)&InputNum;

????return(((UINT)*p<<24)+((UINT)*(p+1)<<16)+

???????????????((UINT)*(p+2)<<8)+(UINT)*(p+3));

}

同樣的原理適用于大端轉(zhuǎn)小端,但是大端轉(zhuǎn)小端時(shí)移位有差別,函數(shù)如下:

1

2

3

4

5

UINT?EndianConvertBToL(UINT?InputNum) {

????UCHAR?*p = (UCHAR*)&InputNum;

????return(((UINT)*p)+((UINT)*(p+1)<<8)+

???????????????((UINT)*(p+2)<<16)+(UINT)*(p+3)<<24);

}

分類:?C/C++

標(biāo)簽:?大端和小端,?轉(zhuǎn)換,?判斷

總結(jié)

以上是生活随笔為你收集整理的大端和小端的判断及转换的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。