2014-09-03 132 views
0

我有一個程序,我的教授給我一個硬件,我想看看你們是否可以解釋我是如何工作的。注意:我不想讓你們給我答案;我想學習,所以如果你們能向我解釋這項工作是如何令人敬畏的,那麼我可以在我的主持下開始工作。在C程序中對位掩碼的理解

說明:

一個)unsigned setbits (unsigned x, int p, int n, unsigned y)其返回x與開始位置p處的n位(右調整)設置爲y的最右邊的n位,而使其他位不變。注意:雖然它不會更改x和y的值。

b)unsigned invertbits (unsigned x, int p, int n)返回x,其中在位置p(右調整)開始的n位反轉,即1變爲0,反之亦然,其餘位保持不變。注意:它不會改變x的值。

#include <stdio.h> 
#include <limits.h> 

void bit_print(int); 
int pack(char, char, char, char); 
char unpack(int, int); 
unsigned getbits(unsigned, int, int); 

void bit_print(int a){ 
    int i; 
    int n = sizeof(int) * CHAR_BIT; 
    int mask = 1 << (n-1); // mask = 100...0 

    for (i=1; i<=n; i++){ 
     putchar(((a & mask) == 0)? '0' : '1'); 
     a <<= 1; 
     if (i % CHAR_BIT == 0 && i < n) 
      putchar(' '); 
    } 
    putchar('\n'); 
} 

int pack(char a, char b, char c, char d){ 
    int p=a; 
    p = (p << CHAR_BIT) | b; 
    p = (p << CHAR_BIT) | c; 
    p = (p << CHAR_BIT) | d; 
    return p; 
} 

char unpack(int p, int k){ // k=0, 1, 2, or 3 
    int n = k * CHAR_BIT; // n = 0, 8, 16, 24 
    unsigned mask = 255; // mask = low-order byte 

    mask <<= n; 
    return ((p & mask) >> n); 
} 

// getbits() extracts n bits from position p(start counting from the right-most bit) in x 
unsigned getbits(unsigned x, int p, int n){ 
    unsigned temp = x >> (p+1-n); 

    unsigned mask = 0; 
    mask = ~mask; 
    mask = mask << n; 
    mask = ~mask; 

    return temp & mask; 
    // return (x >> (p+1-n)) & ~(~0<<n); 
} 

int main(){ 
    int x = 19; 

    printf("The binary rep. of %d is:\n", x); 
    bit_print(x); 

    int p=pack('w', 'x', 'y', 'z'); 
    printf("\n'w', 'x', 'y', and 'z' packed together is equal to %d. Its binary rep. is:\n", p); 
    bit_print(p); 
    printf("calling unpack(p, 0) to extract the byte # 0 from the right:\n"); 
    bit_print(unpack(p, 0)); 
    printf("calling unpack(p, 1) to extract the byte # 1 from the right:\n"); 
    bit_print(unpack(p, 1)); 
    printf("calling unpack(p, 2) to extract the byte # 2 from the right:\n"); 
    bit_print(unpack(p, 2)); 
    printf("calling unpack(p, 3) to extract the byte # 3 from the right:\n"); 
    bit_print(unpack(p, 3)); 

    unsigned result = getbits(p, 20, 7); 
    printf("\ncalling getbits(p, 20, 7) to extract 7 bits from bit # 20 returns %d:\n", result); 
    bit_print(result); 

    return 0; 
} 
+0

您有具體問題嗎?如何工作是非常廣泛的,它看起來像它會在你的課程涵蓋之前,這項作業被分配。 – 2014-09-03 16:23:36

+0

@RetiredNinja他們給了我們一個介紹,但我不明白 – fuscode 2014-09-03 16:42:18

回答

1

使用按位與&,或|,XOR ^,NOT ~和適當的位掩碼可以操縱一個變量中位。您還需要位移>><<

所以,讓我們有一個例子:

讓我們8位VAR x = 0xff,並嘗試反轉其3'rd位:

unsigned char x = 0xff; // Our var 
unsigned char mask = 1<<3; // Our mask 
x = x & ~mask; // Invert mask so its value is b1111_0111 
       // and make a bitwise AND with x 

x中的每一位保持其值,如果有1掩碼,當掩碼位值爲0時變爲0.現在x值爲x = 0xf7。 任何你想要的比特:)使用其它運營商可以做

因此,例如,你的解壓功能的作用:

char unpack(int p, int k){ // k - byte offset 
    int n = k * CHAR_BIT;  // n - bit offset (k * 8) 
    unsigned mask = 255;  // mask with all ones at first byte (0x000f) 
    mask <<= n;    // move mask left n times; 
          // Now the ones are at the k'th byte 
          // if k = 2 => mask = 0x0f00 
    return ((p & mask) >> n); // Mask out k'th byte of p and remove all zeros 
          // from beginning. 
} 

p = 0x3579k = 1

n = k * CHAR_BIT; // n = 8 
mask = 255;  // mask = 0x000f 
mask <<= n;  // mask = 0x00f0 
p &= mask;  // p = 0x0070 
p >>= n;   // p = 0x0007 

我希望這將有助於您!

+0

'>>':當心簽名擴展。 – Arkadiy 2014-09-03 17:38:40

+0

哦,是的,當然!我忘了提及:總是使用無符號類型處理比特! – kleszcz 2014-09-03 17:40:55