【C 语言】多级指针 ( 在函数中生成 二级指针 | 通过传入的 三级指针 进行间接赋值 )

简介: 【C 语言】多级指针 ( 在函数中生成 二级指针 | 通过传入的 三级指针 进行间接赋值 )

文章目录

前言

一、在函数中生成 二级指针 ( 通过传入的 三级指针 进行间接赋值 )

二、完整代码示例

前言

如果要 通过 函数形参 间接赋值 修改 n nn 级指针, 需要向函数中传入 n + 1 n + 1n+1 级指针 形参 ;






一、在函数中生成 二级指针 ( 通过传入的 三级指针 进行间接赋值 )


通过 函数 形参变量 , 间接赋值 返回 生成的 二级指针 函数 ;


如果要生成一个 二级指针 , 必须传入 三级指针 , 才能修改 该 二级指针 ;



注意 : 传入的 三级指针 , 不要直接修改该值 , 先创建一个临时的 局部二级指针变量 , 将 二级指针 生成完毕后 , 最后再给 三级指针 指向的地址 进行赋值 ;



代码示例 :


/**
 * @brief 生成二维指针
 * @param num
 * @return
 */
int generate_memory(char ***p3, int num)
{
    // 循环控制变量
    int i = 0;
    // 声明二维指针
    char **p = NULL;
    // 在堆内存中 , 分配一块内存空间
    // 用于存储 num 个 一维指针
    // 每个 一维指针 指向一块内存空间
    p = (char **)malloc( sizeof(char*) * num );
    if(p == NULL)
    {
        return -1;
    }
    // 遍历 二维指针 指向的多个 一维指针
    // 并为每个 一维指针 在堆内存中 分配 20 字节内存
    for(i = 0; i < num; i++)
    {
        // 为每个字符分配 20 字节空间
        p[i] = (char *)malloc(sizeof (char) * 20);
        // 向内存中写入 字符串 , 字符串内容是 i + 1
        // 注意是通过通配符拼装的字符串
        sprintf(p[i], "%d", i + 1);
    }
    // 将 三维指针 指向 生成的 二维指针 地址
    *p3 = p;
    return 0;
}





二、完整代码示例


完整代码示例 :


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/**
 * @brief 生成二维指针
 * @param num
 * @return
 */
int generate_memory(char ***p3, int num)
{
    // 循环控制变量
    int i = 0;
    // 声明二维指针
    char **p = NULL;
    // 在堆内存中 , 分配一块内存空间
    // 用于存储 num 个 一维指针
    // 每个 一维指针 指向一块内存空间
    p = (char **)malloc( sizeof(char*) * num );
    if(p == NULL)
    {
        return -1;
    }
    // 遍历 二维指针 指向的多个 一维指针
    // 并为每个 一维指针 在堆内存中 分配 20 字节内存
    for(i = 0; i < num; i++)
    {
        // 为每个字符分配 20 字节空间
        p[i] = (char *)malloc(sizeof (char) * 20);
        // 向内存中写入 字符串 , 字符串内容是 i + 1
        // 注意是通过通配符拼装的字符串
        sprintf(p[i], "%d", i + 1);
    }
    // 将 三维指针 指向 生成的 二维指针 地址
    *p3 = p;
    return 0;
}
/**
 * @brief 打印二维指针数据
 * @param array
 * @param num
 */
void printf_array(char **array, int num)
{
    // 循环控制变量
    int i = 0;
    // 判定指针合法性
    if(array == NULL)
    {
        return;
    }
    // 打印字 二维指针 指向的 num 个 一维数组 指向的 字符串
    for(i = 0; i < num; i++)
    {
        printf("%s\n", array[i]);
    }
}
/**
 * @brief 二维指针排序
 * @param p
 * @param num
 * @return
 */
int sort_array(char **p, int num)
{
    // 循环控制变量
    int i = 0, j = 0;
    // 排序时 , 交换指针 , 该指针是存储 要 交换指针 的临时变量
    char *tmp = NULL;
    // 判定指针合法性
    if(p == NULL)
    {
        return -1;
    }
    // 对 二维指针 指向的数据进行排序
    for(i = 0; i < num; i++)
    {
        for(j = i + 1; j < num; j++)
        {
            // 交换 i , j 指针指向的内存数据
            // 从 大 到 小 进行排序
            if(strcmp(p[i], p[j]) < 0)
            {
                tmp = p[i];
                p[i] = p[j];
                p[j] = tmp;
            }
        }
    }
    return 0;
}
/**
 * @brief 释放二维指针内存
 * @param p
 * @param num
 */
