2012-03-20 120 views
3

下面的程序移動最後(初級)和倒數第二個字節變量,我輸入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"); 
} 

回答

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

8

既然你問了簡單的英語:他交換整數的第一個和第二個字節。

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

所以表達式交換兩個最低有效字節,同時保留兩個最高有效字節。