iOS const饶囚、static帕翻、extern實(shí)操

去阿里面試被問到了好多基本功和底層知識(shí),由于沒有總結(jié)過萝风,導(dǎo)致有很多用過的東西并不知道怎么表達(dá)嘀掸,遭到了無情的鄙視;決定總結(jié)一些知識(shí)點(diǎn)闹丐,激勵(lì)自己一下横殴!
先從最基本的寫起:先寫幾個(gè)修飾關(guān)鍵字 const、static卿拴、extern.

一衫仑、const:: 被const修飾的變量是只讀的(變量->只讀變量).

先從最基礎(chǔ)的開始
定義變量

 int a = 1;
 a = 20;// 允許修改值

然后開始進(jìn)入const
const兩種用法
1、const:修飾基本變量p

const int b = 20; // b:只讀變量
int const b = 20; // b:只讀變量
b = 1; // 會(huì)報(bào)錯(cuò)// 不允許修改值

2堕花、const:修飾指針類型*p
定義一個(gè)指向int類型的指針文狱,指向a的地址

int a = 20;
int *p = &a;
NSLog(@"p == %p---&a == %p",p,&a);
int c = 10;
p = &c;
NSLog(@"p == %p---*p == %d",p,*p);
int d = 11;
*p = d;
NSLog(@"p == %p---*p == %d",p,*p);
//打印結(jié)果
2019-07-11 09:45:32.867368+0800 Runtime理解[44662:1691119] p == 0x7ffeefb433ac---*p == 20
2019-07-11 09:45:32.867518+0800 Runtime理解[44662:1691119] p == 0x7ffeefb4339c---*p == 10
// 允許修改p指向的地址
2019-07-11 09:45:32.867637+0800 Runtime理解[44662:1691119] p == 0x7ffeefb4339c---*p == 11
// 允許修改p訪問內(nèi)存空間的值

const修飾指針變量訪問的內(nèi)存空間,修飾的是右邊*p1缘挽,

int a = 20;
const int *p = &a; 
NSLog(@"p == %p---*p == %d",p,*p);
int c =10;
p = &c;
NSLog(@"p == %p---*p == %d",p,*p);
//打印結(jié)果
2019-07-11 10:15:54.968002+0800 Runtime理解[45151:1709783] p == 0x7ffee3f193ac---*p == 20
2019-07-11 10:15:54.968132+0800 Runtime理解[45151:1709783] p == 0x7ffee3f1939c---*p == 10
// 允許修改p指向的地址

 int d = 11;
*p = d;//報(bào)錯(cuò)瞄崇,Read-only variable is not assignable(只讀變量不可賦值)
// 不允許修改p訪問內(nèi)存空間的值

int a = 20;
const *p = &a; 
NSLog(@"p == %p---*p == %d",p,*p);
int c =10;
p = &c;
NSLog(@"p == %p---*p == %d",p,*p);
//打印結(jié)果
2019-07-11 10:15:54.968002+0800 Runtime理解[45151:1709783] p == 0x7ffee3f193ac---*p == 20
2019-07-11 10:15:54.968132+0800 Runtime理解[45151:1709783] p == 0x7ffee3f1939c---*p == 10
// 允許修改p指向的地址

 int d = 11;
*p = d;//報(bào)錯(cuò),Read-only variable is not assignable(只讀變量不可賦值)
// 不允許修改p訪問內(nèi)存空間的值
int a = 20;
int const *p = &a; 
NSLog(@"p == %p---*p == %d",p,*p);
int c =10;
p = &c;
NSLog(@"p == %p---*p == %d",p,*p);
//打印結(jié)果
2019-07-11 10:15:54.968002+0800 Runtime理解[45151:1709783] p == 0x7ffee3f193ac---*p == 20
2019-07-11 10:15:54.968132+0800 Runtime理解[45151:1709783] p == 0x7ffee3f1939c---*p == 10
// 允許修改p指向的地址

 int d = 11;
