知道中國最著名的女程序員是誰麼?----- 宋丹丹!程序員
至於爲啥看看下面這組圖你就知道了算法
放錯了,是下面這組app
在2000年手機纔剛剛普及的時候,就提出了這麼言簡意賅的跨時代結論,中國最著名的女程序員除了宋丹丹的還有誰!?iphone
ps:喬布斯他就是個買手機的,他懂個錘子的iphone!!!函數
首先話很少,爲了證實宋丹丹所言非虛,一張流程圖足以說明一切:ui
若是看着有點暈,畫出路線圖atom
那麼此次來咱們就看看宋丹丹的「三個思想」中的前兩個吧。spa
曹衝曾說過"大象拉麼大,一個冰箱裝不下」,絕大多數大象都不是一個冰箱能裝下的,那就把大象切了分開多裝幾個冰箱唄。翻譯
下面小學3年級的最後一道應用題:3d
已知,每一個冰箱10平方米,一個大象19平方米。問這個大象裝進冰箱後佔多少平方米?
解:19 ÷ 10 = 1....9(平方米)
∵ 根據題意,大象應該裝2個冰箱
∴ 2 x 10 = 20(平方米)
答:大象裝進冰箱後佔20平方米。
問題是電腦可不知道啥「根據題意」,因此他的算法是:
19 + 10 = 29
而後他再把個位數給抹去
獲得20
這個方法有個弊端<冰箱的大小必定至少要是進制的n冪>
,若是十進制,冰箱大小必定要是10,100,1000..... 由於CPU是64位,64/8=8,因此CPU用的是8進制。同理若是是32位則用的是4進制。
這個過程被稱爲<字節對齊>
,翻譯成英文就是<aligned>
,下面就是這個方法的實現
# define WORD_MASK 7UL
static inline uint32_t word_align(uint32_t x) {
return (x + WORD_MASK) & ~WORD_MASK;
}
複製代碼
WORD_MASK = 7,7在2進制中等於8
這裏WORD_MASK就是冰箱大小,x就是大象大小,&~WORD_MASK至關於抹去零頭。
ps: extra也能夠翻譯成益達,沒錯就是那個口香糖。
一頭大象還好,但是我們的app不可能只alloc一個大象吧。因此爲了方便管理,每一個大象裝箱的時候第一個冰箱就放入一個這個大象的檔案袋(<isa>
),而不是大象自己。
爲了防止一個裝箱失誤,因此規定就算這個大象就算他啥都沒有(nill),也要給他留個位置。 因此一個大象至少要佔2個冰箱的位置(2*8)16平方米。
有些大象可能還有些特殊狀況要額外天佔用一些空間。下面就是這個方法的實現
size_t instanceSize(size_t extraBytes) {
size_t size = alignedInstanceSize() + extraBytes;
if (size < 16) size = 16;
return size;
}
uint32_t alignedInstanceSize() {
return word_align(unalignedInstanceSize());
}
複製代碼
而<unalignedInstanceSize>
就是從檔案袋裏讀取大象數據
uint32_t unalignedInstanceSize() {
assert(isRealized());
return data()->ro->instanceSize;
}
複製代碼
如今你把「大象」換成「對象」,「平方米」換成「字節」,是否是很奇妙?
騰地兒自己沒啥好說的,calloc本是就是庫中的最基本函數。在內存的動態存儲區中分配num個長度爲size的連續空間。num:對象個數,size:對象佔據的內存字節數。可是要注意的是
calloc在動態分配完內存後,自動初始化該內存空間爲零,而malloc不作初始化,分配到的空間中的數據是隨機數據。
size就是咱們上邊算出來的大小
雖然咱們如今知道了cpu是把大象分別放進多個冰箱裏,可是如何分配呢?其實想一想也很簡單,cpu並不會傻到把大象剁成肉臊子,而是把它按照部件一塊一塊而後分別放入冰箱中(畢竟後面還要注入靈魂)。 下面就來證明一下
首先建立一個大象類:
@interface Elephant : NSObject
@property (nonatomic, strong) NSObject *noise;
@property (nonatomic, assign) int head;
@property (nonatomic, copy) NSString *body;
@property (nonatomic, assign) int tail;
@property (nonatomic, assign) int legs;
@end
複製代碼
而後建立而且賦值
- (void)viewDidLoad {
[super viewDidLoad];
Elephant *wildElephant = [[Elephant alloc] init];
wildElephant.noise = [NSObject new];
wildElephant.head = 10;
wildElephant.body = @"bigBody";
wildElephant.tail = 20;
wildElephant.legs = 50;
NSLog(@"%@", wildElephant);
}
複製代碼
咱們來看看手機是怎麼存儲的
第一個 0x0010d800100003dd5 就是咱們所說的isa,佔了整整一個冰箱,徹底如咱們所料。
第二個 0x0000001400000000a 這是兩個小部件(tail 和 head),由於是int類型(佔4字節)就放到了一個冰箱裏。
第三個 0x00000000000000032 這個是腿,也是小部件,可是沒有能夠「湊整」的了,因此雖然小可是仍是佔了一個冰箱。
第四個 0x00006000000109d0 這個就是大部件了,單獨放到一個冰箱裏。
第五個 0x0000000010002018 同第四個。
由此咱們能夠看出來calloc的分配空間仍是很合理的。
白雲大媽竟是程序先知,黑土大爺真的一臉懵逼?
注入靈魂究竟從何而來,次幕後是否還另有其人?
敬請期待下回分解。
原本想用《漢尼拔》的人體標原本描述對齊過程的,可是考慮到配圖和你們的心理承受你能力就算了。