【问题标题】:how do i convert an unsigned char array into an unsigned long long?如何将 unsigned char 数组转换为 unsigned long long?
【发布时间】:2016-04-19 05:37:49
【问题描述】:

假设我有 8 个 unsigned char,我想将其转换为 unsigned long long。

例如,如果所有 char 都等于 0xFF,则 unsigned long long 将等于 0xFFFFFFFFFFFFFFFF。

用 C 或 C++ 最有效的方法是什么?

【问题讨论】:

  • 如果所有字符都不等于 0xFF 怎么办?
  • 你的意思是 0xFFFFFFFFFFFFFFFF?
  • 你试过 *reinterpret_cast( your_array );
  • 哪种语言,C 或 C++? C语言没有reinterpret_cast。
  • 大端或小端

标签: c++ c type-conversion


【解决方案1】:

例如:

unsigned char buffer[8] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
unsigned long long target;
memcpy(&target, buffer, sizeof target);

请注意,如果不是buffer 的所有元素都具有相同的值,则结果将取决于字节顺序(小端与大端)。

这也假设unsigned long long 正好是 8 个字节。这通常是正确的,但不能保证。 (也不能保证一个字节正好是 8 位;它可以更多。unsigned char 定义为 1 个字节。)

【讨论】:

  • 使用 <stdint.h> 或 <cstdint> 和 uint64_t 将始终给出 8 个字节。
  • @Jason:不,它总是给出 64 位,或 64 / CHAR_BIT 字节。但是如果你假设CHAR_BIT==8,那么是的,uint64_t 总是 8 个字节(如果它存在的话!)。
  • 非常正确,char 不一定定义为一个字节,这意味着uint64_t 可能无法保存整个字符串。 unsigned long long 的大小不匹配可能会更糟。
  • @Jason:不,char 在 C 和 C++ 中定义为一个字节。一个字节不一定是八位字节(8 位);它可以更大。 unsigned long long 至少为 64 位,但可以更大。另一方面,带有CHAR_BIT > 8 的系统很少见(主要是DSP),而且我从未见过unsigned long long 的大小不是正好64 位。
  • 我知道没有为char 定义签名,但我不认为它实际上被定义为一个字节。
【解决方案2】:

不用memcpy,你可以直接赋值

  unsigned char buffer[8] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
  unsigned long long l = 0;
  for (int i = 0; i < 8; ++i) {
    l = l | ((unsigned long long)buffer[i] << (8 * i));
  }

我相信这不受字节顺序的影响。

【讨论】:

    【解决方案3】:

    很抱歉我最初的愚蠢回答,真的应该更仔细地阅读这个问题。希望这个更有帮助。您转换的方式取决于字节数组中 long long 表示的字节顺序是否与您正在处理的体系结构相匹配。

    C++:

    #include <iostream>
    #include <cstring>
    
    using namespace std;
    
    // Assuming ca is at least 8 bytes, the size of long long, interpret the
    //    first 8 bytes as long long.
    // differentEndian == true means the endianness of the machine is
    //    different from the representation in ca.
    long long getLongLong( unsigned char * ca, bool differentEndian )
    {
       long long retVal;
    
       if (differentEndian)
       {
           for (int i = 0; i < 4; i++)
           {
               unsigned char _tmpCh = ca[i];
               ca[i] = ca[7-i];
               ca[7-i] = _tmpCh;
           }
       }
       retVal = *reinterpret_cast<unsigned long long *>(ca);
    
       return retVal;
    }
    
    int main()
    {
       unsigned char cArray[] = {0xff, 0x1, 0x70, 0x2, 0x61, 0x3, 0x52, 0x4};
    
       unsigned long long ll = getLongLong( cArray, false );
       cout << "Result for same endian: " << hex << ll << " or " << dec << ll << endl;
    
       ll = getLongLong( cArray, true );
       cout << "Result for different endian: " << hex << ll << " or " << dec << ll << endl;
    
       return 0;
    }
    

    C:

    #include <stdio.h>
    #include <string.h>
    
    // Assuming ca is at least 8 bytes, the size of long long, interpret the
    //    first 8 bytes as long long.
    // differentEndian != 0 means the endianness of the machine is
    //    different from the representation in ca.
    long long getLongLong( unsigned char * ca, int differentEndian )
    {
       long long retVal;
    
       if (differentEndian)
       {
           int i;
           for (i = 0; i < 4; i++)
           {
               unsigned char _tmpCh = ca[i];
               ca[i] = ca[7-i];
               ca[7-i] = _tmpCh;
           }
       }
       memcpy( &retVal, ca, sizeof(long long));
    
       return retVal;
    }
    
    int main()
    {
       unsigned char cArray[] = {0xff, 0x1, 0x70, 0x2, 0x61, 0x3, 0x52, 0x4};
    
       unsigned long long ll = getLongLong( cArray, 0 );
       printf("Result for same endian: %llx or %llu\n", ll, ll);
    
       ll = getLongLong( cArray, 1 );
       printf("Result for different endian: %llx or %llu\n", ll, ll);
    
       return 0;
    }
    

    两个版本的输出是:

    Result for same endian: 4520361027001ff or 311315039429591551
    Result for different endian: ff01700261035204 or 1837509111016818739
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多