簡體   English   中英

將字節數組(char數組)轉換為整數類型(short,int,long)

[英]Converting byte array (char array) to an integer type (short, int, long)

我想知道在將字節數組轉換為short / int / long時系統字節順序是否重要。 如果代碼在big-endian和little-endian機器上運行,這會不正確嗎?

short s = (b[0] << 8) | (b[1]);
int i = (b[0] << 24) | (b[1] << 16) | (b[2] << 8) | (b[3])

是的,字節序很重要。 在little endian中,你在short或int的上半部分中有最重要的字節 - 即8-15位為short,24-31為int。 對於大端,字節順序需要反轉:

short s = ((b[1] << 8) | b[0]);
int i = (b[3] << 24) | (b[2] << 16) | (b[1] << 8) | (b[0]);

請注意,這假設字節數組是小端序。 字節數組和整數類型之間的字節順序和轉換不僅取決於CPU的字節順序,還取決於字節數組數據的字節順序。

建議將這些轉換包裝在能夠知道(通過編譯標志或在運行時)系統的字節順序並正確執行轉換的函數中。

此外,為字節數組數據創建一個標准(例如,總是大端),然后使用socket ntoh_sntoh_l將關於字節序的決定卸載到知道這些事情的OS socket實現。 請注意,默認網絡順序是大端( ntoh_xn ),因此將字節數組數據作為大端將是最直接的方法。

正如OP(@Mike)所指出的, boost還提供了字節序轉換功能。

// 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[0] << 8) | c[1];         // 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[1] << 8) | c[0];         // 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;
}

不,就endianness而言,這很好,但如果你的int只有16位寬,你可能會遇到問題。

您指定的問題,即使用現有字節數組的地方,可以在所有計算機上正常運行。 你最終會得到同樣的答案。

但是,根據您創建該流的方式,它可能會受到字節序的影響,您可能無法得到您認為的數字。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM