指標
觀念
現在我們要寫一個交換兩個數的函式,如果這樣寫會發生什麼事呢
1
2
3
4
5
6
7
8
9
10
11
12
| #include<bits/stdc++.h>
using namespace std;
void swap(int x,int y){
int t=x;x=y;y=t;
}
int main(){
int a=1,b=2;
swap(a,b);
cout << a << " " << b << endl;
return 0;
}
|
Output: 1 2
奇怪,ab沒有被交換,
其實,這程式相當於我們又宣告了xy並交換xy,ab跟xy並沒有關係,這時我們就需要用到指標了。
要取得變數的指標,只需在它前面加上 & 就好,如果我們輸出 &a,會得到它的記憶體位址。
而指標的型態,取決於它從哪種變數取得指標,int指標型別就是 int*,double指標型別是double*
宣告指標的方式也很簡單
1
2
| int a;
int *b = &a; // *放在靠int或是靠變數名稱都可以
|
上面程式代表b是a的指標
如果不初始化指標,建議將值設為0或者nullptr(空指標),避免造成不可預期的結果
1
2
| int *a;
*a = nullptr;
|
現在來修改交換函式
1
2
3
4
5
6
7
8
9
10
11
12
| #include<bits/stdc++.h>
using namespace std;
void swap(int &x,int &y){
int t=x;x=y;y=t;
}
int main(){
int a=1,b=2;
swap(a,b);
cout << a << " " << b << endl;
return 0;
}
|
或是這樣寫
1
2
3
4
5
6
7
8
9
10
11
12
| #include<bits/stdc++.h>
using namespace std;
void swap(int *x,int *y){
int t=x;x=y;y=t;
}
int main(){
int a=1,b=2;
swap(&a,&b);
cout << a << " " << b << endl;
return 0;
}
|
指標陣列
其實如果我們直接使用陣列變數,會得到該陣列第一個元素的位址,即輸出arr等同輸出&arr[0],
而陣列索引其實就是位址位移量。
我們有兩種方法計算陣列長度
1
2
3
| int arr[10]={1};
cout << sizeof(arr)/sizeof(arr[0]) << endl; // 利用記憶體占用大小計算
cout << end(arr) - begin(arr) << endl;//end,begin是C++11提供的函式,可以得到陣列位址
|
而C++11還提供for range,利用指標來循序走訪
1
2
3
| for(auto i:arr){
cout << i << " ";
}
|
其實就是把i初始化成陣列首項位址,然後一直+1加到最後一項,也可以寫成
1
2
3
| for(auto i=begin(arr);i!=end(arr);++i){
cout << *i << " ";
}
|
配置記憶體
我們運行程式時,每個變數都會有段生命週期,只存在於程式運行時,放在記憶體的堆疊區,
程式停止就會自動刪除,現在我們試著手動管理記憶體,它將被放在記憶體堆積區,等我們到最後再手動刪除。
配置記憶體可以這樣宣告
1
2
3
4
5
| int *p1 = new int; // 配置int需要的空間
int *p2 = new int(123); // 配置後順便初始化儲存值
*p1 = 321;
cout << p1 << " " << *p1 << endl;
cout << p2 << " " << *p2 << endl;
|
而沒有要用時我們一定要記得刪除,否則記憶體空間會耗盡
1
2
| delete p1;
delete p2;
|
我們還能配置連續空間
1
2
3
4
5
6
7
8
| int *p1 = new int[100];
int *p2 = new int[5]{1,2,3,4,5}; // 初始化
int *p3 = new int[10](); // 全部初始化為0
delete [] p1;
delete [] p2;
delete [] p3;
// 最後一定要全部還給電腦
|
如果要動態配置連續空間,可以當成二維陣列
1
2
| int **arr = new int*[10];
for(int i=0;i<10;i++) arr[i] = new int[12]{1};
|
最後程式宣告的是10*12的二維陣列,並初始化為1。
也一定要記得在最後用迴圈把陣列delete還給電腦。