文章目录

  • 一、指针数组 和 二维数组 数据 拷贝到 自定义二级指针 中
    • 1、函数形参 设计规则
    • 2、三种内存模型 对应 函数形参 指针退化规则
  • 二、完整代码示例

一、指针数组 和 二维数组 数据 拷贝到 自定义二级指针 中


将 指针数组 和 二维数组 中的数据 拷贝到 自定义二级指针 内存模型中 , 并进行排序 ;

1、函数形参 设计规则

函数形参 设计规则 : 向 函数中 传入 二级指针 , 如果只是 使用 该 二级指针 指向的数据 , 可以 直接传入 二级指针 作为形参 ; 如果 需要 修改 二级指针 的指向 , 则需要 传入 三级指针 ;

2、三种内存模型 对应 函数形参 指针退化规则

① 指针数组 : 指针数组 参数 , 外层是数组 , 内层是指针 , 外层数组 退化成 指针 , 整体退化成 二级指针 ;

    // 指针数组char *p1[] = {"ab", "ef", "cd"};

退化为 :二级指针 ;

char **p1

② 二维数组 : 二维数组 , 最高维退化成 指针 , 整体退化成 数组指针 , 指向数组的指针 ;

    // 二维数组char p2[3][5] = {"13", "35", "22"};

退化为 : 数组指针 ;

// 数组指针
char (*p2)[5]

③ 二维指针 : 二维指针 作为参数 不退化 ;

    // 二级指针char **p3 = NULL;

退化为 :

// 二维指针
char **p3

代码示例 :

/*** @brief copy_data 将 指针数组 和 二维数组 中的数据拷贝到 二维指针 中* @param p1 指针数组 参数 , 外层是数组 , 内层是指针 , 外层数组 退化成 指针 , 整体退化成 二级指针* @param count1 指针数组 中的 指针变量元素个数* @param p2 二维数组 , 最高维退化成 指针 , 整体退化成 数组指针 , 指向数组的指针* @param count2 二维数组的 一维数组 个数* @param newp 指向 二级指针 的 三级指针* @param count3p 指向一个数字的指针 , 该 数字是 二级指针 指向的 一级指针 个数* @return*/
int copy_data(char **p1, int count1, char (*p2)[5], int count2, char ***newp, int *count3p)

二、完整代码示例


完整代码示例 :