void free_mem(char ***p3, int num){
    // 循环控制变量
    int i = 0;
    // 设置临时变量 , 接收 p3 指向的二维指针
    char **p = *p3;
    // 判定指针合法性
    if(p3 == NULL)
    {
        return;
    }
    // 释放内存
    // 先释放 num 个 一级指针
    for(i = 0; i < num; i++)
    {
        if(p[i] != NULL)
        {
            free(p[i]);
            p[i] = NULL;
        }
    }
    // 再释放 二级指针
    if(p != NULL)
    {
        free(p);
    }
    // 二维指针 置空
    *p3 = NULL;
}
/**
 * @brief 主函数入口
 * @return
 */
int main()
{
    // 二维指针 指向的 一维指针 个数
    int num = 4;
    // 声明二维指针
    char **p = NULL;
    // 循环控制变量
    int i = 0, j = 0;
    // 排序时 , 交换指针 , 该指针是存储 要 交换指针 的临时变量
    char *tmp = NULL;
    // 在堆内存中 , 分配一块内存空间
    // 用于存储 num 个 一维指针
    // 每个 一维指针 指向一块内存空间
    generate_memory(&p, num);
    // 打印字 二维指针 指向的 num 个 一维数组 指向的 字符串
    printf_array(p, num);
    // 对 二维指针 指向的数据进行排序
    sort_array(p, num);
    // 打印字 二维指针 指向的 num 个 一维数组 指向的 字符串
    printf("\nSort : \n");
    printf_array(p, num);
    // 释放内存
    free_mem(&p, num);
    // 命令行不要退出
    system("pause");
    return 0;
}


执行结果 :


image.png

目录
相关文章
|
11天前
|
安全 C语言
【C语言】如何规避野指针
【C语言】如何规避野指针
19 0
|
1天前
|
C语言
c语言指针总结
c语言指针总结
7 1
|
7天前
|
缓存 安全 编译器
【C 言专栏】C 语言函数的高效编程技巧
【5月更文挑战第1天】本文探讨了C语言中函数的高效编程技巧,包括函数的定义与作用(如代码复用和提高可读性)、设计原则(单一职责和接口简洁)、参数传递方式(值传递、指针传递和引用传递)、返回值管理、调用约定、嵌套与递归调用,以及函数优化技巧和常见错误避免。掌握这些技巧能提升C语言代码的质量和效率。
【C 言专栏】C 语言函数的高效编程技巧
|
7天前
|
存储 程序员 C语言
【C 言专栏】C 语言指针的深度解析
【4月更文挑战第30天】C 语言中的指针是程序设计的关键,它如同一把钥匙,提供直接内存操作的途径。指针是存储其他变量地址的变量,通过声明如`int *ptr`来使用。它们在动态内存分配、函数参数传递及数组操作中发挥重要作用。然而,误用指针可能导致错误,如空指针引用和内存泄漏。理解指针的运算、与数组和函数的关系,以及在结构体中的应用,是成为熟练 C 语言程序员的必经之路。虽然挑战重重,但掌握指针将增强编程效率和灵活性。不断实践和学习,我们将驾驭指针,探索更广阔的编程世界。
|
7天前
|
Java Go 区块链
【Go语言专栏】Go语言中的指针与内存管理
【4月更文挑战第30天】Go语言,由Google开发,是一种静态强类型、编译型、并发型语言,具有垃圾回收功能,常用于云计算、微服务、区块链等领域。本文聚焦Go中的指针和内存管理。指针表示变量内存地址,可用于直接访问和修改变量,如示例代码所示。指针运算有限制,仅支持相同类型变量和数组元素访问。内存管理由Go运行时的垃圾回收机制处理,自动回收无引用对象,简化管理但引入性能开销。可通过`runtime.GC()`手动触发垃圾回收。
|
8天前
|
算法 搜索推荐 程序员
C语言中的函数指针和回调函数
C语言中的函数指针和回调函数
9 2
|
9天前
|
C语言
pta浙大版《C语言程序设计(第3版)》 习题6-4 使用函数输出指定范围内的Fibonacci数 (20分)
pta浙大版《C语言程序设计(第3版)》 习题6-4 使用函数输出指定范围内的Fibonacci数 (20分)
|
9天前
|
C语言
pta 浙大版《C语言程序设计(第3版)》题目集 习题6-6 使用函数输出一个整数的逆序数 (20分)
pta 浙大版《C语言程序设计(第3版)》题目集 习题6-6 使用函数输出一个整数的逆序数 (20分)
|
9天前
|
C语言
(浙大版《C语言程序设计(第3版)》 习题6-5 使用函数验证哥德巴赫猜想 (20分)
(浙大版《C语言程序设计(第3版)》 习题6-5 使用函数验证哥德巴赫猜想 (20分)
|
11天前
|
安全 C语言
【C语言】strcpy与strncpy函数的使用和模拟实现
【C语言】strcpy与strncpy函数的使用和模拟实现
5 0