明确或运算和与运算的含义:
或运算:一个位为1,就为1
00010100
| 00011101
——————
00011101
与运算:每个位都为1,才为1
00010100
& 00011101
——————
00010100
如此一来,我们就可以对经过或运算的值进行判断了,如:
#include <stdio.h>
#define SY_MOVE 0x1
#define SY_SIZE 0x2
#define SY_CLOSE 0x4
#define SY_START 0x8
void setstyle(int style)
{
}
int main()
{
setstyle(SY_MOVE | SY_CLOSE);
setstyle(SY_SIZE | SY_MOVE);
setstyle(SY_CLOSE | SY_START);
setstyle(SY_SIZE | SY_MOVE | SY_CLOSE);
getch();
return 0;
}
现在我们要判断setstyle中传入的参数的值都有哪些,可以进行与运算,如:
#include <stdio.h>
#define SY_MOVE 0x1
#define SY_SIZE 0x2
#define SY_CLOSE 0x4
#define SY_START 0x8
void setstyle(int style)
{
if (style & SY_MOVE)
{
printf("SY_MOVE ");
}
if (style & SY_SIZE)
{
printf("SY_SIZE ");
}
if (style & SY_CLOSE)
{
printf("SY_CLOSE ");
}
if (style & SY_START)
{
printf("SY_START ");
}
printf("\n");
}
int main()
{
setstyle(SY_MOVE | SY_CLOSE);
setstyle(SY_SIZE | SY_MOVE);
setstyle(SY_CLOSE | SY_START);
setstyle(SY_SIZE | SY_MOVE | SY_CLOSE);
getch();
return 0;
}
也就是说,想要知道哪个样式开启了,就和哪个样式相与即可,因为:
如果传入SY_MOVE | SY_CLOSE
宏定义解释之后那就是 1 | 4
转换成二进制就是 00000001 | 00000100
进行运算就是:
00000001
| 00000100
——————
00000101
又因为SY_MOVE表示1,SY_CLOSE表示4,所以第一位和第三位为1表示SY_MOVE属性和SY_CLOSE属性同时开启。
这个判断就可以交给与运算来做。
现在我们知道传入的参数是00000101,所以将其和SY_MOVE进行与运算,即可知SY_MOVE属性是否开启,请看:
00000101 & 00000001
00000101
& 00000001
——————
00000001
因为只有第一位都开启,所以与运算的结果为1,即真,这时我们便知道SY_MOVE属性是开启的。
接下来还有三个属性需要判断:SY_SIZE(对应2),SY_CLOSE(对应4), SY_START(对应8)
依次进行判断:
SY_SIZE 00000010
参数 00000101
00000101 & 00000010
00000101
& 00000010
——————
00000000
结果为假,SY_SIZE属性未开启
SY_CLOSE 00000100
参数 00000101
00000101 & 00000100
00000101
& 00000100
——————
00000100
结果为真,SY_CLOSE属性开启
SY_CLOSE 00000100
参数 00000101
00000101 & 00000100
00000101
& 00000100
——————
00000100
结果为真,SY_CLOSE属性开启
SY_START 00001000
参数 00000101
00000101 & 00001000
00000101
& 00001000
——————
00000000
结果为假,SY_START属性未开启
综上所述,即可判断一个属性是否开启了。
但是属性的宏定义也是有要求的。
一个属性只能对应一个位的开启,否则程序会误以为其它位也开启了,所以每个宏的值都必须从上一个值继续乘以2(初始值不能为0),如1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768……
如果不这样做的话,程序会误判别的属性也开启了,例如:
#define SY_MOVE 0x2
#define SY_SIZE 0x3
setstyle(SY_SIZE);
此时我只设置了SY_SIZE属性,传入的参数就是0x3,即00000011
但是程序在判断的时候:
if(style & SY_MOVE)
{
// ...
}
此时参数style为00000011,和SY_MOVE属性相与,会得到:
SY_MOVE = 0x2 = 00000010
00000011 & 00000010
00000011
& 00000010
——————
00000010
会得到真,因为参数的第二位开启了。
所以,一个属性只能对应一个位的开启。
总结:
想要知道哪个样式开启了,就和哪个样式相与即可
一个属性只能对应一个位的开启