c语言高低位拷贝_C语言中的大小端转换与高低位颠倒
總結(jié)一下最近工作學(xué)到的東西,主要是關(guān)于大小端與高低位。
在說大小端高低位之前,肯定要說明數(shù)據(jù)在計(jì)算機(jī)內(nèi)是如何存儲(chǔ)的。在計(jì)算機(jī)中,我們將數(shù)據(jù)分割成了一個(gè)一個(gè)的字節(jié)(byte),而每個(gè)字節(jié)又有8位(bit)。
一個(gè)字節(jié),可以聲明為unsigned
char型數(shù)據(jù),但是有時(shí)候不夠用,畢竟一個(gè)UCHAR也就能表示0-255的數(shù)據(jù)。所以還會(huì)有short型(2字節(jié)),int型(4字節(jié)),浮點(diǎn)型float(4字節(jié)),double型(8字節(jié))等等。其實(shí)存在計(jì)算機(jī)里,數(shù)據(jù)都還是那些個(gè)數(shù)據(jù),只是讀寫的方式因?yàn)槁暶鞯牟煌煌>秃帽仁且痪湓捯还?4個(gè)字:今天天氣特別好呀我們出去玩吧!假如一個(gè)字就是一個(gè)字節(jié),那么UCHAR型,我們就是這樣從計(jì)算機(jī)中讀寫的:今
天 天 氣 特 別 好 呀 我 們 出 去 玩 吧!
Int型是這樣讀寫的:今天天氣
特別好呀 我們出去 玩吧!這些數(shù)據(jù)在計(jì)算機(jī)的物理地址上是連續(xù)存儲(chǔ)的,只是如果我們拿著int型的聲明,就硬生生的,一次只能讀寫4個(gè)字節(jié),多一點(diǎn)少一點(diǎn)都不行。就像是那個(gè)少一天一秒都不是一輩子的梗一樣……
數(shù)據(jù)都是那些數(shù)據(jù),但是有些計(jì)算機(jī)把值的低位存在低地址,這是小端(little endian)。有些計(jì)算機(jī)把值的高位存在低地址,這是大端(big endian)。不同CPU廠商大小端又不統(tǒng)一,例如,Motorala6800, PowerPC970等是大端,x86,VAX等是小端。這就要求不同計(jì)算機(jī)在交互的過程中可能需要進(jìn)行大小端轉(zhuǎn)換。我之前看了很多帖子學(xué)這個(gè)的時(shí)候有人吐槽說TCP/IP規(guī)定使用大端字節(jié)序?yàn)榫W(wǎng)絡(luò)字節(jié)序非常任性……
下面貼代碼,原理都一樣,非常簡單,我把short,int,float,double型全貼上以造福以后的懶人。除了double那個(gè)都在VC6.0下跑過,可以復(fù)制黏貼直接用~
short型:
unsigned short swapShort16(unsigned short
shortValue){
return ((shortValue & 0x00FF )
<<8) | ((shortValue & 0xFF00)>>8);
}
int 型(原理都一樣!):
int swapInt32(int intValue){
int temp = 0;
temp = ((intValue & 0x000000FF) <<24)
+
((intValue & 0x0000FF00) <<8)
+
((intValue & 0x00FF000) >>8)
+
((intValue & 0xFF000000) >>24);
return temp;
}
不過float型略有不同,稍微麻煩一點(diǎn),還需要建一個(gè)聯(lián)合體。這個(gè)聯(lián)合體建立是因?yàn)?#xff0c;雖然我們拿著int 型和float型的牌子去找計(jì)算機(jī)要數(shù)據(jù),計(jì)算機(jī)都給我們四個(gè)字節(jié)沒錯(cuò)。但是它給的方式不同。所以我們要將float型變成int型(不能強(qiáng)制轉(zhuǎn)換傻孩子)然后再進(jìn)行顛倒。聯(lián)合體超級(jí)好用,我覺得它體現(xiàn)了數(shù)據(jù)存儲(chǔ)的本質(zhì),你可以選擇一萬種方式讀寫,但是其實(shí)數(shù)據(jù)在聯(lián)合體肚子里都是一樣一樣的。
float型:
float swapFloat32(float floatValue){
typedef union SWAP_UNION{
float unionFloat;
int
unionInt;
}SWAP_UNION;
SWAP_UNION swapUnion;
swapUnion.unionFloat = floatValue;
swapUnion.unionInt = swapInt32(
swapUnion.unionInt);
return
swapUnion.unionFloat;
}
double型換一種寫法,用一下指針,不然移位移死了……
void swapDouble64(unsigned char *pIn, unsigned char
*pOut){
for( int i=0;i<8;i++)
pOut[7-i] = pIn[i];
}
王德福啊,連return都不用了。
關(guān)于高低位,雖然通常不用顛倒,該取反取反就行,但是保不齊哪天碰到個(gè)什么事情就叫你把一個(gè)字節(jié)的高低位顛倒一下。反正我就碰到了。一開始覺得這怎么辦,系統(tǒng)給了取反你非叫我顛倒,后來想想也是用笨辦法就這樣移位顛嘛~
Unsigned char bitRevise(unsigned char bitInfo){
Unsigned char bitReturn;
bitReturn = (bitInfo & 0x80)>>7|
(bitInfo
& 0x40)>>5|
(bitInfo &
0x20)>>3|
(bitInfo & 0x10)>>1|
(bitInfo &
0x8)<<1|
(bitInfo &
0x4)<<3|
(bitInfo & 0x2)<<5|
(bitInfo &
0x1)<<7;
Return bitReturn;
}
月中的時(shí)候我告訴自己每個(gè)月應(yīng)該堅(jiān)持寫一篇博客把自己學(xué)到的東西記下來,說不定將來要跳槽呢……今天29號(hào)了……不知道還有沒有下一篇哈哈哈哈。
總結(jié)
以上是生活随笔為你收集整理的c语言高低位拷贝_C语言中的大小端转换与高低位颠倒的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java学习之文件操作
- 下一篇: 嵌入式CANopen协议从入门到落地产品