很多时候我们需要标识某些变量或者事物的状态,即0或者1,对于一个独立的事物,使用一个变量来标识即状态就可以了,如boolean类型(注意C语言中是没有这个类型的)。但遇到一组相似的事物需要同时标识他们的状态时,使用多个变量就显得不太合适了。比如我们经常使用的open函数打开文件时的打开状态,是读方式、写方式、读写方式等。再如,有4个服务进程需要随时报告它们的运行状态(在运行或者不在运行),但由于某些原因我们需要把这4个进程的状态作为参数传递给某个函数处理,要求参数尽可能简单(虽然这种需求有点奇怪^_^),这时候就可以考虑通过位运算作标识了。
下面是位运算的代码:
1 #include <stdio.h> 2 #include <string.h> 3 #include <limits.h> 4 5 #define STATE_1 0X01 6 #define STATE_2 0X02 7 #define STATE_3 0X04 8 #define STATE_4 0X08 9 #define STATE_5 0X10 10 #define STATE_6 0X20 11 #define STATE_7 0X40 12 #define STATE_8 0X80 13 14 //清除所有标识 15 void EMP_STAT(char *stat) 16 { 17 *stat = 0x00; 18 } 19 20 //添加标识s 21 void ADD_STAT(char *stat, char s) 22 { 23 *stat |= s; 24 } 25 26 //清除标识s 27 void CLR_STAT(char *stat, char s) 28 { 29 *stat &= ~s; 30 } 31 32 //检查标识s是否存在 33 int CHK_STAT(char *stat, char s) 34 { 35 return (*stat & s) ? 1 : 0; 36 }
使用示例:
void print_bit(char a, char *buf) { int i; int n = sizeof(char) * CHAR_BIT; unsigned char mask = (unsigned char)1 << (n-1); int buf_off = 0; for(i=1; i<=n; i++){ sprintf(buf+buf_off++, "%c", ((a&mask)==0)?'0':'1'); a = a<<1; } } void my_print(char state) { char buf[512]; memset(buf, 0x0, sizeof(buf)); print_bit(state, buf); printf("%3d[%s]\n", state, buf); } int main(int argc, char *argv[]) { char state; my_print(state); //unknow EMP_STAT(&state); my_print(state); ADD_STAT(&state, STATE_1); my_print(state); ADD_STAT(&state, STATE_2); my_print(state); CLR_STAT(&state, STATE_1); my_print(state); ADD_STAT(&state, STATE_5); my_print(state); ADD_STAT(&state, STATE_7); my_print(state); puts("check flag:"); printf("%d\n", CHK_STAT(&state, STATE_1)); printf("%d\n", CHK_STAT(&state, STATE_2)); printf("%d\n", CHK_STAT(&state, STATE_5)); printf("%d\n", CHK_STAT(&state, STATE_7)); CLR_STAT(&state, STATE_7); printf("%d\n", CHK_STAT(&state, STATE_7)); return 0; }
下面是输出: