用C ++进行整数字节交换

时间:2010-10-12 15:08:51

标签: c++ byte bit-manipulation

我正在为我的C ++课做家庭作业。我正在研究的问题如下:

  

编写一个带有无符号short int(2个字节)的函数并交换字节。例如,如果交换后x = 258(00000001 00000010),x将为513(00000010 00000001)。

到目前为止,这是我的代码:

#include <iostream>

using namespace std;

unsigned short int ByteSwap(unsigned short int *x);

int main()
{
  unsigned short int x = 258;
  ByteSwap(&x);

  cout << endl << x << endl;

  system("pause");
  return 0;
}

unsigned short int ByteSwap(unsigned short int *x)
{
  long s;
  long byte1[8], byte2[8];

  for (int i = 0; i < 16; i++)
  {
    s = (*x >> i)%2;

    if(i < 8)
    {
      byte1[i] = s;
      cout << byte1[i];
    }
    if(i == 8)
      cout << " ";

    if(i >= 8)
    {
      byte2[i-8] = s;
      cout << byte2[i];
    }
  }

  //Here I need to swap the two bytes
  return *x;
}   

我的代码有两个问题,我希望你可以帮我解决。

  1. 由于某些原因,我的两个字节都是01000000
  2. 我真的不确定如何交换字节。我的老师关于位操作的注意事项非常破碎,难以理解,并且对我没有多大意义。
  3. 非常感谢您提前。我真的很感谢你帮助我。

11 个答案:

答案 0 :(得分:20)

我认为你过度复杂,如果我们假设一个短的由2个字节(16位)组成,你需要的只是 要做的是

  • 提取高字节hibyte = (x & 0xff00) >> 8;
  • 提取低字节lobyte = (x & 0xff);
  • 以相反的顺序x = lobyte << 8 | hibyte;
  • 组合它们

答案 1 :(得分:7)

看起来你正试图一次交换它们。那有点......疯了。你需要做的是隔离2个字节,然后做一些移位。让我们分解一下:

uint16_t x = 258;

uint16_t hi = (x & 0xff00); // isolate the upper byte with the AND operator

uint16_t lo = (x & 0xff); // isolate the lower byte with the AND operator

现在你只需要以相反的顺序重新组合它们:

uint16_t y = (lo << 8); // shift the lower byte to the high position and assign it to y
y |= (hi >> 8);         // OR in the upper half, into the low position

当然,这可以用更少的步骤完成。例如:

uint16_t y = (lo << 8) | (hi >> 8);

或者不使用任何临时变量进行交换:

uint16_t y = ((x & 0xff) << 8) | ((x & 0xff00) >> 8);       

答案 2 :(得分:4)

你正在努力工作。

你只需要交换字节。因此,弄清楚如何提取两个字节值,然后如何以相反的方式重新组装它们

(作业所以没有给出完整答案)

编辑:不知道为什么我感到困扰:)回答家庭作业问题的有用性是通过OP(以及其他读者)学习的程度来衡量的,而不是通过直接给出homewortk问题的答案来最大化。 ..

答案 3 :(得分:3)

Jerry建议将short视为两个字节的数组:

#include <iostream>
typedef union mini
{
    unsigned char b[2];
    short s;
} micro;
int main()
{
    micro x;
    x.s = 258;
    unsigned char tmp = x.b[0];
    x.b[0] = x.b[1];
    x.b[1] = tmp;
    std::cout << x.s << std::endl;
}

答案 4 :(得分:3)

这是一个逐字节演示的展开示例:

unsigned int swap_bytes(unsigned int original_value)
{
  unsigned int new_value = 0; // Start with a known value.
  unsigned int byte;          // Temporary variable.

  // Copy the lowest order byte from the original to
  // the new value:
  byte = original_value & 0xFF;  // Keep only the lowest byte from original value.
  new_value = new_value * 0x100; // Shift one byte left to make room for a new byte.
  new_value |= byte;             // Put the byte, from original, into new value.

  // For the next byte, shift the original value by one byte
  // and repeat the process:
  original_value = original_value >> 8; // 8 bits per byte.
  byte = original_value & 0xFF;  // Keep only the lowest byte from original value.
  new_value = new_value * 0x100; // Shift one byte left to make room for a new byte.
  new_value |= byte;             // Put the byte, from original, into new value.

  //...
  return new_value;
}

答案 5 :(得分:1)

虽然可以通过位操作来执行此操作,但如果您愿意,也可以不使用。无论哪种方式,你不应该需要任何循环。要在没有位操作的情况下执行此操作,您将short视为两个char的数组,并交换两个char,大致与交换两个or的方式相同(例如)对数组进行排序时的项目。

要使用位操作,交换版本基本上是向左移位8位unsigned d的低位字节,其中上半部分向左移位8位。您可能希望将其视为{{1}}类型,以确保在执行右移时上半部分不会填充一位。

答案 6 :(得分:1)

这对你也有用。

#include <iostream>

int main() {
    unsigned int i = 0xCCFF;
    std::cout << std::hex << i << std::endl;

    i  = ( ((i<<8) & 0xFFFF) | ((i >>8) & 0xFFFF)); // swaps the bytes

    std::cout << std::hex << i << std::endl;
}

答案 7 :(得分:1)

#include <stdio.h>


int main()
{
   unsigned short a = 258;

   a = (a>>8)|((a&0xff)<<8);

   printf("%d",a);


}

答案 8 :(得分:0)

这是一个问题:

byte2[i-8] = s;
cout << byte2[i];//<--should be i-8 as well

这导致缓冲区溢出。

但是,这不是一个很好的方法。查看位移运算符&lt;&lt;和&gt;&gt;。

答案 9 :(得分:0)

有点老式,但仍然很有趣。

XOR交换:(见How does XOR variable swapping work?

    #include <iostream>
    #include <stdint.h>
    int main()
    {
        uint16_t x = 0x1234;
        uint8_t *a = reinterpret_cast<uint8_t*>(&x);
        std::cout << std::hex << x << std::endl;
        *(a+0) ^= *(a+1) ^= *(a+0) ^= *(a+1);
        std::cout << std::hex << x << std::endl;
    }

答案 10 :(得分:0)

使用库函数,以下代码可能有用(在非家庭作业环境中):

unsigned long swap_bytes_with_value_size(unsigned long value, unsigned int value_size) {
    switch (value_size) {
        case sizeof(char):
            return value;

        case sizeof(short):
            return _byteswap_ushort(static_cast<unsigned short>(value));

        case sizeof(int):
            return _byteswap_ulong(value);

        case sizeof(long long):
            return static_cast<unsigned long>(_byteswap_uint64(value));

        default:
            printf("Invalid value size");
            return 0;
    }
}

至少在使用MinGW工具链时,stdlib.h中定义了字节交换功能。