轉換的字節數組時到短/ INT /長我想知道如果系統字節序的事項。如果代碼在big-endian和little-endian機器上運行,這會不正確嗎?轉換字節陣列(char數組),以一個整數類型(短整型,整型,長)
short s = (b[0] << 8) | (b[1]);
int i = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3])
轉換的字節數組時到短/ INT /長我想知道如果系統字節序的事項。如果代碼在big-endian和little-endian機器上運行,這會不正確嗎?轉換字節陣列(char數組),以一個整數類型(短整型,整型,長)
short s = (b[0] << 8) | (b[1]);
int i = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3])
是的,字節順序很重要。在little endian中,short或int的上半部分是最重要的字節 - 即short爲8-15,int爲24-31。大端字節順序將需要扭轉:
short s = ((b[1] << 8) | b[0]);
int i = (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0]);
注意,這個假設的字節數組是小尾數順序。字節數組和整數類型之間的字節順序和轉換不僅取決於CPU的字節順序,還取決於字節數組數據的字節順序。
建議在功能將知道(或者通過編譯標誌或在運行時)來包裝這些轉換的系統的字節序和正確地執行轉換。
另外,開創了字節數組數據的標準(總是大端,例如),然後使用socket
ntoh_s
和ntoh_l
會卸載有關字節序的OS socket
實現,意識到這樣的事情的決定。請注意,默認的網絡順序是big endian(n
,位於ntoh_x
),所以將字節數組數據設置爲big endian是實現此目的最直接的方法。
作爲由OP(@Mike),boost
還提供端序轉換函數指出。
如何在同一機器上使用與CPU不同的字節序列數據? –
嗯好吧,讓所有的字節數組在big-endian中確實讓事情變得更簡單。因此,爲了轉換爲實際類型,我可以使用類似boost的asio庫來完成上述代碼之後的轉換(例如s = ntohs(s)),並且在編碼時,我可以使用htons() – Mike
@HunterMcMillen - Easy:for短0x1234你可以有字節數組[0x12,0x34]和[0x34,0x12]。第一個是大端,第二個是小端。 –
沒有,那也沒關係,只要字節順序而言的,但你可能有問題,如果你的int
s爲只有16位寬。
你指定的問題,你正在使用現有的字節數組,將在所有機器上正常工作。你會得到相同的答案。
但是,這取決於你如何創建一個流,可以通過字節序的影響,可能會無法用你認爲你會數結束。
// on little endian:
unsigned char c[] = { 1, 0 }; // "one" in little endian order { LSB, MSB }
int a = (c[1] << 8) | c[0]; // a = 1
// ----------------------------------------- -----------------------------------
// on big endian:
unsigned char c[] = { 0, 1 }; // "one" in big endian order { MSB, LSB }
int a = (c[1] << 8) | c[0]; // a = 1
// ------ -------------------------------------------------- --------------------
// on little endian:
unsigned char c[] = { 0, 1 }; // "one" in big endian order { MSB, LSB }
int a = (c[0] << 8) | c[1]; // a = 1 (reverse byte order)
// --------------------- -------------------------------------------------- -----
// on big endian:
unsigned char c[] = { 1, 0 }; // "one" in little endian order { LSB, MSB }
int a = (c[0] << 8) | c[1]; // a = 1 (reverse byte order)
您可以爲此使用工會。字節順序很重要,爲了改變它,你可以使用x86 BSWAP指令(或其他平臺的類似物),由大多數c編譯器提供作爲內部函數。
#include <stdio.h>
typedef union{
unsigned char bytes[8];
unsigned short int words[4];
unsigned int dwords[2];
unsigned long long int qword;
} test;
int main(){
printf("%d %d %d %d %d\n", sizeof(char), sizeof(short), sizeof(int), sizeof(long), sizeof(long long));
test t;
t.qword=0x0001020304050607u;
printf("%02hhX|%02hhX|%02hhX|%02hhX|%02hhX|%02hhX|%02hhX|%02hhX\n",t.bytes[0],t.bytes[1] ,t.bytes[2],t.bytes[3],t.bytes[4],t.bytes[5],t.bytes[6],t.bytes[7]);
printf("%04hX|%04hX|%04hX|%04hX\n" ,t.words[0] ,t.words[1] ,t.words[2] ,t.words[3]);
printf("%08lX|%08lX\n" ,t.dwords[0] ,t.dwords[1]);
printf("%016qX\n" ,t.qword);
return 0;
}
如果你在同一臺機器上做那麼沒有也沒關係,如果您要發送它在網絡上的機器*威力*有不同的字節序,然後試圖轉換,那麼是的,這很重要。 –
簡短的回答是,大於1個字節的整數對字節順序很重要。不適用於其他任何東西(在「普通」計算機上) – xaxxon