位運算和枚舉

我看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閱讀 229,117評論 6 537
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,860評論 3 423
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,128評論 0 381
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,291評論 1 315
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,025評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,421評論 1 324
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,477評論 3 444
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,642評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,177評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,970評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,157評論 1 371
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,717評論 5 362
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,410評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,821評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,053評論 1 289
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,896評論 3 395
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,157評論 2 375

推薦閱讀更多精彩內容

  • 1. 關于診斷X線機準直器的作用,錯誤的是()。 (6.0 分) A. 顯示照射野 B. 顯示中心線 C. 屏蔽多...
    我們村我最帥閱讀 10,756評論 0 5
  • 01. 顱腦CT掃描采用的聽眶線是()。 (1.0 分) A. 外耳孔與外眼眥的連線 B. 外耳孔上緣與眶下緣的連...
    我們村我最帥閱讀 3,356評論 0 6
  • 歡迎收聽晚間電臺:一起走過青春。我是小玥,大家晚上好。我們生活在鋼鐵叢林般的城市里,每天都在以自己的方式生活著,...
    文玲子閱讀 744評論 0 5
  • 1.兼容getElementsByClassName 2.獲取屬性getAttribute,getAttribut...
    lmem閱讀 215評論 0 0
  • 1.ardunio(硬件開發板) Arduinois an open-source project that cr...
    設計思維第八組閱讀 1,029評論 0 1