文章目录
一、指针数组 和 二维数组 数据 拷贝到 自定义二级指针 中
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 22 Sort : 13 22 35 ab cd ef 请按任意键继续. . .