接續上篇 [C語言基礎及指針②之指針內存分析](http://www.jianshu.com/p/d556070b12ef)
在上一篇中 , 我們分析了指針在內存中是怎樣存儲的 , 以及它是怎樣操作變量的 , 接下來 , 我們談談 , 函數 , 二級指針 。
### 函數
C語言中函數的定義和java中方法的定義類似 , 只是沒有public , private等這樣的權限控制 , 定義如下:
```c
返回值類型 functionName(參數類型 參數名稱 , 參數類型 參數名稱) {
// 函數體
}
int add(int num1 , int num2) {
return num1 + num2 ;
}
```
如果我們想在函數里面 ,修改傳入的參數的值 , 就如同java里面將對象傳入方法中修改對象的屬性 , 在C語言通過指針也可以達到同樣的效果 。
```c
/* 想要修改傳入變量的值 , 則需要使用指針通過變量的地址 , 來修改變量的值 */
void changeNum(int* i) {
*i = 300;
}
```
如果不采用指針`changeNum(int i)` , 函數參數里面的`int i` 則會為`i`變量開辟一個新的內存空間 , 而不是我們傳入的變量 。下面我們就來看看 , 他們在內存中是怎樣表現的 。
``` c
/*沒有使用指針的函數*/
void changeNum(int i) {
printf("函數中i的地址:%#x\n", &i);
i = 300;
}
void main() {
int i = 100;
printf("傳入函數的 i 的地址:%#x\n",&i);
// 將變量i傳入到函數中 , 不對變量去區地址
changeNum(i);
printf("修改后的值:%d\n", i);
system("pause");
}
```
輸出:
```c
傳入函數的 i 的地址:0x9a2ffcd4
函數中i的地址:0x9a2ffcb0
修改后的值:100
```
我們看到傳入的`i`變量的內存地址和函數中的`i`變量內存地址不一樣 , 并且函數也沒有修改我們的`i`變量 , 我們將上述代碼 , 做一下簡單的修改 , 只要將函數的形參改變為指針變量, 將修改的變量的變量內存地址傳入到函數中 , 如此在函數里面就可以修改傳入的變量的值了 。
```c
/* 想要修改傳入變量的值 , 則需要使用指針通過變量的地址 , 來修改變量的值*/
void changeNum(int* num) {
printf("函數中i的地址:%#x\n", num);
*num = 300;
}
changeNum(&i);
```
輸出:
```c
傳入函數的 i 的地址:0x4ccff624
函數中i的地址:0x4ccff624
修改后的值:300
```
因為我們傳入的是`i`變量的內存地址 , 所以函數中的`num `變量打印出的就是傳入的`i`變量的內存地址 , 拿到了`i`變量地址 , 我們就可以通過指針操作傳入地址的內存空間了 , 我們將其修改為`300` , 所以我們打出修改后的值是 : 300
### 二級指針
所謂的二級指針 , 就是指針的指針 , 二級指針的內存空間中 , 存儲的是一級指針的內存地址 ,示例如下:
```c
void main() {
int i = 10;
// p指針變量存儲的是i的內存地址
int* p = &i;
// p1指針變量存儲的是p的內存地址
int** p1 = &p;
int *p2 = 100;
printf("指針作為普通變量:%d\n", p2);
printf("i 的地址:%#x\n", &i);
printf("p 地址:%#x\n", &p);
printf("通過p1取得p的地址:%#x\n", p1);
printf("通過p1取得i的地址:%#x\n", *p1);
printf("通過p1取得i的值:%d\n", **p1);
// 通過p1修改i的值
**p1 = 100;
printf("通過p1修改過的i的值:%d\n", i);
getchar();
}
```
多級指針 , 就是要往上一級一級追溯 , 然后通過`*`操作符來操作內存空間 ,二級指針內存模擬圖:

指針是操作內存的神器 , 多級指針 , 只要記住 , 多級指針里面存儲的是上級指針的地址即可 。
Android程序員學C系列:
[C語言基礎及指針①](http://www.jianshu.com/p/4701cd1e1914)
[C語言基礎及指針②之指針內存分析](http://www.jianshu.com/p/d556070b12ef)
[C語言基礎及指針③函數與二級指針](http://www.jianshu.com/p/184df8a1f195)
[C語言基礎及指針④函數指針](http://www.jianshu.com/p/181b50e02c89)
[C語言基礎及指針⑤動態內存分配](http://www.jianshu.com/p/93db7c692d1b)
[C語言基礎及指針⑥字符操作](http://www.jianshu.com/p/b7e6fc094087)
[C語言基礎及指針⑦結構體與指針](http://www.jianshu.com/p/36cc18151e87)
- 簡介
- C語言基礎及指針①語法基礎
- C語言基礎及指針②之指針內存分析
- C語言基礎及指針③函數與二級指針
- C語言基礎及指針④函數指針
- C語言基礎及指針⑤動態內存分配
- C語言基礎及指針⑥字符操作
- C語言基礎及指針⑦結構體與指針
- C語言基礎及指針⑧文件IO
- C語言基礎及指針⑨聯合體與枚舉
- C語言基礎及指針⑩預編譯及jni.h分析
- JNI開發系列①JNI概念及開發流程
- JNI開發系列②.h頭文件分析
- JNI開發系列③C語言調用Java字段與方法
- JNI開發系列④C語言調用構造方法
- JNI開發系列⑤對象引用的處理
- NDK開發基礎①使用Android Studio編寫NDK
- NDK開發基礎②文件加密解密與分割合并
- NDK開發基礎③增量更新之服務器端生成差分包
- C++基礎①命名空間結構體和引用