*p = d;//報(bào)錯(cuò)壕曼,Read-only variable is not assignable(只讀變量不可賦值)
// 不允許修改p訪問內(nèi)存空間的值
總結(jié):const int *p 作用等同于 int const *p 
*p 是常量 p是變量
int a = 20;
int * const p = &a; 
NSLog(@"p == %p---*p == %d",p,*p);
int c =10;
p = &c; //報(bào)錯(cuò)苏研,Read-only variable is not assignable(只讀變量不可賦值)
// 不允許修改p指向的地址
int d = 11;
*p = d;
NSLog(@"p == %p---*p == %d",p,*p);
// 打印結(jié)果
2019-07-11 10:50:44.694506+0800 Runtime理解[45665:1731013] p == 0x7ffee8f413ac---*p == 20
2019-07-11 10:50:44.694684+0800 Runtime理解[45665:1731013] p == 0x7ffee8f413ac---*p == 11
// 允許修改p訪問內(nèi)存空間的值

總結(jié): int *const p    *p是變量 p是常量;
通過以上代碼總結(jié):const修飾的緊右邊的為常量腮郊,在此就不一一驗(yàn)證摹蘑,有興趣的可以自己寫代碼驗(yàn)證一下;
const int *p              // *p:常量   p:變量
int const *p              // *p:常量   p:變量
int *const p              // *p:變量   p:常量
const int * const p       // *p:常量   p:常量
int const * const p       // *p:常量   p:常量

下面來試驗(yàn)一下const最常用的方法:修飾NSString轧飞,廢話少說衅鹿,上代碼:

NSString * const str1=@"sdh";
str1 = @"123" //報(bào)錯(cuò)
//因?yàn)镹SString是不可變字符串:指針指向內(nèi)存的內(nèi)容是不允許改變的撒踪,因?yàn)閏onst修飾的是指針 str1:指針不允許指向其他內(nèi)存;
//所以不可以修改指針指向的原內(nèi)存中的內(nèi)容大渤,指針不可以指向其他的內(nèi)存


 NSString const *str2 = @"sdh";
 str2 = @"123"; //不報(bào)錯(cuò)
//因?yàn)镹SString是不可變字符串:指針指向內(nèi)存的內(nèi)容是不允許改變的制妄,因?yàn)閏onst修飾的是指針 *str2:指針指向內(nèi)存的內(nèi)容不允許改變,所以 *str2 是常量 但str2是變量指針可以指向一天內(nèi)存;
//所以不可以修改指針指向的原內(nèi)存中的內(nèi)容泵三,指針可以指向其他的內(nèi)存


NSMutableString *const var1 =[NSMutableString string];
NSMutableString *var2 = [NSMutableString stringWithFormat:@"%@",@"123"];
var1 = var2; //報(bào)錯(cuò) 因?yàn)閏onst修飾的是指針 var1:指針不允許指向其他內(nèi)存耕捞;
[var1  appendString:@"123"]; //不報(bào)錯(cuò) 因?yàn)镹SMutableString是可變字符串:指針指向內(nèi)存的內(nèi)容是允許改變的
//所以可以修改指針指向的原內(nèi)存中的內(nèi)容,指針不可以指向其他的內(nèi)存

NSMutableString const *var3 =[NSMutableString string];
var3 = var2; //不報(bào)錯(cuò)  因?yàn)閏onst修飾的是指針 *var3 所以var3是變量烫幕,指針可以指向其他內(nèi)存地址
[var3 appendString:@"123456"]; //不報(bào)錯(cuò) 因?yàn)関ar3是可變字符串指針指向的原內(nèi)存中的內(nèi)容可以改變
//所以可以修改指針指向的原內(nèi)存中的內(nèi)容砸脊,常量指針可以指向其他的內(nèi)存
NSLog(@"str1 = %@ -- str2 = %@ -- var1 = %@ -- var2 = %@",str1,str2,var1,var2);
//打印結(jié)果
2019-07-11 11:28:43.957979+0800 Runtime理解[46292:1755776] str1 = sdh -- str2 = 123 -- var1 = 123 -- var2 = sdh123456

const修飾字符串總結(jié):

NSString *const str1
不可以修改指針指向的原內(nèi)存中的內(nèi)容,指針不可以指向其他的內(nèi)存
NSString const *str2
不可以修改指針指向的原內(nèi)存中的內(nèi)容纬霞,指針可以指向其他的內(nèi)存
NSMutableString const *var1
可以修改指針指向的原內(nèi)存中的內(nèi)容凌埂,指針可以指向其他的內(nèi)存
NSMutableString *const var2
可以修改指針指向的原內(nèi)存中的內(nèi)容,指針不可以指向其他的內(nèi)存

