交换整数中的交替字节

Swap alternate bytes in a integer

问题:交换备用字节如下:

输入:uint8_t buf[4] = {0xab,0xcd,0xef,0xba};

输出:0xcdababef

我有下面的代码可以做到这一点,但我想知道是否有更好的方法来缩短代码。

#include <stdint.h>
#define SWAP_16(buf) (((buf & 0xFF00) >> 8) | ((buf & 0x00FF) << 8))
int main()
{
    unsigned int value;
    int i, j=0;
    uint8_t buf[4] = {0,4,0,0};
    unsigned int mask = 0xFFFF;
    unsigned int tmp_value;
    unsigned int size = 4;

    for (i = size - 1 ;i >= 0; i--) {
        tmp_value |= (buf[j] << 8*i);
        j++;
    }

    value = SWAP_16((tmp_value & (mask << 16)) >> 16) << 16 |
        SWAP_16(tmp_value & mask);  
    return 0;
}

使用联合

#include <stdint.h>


#define SWAP_VAR(T, v1, v2) do { \
  T v = (v1); \
  (v1) = (v2); \
  (v2) = v; \
} while (0);

union U32
{
  uint32_t u;
  unsigned char a[4];
};

uint32_t swap32(uint32_t u)
{
  union U32 u32 = {u};

  SWAP_VAR(unsigned char, u32.a[0], u32.a[1]);
  SWAP_VAR(unsigned char, u32.a[2], u32.a[3]);

  return u32.u;
}

这样使用:

#include <stdint.h>

uint32_t swap32(uint32_t u);


int main(void)
{
  uint32_t u = 0x12345678;
  u = swap32(u);
}
unsigned int forward = 0x12345678;
unsigned int reverse;

unsigned char *f = &forward;
unsigned char *r = &reverse;

r[0]=f[3];
r[1]=f[2];
r[2]=f[1];
r[3]=f[0];

现在反转为 0x78563412

这是一种方法:

#include <stdio.h>
#include <stdint.h>

int main(void)
{
    uint8_t buf[4] = {0xab,0xcd,0xef,0xba};

    unsigned int out = buf[1] * 0x1000000u + buf[0] * 0x10000u + buf[3] * 0x100u + buf[2];
    printf("%x\n", out);
}

从你的问题中不能立即清楚它是否不是一个选项,但如果你知道大小不会改变,你可以只交换数组中的字节:

#include <stdio.h>
#include <stdint.h>
#define SWAPPED(b) { b[1], b[0], b[3], b[2] }
#define PRINT(b) printf("0x0%x\n", *((uint32_t*)b));

int main()
{
    uint8_t buf[4] = {8,4,6,1};
    uint8_t swapped[4] = SWAPPED(buf);
    PRINT(buf);
    PRINT(swapped);
    return 0;
}

我机器上的输出是:

0x01060408
0x06010804

这是因为字节序和打印一个转换为整数类型的数组,但字节会按照您在问题中的提问进行交换。

希望对您有所帮助。

假设 unsigned int 是 32 位,您可以简单地使用:

value = ((value & 0xff00ff00) >> 8) | ((value & 0x00ff00ff) << 8);

交换value中每对字节中的字节。它与您的 SWAP_16() 宏类似,只是它同时处理了值的两半。

unsigned int n = ((unsigned int)buf[0] << 16) |
                 ((unsigned int)buf[1] << 24) |
                 ((unsigned int)buf[2] <<  0) |
                 ((unsigned int)buf[3] <<  8);