位移及其逻辑运算符

时间:2012-03-20 13:43:39

标签: c++ c

下面这个程序移动最后一个(初级)和倒数第二个字节变量i type int。我试图理解为什么程序员写这个

i = (i & LEADING_TWO_BYTES_MASK) | ((i & PENULTIMATE_BYTE_MASK) >> 8) | ((i & LAST_BYTE_MASK) << 8);

任何人都可以用简单的英语向我解释在下面的程序中发生的事情。

#include <stdio.h>
#include <cstdlib>

#define LAST_BYTE_MASK 255 //11111111
#define PENULTIMATE_BYTE_MASK 65280 //1111111100000000
#define LEADING_TWO_BYTES_MASK 4294901760 //11111111111111110000000000000000


int main(){
    unsigned int i = 0;
    printf("i = ");
    scanf("%d", &i);
    i = (i & LEADING_TWO_BYTES_MASK) | ((i & PENULTIMATE_BYTE_MASK) >> 8) | ((i & LAST_BYTE_MASK) << 8);
    printf("i = %d", i);
    system("pause");
}

3 个答案:

答案 0 :(得分:8)

因为你要求简单的英语:他交换整数的第一个和第二个字节。

答案 1 :(得分:6)

这个表达确实有点复杂,但实际上作者这样做了:

// Mask out relevant bytes
unsigned higher_order_bytes = i & LEADING_TWO_BYTES_MASK;
unsigned first_byte = i & LAST_BYTE_MASK;
unsigned second_byte = i & PENULTIMATE_BYTE_MASK;

// Switch positions:
unsigned first_to_second = first_byte << 8;
unsigned second_to_first = second_byte >> 8;

// Concatenate back together:
unsigned result = higher_order_bytes | first_to_second | second_to_first;

顺便说一句,使用十六进制表示法定义掩码比使用十进制更可读。此外,在这里使用#define是错误的。 C和C ++都有const

unsigned const LEADING_TWO_BYTES_MASK = 0xFFFF0000;
unsigned const PENULTIMATE_BYTE_MASK = 0xFF00;
unsigned const LAST_BYTE_MASK = 0xFF;

要理解此代码,您需要了解&|和位移are doing on the bit level

答案 2 :(得分:3)

以十六进制而不是十进制来定义掩码更有启发性,因为它们直接对应于二进制表示,并且很容易看到哪些位是打开和关闭的:

#define LAST 0xFF          // all bits in the first byte are 1
#define PEN 0xFF00         // all bits in the second byte are 1
#define LEAD 0xFFFF0000    // all bits in the third and fourth bytes are 1 

然后

i = (i & LEAD)             // leave the first 2 bytes of the 32-bit integer the same
    | ((i & PEN) >> 8)     // take the 3rd byte and shift it 8 bits right
    | ((i & LAST) << 8)    // take the 4th byte and shift it 8 bits left 
    );

因此表达式交换两个最低有效字节,同时保留两个最高有效字节。