const用法總結(jié)道這里诗芜。

二瞳抓、static和extern簡(jiǎn)單使用
"static作用":
1、修飾局部變量:
1)延長(zhǎng)局部變量的生命周期,程序結(jié)束才會(huì)銷毀伏恐。
2)局部變量只會(huì)生成一份內(nèi)存,只會(huì)初始化一次孩哑。
3)Static關(guān)鍵字不可以改變局部變量的作用域。

@implementation Person
-(instancetype)init{
    self = [super init];
    if (self) {
        [self conlogAge];
        [self conlogAge];
    }
    return self;
}

-(void)conlogAge{
    static NSInteger age = 18;
    age ++;
    NSLog(@"%ld",age);
}


#import "Person.h"
@interface ConstStaticViewController ()
@end
@implementation ConstStaticViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    Person *per = [Person new];
    Person *per2 = [Person new];
}
//打印輸出
//2019-07-11 15:19:25.617612+0800 Runtime理解[49598:1888382] 19
//2019-07-11 15:19:25.617712+0800 Runtime理解[49598:1888382] 20
//2019-07-11 15:19:25.617800+0800 Runtime理解[49598:1888382] 21
//2019-07-11 15:19:25.617892+0800 Runtime理解[49598:1888382] 22

注意:ConstStaticViewController是二級(jí)頁(yè)面翠桦,我們返回到一級(jí)頁(yè)面横蜒,該頁(yè)面銷毀,在重新創(chuàng)建改頁(yè)面销凑,viewDidLoad會(huì)重新執(zhí)行一次丛晌,我們?cè)诳创蛴?shù)據(jù):

2019-07-11 15:42:11.181260+0800 Runtime理解[50022:1905671] 19
2019-07-11 15:42:11.181433+0800 Runtime理解[50022:1905671] 20
2019-07-11 15:42:11.181541+0800 Runtime理解[50022:1905671] 21
2019-07-11 15:42:11.181711+0800 Runtime理解[50022:1905671] 22
2019-07-11 15:42:14.761006+0800 Runtime理解[50022:1905671] 23
2019-07-11 15:42:14.761159+0800 Runtime理解[50022:1905671] 24
2019-07-11 15:42:14.761285+0800 Runtime理解[50022:1905671] 25
2019-07-11 15:42:14.761378+0800 Runtime理解[50022:1905671] 26

說明:
1、age這個(gè)變量并未因持有他的對(duì)象的銷毀兒銷毀斗幼,局部變量的生命周期被延長(zhǎng)
2澎蛛、而且, [self conlogAge]函數(shù)被調(diào)用多次蜕窿,age這個(gè)變量并未重新初始化谋逻,而是跳過初始化,繼續(xù)進(jìn)行 ++操作桐经,所以:局部變量只會(huì)生成一份內(nèi)存,只會(huì)初始化一次毁兆。


-(void)conlogAge{
    static NSInteger age = 18;
    age ++;
    NSLog(@"%ld",age);
}
-(void)showAge{
    age++;//直接報(bào)錯(cuò)
    extern NSInteger age; //編譯時(shí)報(bào)錯(cuò)
    NSLog(@"%ld",age);
}

3、被static修飾過的變量阴挣,在其他作用域是不能訪問的气堕。

2、static修飾全局變量

1)只能在本文件中訪問,修改全局變量的作用域,生命周期不會(huì)改
2)避免重復(fù)定義全局變量

NSString *allChange = @"allChange";//全局變量,本文件直接用送巡,其他文件借助extern調(diào)用
static NSString *changes =@"change";//全局變量,本文件直接用盒卸,其他文件借助不能調(diào)用,用extern調(diào)用骗爆,會(huì)報(bào)錯(cuò)

