下面这个程序移动最后一个(初级)和倒数第二个字节变量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");
}
答案 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
);
因此表达式交换两个最低有效字节,同时保留两个最高有效字节。