前言
在實際開發(fā)中,const,static,extern
是被我們高頻率的使用的關(guān)鍵字睬澡。下面具體說明下,這三個關(guān)鍵字最基本的用法斗躏。
目錄
一啄糙、 宏與const的區(qū)別
二云稚、 const作用:限制類型
三、 const使用場景
四燕雁、static和extern使用
五拐格、static與const聯(lián)合使用
六刑赶、extern與const聯(lián)合使用
一、 宏與const的區(qū)別
現(xiàn)在定義常用的字符串常量金踪,一般抽成宏來處理。but
蘋果不建議我們這樣使用沛申,而是推薦我們使用const
這個關(guān)鍵字定義姐军。
具體區(qū)別
-
編譯時刻:
宏是預(yù)編譯奕锌,const是編譯階段村生。 -
編譯檢查:
宏不做檢查,不會報編譯錯誤辽话,只是替換;const會編譯檢查油啤,能編譯報錯蟀苛。 -
宏的好處:
宏能定義一些函數(shù)、方法幽告。const不能冗锁。 -
宏的缺點:
大量使用宏嗤栓,會造成編譯時間太久(每次都要重新替換)。
二芋绸、 const作用:限制類型
- const僅僅用來修飾右邊的變量(基本數(shù)據(jù)變量p摔敛,指針變量*p)
- 被const修飾的變量是 只讀 的全封。
具體使用桃犬,代碼如下:
- (void)viewDidLoad {
[super viewDidLoad];
int a = 1; // 定義變量
a = 20; // 允許修改值
// const兩種用法
//第一:const:修飾基本變量p. 這兩種寫法是一樣的攒暇,const只修飾右邊的基本變量b
const int b = 20; // b:只讀變量
int const b = 20; // b:只讀變量
b = 1;// 不允許修改值
// 第二:const:修飾指針變量*p形用。
// 定義一個指向int類型的指針變量证杭,指向a的地址
int *p = &a;
int c = 10;
p = &c;
// 允許修改p指向的地址解愤, 允許修改p訪問內(nèi)存空間的值
*p = 20;
// const修飾指針變量訪問的內(nèi)存空間,修飾的是右邊*p1奸笤,
//兩種方式一樣
(第一種)
const int *p1; // *p1:常量 p1:變量
int const *p1; // *p1:常量 p1:變量
(第二種)
// const修飾指針變量p1
int * const p1; // *p1:變量 p1:常量
// 第一個const修飾*p1 第二個const修飾 p1
// 兩種方式一樣
const int * const p1; // *p1:常量 p1:常量
int const * const p1; // *p1:常量 p1:常量
}
三监右、const使用場景
- 提供一個方法魄宏,這個方法的參數(shù)是地址宠互,里面只能通過地址讀取值,而不能通過地址修改值搏色。
- 提供一個方法券册,這個方法的參數(shù)是地址烁焙,里面不能修改參數(shù)的地址。
具體使用場景膳殷,代碼如下
- (void)test1:(const int * )a
{
*a = 20;//const放*前面約束參數(shù)九火,表示*a只讀 (此處編譯不通過)
int b;
a = &b; // 只能修改地址a,不能通過a修改訪問的內(nèi)存空間
}
// const放*后面約束參數(shù),表示a只讀
- (void)test2:(int * const)a
{
int b;
a = &b; // 不能修改a的地址勒极。(此處編譯不通過)
*a = 2; //可以通過a的地址修改值
}
- (void)viewDidLoad {
[super viewDidLoad];
int a = 10;
// 需求1:提供一個方法,這個方法的參數(shù)是地址键痛,里面只能通過地址讀取值,不能通過地址修改值散休。
// 這時候就需要使用const乐尊,約束方法的參數(shù)只讀.
[self test1:&a];
// 需求2:提供一個方法划址,這個方法的參數(shù)是地址夺颤,里面不能修改參數(shù)的地址。
[self test2:&a];
}
四独旷、static和extern使用
-
static作用
-
修飾局部變量
- 延長局部變量的生命周期寥裂,程序結(jié)束才銷毀
- 局部變量只會生成一份封恰,只會初始化一次。
- 改變局部變量的作用域
-
修飾全局變量
- 只能在本文件中訪問鳖昌,修改全局變量的作用域低飒,生命周期不會改變
- 避免重復(fù)定義全局變量
-
-
extern作用
- 用來獲取全局變量的值褥赊,但是不能用于定義常量
-
extern工作原理
- 首先在當(dāng)前文件查找有沒有全局變量,未找到會去其他文件查找
具體使用翼岁,代碼如下
int a = 20;
static int age = 2;
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[self test];
extern int age;
age++;
NSLog(@"%d,%d",age,a);
}
- (void)test
{
static int age = 0;
age++;
NSLog(@"%d",age);
}
五、static與const聯(lián)合使用
- static與const作用:聲明一個只讀的靜態(tài)變量
- 開發(fā)使用場景:在一個文件中經(jīng)常使用的字符串常量悉患,可以使用static和const組合
*** 代碼如下 ***
// 開發(fā)中常用static修飾全局變量,只改變作用域
// 為什么要改變?nèi)肿兞孔饔糜蚴墼辏乐怪貜?fù)聲明全局變量茴晋。
// 開發(fā)中聲明的全局變量,有些不希望外界改動市袖,只允許讀取烁涌。
// 比如一個基本數(shù)據(jù)類型不希望別人改動
// 聲明一個靜態(tài)的全局只讀常量
static const int a = 20;
// 開發(fā)中經(jīng)常拿到key修改值撮执,因此用const修飾key,表示key只讀,不允許修改蜓肆。
static NSString * const key = @"name";
// 如果 const修飾 *key1,表示*key1只讀谋币,key1還是能改變。
static NSString const *key1 = @"name";
六厉颤、extern與const聯(lián)合使用
使用場景:在
多個文件中
共用一個字符串常量逼友,可以使用extern和const組合秤涩。-
原因
- static與const組合:在每個文件都需要定義一份靜態(tài)全局常量
extern與const組合: 只需要定義一份全局變量,多個文件共享
全局常量寫法: 開發(fā)中便于管理所有的全局常量黎烈,一般會創(chuàng)建一個專門的類來管理照棋。
*** xxx .h***
extern NSString * const Key = @"name";
*** xxx.m***
NSSting *const key =@"name";