交换未知变量类型的每两位

时间:2013-09-26 17:17:17

标签: c bit-manipulation bit generic-programming

我需要将每两个相邻位交换为一个通用操作,这将对给定的每个变量类型执行此操作。

我想到了每个字节所需的掩码和操作:

(var & 0x55) << 1 | (var & 0xAA) >> 1

但是如何让这个适用于让我们说一个整数? 我是否需要使用上述掩码创建sizeof(int) unsigned char的数组并以此方式应用操作?

3 个答案:

答案 0 :(得分:4)

您可以逐字节执行此操作(与char相同)。

例如:

int n = 0xAA55A55A;
unsigned char *p = (unsigned char *) &n;

for (; p < (unsigned char *) &n + sizeof(n); p++)
   *p = (*p & 0x55) << 1 | (*p & 0xAA) >> 1;

答案 1 :(得分:2)

两个建议: 您可以使用256个字符的查找表来代替使用逻辑运算。

char lookUpTable[256] = {0x00, 0x02, 0x01 ...};

如果您不想静态初始化此查找,可以编写一个使用逻辑运算初始化它的函数。

如果要交换字节b,只需编写lookUpTable [b],或者用函数包装它。

至于交换任何类型,你编写一个类似于:

的函数
void SwapBits(char* data, size_t len)
{
    For (; len > 0; len--)
    {
        *data = lookUpTable[*data];
        data++;
    }
}

然后你可以这样使用:

AnyType swapMe = whatever;
SwapBits((char*)(&swapMe), sizeof(AnyType));

请注意,这将取代swapMe的“内容”。

还有一件事,右移行为是特定于架构的,一些架构可能在右移时签署。使用如下表达式会更通用:

SwappedByte = ((Byte >> 1)&0x55) | ((Byte << 1)&0xaa)

通过这种方式,您可以删除任何符号扩展工件。

答案 2 :(得分:1)

像这样的东西。将任何变量的地址转换为char *,然后迭代字节。

#include <stdio.h>

char swap_c(char);
void swap_r(char *, int);

int main(void) {
    char c = 10;
    c = swap_c(c);
    printf("%i\n", c);
    int i = 10;
    char * r = (char *) &i; //you can cast the address of any variable into a char *
    swap_r(r, sizeof(int));
    printf("%i\n", i);
}

void swap_r(char * c, int length) {
    int i = 0;
    while(i < length) {
        c[i] = swap_c(c[i]);
        i++;
    }       
}

char swap_c(char c) {
    return (c & 0x55) << 1 | (c & 0xAA) >> 1;
}

//1010
//0101