在程序中,有一些类型会包含许多表示二元的属性,或者函数会包含这样的参数,这些属性或参数被称为旗标。旗标的最大特点是只有两种状态,可以用布尔类型表示。
1 | class Service{ |
直接简单粗暴的给每个旗标开一个属性或者安排一个参数固然可行,但是旗标数量一多,一大片地方都是旗标,显然不太优雅。那么有什么解决方法吗?有的,这就是今天的主角:位元旗标。
旗标一般用布尔类型表示,只需要一个位就能储存。再看其他类型,比如 int
,有32个位,那么能否将32个旗标塞进这个 int
呢?可行,位元旗标就这样诞生了。位元旗标顾名思义,就是用变量的不同位来储存多个旗标。
将一个 int
以二进制形式写出来,大概长这样:
1 | 0b1000100010000010111101010011111 |
那么如何读取这个 int
中储存的32个旗标呢?旗标只有两种属性,读取某个旗标只用关心那一位是0还是1就可以了。为了获取那一位的值,可以使用只在那一位是1、其余位都是0的 int
来和这个 int
位与一下。
1 | int flag = 0b1000100010000010111101010011111; |
在这个例子中,用 test
和 flag
位与,test
除了目标位以外的位均为0,与 flag
对应位位与的结果只会是0,这样结果就仅由两个数目标位位与的结果决定。如果 flag
对应位为0,位与结果就为0;对应位为1,结果就会是 test
自身,实际应用中只用判断是否大于0即可。
位元旗标可以通过位与读取,也可以组装。与读取对应,组装使用位与。
1 |
|
这个例子中,这些宏通过位或组合,位或保留位信息,使得 flag
变量中对应位的值为1,这样就组装出来了一个位元旗标。
这样一个位元旗标可以承载多个旗标,读取时使用位与读取,极大提高了存储密度。
1 |
|