29.指针-多级指针
29.1 知识点
多级指针是什么
多级指针是指向指针的指针,也可以理解为嵌套指针。它的作用是存储指针变量的地址,用于在不同的层次上访问数据。
一级指针
一级指针是最常见的指针类型,用来存储普通变量的地址。
int a = 99; // 普通变量 a
int* p = &a; // p 是一个指针,存储变量 a 的地址
// 输出指针 p 存储的地址(即变量 a 的地址)
cout << "p 存储的地址: " << p << endl; // 输出结果: 00000079E513F934
// 输出指针 p 指向的值,即变量 a 的值
cout << "p 指向的值: " << *p << endl; // 输出结果: 99
二级指针
二级指针是指向一级指针变量地址的指针。换句话说,二级指针存储一级指针的地址。
int** pp = &p; // pp 是一个指针,存储 p 的地址
// 输出二级指针 pp 存储的地址(即一级指针 p 的地址)
cout << "pp 存储的地址: " << pp << endl; // 输出结果: 00000079E513F958
// 输出二级指针 pp 解引用一次,得到一级指针 p 的地址
cout << "pp 解引用一次: " << *pp << endl; // 输出结果: 00000079E513F934
// 输出二级指针 pp 解引用两次,得到一级指针 p 存储的值(即 a 的值)
cout << "pp 解引用两次: " << **pp << endl; // 输出结果: 99
三级指针
三级指针是指向二级指针变量地址的指针。也就是说,三级指针存储二级指针的地址。
int*** ppp = &pp; // ppp 是一个指针,存储 pp 的地址
// 输出三级指针 ppp 存储的地址(即二级指针 pp 的地址)
cout << "ppp 存储的地址: " << ppp << endl; // 输出结果: 00000079E513F978
// 输出三级指针 ppp 解引用一次,得到二级指针 pp 的地址
cout << "ppp 解引用一次: " << *ppp << endl; // 输出结果: 00000079E513F958
// 输出三级指针 ppp 解引用两次,得到一级指针 p 的地址
cout << "ppp 解引用两次: " << **ppp << endl; // 输出结果: 00000079E513F934
// 输出三级指针 ppp 解引用三次,得到变量 a 的值
cout << "ppp 解引用三次: " << ***ppp << endl; // 输出结果: 99
// 输出变量 a 的值
cout << "a 的值: " << ***ppp << endl; // 输出结果: 99
多级指针
多级指针本质上就是指向指针的指针,可以有多层嵌套。第 n 级指针存储第 n-1 级指针的地址。如果想访问多级指针的最底层值,只需要使用 n 个解引用操作符 (*
)。
29.2 知识点代码
Lesson29_指针_多级指针.cpp
#include <iostream>
using namespace std;
int main()
{
cout << "多级指针\n";
#pragma region 知识点一 多级指针是什么
// 多级指针是指向指针的指针,也可以理解为嵌套指针。
// 它的作用是存储指针变量的地址。多级指针用于在不同的层次上访问数据。
#pragma endregion
#pragma region 知识点二 一级指针
// 一级指针是最常见的指针类型,它用来存储普通变量的地址。
// 例如,int* p = &a; p 存储的是变量 a 的地址。
int a = 99; // 普通变量 a
int* p = &a; // p 是一个指针,存储变量 a 的地址
// 输出指针 p 存储的地址(即变量 a 的地址)
cout << "p 存储的地址: " << p << endl; // 输出结果: 00000079E513F934
// 输出指针 p 指向的值,即变量 a 的值
cout << "p 指向的值: " << *p << endl; // 输出结果: 99
#pragma endregion
#pragma region 知识点三 二级指针
// 二级指针是指向一级指针变量地址的指针。换句话说,二级指针存储一级指针的地址。
// 例如,int** pp = &p; pp 存储的是 p 的地址。
int** pp = &p; // pp 是一个指针,存储 p 的地址
// 输出二级指针 pp 存储的地址(即一级指针 p 的地址)
cout << "pp 存储的地址: " << pp << endl; // 输出结果: 00000079E513F958
// 输出二级指针 pp 解引用一次,得到一级指针 p 的地址
cout << "pp 解引用一次: " << *pp << endl; // 输出结果: 00000079E513F934
// 输出二级指针 pp 解引用两次,得到一级指针 p 存储的值(即 a 的地址)
cout << "pp 解引用两次: " << **pp << endl; // 输出结果: 99
#pragma endregion
#pragma region 知识点四 三级指针
// 三级指针是指向二级指针变量地址的指针。也就是说,三级指针存储二级指针的地址。
// 例如,int*** ppp = &pp; ppp 存储的是 pp 的地址。
int*** ppp = &pp; // ppp 是一个指针,存储 pp 的地址
// 输出三级指针 ppp 存储的地址(即二级指针 pp 的地址)
cout << "ppp 存储的地址: " << ppp << endl; // 输出结果: 00000079E513F978
// 输出三级指针 ppp 解引用一次,得到二级指针 pp 的地址
cout << "ppp 解引用一次: " << *ppp << endl; // 输出结果: 00000079E513F958
// 输出三级指针 ppp 解引用两次,得到一级指针 p 的地址
cout << "ppp 解引用两次: " << **ppp << endl; // 输出结果: 00000079E513F934
// 输出三级指针 ppp 解引用三次,得到变量 a 的地址
cout << "ppp 解引用三次: " << ***ppp << endl; // 输出结果: 99
// 输出变量 a 的值
cout << "a 的值: " << ***ppp << endl; // 输出结果: 99
#pragma endregion
#pragma region 知识点五 多级指针
// 多级指针本质上就是指向指针的指针,可以有多层嵌套。
// 第n级指针存储第n-1级指针的地址。如果想访问多级指针的最底层值,只需要使用n个解引用操作符(*)。
#pragma endregion
}
29.3 练习题
编写一个函数,在函数内部需要将传入的指针改变指向到一个函数内部的静态变量,该修改会影响实参的指向
// 这个函数接受一个二级指针作为参数,修改该指针指向一个静态变量。
// 由于是二级指针(指向一级指针),所以函数内部修改指针的指向会影响实参。
void changePtr(int** p2)
{
// 静态变量 c,其生命周期贯穿整个程序
static int c = 10;
// 输出形参 p2 存储的地址,实际上是 c 的地址
cout << "赋值前,二级指针形参 p2 存储的地址: " << *p2 << endl;
// 修改传入的指针 p 的指向,让它指向静态变量 c 的地址
*p2 = &c;
// 输出形参 p2 存储的地址,实际上是 c 的地址
cout << "赋值后,二级指针形参 p2 存储的地址: " << *p2 << endl;
// 输出静态变量 c 的值
cout << "静态变量 c 的值: " << c << endl;
}
// 定义一个普通整型变量 a,初始化为 12
int a = 12;
// 定义一个一级指针 p,指向变量 a 的地址
int* p = &a;
// 输出指针 p 存储的地址,即变量 a 的地址
cout << "修改前,实参p 存储的地址(a 的地址): " << p << endl; // 修改前,实参p 存储的地址(a 的地址) : 000000868C5BFA34
// 调用 changePtr 函数,将 p 作为实参传入
changePtr(&p);
// 赋值前,二级指针形参 p2 存储的地址 : 000000868C5BFA34
// 赋值后,二级指针形参 p2 存储的地址 : 00007FF6DD63E000
// 静态变量 c 的值 : 10
// 输出指针 p 现在存储的地址,即变更后的指向
cout << "修改后,实参p 被修改后的地址: " << p << endl; // 修改后,实参p 被修改后的地址 : 00007FF6DD63E000
cout << "取值*p : " << *p << endl; // 取值*p : 10
29.4 练习题代码
Lesson29_练习题.cpp
#include <iostream>
using namespace std;
void changePtr(int** p);
int main()
{
cout << "多级指针 练习题\n";
// 定义一个普通整型变量 a,初始化为 12
int a = 12;
// 定义一个一级指针 p,指向变量 a 的地址
int* p = &a;
// 输出指针 p 存储的地址,即变量 a 的地址
cout << "修改前,实参p 存储的地址(a 的地址): " << p << endl; //修改前,实参p 存储的地址(a 的地址) : 000000868C5BFA34
// 调用 changePtr 函数,将 p 作为实参传入
changePtr(&p);
//赋值前,二级指针形参 p2 存储的地址 : 000000868C5BFA34
//赋值后,二级指针形参 p2 存储的地址 : 00007FF6DD63E000
//静态变量 c 的值 : 10
// 输出指针 p 现在存储的地址,即变更后的指向
cout << "修改后,实参p 被修改后的地址: " << p << endl;//修改后,实参p 被修改后的地址 : 00007FF6DD63E000
cout << "取值*p : " << *p << endl; //取值*p : 10
return 0;
}
#pragma region 练习题
// 编写一个函数,在函数内部需要将传入的指针改变指向到一个函数内部的静态变量,该修改会影响实参的指向
// 这个函数接受一个二级指针作为参数,修改该指针指向一个静态变量。
// 由于是二级指针(指向一级指针),所以函数内部修改指针的指向会影响实参。
void changePtr(int** p2)
{
// 静态变量 c,其生命周期贯穿整个程序
static int c = 10;
// 输出形参 p 存储的地址,实际上是 c 的地址
cout << "赋值前,二级指针形参 p2 存储的地址: " << *p2 << endl;
// 修改传入的指针 p 的指向,让它指向静态变量 c 的地址
*p2 = &c;
// 输出形参 p 存储的地址,实际上是 c 的地址
cout << "赋值后,二级指针形参 p2 存储的地址: " << *p2 << endl;
// 输出静态变量 c 的值
cout << "静态变量 c 的值: " << c << endl;
}
#pragma endregion
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com