#include <stdio.h>
#include <stdlib.h>
#include <string.h>/* 计算数组 array 大小 */
#define LENGTH(array) (sizeof(array)/sizeof(*array))/*** @brief copy_data 将 指针数组 和 二维数组 中的数据拷贝到 二维指针 中* @param p1 指针数组 参数 , 外层是数组 , 内层是指针 , 外层数组 退化成 指针 , 整体退化成 二级指针* @param count1 指针数组 中的 指针变量元素个数* @param p2 二维数组 , 最高维退化成 指针 , 整体退化成 数组指针 , 指向数组的指针* @param count2 二维数组的 一维数组 个数* @param newp 指向 二级指针 的 三级指针* @param count3p 指向一个数字的指针 , 该 数字是 二级指针 指向的 一级指针 个数* @return*/
int copy_data(char **p1, int count1, char (*p2)[5], int count2, char ***newp, int *count3p)
{// 返回值int ret = 0;// 循环控制变量int i = 0, j = 0;// 临时长度int len = 0;// 创建的新的 二级指针 , 用于存放 指针数组 二维指针 中的数据char **p3 = NULL;// 分配一块内存 , 这块内存中存放 count1 + count2 个一级指针p3 = (char **)malloc((count1 + count2) * sizeof(char *));// 验证指针合法性if (p3 == NULL){ret = -1;return ret;}// 遍历将 p1 指针数组 中的数据 拷贝到 二级指针 中for (i = 0; i < count1; i++){// 指针数组 中指针 指向的 字符串长度// 最后的 + 1 是加上 \0 字符len = strlen(p1[i]) + 1;// 为 指向字符串的 一级指针 在堆内存中分配内存p3[i] = (char *)malloc( len * sizeof(char)) ;// 如果堆内存分配失败 , 直接退出if (p3[i] == NULL){return -2;}// 向堆内存中拷贝 字符串 数据strcpy(p3[i], p1[i]);}// 遍历将 p2 二维数组 中的数据 拷贝到 二级指针 中// 之前已经拷贝了 count1 个 , 因此从第 count1 + 1 位置开始拷贝// 第 count1 + 1 个的索引从 0 开始 , 其索引是 count1 ;for (j = 0; j < count2; j++){// 计算 二维数组 中第 j 个一维数组 字符串长度// 最后的 + 1 是加上 \0 字符len = strlen(p2[j]) + 1;// 为 指向字符串的 一级指针 在堆内存中分配内存p3[count1 + j] = (char *)malloc(len * sizeof(char));// 堆内存分配失败 , 退出if (p3[count1 + j] == NULL){return -3;}// 向堆内存中拷贝 字符串 数据strcpy(p3[count1 + j], p2[j]);}// p3 二维指针 中存储的 字符串个数len = count1 + count2;// 指针 间接赋值 作为 返回值*count3p = len; // 二维指针 赋值给 三维指针形参 指向的内存地址*newp = p3;     // 字符串个数 赋值return 0;
}/*** @brief sort_data 二级指针 指向的 一级指针 数据排序* 需要修改 二级指针 指向的一级指针次序* 二级指针 不需要修改 , 因此这里传入 二级指针即可* 如果需要修改 二级指针 , 则需要传入 三级指针* @param p3 二级指针 数据* @param num3 二级指针 指向的 一级指针 个数* @return*/
int sort_data(char **p3, int len)
{// 循环控制变量int i = 0, j = 0;// 交换 字符串 时的临时变量char *p = NULL;// 验证指针合法性if(p3 == NULL){return -1;}// p3 指向的 若干 字符串 之间的排序for (i = 0; i < len; i++){for (j = i + 1; j < len; j++){if ( strcmp(p3[i], p3[j]) > 0 ){// 交换 i, j 位置的 一级指针p = p3[i];p3[i] = p3[j];p3[j] = p;}}}return 0;
}/*** @brief sort_data 二级指针 指向的 一级指针 数据排序* 需要修改 二级指针 指向的一级指针次序* 二级指针 不需要修改 , 因此这里传入 二级指针即可* 如果需要修改 二级指针 , 则需要传入 三级指针* @param p3 二级指针 数据* @param num3 二级指针 指向的 一级指针 个数* @return*/
int print_data(char **p3, int len)
{// 循环控制变量int i = 0;// 交换 字符串 时的临时变量char *p = NULL;// 验证指针合法性if(p3 == NULL){return -1;}// p3 指向的 若干 字符串 之间的排序for (i = 0; i < len; i++){printf("%s\n", p3[i]);}return 0;
}/*** @brief 主函数入口* @return*/
int main(int argc, char* argv[], char**env)
{// 指针数组char *p1[] = {"ab", "ef", "cd"};// 二维数组char p2[3][5] = {"13", "35", "22"};// 二级指针char **p3 = NULL;// 存储 p3 指向的一级指针个数int len3 = 0;// 将 指针数组 二维数组 数据 拷贝到 二级指针 中copy_data(p1, 3, p2, 3, &p3, &len3);// 拷贝之后的结果print_data(p3, len3);// 数据排序sort_data(p3, len3);// 打印排序之后的结果printf("\nSort :\n");print_data(p3, len3);// 命令行不要退出system("pause");return 0;
}

执行结果 :

ab
ef
cd
13
35
22Sort :
13
22
35
ab
cd
ef
请按任意键继续. . .

