IOS const static extern 深度解析
我想對於ios開發的人來講這3個關鍵字一定都很熟悉,但是你真的都明白了嗎?下面模擬一下面試。我們一層層的深入分析。
1.請你說一下const和巨集的區別
首先,很多字串我們都定義成巨集,但是蘋果推薦的是使用const。
區別:
1.編譯時刻:const是編譯階段,define是預編譯階段
2.編譯檢查:由於巨集是預編譯階段處理,巨集不做檢查,只是單純的替換。 const是會編譯檢查, 可以報編譯錯誤。
3.巨集的優勢:可以定義函式,方法。const不行
4.巨集的劣勢:大量巨集,會造成編譯時間久,每次都需要重新替換。
好了,記下來會繼續深入問你const
2.那你看這段程式碼給我說一下兩種寫法哪個會有問題
答案是兩種寫法都是對的。都是定義一個常量b,如果對b修改會引起報錯;
下面繼續:
int a = 10;
int *const p = &a;
int const *p = &a;
*p = 20;
p = &b;
說一下這兩種寫法有什麼區別:
如果const修飾的是p,那麼p的值是不能改變的,也就是p中存放的a的地址無法改變(p是int型別的指標變數)。但是*p是可以變化的,我們並沒有
用const去修飾*p,所以可以通過*p去改變a的值
如果const修飾的是*p,那麼*p的值是不能改變也,也就是p中存放的a的地址中的值無法改變,但是p的值是可以改變的(也就是p此時可以改變指向)
3.那你跟我說下static吧,static是做什麼用的。
static就是修飾變數的,可以延長區域性變數的生命週期,從棧區拿到全域性區。恭喜你,這樣答分數很低。面試官會給你幾個demo。看看你是否真的理解了static。其實static的作用是需要細分的。
-
修飾區域性變數:
1.延長區域性變數的生命週期,程式結束才會銷燬。
2.區域性變數只會生成一份記憶體,只會初始化一次。
3.改變區域性變數的作用域。
-
修飾全域性變數
1.只能在本檔案中訪問,修改全域性變數的作用域,生命週期不會改
2.避免重複定義全域性變數
為了考察你的理解:會問你,那你說一下static在記憶體上怎麼處理的。比如我現在有一個類,類中用static定義一個區域性變數,每次執行這個static記憶體做了哪些事(從記憶體空間的角度)
-(void)method3:(NSMutableString *)str
{
static int n = 1;
// static等價語句
// if (變數n沒有儲存空間)
// {
// 給n分配儲存空間
// }
[str appendFormat:@"%d ", n];
n++;
g1 = 400;
}
答:如同註釋,將Int n 從棧區拿到全域性區,延長n的生命週期到程式結束。如果多次呼叫method3方法。都會判斷是否已經初始化了n,如果沒有初始化,開闢記憶體空間,如果已經分配了,就把全域性區的n,拿過來繼續使用。
應該怎麼理解呢。我們來看一下程式碼:
// static修飾全域性變數
static int age = 10;
- (void)test
{
// static修飾區域性變數
static int age = 0;
age++;
NSLog(@"%d",age);
}
- (void)viewDidLoad {
[super viewDidLoad];
[self test];
[self test];
extern int age;
NSLog(@"%d",age);
}
如果你回答很含糊,很簡單,面試官就會讓你看一段虛擬碼,來考察一下你是不是真的懂了。首先輸出結果是 1 , 2 ,10。這就考察了你是否真的理解static,首先,test裡面試區域性變數age。static的修飾只是延長了區域性變數的生命週期。從棧區拿到了全域性區。所以第一次輸出1,第二次輸出2,每次+1。最後一個行輸出考察了extern,其實就是獲取本檔案的全域性變數,後面我們會細說。所以這裡全域性變數定義了10,就輸出10,而沒有輸出區域性變數2.
好了,繼續深入問:
.m中
const NSString *HSCoder = @"hello word";
另一個類的.m中
extern NSString *HSCoder;
NSLog(@"%@",HSCoder);
問你可以輸出嗎?hello word嗎?
.m中
NSString *const nameKey = @"name"
.h中
extern NSString * const nameKey;
另一個類的.m中
NSLog(@"%@",nameKey);
問你可以輸出name嗎?
答案是都可以。這就是extern的用法
extern作用
:- 只是用來獲取全域性變數(包括全域性靜態變數)的值,不能用於定義變數
extern工作原理
:- 先在當前檔案查詢有沒有全域性變數,沒有找到,才會去其他檔案查詢。
好了,繼續問。如果將全域性常量,加上static修飾,上面的程式碼會輸出什麼
static const NSString *HSCoder = @"hello word";
這裡又考到了static的作用,千萬不要想成什麼延長生命週期,繼續累加等等。。。注意到static的作用分為兩方面。這裡問的是修飾全域性的。不改變生命週期,單純的修改作用域。讓這個常量只能在當前.m使用。所以,這段程式碼編譯會報錯