三、const蔽介、static配合使用
開發(fā)時(shí)常用的寫法摘投,用const、和static配合使用來代替宏的部分功能(#define)
一虹蓄、const與宏的區(qū)別(面試題):

  • "const簡(jiǎn)介":之前常用的字符串常量犀呼,一般是抽成宏,但是蘋果不推薦我們抽成宏薇组,推薦我們使用const常量外臂。
  • "執(zhí)行時(shí)刻":宏是預(yù)編譯(編譯之前處理),const是編譯階段律胀。
  • "編譯檢查":宏不做檢查宋光,不會(huì)報(bào)編譯錯(cuò)誤,只是替換炭菌,const會(huì)編譯檢查罪佳,會(huì)報(bào)編譯錯(cuò)誤。
  • "宏的好處":宏能定義一些函數(shù)黑低,方法赘艳。 const不能。
  • "宏的壞處":使用大量宏克握,容易造成預(yù)編譯時(shí)間久蕾管。
#define CHANGE @"change";
static NSString *const changes =@"change";

雖然測(cè)試過,及時(shí)用相當(dāng)數(shù)量的宏編譯時(shí)間并不會(huì)差很多菩暗,但是娇掏,我們還是要按照蘋果的推薦來的好,用第二個(gè)表示方法勋眯。

四婴梧、extern使用
"extern作用":只是用來獲取全局變量(包括全局靜態(tài)變量)的值,不能用于定義變量客蹋。
"extern工作原理":先在當(dāng)前文件查找有沒有全局變量塞蹭,沒有找到,才會(huì)去其他文件查找讶坯。
廢話補(bǔ)多說:代碼解釋

#import "SLStaticDemo.h"
NSInteger age = 10;
@implementation SLStaticDemo
@end
#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    self.view.backgroundColor = [UIColor whiteColor];
    
    extern NSInteger age;
    NSLog(@"age = %ld", (long)age);
    
    age += 10;
    NSLog(@"age = %ld", (long)age);
}
@end

打印結(jié)果:

image

從輸出結(jié)果 age = 10 我們可以看到即便我們?cè)赩iewController.m中并沒有import SLStaticDemo.h也能得到SLStaticDemo中定義的age變量番电,這就是extern關(guān)鍵字的功勞(extern可以訪問全局變量);
注:這里理解起來很簡(jiǎn)單,懶得自己寫了漱办,參照的大神的代碼这刷,網(wǎng)址:http://www.reibang.com/p/9c09989b6862

好,用了將近一天的時(shí)間娩井,把這三個(gè)基本的關(guān)鍵字理清了暇屋,可能有寫啰嗦,希望大家選擇性參考洞辣。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末咐刨,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子扬霜,更是在濱河造成了極大的恐慌定鸟,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,948評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件著瓶,死亡現(xiàn)場(chǎng)離奇詭異联予,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)材原,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門躯泰,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人华糖,你說我怎么就攤上這事麦向。” “怎么了客叉?”我有些...
    開封第一講書人閱讀 157,490評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵诵竭,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我兼搏,道長(zhǎng)卵慰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,521評(píng)論 1 284
  • 正文 為了忘掉前任佛呻,我火速辦了婚禮裳朋,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘吓著。我一直安慰自己鲤嫡,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評(píng)論 6 386
  • 文/花漫 我一把揭開白布绑莺。 她就那樣靜靜地躺著暖眼,像睡著了一般。 火紅的嫁衣襯著肌膚如雪纺裁。 梳的紋絲不亂的頭發(fā)上诫肠,一...
    開封第一講書人閱讀 49,842評(píng)論 1 290
  • 那天司澎,我揣著相機(jī)與錄音,去河邊找鬼栋豫。 笑死挤安,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的丧鸯。 我是一名探鬼主播蛤铜,決...
    沈念sama閱讀 38,997評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼骡送!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起絮记,我...
    開封第一講書人閱讀 37,741評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤摔踱,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后怨愤,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體派敷,經(jīng)...
    沈念sama閱讀 44,203評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評(píng)論 2 327
  • 正文 我和宋清朗相戀三年撰洗,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了篮愉。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,673評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡差导,死狀恐怖试躏,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情设褐,我是刑警寧澤颠蕴,帶...
    沈念sama閱讀 34,339評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站助析,受9級(jí)特大地震影響犀被,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜外冀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評(píng)論 3 313
  • 文/蒙蒙 一寡键、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧雪隧,春花似錦西轩、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至捅伤,卻和暖如春劫流,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工祠汇, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留仍秤,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,394評(píng)論 2 360
  • 正文 我出身青樓可很,卻偏偏與公主長(zhǎng)得像诗力,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子我抠,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容