我們先看一組簡(jiǎn)單的代碼,猜一猜控制臺(tái)會(huì)輸出什么呢?
NSInteger a = -1;
NSArray *array = @[@"str"];
if (a > array.count) {
NSLog(@"測(cè)試1");
}else{
NSLog(@"測(cè)試2");
}
答案是:

答案.png
控制臺(tái)為輸出 “測(cè)試1”,也就是說(shuō)if里面的判斷,-1>1是成立的,這明顯是反常識(shí)的,為什么if條件會(huì)成立的,我們繼續(xù)往下看。

typedef.png
在CPU為64位情況下(iPhone5s及以后的機(jī)型,均為64位)
NSInteger即為long類(lèi)型 64位下
NSUInteger 即為 unsigned long 類(lèi)型
64位下,long和unsigned long下所占字節(jié)均為8字節(jié)。
首先變量a是NSInteger類(lèi)型,而NSArray的count屬性,我們點(diǎn)進(jìn)去去看,可以看到是NSUInteger類(lèi)型(NSString的length類(lèi)型同為NSUInteger),所以if里面的表達(dá)式本質(zhì)就成為了long 和 unsigned long 進(jìn)行數(shù)值比較。即有符號(hào)和無(wú)符號(hào)數(shù)的比較。
而編譯器在判斷有符號(hào)數(shù)和無(wú)符號(hào)數(shù)進(jìn)行比較時(shí),一律會(huì)將有符號(hào)數(shù)轉(zhuǎn)化為無(wú)符號(hào)數(shù)。即將NSInteger類(lèi)型的值-1轉(zhuǎn)換為NSUInteger類(lèi)型
那么,有符號(hào)數(shù)如何轉(zhuǎn)化為無(wú)符號(hào)數(shù)呢?
在計(jì)算機(jī)內(nèi)存存儲(chǔ)的有符號(hào)數(shù)的最高位變?yōu)閿?shù)據(jù)位,即有符號(hào)數(shù)轉(zhuǎn)為無(wú)符號(hào)數(shù)。
在計(jì)算機(jī)中,數(shù)據(jù)是以補(bǔ)碼的形式存在的。
原碼:正數(shù)的原碼是自己
補(bǔ)碼:除符號(hào)位外,按位取反,然后+1
所以十進(jìn)制的-1轉(zhuǎn)成8個(gè)字節(jié)64位二進(jìn)制后,為
1000 0000 0000 ... 0001 (共64位,首位為符號(hào)位1 表示為負(fù)數(shù))
而實(shí)際上計(jì)算機(jī)存儲(chǔ)的-1是它的補(bǔ)碼 即:
1111 1111 1111 ... 1111
轉(zhuǎn)成無(wú)符號(hào)數(shù)后,最高位的1不在表示符號(hào)位,而表示數(shù)據(jù)位。
64個(gè)1 即(2的64次方-1)
結(jié)果是
18446744073709551615
所以if里面的表達(dá)式-1 在轉(zhuǎn)為無(wú)符號(hào)數(shù)以后,最后變成了:18446744073709551615
所以,就有了開(kāi)頭的那個(gè)結(jié)果。