【C 语言】二级指针内存模型 ( 指针数组 | 二维数组 | 自定义二级指针 | 将 一、二 模型数据拷贝到 三 模型中 并 排序 )相关推荐

  1. 【C 语言】二级指针 内存模型图 ( 指针数组 | 二维数组 | 自定义二级指针内存 )

    文章目录 前言 一.指针数组 二.二维数组 三.自定义二维指针内存 前言 绘制如下 333 种二级指针的内存模型 : // I. 指针数组 char *p1 []= {"12", ...

  2. 【C 语言】二级指针作为输入 ( 二维数组 | 二维数组内存大小计算 | 指针跳转步长问题 )

    文章目录 一.二维数组内存大小计算 二.二维数组内存大小意义 一.二维数组内存大小计算 给定一个二维数组 : 该 二维数组 中有 444 个 一维数组 , 每个一维数组有 101010 个 char ...

  3. C语言中的二级指针和二维数组问题

    关于二级指针和二维数组两者差别很大,不可以直接用二级指针传递二维数组 首先来看看二维数组在内存中是如何组织的呢? 一维数组 T arr1 = new T[9]  二维数组T arr2 = new T[ ...

  4. 二维数组的动态内存申请,采用子函数的方式 为二级指针申请内存,和释放内存

    原理:二级指针,行指针+列指针 照着葫芦画瓢就行. 方法一:用c语言malloc实现 #include<cstdio> #include<iostream> #include& ...

  5. 【C 语言】二级指针作为输入 ( 二维数组 | 抽象业务函数 | 二维数组打印函数 | 二维数组排序函数 )

    文章目录 一.抽象 二维数组 业务函数 1.二维数组 打印函数 2.二维数组 排序函数 二.完整代码示例 一.抽象 二维数组 业务函数 1.二维数组 打印函数 注意 , 二维数组 作为 函数参数 输入 ...

  6. 指针:C语言二级指针与二维数组

    前言   最近用C语言写LeetCode 有的题目给的函数把二维数组用二级指针传进来 并传入行数和列数 引起一些疑惑 本来以为C语言学得海星,查了一些资料后,觉得自己还是个弟弟 : (   按一维数组 ...

  7. C语言基础知识之define宏定义表达式,undef,内存对齐,a和a的区别,数组知识点,int (*)[10] p,二维数组参数与二维指针参数,函数指针数组,常见的内存错误及对策

    一.用define宏定义表达式 1.定义一年有多少秒: #define SEC_A_YEAR 60*60*24*365 //上述描述不可靠,没有考虑到在16位系统下把这样一个数赋给整型变量的时候可能会 ...

  8. 【C 语言】二级指针案例 ( 字符串切割 | 返回 二维数组 作为结果 )

    文章目录 一.二级指针案例 ( 返回二维数组 ) 二.完整代码示例 一.二级指针案例 ( 返回二维数组 ) 将 "12,ab,345," 字符串 以 逗号 "," ...

  9. 【C 语言】二级指针作为输入 ( 二维数组 | 二维数组遍历 | 二维数组排序 )

    文章目录 一.二维数组 1.二维数组声明及初始化 2.二维数组遍历 3.二维数组排序 二.完整代码示例 一.二维数组 前几篇博客中 , 介绍的是指针数组 ; 指针数组 的 结构特征 是 , 数组中的每 ...

最新文章

  1. css的repaint和reflow
  2. 2019年春季学期第4周作业.
  3. Oracle海量数据优化-02分区在海量数据库中的应用-更新中
  4. CSS画基本图形——圆
  5. Scaleform GFx
  6. leetcode 839. 相似字符串组(并查集)
  7. java socket发送定长报文_socket编程
  8. C++C面试题100道分析(21-40)
  9. ProtoBuf和Netty的简单使用
  10. 安装 cachecloud 并搭建redis cluster集群
  11. StaMPS 在 SBAS 第一步报错 unable to read file ‘../slcosfactor.1.in‘ no such file or directory
  12. sketch插件 android,用这个免费的Sketch插件,帮你完美还原安卓界面!
  13. 聚宽量化投资策略研究
  14. Java类和对象(未完待续,持续更新)
  15. UG二次开发之快速重量计算
  16. 【CSS 用户界面属性 (Basic user interface)】
  17. postgresql中recovery.conf分析
  18. 学习Matlab第三天——画3D图
  19. docker安装torna1.16.2
  20. 生活-啤酒鸡 鸡啤酒 酒啤鸡 啤鸡酒- 做法

热门文章

  1. Apache 配置支持HTTPS的SSL证书
  2. 在WebView中如何让JS与Java安全地互相调用
  3. myeclipse2014新感悟
  4. poj 3565 uva 1411 Ants KM算法求最小权
  5. QT发布中遇到的问题 - wufan的专栏 - 博客频道 - CSDN.NET
  6. Delphi实例分析:远程传输数据和文件
  7. Centos 7 下 Corosync + Pacemaker + DRBD + psc + crmsh 实现 mysql 服务高可用
  8. 公钥和私钥的简单通俗说明
  9. C# 尝试读取或写入受保护的内存,这通常指示其他内存已损坏。错误类型为:System.AccessViolationException。...
  10. 提取变异的转录组序列