【问题标题】:C++ int to byte arrayC++ int 到字节数组
【发布时间】:2011-07-31 22:17:01
【问题描述】:

我的 java 代码中有这个方法,它返回给定 int 的字节数组:

private static byte[] intToBytes(int paramInt)
{
     byte[] arrayOfByte = new byte[4];
     ByteBuffer localByteBuffer = ByteBuffer.allocate(4);
     localByteBuffer.putInt(paramInt);
     for (int i = 0; i < 4; i++)
         arrayOfByte[(3 - i)] = localByteBuffer.array()[i];
     return arrayOfByte;
}

谁能给我提示我如何将该方法转换为 C++?

【问题讨论】:

    标签: c++ arrays byte int


    【解决方案1】:

    你不需要一个完整的函数;一个简单的演员就足够了:

    int x;
    static_cast<char*>(static_cast<void*>(&x));
    

    C++ 中的任何对象都可以重新解释为字节数组。如果你想真正将字节复制到一个单独的数组中,你可以使用std::copy

    int x;
    char bytes[sizeof x];
    std::copy(static_cast<const char*>(static_cast<const void*>(&x)),
              static_cast<const char*>(static_cast<const void*>(&x)) + sizeof x,
              bytes);
    

    这两种方法都没有考虑字节顺序,但由于您可以将 int 重新解释为字节数组,因此您自己执行任何必要的修改是微不足道的。

    【讨论】:

    • 也许吧。不在英特尔机器上(或者至少不会给出相同的结果)。
    • 我很好奇:你为什么用两个static_cast&lt;&gt;s 而不是一个reinterpret_cast&lt;&gt;
    • 详细说明:一两年前,关于 reinterpret_cast 是否保证与 static_cast 对等价的问题进行了长时间的讨论。如果我没记错的话,基本上都同意两者都应该始终有效,但这一切都非常复杂,所以我仍然避免reinterpret_cast
    • 这种方法的结果似乎取决于字节序。假设 x=0x4142,在小端机器上运行这个过程,迭代字节数组并打印每个字节,你会得到“BA”。如果你想得到“AB”,你必须自己反转结果。
    • 将int转换为字节数组是否定义明确?我认为像访问其他类型一样访问对象是未定义的行为。
    【解决方案2】:

    使用std::vector&lt;unsigned char&gt;

    #include <vector>
    using namespace std;
    
    vector<unsigned char> intToBytes(int paramInt)
    {
         vector<unsigned char> arrayOfByte(4);
         for (int i = 0; i < 4; i++)
             arrayOfByte[3 - i] = (paramInt >> (i * 8));
         return arrayOfByte;
    }
    

    【讨论】:

    • Java 代码生成大端表示;你生成一个小端序。 (我也只是使用移位计数作为循环控制:int i = 32; while ( i != 0 ) { arrayOfByte[i] = paramInt &gt;&gt; i; i -= 8; }
    • @JamesKanze: 等等...你真的可以使用i 访问arrayOfByte,当它的值是[32, 24, 16, 8] 时?我认为你应该这样做arrayOfByte[i/8]
    • @TomášZato 是的;索引应该是i/8
    【解决方案3】:

    您可以通过 anding 和 shift 操作获取单个字节:

    byte1 =  nint & 0x000000ff
    byte2 = (nint & 0x0000ff00) >> 8
    byte3 = (nint & 0x00ff0000) >> 16
    byte4 = (nint & 0xff000000) >> 24
    

    【讨论】:

      【解决方案4】:

      我使用的另一种有用的方法是联合:

      union byteint
      {
          byte b[sizeof int];
          int i;
      };
      byteint bi;
      bi.i = 1337;
      for(int i = 0; i<4;i++)
          destination[i] = bi.b[i];
      

      这将使字节数组和整数“重叠”(共享相同的内存)。 这可以用各种类型来完成,只要字节数组的大小与类型相同(否则其中一个字段不会受到另一个字段的影响)。当您必须在整数操作和字节操作/复制之间切换时,将它们作为一个对象也很方便。

      【讨论】:

      • 从错误的联合成员读取是未定义的行为和滥用联合
      • 这是错误的。这不是工会的目的。这不是工会的工作方式。神话!
      • 在某些机器上这是非常聪明的,但遗憾的是它不是标准的并且很危险。见this union reference。 “联合仅与容纳其最大数据成员所需的一样大。其他数据成员分配在与该最大成员的一部分相同的字节中。该分配的细节是实现定义的,它是未定义的行为从最近未编写的联合成员中读取。 许多编译器作为非标准语言扩展实现了读取联合中非活动成员的能力。”
      【解决方案5】:
      std::vector<unsigned char> intToBytes(int value)
      {
          std::vector<unsigned char> result;
          result.push_back(value >> 24);
          result.push_back(value >> 16);
          result.push_back(value >>  8);
          result.push_back(value      );
          return result;
      }
      

      【讨论】:

        【解决方案6】:

        Int 到字节,反之亦然。

        unsigned char bytes[4];
        unsigned long n = 1024;
        
        bytes[0] = (n >> 24) & 0xFF;
        bytes[1] = (n >> 16) & 0xFF;
        bytes[2] = (n >> 8) & 0xFF;
        bytes[3] = n & 0xFF;
        
        printf("%x %x %x %x\n", bytes[0], bytes[1], bytes[2], bytes[3]);
        
        
        int num = 0;
        for(int i = 0; i < 4; i++)
         {
         num <<= 8;
         num |= bytes[i];
         }
        
        
        printf("number %d",num);
        

        【讨论】:

          【解决方案7】:

          int(或任何其他数据类型)已经作为字节存储在内存中。那么为什么不直接复制内存呢?

          memcpy(arrayOfByte, &x, sizeof x);
          

          一个简单优雅的单行列,也适用于任何其他数据类型。



          如果您需要反转字节,您可以使用 std::reverse

          memcpy(arrayOfByte, &x, sizeof x);
          std::reverse(arrayOfByte, arrayOfByte + sizeof x);
          

          或者更好的是,只需反向复制字节以开始

          BYTE* p = (BYTE*) &x;
          std::reverse_copy(p, p + sizeof x, arrayOfByte);
          

          如果你根本不想复制数据,只需要它的字节表示

          BYTE* bytes = (BYTE*) &x;
          

          【讨论】:

            【解决方案8】:
            return ((byte[0]<<24)|(byte[1]<<16)|(byte[2]<<8)|(byte[3]));
            

            :D

            【讨论】:

            • 他问的正好相反 :)
            • 哇,我失败了!总是觉得如果我不立即回复,会有一百万人会回复。我是对的,但我想我应该确保问题正确哈哈哈
            • 是的,我也是尽量快点回答,有时候会写出这样的废话;)
            • 还是有用的。
            【解决方案9】:

            我知道这个问题已经有了答案,但我会给出我的解决方案。我正在使用模板函数和整数约束。

            这是我的解决方案:

            #include <type_traits>
            #include <vector>
            
            template <typename T,
                      typename std::enable_if<std::is_arithmetic<T>::value>::type* = nullptr>
            std::vector<uint8_t> splitValueToBytes(T const& value)
            {
                std::vector<uint8_t> bytes;
            
                for (size_t i = 0; i < sizeof(value); i++)
                {
                    uint8_t byte = value >> (i * 8);
                    bytes.insert(bytes.begin(), byte);
                }
            
                return bytes;
            }
            

            【讨论】:

              【解决方案10】:

              希望能帮到你

              template <typename t_int>
              std::array<uint8_t, sizeof (t_int)> int2array(t_int p_value) {
                  static const uint8_t _size_of (static_cast<uint8_t>(sizeof (t_int)));
                  typedef std::array<uint8_t, _size_of> buffer;
                  static const std::array<uint8_t, 8> _shifters = {8*0, 8*1, 8*2, 8*3, 8*4, 8*5, 8*6, 8*7};
              
                  buffer _res;
                  for (uint8_t _i=0; _i < _size_of; ++_i) {
                      _res[_i] = static_cast<uint8_t>((p_value >> _shifters[_i]));
                  }
                  return _res;
              }
              

              【讨论】:

                猜你喜欢
                • 2016-04-05
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-08-12
                • 2010-11-22
                相关资源
                最近更新 更多