iOS本身定義的枚舉里面經(jīng)常會(huì)使用左移(<<)來定義枚舉的值,一開始我還不懂,看了下面的原理就明白了,文章出處下面有鏈接
1、舉個(gè)例子
定義:
typedefe num{? ? 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位的形式呢?看枚舉值的二進(jìn)制形式:
1 << 0? 是00000001
1 << 1 是00000010
1 << 2 是00000100
規(guī)律就是只有一個(gè)位上為1,但其他為都為0.這樣 e = a | b,二進(jìn)制形式就是00000011,然后e & b的時(shí)候,因?yàn)槲慌c(&)的性質(zhì),只有都為1才會(huì)是1,這樣e & a和e & b都會(huì)有值,不是0,也就為true。
用移位來定義枚舉就是為了把1的位置錯(cuò)開,然后當(dāng)你需要同時(shí)滿足多個(gè)枚舉值的時(shí)候,可以使用位或(|)操作把多個(gè)枚舉值合并,而不會(huì)互相影響。比如 00010000? 和? 00100000合并,他們的1位置是錯(cuò)開的,合并之后1的位置都保留下來了,變成00110000. 然后使用位與(&)來檢測(cè)某個(gè)位上的1,因?yàn)槊總€(gè)枚舉值只有一個(gè)位上是1,除非你的位上也是1,否則位與操作后就為0了。比如0010000和00010000位與就為0;而00100000和00110000位與就不是0。而前面位或操作又可以把每個(gè)枚舉值的1都保留了,所以后面位與操作會(huì)把它包含的每個(gè)枚舉值都體現(xiàn)出來。
也就是如果e = a| b | c | d,那么e & a 、e & b 、e & c 、 e & d都為true.就是你這個(gè)枚舉值包含了那些原始枚舉值,&操作值都為true.這樣代碼寫起來,邏輯就符合人的思維了。
《大學(xué)計(jì)算機(jī)原理》講過這些內(nèi)容,但是我比較懶,平時(shí)都不比較細(xì)的去思考,最后明白了知識(shí)只有學(xué)透了才是自己的,不然只能漂浮在表面。
2、引申一下
上面是使用了2進(jìn)制來錯(cuò)開,保留每個(gè)位,其實(shí)其他進(jìn)制也可以,但位數(shù)是2的n次方。
比如0000 0000 8個(gè)位,可以前4個(gè)位存儲(chǔ)一個(gè)值,后4個(gè)位存儲(chǔ)一個(gè)值:
typedefenum{? ? 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內(nèi)的值位或操作,是沒法保存兩者的,比如一個(gè)數(shù)是0000 0011,它可以是d,也可以是d | b,沒法判斷是否含有枚舉b,因?yàn)?和3的最后一位都是1,一個(gè)數(shù)末位是1,你不知道這個(gè)1是從哪個(gè)枚舉值帶來的。
所以這樣定義a b c d之間是沒法共存的。但是a b c d中任何一個(gè)都可以和e f g h中任何一個(gè)共存。因?yàn)樗鼈冎荡娴奈恢貌灰粯印?/p>
這種枚舉舉個(gè)例子,比如使用枚舉給一個(gè)蘋果指定類型,a b c d可以是4中不同產(chǎn)地,e f g h 可以是不同的品種,你看產(chǎn)地只能有一個(gè)、品種也只能有一個(gè),但是品種和產(chǎn)地是可以共存的。
3、該怎么定義枚舉
在上面一段的基礎(chǔ)上看應(yīng)用實(shí)例,反過來再某個(gè)使用環(huán)境下怎么定義枚舉?我的理解是要分層。
比如有a b c是不可共存的,那好,把他們定義成0 1 2 3 ,然后它們只會(huì)占2個(gè)位,因?yàn)?最大,是0000 00 11,那么接下來其他的枚舉值就可以左移2個(gè)位來和他們避開。然后 d e是不可共存的,那么就把d e 定義為 0 << 2和1<< 2。注意:a b c 分成第一組,d e分成第二組的意思,除了組內(nèi)不可共存,也代表組之間可以共存,這就是我說分層的意思。照著這個(gè)邏輯就可以把復(fù)雜的共存和不共存的相互關(guān)系捋清,然后分別定義枚舉。組之間的取值區(qū)域不能重疊,組之間可以。
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、最后,我覺得這個(gè)思想在使用任何數(shù)做基數(shù)都適用,只是計(jì)算機(jī)的位操作讓2變得特別。
比如有個(gè)物品A有10個(gè)不同的屬性,每個(gè)屬性都有7個(gè)以內(nèi)的取值,即有屬性a b c d e f g h i j,然后a有5個(gè)可能取值,b有4個(gè)可能取值,c有7個(gè)可能取值,等等。按理說,需要10個(gè)變量來保存,但其實(shí)可以一個(gè)數(shù)就搞定,讓N = a + b * 7 + c * 7的平方 + d * 7的立方 + ...,反之,知道一個(gè)數(shù),把它用7進(jìn)制表示,從低到高就是a b c d ...的值了。
文章出處鏈接:http://m.itdecent.cn/p/4f896df73d11