3

我有这个面试问题-

在整数序列中交换字节2和字节。4整数是一个4字节宽,即 32 位

我的方法是使用char *pointer和 atemp char交换字节。为了清楚起见,我已经打破了这些步骤,否则可以考虑使用字符数组。

unsigned char *b2, *b4, tmpc;
int n = 0xABCD; ///expected output 0xADCB
b2 = &n;   b2++;  
b4 = &n;   b4 +=3;
///swap the values;
tmpc = *b2;
*b2 = *b4;
*b4 = tmpc;

还有其他方法吗?

4

3 回答 3

7
int someInt = 0x12345678;

int byte2 = someInt & 0x00FF0000;
int byte4 = someInt & 0x000000FF;
int newInt = (someInt & 0xFF00FF00) | (byte2 >> 16) | (byte4 << 16);

为避免对符号扩展的任何担忧:

int someInt = 0x12345678;
int newInt = (someInt & 0xFF00FF00) | ((someInt >> 16) & 0x000000FF) | ((someInt << 16) & 0x00FF0000);

(或者,要真正打动他们,您可以使用三重异或技术。)

只是为了好玩(可能是某个地方的图波):

int newInt = someInt ^ ((someInt >> 16) & 0x000000FF);
newInt = newInt ^ ((newInt << 16) & 0x00FF0000);
newInt = newInt ^ ((newInt >> 16) & 0x000000FF);

(实际上,我只是测试了它并且它有效!)

于 2013-07-01T17:11:59.023 回答
4

你可以屏蔽掉你想要的字节并将它们移动。像这样的东西:

unsigned int swap(unsigned int n) {
  unsigned int b2 = (0x0000FF00 & n);
  unsigned int b4 = (0xFF000000 & n);
  n ^= b2 | b4;                 // Clear the second and fourth bytes
  n |= (b2 << 16) | (b4 >> 16); // Swap and write them.
  return n;
}

这假定“第一个”字节是最低位字节(即使在内存中它可能存储为big-endian)。

此外,它在任何地方都使用无符号整数来避免由于符号扩展而引入额外的 1 的右移。

于 2013-07-01T17:12:35.933 回答
2

工会呢?

int main(void)
{
    char  tmp;
    union {int n; char ary[4]; } un;

    un.n = 0xABCDEF00;
    tmp = un.ary[3];
    un.ary[3] = un.ary[1];
    un.ary[1] = tmp;
    printf("0x%.2X\n", un.n);
}

> 0xABCDEF00

输出>0xEFCDAB00

请不要忘记检查字节序。这仅适用于小端,但不难使其便携。

于 2013-07-01T17:57:52.260 回答