我們先看一組簡單的代碼复哆,猜一猜控制臺會輸出什么呢歧沪?
NSInteger a = -1;
NSArray *array = @[@"str"];
if (a > array.count) {
NSLog(@"測試1");
}else{
NSLog(@"測試2");
}
答案是:
答案.png
控制臺為輸出 “測試1”,也就是說if里面的判斷,-1>1是成立的看疗,這明顯是反常識的沙峻,為什么if條件會成立的,我們繼續(xù)往下看两芳。
typedef.png
在CPU為64位情況下(iPhone5s及以后的機型摔寨,均為64位)
NSInteger即為long類型 64位下
NSUInteger 即為 unsigned long 類型
64位下,long和unsigned long下所占字節(jié)均為8字節(jié)怖辆。
首先變量a是NSInteger類型是复,而NSArray的count屬性,我們點進去去看竖螃,可以看到是NSUInteger類型(NSString的length類型同為NSUInteger)淑廊,所以if里面的表達式本質(zhì)就成為了long 和 unsigned long 進行數(shù)值比較。即有符號和無符號數(shù)的比較特咆。
而編譯器在判斷有符號數(shù)和無符號數(shù)進行比較時季惩,一律會將有符號數(shù)轉(zhuǎn)化為無符號數(shù)。即將NSInteger類型的值-1轉(zhuǎn)換為NSUInteger類型
那么腻格,有符號數(shù)如何轉(zhuǎn)化為無符號數(shù)呢画拾?
在計算機內(nèi)存存儲的有符號數(shù)的最高位變?yōu)閿?shù)據(jù)位,即有符號數(shù)轉(zhuǎn)為無符號數(shù)荒叶。
在計算機中碾阁,數(shù)據(jù)是以補碼的形式存在的。
原碼:正數(shù)的原碼是自己
補碼:除符號位外些楣,按位取反脂凶,然后+1
所以十進制的-1轉(zhuǎn)成8個字節(jié)64位二進制后,為
1000 0000 0000 ... 0001 (共64位愁茁,首位為符號位1 表示為負數(shù))
而實際上計算機存儲的-1是它的補碼 即:
1111 1111 1111 ... 1111
轉(zhuǎn)成無符號數(shù)后蚕钦,最高位的1不在表示符號位,而表示數(shù)據(jù)位鹅很。
64個1 即(2的64次方-1)
結(jié)果是
18446744073709551615
所以if里面的表達式-1 在轉(zhuǎn)為無符號數(shù)以后嘶居,最后變成了:18446744073709551615
所以,就有了開頭的那個結(jié)果促煮。