指標的指標
Prerequisites:
指標的指標,意思是指標的記憶體位址。
指標的位址
1
2
3
4
5
6
7
8
9
10
int main() {
int i = 40;
cout << "i的值 = " << i << ",i的位址 = " << &i << endl;
int *p = &i;
cout << "指標p指向的位址 = " << p << ",指標p的位址 = " << &p << ",指標p指向位址的值=" << *p << endl;
int **pp = &p;
cout << "指標pp指向的位址 = " << pp << ",指標pp的位址 = " << &pp << ",指標pp指向的位址(p)指向的位址(i)=" << *pp << endl;
cout << "指標pp指向的位址(p)指向的位址(i)的值=" << **pp << endl;
return 0;
}
i的值 = 40,i的位址 = 0x7ff7bfeff468
指標p指向的位址 = 0x7ff7bfeff468,指標p的位址 = 0x7ff7bfeff460,指標p指向位址的值=40
指標pp指向的位址 = 0x7ff7bfeff460,指標pp的位址 = 0x7ff7bfeff458,指標pp指向的位址(p)指向的位址(i)=0x7ff7bfeff468
指標pp指向的位址(p)指向的位址(i)的值=40
其它程式碼解釋
1
2
3
4
5
6
7
8
9
10
11
12
13
14
int main() {
int i4 = 40;
//宣告一個指標存i4的位址
int *p2 = &i4;
//將p2指標的位址傳給pp2
int **pp2 = &p2;
//1.把pp2存放的位址,使用取值運算子*,也就是指標p2的位址
//*pp2;
//2.再把p2位址,使用取值運算子*,也就是40
//**pp2
printf("解出pp2的值:%d\n",**pp2);
return 0;
}
執行結果
解出pp2的值:40
函式參數為指標的指標
在函式中若要修改指標所指向的記憶體位址,就要用到指標的指標。
引數為指標的位址,函式參數宣告為指標資料型態** 指標變數,這樣才可以接收指標的記憶體位址。
參考以下文章
https://www.geeksforgeeks.org/passing-reference-to-a-pointer-in-c/
If a pointer is passed to a function as a parameter and tried to be modified then the changes made to the pointer does not reflects back outside that function. This is because only a copy of the pointer is passed to the function. It can be said that “pass by pointer” is passing a pointer by value. In most cases, this does not present a problem. But the problem comes when you modify the pointer inside the function. Instead of modifying the variable, you are only modifying a copy of the pointer and the original pointer remains unmodified.
(google翻譯)如果將指標作為參數傳遞給函數並嘗試對其進行修改,則對指標所做的更改不會反映回該函數外部。這是因為僅將指標的副本傳遞給函數。可以說「透過指標傳遞」就是按值傳遞指標。在大多數情況下,這不會出現問題。但當你修改函數內部的指標時,問題就來了。您只是修改指標的副本,而不是修改變量,而原始指標保持不變。
- 函式語法
傳回型態 函式名(指標資料型態** 指標) {
*指標 = 其它記憶體位址
}
- 呼叫函式語法
函式(&指標位址)
程式碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
using namespace std;
int global_var = 100;
void changePointerValue(int** ptr_ptr){
*ptr_ptr = &global_var; //改為指向global_var
}
int main() {
int var = 1;
int* pointer_to_var = &var; //指向var
cout << "Before:" << *pointer_to_var << endl;
//passing the address of the pointer
//把指標的位址傳進函式中
changePointerValue(&pointer_to_var);
cout << "After:" << *pointer_to_var << endl;
return 0;
}
Before:1
After:100
指標的指標與new
參考文章
new會返回動態配置記憶體的開始位址,將p_to_p使用*取值運算子修改p指向的位址。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
using namespace std;
//宣告一個函式initAddress() 指標是p_to_p,指向外部指標的位址
void initAddress(int** p_to_p){
//印出指向外部指標p的記憶體位址
cout << "Before p address = " << *p_to_p << endl;
//動態配置記憶體位址,位址存放的內容為10,使用new會返回動態配置記憶體的開始位址。
//使用*取值運算子修改指標p指向的位址
*p_to_p = new int(10);
//印出指向外部指標的記憶體位址與值
cout << "After p address= " << *p_to_p << ",After p value = " << **p_to_p << endl;
}
int main() {
//宣告指標p,初始化為nullptr,也就是沒有指向任何位址
int* p = nullptr;
//呼叫函式initAddress,引數為指標p的位址
initAddress(&p);
//印出指標p的位址,印出指標p指向的位址,對指向的位址取出內容。
cout << "== outside == " << endl;
cout << "outside pointer address = " << p << ",outside pointer value = " << *p << endl;
return 0;
}
Before p address = 0x0
After p address= 0x60000000c010,After p value = 10
== outside ==
outside pointer address = 0x60000000c010,outside pointer value = 10