目录
- 二级指针
- 二级指针的定义和声明
- 二级指针的初始化
- 二级指针的使用
- 二级指针和函数参数
- 二级指针和动态内存分配
- 数组指针
- 二维数组
- 二维数组的初始化
- 二维数组与指针
- 二维数组的遍历
二级指针
当涉及到多级指针时,C语言的灵活性和强大的指针功能可以得到充分的发挥。二级指针是指指向指针的指针,也被称为指向指针的引用。
使用二级指针可以实现以下功能:
- 动态内存分配:通过二级指针可以动态地分配内存块,并将其地址传递给其他函数或模块进行操作。这对于动态数据结构如链表、树等非常有用。
- 函数参数传递:二级指针可以用作函数的参数,通过传递指向指针的指针,函数可以修改原始指针的值,实现对指针本身的修改,而不仅仅是对指针所指向的数据的修改。
- 多维数组:在处理多维数组时,二级指针可以用于动态创建和操作二维及更高维的数组结构。
- 字符串处理:通过二级指针可以实现字符串的动态分配和修改,以及指针数组的管理。
二级指针的使用要注意以下几点:
- 内存管理:使用二级指针进行动态内存分配时,需要手动管理内存的分配和释放,确保在不需要使用时及时释放内存,避免内存泄漏。
- 空指针检查:在使用二级指针之前,务必进行空指针检查,避免对空指针进行操作导致程序崩溃或出现未定义行为。
- 间接访问:二级指针需要通过多次间接访问才能获得最终的数据,因此需要小心处理指针的层级关系,确保每一级指针的有效性和正确性。
总之,二级指针是C语言中一个强大且灵活的工具,它提供了对指针本身的操作和控制,使得程序可以更加高效地管理内存、处理复杂的数据结构以及实现更灵活的函数参数传递。但同时,使用二级指针也需要小心处理指针的有效性和内存管理,以确保程序的正确性和稳定性。
二级指针(double pointer)是指指针的指针,它可以用于在函数中传递和修改指针的值,或者动态管理内存。
定义
int data = 100;
int *p = &data;
int **pp = &p;
//可以定义int *pp = &p, 但是在取内容时只能向上取一级,即*pp 为 p的地址
printf("%d", **pp);
举例
#include <stdio.h>
//二维数组表示一共3个人,每个人有4科成绩,调用函数传入二级指针,将一个人的4科成绩地址放入二级指针指向的地址
void getPosPerson(int pos, int (*pstu)[4], int **ppos)
{
*ppos = (int *)(pstu + pos);
}
int main()
{
int scores[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
int *ppos;
int pos;
scanf("%d", &pos);
getPosPerson(pos, scores, &ppos);
for (int i = 0; i < 4; i++)
printf("%d ", *ppos++);
return 0;
}
C语言中的二级指针(指向指针的指针)在处理多级指针或者动态内存分配等情况下非常有用。下面是关于C语言二级指针的一些重要知识点:
二级指针的定义和声明
二级指针是指向指针的指针,使用两个星号(**
)表示。例如:
int** ptr;
二级指针的初始化
二级指针需要进行两级的内存分配。首先,分配一个指针变量的内存,然后为该指针变量分配指向的内存。示例:
int* p;
int** ptr = &p;
二级指针的使用
通过二级指针可以访问和修改指针指向的内存。例如,通过二级指针可以间接修改一级指针所指向的变量的值。示例:
int x = 10;
int* p = &x;
int** ptr = &p;
**ptr = 20; // 修改p指向的变量的值为20
二级指针和函数参数
二级指针常用于函数参数,可以通过传递指针的指针来修改原始指针的值。这在需要修改指针本身的情况下非常有用。示例:
void updatePointer(int** ptr) {
int* newPtr = malloc(sizeof(int));
*newPtr = 100;
*ptr = newPtr;
}
int main() {
int* p = NULL;
updatePointer(&p);
// 现在p指向了动态分配的内存
// 可以通过*p访问该内存的值
return 0;
}
二级指针和动态内存分配
二级指针可以用于动态分配内存。通过二级指针,可以分配指针数组或多维数组的内存。示例:
int numRows = 3;
int numCols = 4;
int** matrix = malloc(numRows * sizeof(int*));
for (int i = 0; i < numRows; i++) {
matrix[i] = malloc(numCols * sizeof(int));
}
// 现在可以通过matrix[i][j]访问二维数组的元素
以上是关于C语言二级指针的一些基本知识点和用法。二级指针在处理多级指针、动态内存分配和函数参数传递等场景下非常有用,可以灵活地管理和操作指针的指针。
数组指针
二级指针和二维数组注意:
不能直接用二级指针指向二维数组,int **p = scores后虽然指向的地址相同,但是含义类型并不相同,错误,应该用数组指针指向二维数组。
int scores[3][4] = {
{1, 2, 3, 4},
{5, 6, 7, 8},
{9, 10, 11, 12}
};
int **p;
//p = scores; 错误
int (*p2)[4] = scores; //数组指针,定义一个指针,指向一个数组,数组指针才是真正等同于二维数组名
p = &p2; //可以用二级指针指向数组指针的地址
**p = 100; //修改的是scores[0][0]的值
二维数组
二维数组的初始化
- 按行列初始化
- 没明确行列,类似一维数组
-
部分赋初值
2.
4.
二维数组与指针
C语言规定数组名代表数组首元素地址
int a[3][3];
a[0],a[1],a[2] 是一维数组名,则
a[0] 代表一维数组a[0]中第0列元素的地址,即
a[0] = &a[0][0]
a[1] = &a[1][0]
a[2] = &a[2][0]
------------------------
a = &a[0]
*a = a[0]
**a = a[0][0]
a + 1 = &a[1]
*(a + 1) = a[1]
a[0] + 1 = &a[0][1] = *(a + 0) + 1
------------------------------
参考
总结
二维数组的遍历
操作数组名
int array[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
for (int i = 0; i < 3; i++)
for (int j = 0; j < 4; j++) {
//几种写法一样效果
printf("%d ", array[i][j]);
printf("%d ", *(array[i] + j));
printf("%d ", *(*(array + i) + j));
}
操作指针
int array[3][4] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
int *p1 = &array[0][0];
int (*p2)[4] = array; //数组指针,定义一个指针,指向一个数组,数组指针才是真正等同于二维数组名
for (int i = 0; i < 3; i++)
for (int j = 0; j < 4; j++) {
printf("%d ", *p1++);
printf("%d ", *(*(p2 + i) + j));
}