二级指针
二级指针(指向指针的指针)用于需要修改指针本身的场景:动态二维数组、链表操作、通过函数修改指针值等。理解二级指针,是掌握动态数据结构和高级内存操作的关键。
基本语法
int x = 10;
int *p = &x; /* p 指向 x */
int **pp = &p; /* pp 指向 p */
printf("%d\n", x); /* 10 */
printf("%d\n", *p); /* 10 */
printf("%d\n", **pp); /* 10 */
修改指针值
void allocate(int **pp, int n)
{
*pp = malloc(n * sizeof(int)); /* 修改调用者的指针 */
}
int *arr = NULL;
allocate(&arr, 10); /* arr 现在指向动态分配的内存 */
if (arr != NULL) {
/* 使用 arr */
free(arr);
}
动态二维数组
int **create_matrix(int rows, int cols)
{
int **mat = malloc(rows * sizeof(int *));
for (int i = 0; i < rows; i++)
mat[i] = malloc(cols * sizeof(int));
return mat;
}
/* 使用 */
int **m = create_matrix(3, 4);
m[1][2] = 10;
/* 释放 */
for (int i = 0; i < 3; i++)
free(m[i]);
free(m);
命令行参数
int main(int argc, char **argv)
{
/* argv 是 char* 数组,即 char** */
for (int i = 0; i < argc; i++)
printf("%s\n", argv[i]);
return 0;
}
常见错误
混淆一级和二级指针:
int x = 10;
int *p = &x;
int **pp = &p;
**pp = 20; /* 修改 x */
*pp = NULL; /* 修改 p,让 p 指向 NULL */
pp = NULL; /* 修改 pp 本身 */
忘记取地址:
int *p;
allocate(p, 10); /* 错误:传递的是 p 的值(未初始化) */
allocate(&p, 10); /* 正确 */
最佳实践
- 需要修改指针时,传二级指针
- 动态二维数组考虑连续内存方式(缓存友好)
- 三级以上指针尽量避免(可读性差)
- 释放动态分配的指针数组时,先释放内层再释放外层