29.多级指针

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

×

喜欢就点赞,疼爱就打赏