二级指针

当涉及到多级指针时,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 <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]的值

二维数组

二维数组的初始化
  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));
    }
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