目录

    • 二级指针
    • 二级指针的定义和声明
    • 二级指针的初始化
    • 二级指针的使用
    • 二级指针和函数参数
    • 二级指针和动态内存分配
    • 数组指针
      • 二维数组
        • 二维数组的初始化
        • 二维数组与指针
        • 二维数组的遍历

二级指针

当涉及到多级指针时,C语言的灵活性和强大的指针功能可以得到充分的发挥。二级指针是指指向指针的指针,也被称为指向指针的引用。

使用二级指针可以实现以下功能:

  1. 动态内存分配:通过二级指针可以动态地分配内存块,并将其地址传递给其他函数或模块进行操作。这对于动态数据结构如链表、树等非常有用。
  2. 函数参数传递:二级指针可以用作函数的参数,通过传递指向指针的指针,函数可以修改原始指针的值,实现对指针本身的修改,而不仅仅是对指针所指向的数据的修改。
  3. 多维数组:在处理多维数组时,二级指针可以用于动态创建和操作二维及更高维的数组结构。
  4. 字符串处理:通过二级指针可以实现字符串的动态分配和修改,以及指针数组的管理。

二级指针的使用要注意以下几点:

  1. 内存管理:使用二级指针进行动态内存分配时,需要手动管理内存的分配和释放,确保在不需要使用时及时释放内存,避免内存泄漏。
  2. 空指针检查:在使用二级指针之前,务必进行空指针检查,避免对空指针进行操作导致程序崩溃或出现未定义行为。
  3. 间接访问:二级指针需要通过多次间接访问才能获得最终的数据,因此需要小心处理指针的层级关系,确保每一级指针的有效性和正确性。

总之,二级指针是C语言中一个强大且灵活的工具,它提供了对指针本身的操作和控制,使得程序可以更加高效地管理内存、处理复杂的数据结构以及实现更灵活的函数参数传递。但同时,使用二级指针也需要小心处理指针的有效性和内存管理,以确保程序的正确性和稳定性。

二级指针(double pointer)是指指针的指针,它可以用于在函数中传递和修改指针的值,或者动态管理内存。

定义

int data = 100;int *p = &data;int **pp = &p; //可以定义int *pp = &p, 但是在取内容时只能向上取一级,即*pp 为 p的地址printf("%d", **pp);

举例

#include //二维数组表示一共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]的值

二维数组

二维数组的初始化
  1. 按行列初始化

  1. 没明确行列,类似一维数组

  1. 部分赋初值


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));}