位运算和枚举

我看iOS本身定义的枚举里面经常会使用左移(<<)来定义枚举的值,一开始我还不懂为啥要这么定义。这么处理的逻辑跟iOS系统没关系。

1、举个例子

定义:

typedef enum{
    a = 1 << 0,
    b = 1 << 1,
    c = 1 << 2,
    d = 1 << 3
}testEnum;

使用:

testEnum e = a | b;
    
    if (e & a) {
        printf("满足条件a");
        //满足a要做的事
    }
    if (e & b) {
        printf("满足条件b");
        //满足b要做的事
    }
    if (e & c) {
        printf("满足条件c");
        //满足c要做的事
    }

为什么枚举值定义成1左移n位的形式呢?看枚举值的二进制形式:

  • 1 << 0 是00000001
  • 1 << 1 是00000010
  • 1 << 2 是00000100

规律就是只有一个位上为1,但其他为都为0.这样 e = a | b,二进制形式就是00000011,然后e & b的时候,因为位与(&)的性质,只有都为1才会是1,这样e & a和e & b都会有值,不是0,也就为true。

用移位来定义枚举就是为了把1的位置错开,然后当你需要同时满足多个枚举值的时候,可以使用位或(|)操作把多个枚举值合并,而不会互相影响。比如 00010000 和 00100000合并,他们的1位置是错开的,合并之后1的位置都保留下来了,变成00110000. 然后使用位与(&)来检测某个位上的1,因为每个枚举值只有一个位上是1,除非你的位上也是1,否则位与操作后就为0了。比如0010000和00010000位与就为0;而00100000和00110000位与就不是0。而前面位或操作又可以把每个枚举值的1都保留了,所以后面位与操作会把它包含的每个枚举值都体现出来。

也就是如果e = a| b | c | d,那么e & a 、e & b 、e & c 、 e & d都为true.就是你这个枚举值包含了那些原始枚举值,&操作值都为true.这样代码写起来,逻辑就符合人的思维了。

不知道这个是不是常识,我大学不是计算机专业,也没人跟我专门讲过这个。

2、引申一下

上面是使用了2进制来错开,保留每个位,其实其他进制也可以,但位数是2的n次方。
比如0000 0000 8个位,可以前4个位存储一个值,后4个位存储一个值:

typedef enum{
    a = 0 << 0,
    b = 1 << 0,
    c = 2 << 0,
    d = 3 << 0,
    
    e = 0 << 4,
    f = 1 << 4,
    g = 2 << 4,
    h = 3 << 4
}testEnum;

这里的话,a b c d的前4为都是0,值的变化在后4位,而e f g h正好相反。如果你使用 a b c d内的值位或操作,是没法保存两者的,比如一个数是0000 0011,它可以是d,也可以是d | b,没法判断是否含有枚举b,因为1和3的最后一位都是1,一个数末位是1,你不知道这个1是从哪个枚举值带来的。

所以这样定义a b c d之间是没法共存的。但是a b c d中任何一个都可以和e f g h中任何一个共存。因为它们值存的位置不一样。

这种枚举举个例子,比如使用枚举给一个苹果指定类型,a b c d可以是4中不同产地,e f g h 可以是不同的品种,你看产地只能有一个、品种也只能有一个,但是品种和产地是可以共存的。

3、该怎么定义枚举

在上面一段的基础上看应用实例,反过来再某个使用环境下怎么定义枚举?我的理解是要分层。

比如有a b c是不可共存的,那好,把他们定义成0 1 2 3 ,然后它们只会占2个位,因为3最大,是0000 00 11,那么接下来其他的枚举值就可以左移2个位来和他们避开。然后 d e是不可共存的,那么就把d e 定义为 0 << 2和1<< 2。注意:a b c 分成第一组,d e分成第二组的意思,除了组内不可共存,也代表组之间可以共存,这就是我说分层的意思。照着这个逻辑就可以把复杂的共存和不共存的相互关系捋清,然后分别定义枚举。组之间的取值区域不能重叠,组之间可以。

typedef enum{
    a = 0 << 0,
    b = 1 << 0,
    c = 2 << 0,
    
    d = 0 << 2,
    e = 1 << 2,
    
    f = 0 << 3,
    g = 1 << 3,
    h = 2 << 3
}testEnum;
4、最后,我觉得这个思想在使用任何数做基数都适用,只是计算机的位操作让2变得特别。

比如有个物品A有10个不同的属性,每个属性都有7个以内的取值,即有属性a b c d e f g h i j,然后a有5个可能取值,b有4个可能取值,c有7个可能取值,等等。按理说,需要10个变量来保存,但其实可以一个数就搞定,让N = a + b * 7 + c * 7的平方 + d * 7的立方 + ...,反之,知道一个数,把它用7进制表示,从低到高就是a b c d ...的值了。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 142,680评论 1 300
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 61,177评论 1 256
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 94,249评论 0 212
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 40,981评论 0 175
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 48,746评论 1 255
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 38,763评论 1 176
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 30,362评论 2 268
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 29,151评论 0 165
  • 想象着我的养父在大火中拼命挣扎,窒息,最后皮肤化为焦炭。我心中就已经是抑制不住地欢快,这就叫做以其人之道,还治其人...
    爱写小说的胖达阅读 28,964评论 6 229
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 32,501评论 0 213
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 29,285评论 2 215
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 30,614评论 1 229
  • 白月光回国,霸总把我这个替身辞退。还一脸阴沉的警告我。[不要出现在思思面前, 不然我有一百种方法让你生不如死。]我...
    爱写小说的胖达阅读 24,232评论 0 31
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 27,117评论 2 213
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 31,498评论 3 204
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 25,615评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,012评论 0 167
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 33,512评论 2 230
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 33,594评论 2 231

推荐阅读更多精彩内容

  • 1. 关于诊断X线机准直器的作用,错误的是()。 (6.0 分) A. 显示照射野 B. 显示中心线 C. 屏蔽多...
    我们村我最帅阅读 9,015评论 0 5
  • 01. 颅脑CT扫描采用的听眶线是()。 (1.0 分) A. 外耳孔与外眼眦的连线 B. 外耳孔上缘与眶下缘的连...
    我们村我最帅阅读 2,464评论 0 6
  • 欢迎收听晚间电台:一起走过青春。我是小玥,大家晚上好。我们生活在钢铁丛林般的城市里,每天都在以自己的方式生活着,...
    文玲子阅读 639评论 0 5
  • 1.兼容getElementsByClassName 2.获取属性getAttribute,getAttribut...
    lmem阅读 195评论 0 0
  • 1.ardunio(硬件开发板) Arduinois an open-source project that cr...
    设计思维第八组阅读 882评论 0 1