-
C語言中#define 宏定義的命令
- 只是在預(yù)處理階段對(duì)用#define 所定義的內(nèi)容進(jìn)行替換,不會(huì)檢查數(shù)據(jù)類型
- 講的好的原文鏈接: iOS開發(fā)中你會(huì)用#define么?
-
C 語言中的全局變量和局部變量
- 全局變量和局部變量是按照變量的作用域來劃分的伯顶。簡單地說囚灼,局部變量是定義在函數(shù)內(nèi)部的變量骆膝;全局變量是定義在函數(shù)之外的變量。全局變量可以為當(dāng)前文件中其他函數(shù)所共用灶体。
- 在 C 語言中全局變量和局部變量可以重名阅签,并且局部變量會(huì)屏蔽全局變量。因?yàn)樗麄兊淖饔糜虿煌椤T诤瘮?shù)內(nèi)政钟,默認(rèn)使用的是局部變量。
全局變量和局部變量的內(nèi)存存放
全局變量儲(chǔ)存在靜態(tài)數(shù)據(jù)庫中樟结,局部變量儲(chǔ)存在堆棧中养交。全局變量在程序開始執(zhí)行時(shí)分配存儲(chǔ)區(qū),程序執(zhí)行完畢釋放瓢宦,在程序執(zhí)行過程中全局變量始終占據(jù)固定的存儲(chǔ)單元碎连;局部變量是動(dòng)態(tài)分配存儲(chǔ)空間的,在調(diào)用變量所在函數(shù)時(shí)刁笙,系統(tǒng)會(huì)給函數(shù)內(nèi)的局部變量分配存儲(chǔ)空間破花,在函數(shù)結(jié)束時(shí)自動(dòng)釋放這些存儲(chǔ)空間。
iOS 技術(shù)學(xué)習(xí)群號(hào):529560119 疲吸,提供各種最新權(quán)威學(xué)習(xí)書籍及開發(fā)視頻
-
staitc 關(guān)鍵字
C語言中的 static 關(guān)鍵字
- 函數(shù)體內(nèi),static 變量的作用范圍為該函數(shù)體前鹅,不同于 auto 變量摘悴,該變量的內(nèi)存只會(huì)被分配一次,因此其值在下次調(diào)用時(shí)仍維持上次的值舰绘。
- 在模塊內(nèi)的 static 全局變量可以被模塊內(nèi)所有函數(shù)訪問蹂喻,但不能被模塊外的其他函數(shù)訪問。
- 在模塊內(nèi)的 static 函數(shù)只可被這一模塊內(nèi)的其他函數(shù)調(diào)用捂寿,這個(gè)函數(shù)的使用范圍被限制在聲明它的模塊內(nèi)口四。
#include <stdio.h>
static int i;
void fun1(void){
i = 0;
i++;
printf("i = %d <>",i);
}
void fun2(){
static int j = 0;
j++;
printf(" j = %d\n",j);
}
int main(int argc, const char * argv[]) {
int n;
for (n = 0; n < 10; n++) {
fun1();
fun2();
}
return 0;
}
輸出結(jié)果:
i = 1 <> j = 1
i = 1 <> j = 2
i = 1 <> j = 3
i = 1 <> j = 4
i = 1 <> j = 5
i = 1 <> j = 6
i = 1 <> j = 7
i = 1 <> j = 8
i = 1 <> j = 9
i = 1 <> j = 10
// 上面代碼定義了一個(gè)靜態(tài)全局變量 i 和靜態(tài)局部變量 j 。每次調(diào)用函數(shù)的時(shí)秦陋,改變變量的值蔓彩,使其累加滤蝠。
// 由于 i 在每次調(diào)用函數(shù)時(shí)都被賦予了新值巾遭,所以每次的值都是1;
// j 被定義為靜態(tài)局部變量辅髓,其值在每次函數(shù)結(jié)束時(shí)都會(huì)被保留顺又,所以結(jié)果都是上次值加1更卒。
靜態(tài)全局變量只能在變量被定義的文件中使用,其他文件即使用 extern 聲明也沒法使用它稚照。準(zhǔn)確地說蹂空,作用域是從定義之處開始俯萌,到文件結(jié)尾處結(jié)束,在定義之處前面的那些代碼行也不能使用它上枕,想要使用就得前面再加 extern
OC語言中的 static 關(guān)鍵字
雖然 Objective-C 也提供了static 關(guān)鍵字咐熙,但這個(gè) static 關(guān)鍵字不能用于修飾成員變量,它只能修飾局部變量姿骏,全局變量和函數(shù)糖声,static 修飾局部變量表示將該局部變量存儲(chǔ)到靜態(tài)存儲(chǔ)區(qū);static 修飾全局變量用于限制該全局變量只能在當(dāng)前源文件中訪問分瘦;static 修飾函數(shù)用于限制該函數(shù)只能在當(dāng)前文件中調(diào)用蘸泻。
- 成員變量 - 不能修飾成員變量。
- 局部變量 - 可以修飾局部變量嘲玫,存儲(chǔ)到靜態(tài)存儲(chǔ)區(qū)悦施。
- 延長局部變量的生命周期,程序結(jié)束才會(huì)銷毀。
- 局部變量只會(huì)生成一份內(nèi)存,只會(huì)初始化一次去团。
- 并沒有改變變量的作用域抡诞。
- 全局變量 - 只能在當(dāng)前源文件中訪問
- 使全局變量的作用域僅限于當(dāng)前文件內(nèi)部,即當(dāng)前文件內(nèi)部才能訪問該全局變量土陪。
- 避免重復(fù)定義全局變量昼汗。
@implementation LoginTool
//static修飾全局變量,讓外界文件無法訪問
static LoginTool *_sharedManager = nil;
+ (LoginTool *)sharedManager {
static dispatch_once_t oncePredicate;
dispatch_once(&oncePredicate, ^{
_sharedManager = [[self alloc] init];
});
return _sharedManager;
}
// iOS中在一個(gè)文件聲明的全局變量鬼雀,工程的其他文件也是能訪問的,
// 但是我又不想讓其他文件訪問顷窒,這時(shí)就可以用static修飾它了,
// 比較典型的是使用GCD一次性函數(shù)創(chuàng)建的單例源哩,全局變量基本上都會(huì)用static修飾鞋吉。
- 函數(shù) - 該函數(shù)只能在當(dāng)前源文件中訪問
-
const 關(guān)鍵字
const 字面意思,只讀励烦、常量的意思谓着,用來修飾右邊的變量或指針,值不能改變坛掠。指定變量不可被當(dāng)前線程/進(jìn)程改變(但有可能被系統(tǒng)
或其他線程/進(jìn)程改變)赊锚。
- 要阻止一個(gè)變量的值被改變,可以使用 const 關(guān)鍵字却音,在定義 const 變量時(shí)改抡,通常要對(duì)它進(jìn)行初始化,因?yàn)橐院缶蜎]有機(jī)會(huì)去改變它了系瓢。
- 對(duì)指針來說阿纤,可以指定指針本身為 const,也可以指定指針?biāo)傅臄?shù)據(jù)為 const夷陋,或者二者同時(shí)指定為 const欠拾。
- 在一個(gè)函數(shù)聲明中胰锌,const 可以修飾形參,表明它是一個(gè)輸入?yún)?shù)藐窄,在函數(shù)內(nèi)部不能修改其值资昧。
const 作用
- 可以定義const常量,具有不可變性荆忍。 例如:
const int Max=100; int Array[Max];```
- 便于進(jìn)行類型檢查格带,使編譯器對(duì)處理內(nèi)容有更多了解,消除了一些隱患刹枉。
``` void fun(const int i) { .........} ```
例如: 編譯器就會(huì)知道i是一個(gè)常量叽唱,不允許修改;
- 可以保護(hù)被修飾的東西,防止意外的修改微宝,增強(qiáng)程序的健壯性棺亭。 還是上面的例子,如果在 函數(shù)體內(nèi)修改了i蟋软,編譯器就會(huì)報(bào)錯(cuò);
void fun(const int i) {
i=10;//error!
}
- 可以節(jié)省空間镶摘,避免不必要的內(nèi)存分配。 例如:
define PI 3.14159 //常量宏
const doulbe Pi=3.14159; //此時(shí)并未將Pi放入ROM中 ......
double i=Pi; //此時(shí)為Pi分配內(nèi)存岳守,以后不再分配!
double I=PI; //編譯期間進(jìn)行宏替換凄敢,分配內(nèi)存
double j=Pi; //沒有內(nèi)存分配
double J=PI; //再進(jìn)行宏替換,又一次分配內(nèi)存!
const定義常量從匯編的角度來看湿痢,只是給出了對(duì)應(yīng)的內(nèi)存地址贡未,而不是象#define一樣給出的是 立即數(shù),所以蒙袍,const定義的常量在程序運(yùn)行過程中只有一份拷貝,而#define定義的常量在內(nèi)存 中有若干個(gè)拷貝嫩挤。
- 提高了效率害幅。 編譯器通常不為普通const常量分配存儲(chǔ)空間,而是將它們保存在符號(hào)表中岂昭,這使得它成為一個(gè)編譯期間的常量以现,沒有了存儲(chǔ)與讀內(nèi)存的操作,使得它的效率也很高约啊。
####const 實(shí)際使用
- 修飾一般常量 一般常量是指簡單類型的常量邑遏。這種常量在定義時(shí),修飾符const可以用在類 型說明符前恰矩,也可以用在類型說明符后记盒。
例如:
int const x=2; 或 const int x=2;
(當(dāng)然,我們可以偷梁換柱進(jìn)行更新: 通過強(qiáng)制類型轉(zhuǎn)換外傅,將地址賦給變量纪吮,再作修改即可以改變const常量值俩檬。)

- 修飾常數(shù)組(值不能夠再改變了) 定義或說明一個(gè)常數(shù)組可采用如下格式:
int const a[5]={1, 2, 3, 4, 5};
const int a[5]={1, 2, 3, 4, 5};

- 修飾函數(shù)的常參數(shù) const修飾符也可以修飾函數(shù)的傳遞參數(shù),格式如下:
void Fun(const int Var);
告訴編譯器Var在函數(shù)體中的無法改變碾盟,從而防止了使用者的一些無 意的或錯(cuò)誤的修改棚辽。
- 修飾函數(shù)的返回值: const修飾符也可以修飾函數(shù)的返回值,是返回值不可被改變冰肴,格式如下:
const int Fun1();
const MyClass Fun2();
- 修飾常指針
>const int *A; //const修飾指針屈藐,A可變,A指向的值不能被修改

> int const *A; //const修飾指向的對(duì)象熙尉,A可變联逻,A指向的對(duì)象不可變

>int *const A; //const修飾指針A, A不可變骡尽,A指向的對(duì)象可變

>const int *const A;//指針A和A指向的對(duì)象都不可變

//技巧: 先看“*”的位置
// 如果const 在 *的左側(cè) 表示值不能修改遣妥,但是指向可以改。
// 如果const 在 的右側(cè) 表示指向不能改攀细,但是值可以改
// 如果在“”的兩側(cè)都有const 標(biāo)識(shí)指向和值都不能改箫踩。
更多精彩,關(guān)注群號(hào):529560119