指針和引用:
指針是一個變量,其值爲另一個變量的地址。引用則可以看做是一個變量的別名。
#include <iostream>
using namespace std;
int main() {
int a = 1;
int *p = &a;
cout << "a: " << a << endl;
cout << "&a: " << &a << endl;
cout << "p: " << p << endl;
cout << "*P: " << *p << endl;
return 0;
}
運行輸出結果:
a: 1
&a: 0x7fff8e9e86a4
p: 0x7fff8e9e86a4
*P: 1
指針調用和引用調用:
首先來看一段示例代碼:
#include <iostream>
using namespace std;
void change_value(int a);
int main() {
int a = 1;
cout << "a: " << a << endl;
change_value(a);
cout << "a: " << a << endl;
return 0;
}
void change_value(int a) {
a = 0;
}
運行輸出結果爲:
a: 1
a: 1
可以看到我們想要實現的功能是改變變量的值,但是實際上並沒有達到我們想要的效果。這種情況屬於函數參數中的傳值調用,該方法把參數的實際值複製給函數的形式參數,修改函數內的形式參數對實際參數沒有影響。另外兩種便是指針調用和引用調用:指針調用把參數的地址複製給形式參數,在函數內,該地址用於訪問調用中要用到的實際參數。這意味着,修改形式參數會影響實際參數;引用調用把參數的引用複製給形式參數。在函數內,該引用用於訪問調用中要用到的實際參數。這意味着,修改形式參數會影響實際參數。那麼既然這兩種方式都能改變實際參數的值,我們該選用哪一種呢?一般情況下,應該使用引用而不是指針,引用可以讓程序更簡潔並易於理解。此外,引用比指針安全:不可能存在無效的引用,也不需要顯式的解除引用。對象的引用甚至可以像指針那樣支持多態性。只有在需要改變所指地址的時候,才需要指針。例如:當動態分配內存的時候,應該將結果存儲在指針而不是引用中。示例代碼如下:
#include <iostream>
using namespace std;
void change_value_1(int *a);
void change_value_2(int &a);
int main() {
int i = 1;
int *a = &i;
int &b = i;
cout << "i: " << i << endl;
change_value_1(a);
cout << "i: " << i << endl;
change_value_2(b);
cout << "i: " << i << endl;
return 0;
}
void change_value_1(int *a) {
*a = 0;
}
void change_value_2(int &a) {
a = 2;
}
運行輸出結果爲:
i: 1
i: 0
i: 2
二級指針和指針引用:
上面我們已經說到指針和引用可以改變實際參數的值,那麼假如我們現在想改變指針變量的值即改變指針的指向怎麼辦呢?用到的則是二級指針和指針引用。下面看一段代碼,實現的功能是交換兩個指針變量的指向:
#include <iostream>
using namespace std;
void swap_1(int **a, int **b);
void swap_2(int *&a, int *&b);
int main() {
int a = 1;
int b = 2;
int *c = &a;
int *d = &b;
int **e = &c;
int **f = &d;
int *&g = c;
int *&h = d;
cout << "*c: " << *c << endl;
cout << "*d: " << *d << endl;
swap_1(e, f);
cout << "*c: " << *c << endl;
cout << "*d: " << *d << endl;
swap_2(g, h);
cout << "*c: " << *c << endl;
cout << "*d: " << *d << endl;
return 0;
}
void swap_1(int **a, int **b) {
int *temp = *a;
*a = *b;
*b = temp;
}
void swap_2(int *&a, int *&b) {
int *temp = a;
a = b;
b = temp;
}
運行輸出結果:
*c: 1
*d: 2
*c: 2
*d: 1
*c: 1
*d: 2