二级指针就是:指向指针的指针,它存储的是“另一个指针变量的地址”。

int a = 10;
int* p = &a;      // p 是一级指针,指向 int
int** pp = &p;    // pp 是二级指针,指向 int*
┌─────────────┐
│    a = 10   │
└─────┬───────┘
      │
      ▼
┌─────────────┐
│ p = &a      │ → 保存了 a 的地址
└─────┬───────┘
      │
      ▼
┌─────────────┐
│ pp = &p     │ → 保存了 p 的地址
└─────────────┘

a 是变量;

p 是指针,*p 取出 a 的值;

pp 是二级指针,*pp 就是 p;

**pp 取出最终的值 a。

std::cout << a << std::endl;     // 10
std::cout << *p << std::endl;    // 10
std::cout << **pp << std::endl;  // 10

用途:

1、动态分配二维数组

例如动态创建一个 3×4 的二维整型数组:

#include <iostream>

int main() {
    int rows = 3, cols = 4;

    // 创建“指针数组”
    int** arr = new int*[rows];

    // 为每一行分配列
    for (int i = 0; i < rows; ++i)
        arr[i] = new int[cols];

    // 使用
    for (int i = 0; i < rows; ++i)
        for (int j = 0; j < cols; ++j)
            arr[i][j] = i * 10 + j;

    // 输出
    for (int i = 0; i < rows; ++i) {
        for (int j = 0; j < cols; ++j)
            std::cout << arr[i][j] << " ";
        std::cout << std::endl;
    }

    // 释放内存
    for (int i = 0; i < rows; ++i)
        delete[] arr[i];
    delete[] arr;

    return 0;
}

2、修改指针本身(函数参数)

假设有一个函数需要在函数内部改变指针的指向(例如 mallocnew 分配内存),那么必须用“指针的指针”。

#include <iostream>

void allocateMemory(int** p) {
    *p = new int(100);   // 改变调用者传入的指针
}

int main() {
    int* ptr = nullptr;
    allocateMemory(&ptr);  // 传入指针的地址
    std::cout << *ptr << std::endl;  // 输出 100
    delete ptr;
}

3、C 语言字符串数组(char**

int main(int argc, char** argv)

这里的 argv 就是一个“指向字符串指针数组的指针”。

也就是说:

  • argvchar**

  • argv[i]char*

  • argv[i][j] 是一个 char

示例:

for (int i = 0; i < argc; ++i) 
{ 
    std::cout << argv[i] << std::endl;
}
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