给字节存在的字节值(作业)

时间:2014-03-20 11:04:26

标签: c bit-manipulation

我需要做一个我切换某个int的值的赋值。例如:0xaabbccdd应该转为0xddccbbaa

我已经从给定数字中提取了所有字节,它们的值是正确的。

unsigned int input;

scanf("%i", &input);

unsigned int first_byte = (input >> (8*0)) & 0xff;
unsigned int second_byte = (input >> (8*1)) & 0xff;
unsigned int third_byte = (input >> (8*2)) & 0xff;
unsigned int fourth_byte = (input >> (8*3)) & 0xff;

现在我正在尝试将一个空的int变量(又名00000000 00000000 00000000 00000000)设置为这些字节值,但转过来了。那么我怎么能说空变量的第一个字节是给定输入的第四个字节呢?我一直在尝试不同的按位运算组合,但我似乎无法绕过它。我很确定我应该能够做到这样的事情:

answer *first byte* | fourth_byte;

我会感激任何帮助,因为我已经被困住了,并且在几个小时内寻找答案。

4 个答案:

答案 0 :(得分:4)

根据您的代码:

#include <stdio.h>

int main(void)
{
    unsigned int input = 0xaabbccdd;
    unsigned int first_byte = (input >> (8*0)) & 0xff;
    unsigned int second_byte = (input >> (8*1)) & 0xff;
    unsigned int third_byte = (input >> (8*2)) & 0xff;
    unsigned int fourth_byte = (input >> (8*3)) & 0xff;

    printf(" 1st : %x\n 2nd : %x\n 3rd : %x\n 4th : %x\n", 
        first_byte, 
        second_byte, 
        third_byte, 
        fourth_byte);

    unsigned int combo = first_byte<<8 | second_byte;
    combo = combo << 8 | third_byte;
    combo = combo << 8 | fourth_byte;

    printf(" combo : %x ", combo);

    return 0;
}

将输出0xddccbbaa

这是一个更优雅的功能:

unsigned int setByte(unsigned int input, unsigned char byte, unsigned int position)
{
    if(position > sizeof(unsigned int) - 1)
        return input;

    unsigned int orbyte = byte;
    input |= byte<<(position * 8);

    return input;
}

用法:

unsigned int combo = 0;
    combo = setByte(combo, first_byte, 3);
    combo = setByte(combo, second_byte, 2);
    combo = setByte(combo, third_byte, 1);
    combo = setByte(combo, fourth_byte, 0);

    printf(" combo : %x ", combo);

答案 1 :(得分:1)

unsigned int result;

result =((first_byte&lt;&lt;(8 * 3))|(second_byte&lt;&lt;(8 * 2))|(third_byte&lt;&lt;(8 * 1))|(fourth_byte))< / p>

答案 2 :(得分:1)

您可以在尝试时提取字节并将它们按顺序放回,这是一种非常有效的方法。但这里还有其他一些可能性:

bswap,如果您有权访问它。这是一个x86指令就是这样做的。它没有变得更简单。其他平台上可能存在类似的指令。虽然可能不适合C任务。

或者,交换相邻的“字段”。如果您有AABBCCDD并首先交换相邻的8位组(获取BBAADDCC),然后交换相邻的16位组,则可以根据需要获得DDCCBBAA。这可以实现,例如:(未测试)

x = ((x & 0x00FF00FF) <<  8) | ((x >>  8) & 0x00FF00FF);
x = ((x & 0x0000FFFF) << 16) | ((x >> 16) & 0x0000FFFF);

或者,一种密切相关的方法,但有旋转。在AABBCCDD中,AA和CC都向左旋转8个位置,BB和DD都向右旋转8个位置。所以你得到:

x = rol(x & 0xFF00FF00, 8) | ror(x & 0x00FF00FF, 8);

然而,这需要旋转,大多数高级语言都不提供,并且用两个班次模拟它们并且OR否定了它们的优势。

答案 3 :(得分:0)

#include <stdio.h>

int main(void)
{
    unsigned int input = 0xaabbccdd,
                 byte[4] = {0},
                 n = 0,
                 output = 0;
    do
    {
        byte[n] = (input >> (8*n)) & 0xff;
        n = n + 1;
    }while(n < 4);

    n = 0;
    do
    {
        printf(" %d : %x\n", byte[n]);
        n = n + 1;
    }while (n < 4);

    n = 0;
    do
    {
        output = output << 8 | byte[n];
        n = n + 1;
    }while (n < 4);

    printf(" output : %x ", output );

    return 0;
}

您应该尽量避免重复代码。