C是OC學(xué)習(xí)的基礎(chǔ)鸯檬,OC是從C衍生出來(lái)的决侈,所以先學(xué)習(xí)C語(yǔ)言,主要學(xué)習(xí)編程語(yǔ)言的語(yǔ)法喧务,積累一個(gè)編程思想
我搜到了一個(gè)很好的C語(yǔ)言入門(mén)技術(shù)博客赖歌,覺(jué)得很好,借鑒到這里記錄起來(lái)功茴,膜拜學(xué)習(xí)
根據(jù)變量的作用域庐冯,可分為:
局部變量:
1> 定義:在函數(shù)(代碼塊)內(nèi)部定義的變量
2> 作用域:從定義變量的那一行開(kāi)始,一直到代碼塊結(jié)束
3> 生命周期:從定義變量的那一行開(kāi)始分配存儲(chǔ)空間坎穿,代碼塊結(jié)束后展父,就會(huì)被回收
4> 沒(méi)有固定的初始值全局變量
1> 定義:在函數(shù)外面定義的變量
2> 作用域:從定義變量的那一行開(kāi)始,一直到文件結(jié)尾(能被后面的所有函數(shù)共享)
3> 生命周期:程序一啟動(dòng)就會(huì)分配存儲(chǔ)空間玲昧,程序退出時(shí)才會(huì)被銷(xiāo)毀
4> 默認(rèn)的初始值就是0
題另出一些OC中經(jīng)常用到的難點(diǎn)
1. extern
-
extern 和
外部函數(shù)
-
外部函數(shù)
:定義的函數(shù)能被本文件和其他文件訪問(wèn) - 默認(rèn)情況下所有的函數(shù)都是外部函數(shù)
- 不允許有同名的外部函數(shù)
-
-
extern 對(duì)
外部函數(shù)
的作用- 完整地 定義 和 聲明 一個(gè)外部函數(shù)
- extern
可以省略
犯祠,默認(rèn)情況下 聲明 和 定義 的函數(shù)都是外部函數(shù)
extern void june(); // 完整地聲明一個(gè)外部函數(shù),extern 可以省略
extern void june() // 完整地定義一個(gè)外部函數(shù)酌呆,extern 可以省略
{
...
}
全局變量 分2種 : 外部變量、 內(nèi)部變量
-
extern 和
外部變量
外部變量
- 默認(rèn)情況下搔耕,所有的外部變量都是全局變量
- 不同文件中的同名 外部變量隙袁,都代表著同一個(gè)變量
-
extern 對(duì)
外部變量
的作用- 聲明 一個(gè)外部變量
- 可以聲明在文件頭部痰娱,也可以在函數(shù)里面聲明,意味著在文件的任意位置都可以聲明
2. static
-
static 和
內(nèi)部函數(shù)
-
內(nèi)部函數(shù)
:定義的函數(shù)只能被本文件訪問(wèn)菩收,其他文件不能訪問(wèn) - 允許不同的文件中有同名的 內(nèi)部函數(shù)
-
-
static 對(duì)
內(nèi)部函數(shù)
的作用- 定義 和 聲明一個(gè)內(nèi)部函數(shù)
static void june(); // 聲明一個(gè)內(nèi)部函數(shù)
static void june() // 定義一個(gè)內(nèi)部函數(shù)
{
...
}
-
static 和
全局內(nèi)部變量
-
全局內(nèi)部變量
:定義的 全局內(nèi)部變量 只能被本文件訪問(wèn)梨睁,不能被其他文件訪問(wèn) - 不同文件中的同名 全局內(nèi)部變量,互不影響
-
-
static 對(duì)
全局內(nèi)部變量
的作用- 定義一個(gè) 全局內(nèi)部變量(全部變量的作用域僅限于當(dāng)前文件)
static 和
局部變量
-
static 對(duì)
局部變量
的作用- 讓局部變量只初始化一次
- 局部變量在程序中只有一份內(nèi)存
- 延長(zhǎng)局部變量的生命周期娜饵,直到程序結(jié)束坡贺,才會(huì)被銷(xiāo)毀
- 并不會(huì)改變局部變量的作用域
-
static
修飾局部變量
的使用場(chǎng)合
- 如果某個(gè)函數(shù)的調(diào)用頻率特別高
- 這個(gè)函數(shù)內(nèi)部的某個(gè)變量值是固定不變的
3. const
-
const 和
全局常量
例: #define a 0.5 VS const CGFloat a = 0.5;
- 類(lèi)似宏,不能改值
- 有多少使用宏的地方箱舞,就會(huì)開(kāi)辟多少臨時(shí)存儲(chǔ)空間
- 使用 const 遍坟,就只會(huì)開(kāi)辟一個(gè)存儲(chǔ)空間
- 還可以使用 extern 全局引用
- 如果 extern 全局引用的是個(gè)常量,最好加一個(gè) const
例:extern const CGFloat a (編譯階段就能很快發(fā)現(xiàn)晴股,避免修改被 const 修飾的常量愿伴,運(yùn)行時(shí)崩潰)【extern 可以寫(xiě)成 UIKIT_EXTERN(一定要引入 UIKit 框架)】
const 和
指針
定義一個(gè)指針變量
int *p = NULL;
定義1個(gè) int 類(lèi)型的變量
int a = 10;
p = &a; // 把 a 的地址給了p,指針變量 p 指向 a
*p = 20; // 將 a 的值改為了 20
const右邊是誰(shuí)电湘,就代表著修飾的是誰(shuí)
const int *p : 這樣寫(xiě)代表 `*p` 是一個(gè)常量隔节,const右邊是 `*p`,代表 `*p`` 不能修改所指向變量的值寂呛,p 可以改怎诫,可以指向其他變量
int const *p : 同上
int * const p : 這樣寫(xiě)代表 `p` 是一個(gè)常量,const右邊是 `p`贷痪,代表 `p` 不能被修改幻妓,不能再指向其他變量,`*p` 可以修改所指向變量的值
const int * const p : (指針 p指向的變量 和 p 指向的變量值都不可修改)
- const 和
OC字符串
- NSString * const name = @"Vampire";
- 修改字符串的值是
name = @"June"
呢诬; - 所以涌哲,const 右邊是
name
,修飾的是name
尚镰,才不能修改 -
*name
在 OC 中是不合理的阀圾,所以沒(méi)有意義
4. 數(shù)組 和 指針
```
int * p;
int numbers[4] = {1, 2, 3, 4};
## 指針 p 的加減法運(yùn)算
// 指針 p + N
* p 里面存儲(chǔ)的地址值 + N * 所指向類(lèi)型所占用的字節(jié)數(shù)
// 指針 p - N
* p 里面存儲(chǔ)的地址值 - N * 所指向類(lèi)型所占用的字節(jié)數(shù)
## 數(shù)組名 含義
* 存儲(chǔ)的是`數(shù)組首元素`的地址
* 等價(jià)于 一個(gè)指向`數(shù)組首元素`的指針
* `數(shù)組名 + 1` 的跨度 : `數(shù)組首元素`的占用字節(jié)數(shù)
## 其他結(jié)論
* `&num + 1` 的跨度 : `num` 的占用字節(jié)數(shù)
* numbers : 相當(dāng)于 &numbers[0],等價(jià)于指向 numbers[0] 的指針
* &numbers : 等價(jià)于指向 numbers 數(shù)組的指針
int num[2][2] = {
{1, 2} // num[0]
{3, 4} // num[1]
};
// num[0] : 相當(dāng)于 &num[0][0],等價(jià)于指向 num[0][0] 的指針
// num[1] : 相當(dāng)于 &num[1][0]狗唉,等價(jià)于指向 num[1][0] 的指針
// num : 相當(dāng)于 & num[0],等價(jià)于指向 num[0] 的指針
// & num : 等價(jià)于指向 num 數(shù)組的指針
```
**一道面試題**
```
int number[4] = {10, 20, 30, 40};
int *p = (int *)(& number + 1)
NSLog(@"%d", *(p - 1)); // 40
```