交换整数中的备用字节

时间:2016-10-08 06:58:29

标签: c byte bit swap

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

输入: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;
}

6 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

假设unsigned int是32位,您只需使用:

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

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

答案 2 :(得分: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);
}

答案 3 :(得分:0)

这是一种方式:

#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);
}

答案 4 :(得分:0)

从您的问题中不能立即清楚它是否不是一个选项,但如果您知道尺寸不会改变,那么您只需交换数组中的字节:

#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

这是因为endian-ness并且打印了一个转换为整数类型的数组,但是在你的问题中你可以交换字节。

希望有所帮助。

答案 5 :(得分:0)

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