C 語言中位操作技巧

作者: comcat 發表日期: 2006-10-17 21:04     http://comcat.blog.openrays.org/blog.php?do=showone&tid=130

 

注: 本文僅討論常見的小端機器

1. 聲明

對於RGB模式下, 8 bit 顏色可以用一個字節描述:

7 5 4 2 1 0
|-------|--------|-----|
R G B
|---------------------|


則可以定義數據結構爲:

struct color8
{
unsigned char blue : 2; // 2 bit for B
unsigned char green : 3; // 3 bit for G
unsigned char red : 3; // 3 bit for R
};

容易得到 sizeof(struct color8) 的值爲 1 Byte


注意 struct color8 中成員的聲明順序, 先聲明的成員,在內存中的位置在低位

使用上面的 struct color8, 可以很容易的轉爲1字節,用於顯示:

struct color8 c8;

c8.red = 4; // 值不能超過7
c8.green = 0;
c8.blue = 2;
unsigned char * tran = (unsigned char *)&c8

printf("8 bit color value is: 0x%x\n", *tran);

//100 000 10
則輸出爲: 8 bit color value is: 0x82


2. 賦值

低位賦予原則,直至目的變量之所有位填滿.

如:

struct color8 c8;
unsigned char i = 0x82; // 1000 0010

c8.blue = i; // 將 i 之低2位(1~0)賦給成員blue(長2位), 其值爲 0x2
c8.green = i >> 2; // 將 i 之 4~2 位賦予成員green(長3位), 其值爲 0x0
c8.red = i >> 5; // 將 i 之 7~5 位賦給成員red(長3位), 其值爲 0x4


3. 16bit 值的合併

在RGB模式下, 16 bit 顏色可以用二個字節描述:

15 14 10 9 5 4 0
|---|-------|-------|-------|
| x | R | G | B |
|--------------------------|

struct color16
{
unsigned char b:5;
unsigned char g:5;
unsigned char r:5;
unsigned char ge:1;
};

注意到 sizeof(struct color16) 的值爲 3 Byte

因爲要便於機器訪問以字節爲單位的存儲單元,上述結構在內存中的佈局爲:

7 5 4 0
|------|---------| 低地址
| 0 | b |
|------|---------|
| 0 | g |
|------|---------|
| 0 |ge| r |
|------|---------| 高地址

故而:

struct color16 cx;
cx.r = 4;
cx.g = 1;
cx.b = 3;
cx.ge = 1;
printf(" 0x%x \n", *((unsigned short*)&cx));

輸出爲 0x103,

分析:

經賦值後內存映象爲:

000 00011 -----> 1st byte
000 00001 -----> 2nd byte
001 00100 -----> 3rd byte

強制地址轉換後訪問前二個字節,輸出時則爲: 0000 0001 0000 0011


又:
printf(" 0x%x \n", *((unsigned char*)&cx + 2));

輸出爲 0x24, 即爲第三個字節 0010 0100 的值


經以上分析,在非對齊的數據結構中使用指針強制轉換的方式合併數據位是不可行的,
可用以下方法實現:

unsigned short tt = 0, t = 0;
t = cx.ge;
t <<= 15;
tt = t;

t = cx.r;
t <<= 10;
tt |= t;

t = cx.g;
t <<= 5;
tt |= t;

tt |= cx.b;
發佈了1 篇原創文章 · 獲贊 3 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章