二级指针(作为输入)的3中内存模型
来源:互联网 发布:淘宝店充值话费怎么开 编辑:程序博客网 时间:2024/05/21 12:49
0、作函数参数的输入
在主调函数中分配二级指针(一般是二维数组),把指针传给被调函数使用
1、第一种内存模型(指针数组)
主调函数里形如 char* myArr[] = { "ddd", "cccc", "bbbb", "aaaaaaa" };
使用的函数参数模型 int sort_arr(char **myArr, int num);
程序实例
#include <stdio.h> #include <stdlib.h> #include <string.h> int sort_arr(char **myArr, int num){ char *temp; char **p = myArr; int i, j; for (i = 0; i<num; i++) { for (j = i + 1; j<num; j++) { if (strcmp(p[i], p[j])>0) { temp = p[i];//主意我们交换的只是指针的值,改变指针的指向 p[i] = p[j]; p[j] = temp; } } } return 0;}int print_arr(char **myArr, int num){ int i = 0; for (i = 0; i<num; i++) { printf("num:%s\n", *(myArr + i)); } return 0;}int main(){ //数组,数组中的每一个元素是指针,指针数组 //主调函数内分配好内存,传给被调函数使用 char* myArr[] = { "ddd", "cccc", "bbbb", "aaaaaaa" }; print_arr(myArr, 4); sort_arr(myArr, 4); printf("----------\n"); print_arr(myArr, 4); system("pause"); return 0;}
运行结果
内存模型
注意:图中的地址是假设值
2、第二种内存模型(二维数组,数组指针)
主调函数里形如 char myArr[10][20] = { "fff", "bbbbb", "ddddd", "ccccc", "eeeee" };
使用的函数参数模型
int sort_arr(char (*myArr)[20], int num);int sort_arr(char myArr[][20], int num);int sort_arr(char myArr[10][20], int num);
程序实例
#include<stdio.h> #include<stdlib.h> #include <string.h> //int sort_arr(char **myArr,int num)//不能正确使用//下面三个都可以//int sort_arr(char (*myArr)[20], int num)//int sort_arr(char myArr[][20], int num)int sort_arr(char myArr[10][20], int num){ char temBuf[20]; int i, j; for (i = 0; i<num; i++) { for (j = i + 1; j<num; j++) { if (strcmp(myArr[i], myArr[j])>0) { strcpy(temBuf, myArr[i]);//把数据交换,内存块 strcpy(myArr[i], myArr[j]); strcpy(myArr[j], temBuf); } } } return 0;}/*//第一种内存模型打印函数不适用第二种内存模型//原因:二级指针做输入,第一种内存模型 myArr + 1 与第二种内存模型 myArr + 1//指针步长不一样哈 指针所指向内存空间的数据不一样int print_arr(char **myArr,int num){int i = 0; for (i=0;i<num;i++) { printf("num:%s\n",*(myArr+i)); } return 0;}*///下面三个都可以//int print_arr(char (*myArr)[20], int num)//int print_arr(char myArr[][20], int num)int print_arr(char myArr[10][20], int num){ int i = 0; for (i = 0; i<num; i++) { printf("num:%s\n", *(myArr + i)); } return 0;}int main(){ char myArr[10][20] = { "fff", "bbbbb", "ddddd", "ccccc", "eeeee" }; int num = 5; print_arr(myArr, num); sort_arr(myArr, num); printf("---------\n"); print_arr(myArr, num); system("pause"); return 0;}
运行结果
内存模型
3、第三种内存模型(二级指针)
主调函数里使用malloc分配内存,形如:
pArray = (char **)malloc(100*sizeof(char *)); pArray[0] = (char *)malloc(12*sizeof(char)); pArray[1] = (char *)malloc(200*sizeof(char));
使用的函数参数模型
int sort_arr(char **myArr, int num);
程序实例
#include <stdio.h> #include <stdlib.h> #include <string.h> int print_arr(char **pArray, int num){ int i = 0; if (pArray == NULL) { return -1; } for (i = 0; i<num; i++) { printf("%s \n", pArray[i]); } return 0;}int sort_arr(char **pArray, int num){ char *tmp = NULL; int i = 0, j = 0; if (pArray == NULL) { return -1; } for (i = 0; i<num; i++) { for (j = i + 1; j<num; j++) { if (strcmp(pArray[i], pArray[j]) > 0) { //交换的是数组元素 数组元素是指针 tmp = pArray[i]; pArray[i] = pArray[j]; pArray[j] = tmp; } } }}void main(){ int i = 0, j = 0; char **pArray = NULL; char *tmp = NULL; //构造内存 pArray = (char **)malloc(100 * sizeof(char *)); //int pArray[100]; pArray[0] = (char *)malloc(12 * sizeof(char)); //char buf[12]; pArray[1] = (char *)malloc(200 * sizeof(char)); //char buf[200]; pArray[2] = (char *)malloc(200 * sizeof(char)); //char buf[200]; pArray[3] = (char *)malloc(200 * sizeof(char)); //char buf[200]; strcpy(pArray[0], "cccccc"); strcpy(pArray[1], "aaaa"); strcpy(pArray[2], "bbbb"); strcpy(pArray[3], "11111"); print_arr(pArray, 4); sort_arr(pArray, 4); printf("第三种内存排序之后\n"); print_arr(pArray, 4); //释放内存 for (i = 0; i<4; i++) { if (pArray[i] != NULL) { free(pArray[i]); } } if (pArray != NULL) { free(pArray); } system("pause");}
运行结果
内存模型
注意,图中的地址仅为参考值
4、二级指针技术推演
指针演变
void fun(int a[5]) →void fun(int a[]) →void fun(int* a);
void fun(int a[2][3]) →void fun(int a[][3]) →void fun(int (*a)[3]);
5、二级指针强化练习——两个辅助指针挖字符串
有一个字符串符合以下特征(”abcdefg,hjkln,sssss,kkk,hhh,j”;),要求写一个函数(接口),输出以下结果
1) 以逗号分割字符串,形成二维数组,并把结果传出;
2) 把二维数组行数运算结果也传出。
1) 使用第二种内存模型,主调函数分配内存
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> /*函数功能 根据字符c来分割字符串str*/int splitStr(const char *str, char c, char buf[10][20], int *num){ char* p = NULL, *pTmp = NULL;//两个辅助指针变量 int tmpcount = 0, len; p = str; pTmp = str; do { p = strchr(p, c); if (p != NULL) { if (p - pTmp>0) { strncpy(buf[tmpcount], pTmp, p - pTmp); buf[tmpcount][p - pTmp] = '\0'; //printf("%s\n",buf[tmpcount]); tmpcount++; pTmp = p = p + 1; len = strlen(p);//用来保存最后一个字符串的长度 } } else { //拷贝最后一个分割的字符串包括\0 strncpy(buf[tmpcount], pTmp, len + 1); break; } } while (*p != '\0'); *num = tmpcount + 1; //一般不会直接使用*num = *num + 1 ,而是使用中间变量过度 return 0;}/*函数功能 打印二维数组*/void printArr(char a[10][20], int n){ int i; for (i = 0; i<n; i++) { printf("%s\n", *(a + i)); }}int main(){ char *input = "abcdefg,hjkln,sssss,kkk,hhh,j"; char ctemp = ','; char myArr[10][20] = { 0 };//主调函数分配内存 int ret; int n; ret = splitStr(input, ctemp, myArr, &n); if (ret != 0) { printf("error\n"); } printArr(myArr, n); system("pause"); return 0;}
2)使用第三种内存模型,主调函数分配内存
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> int splitStr(const char *str, char c, char **buf, int *count){ char* p = NULL, *pTmp = NULL;//两个辅助指针变量 int tmpcount = 0, len; p = str; pTmp = str; do { p = strchr(p, c); if (p != NULL) { if (p - pTmp>0) { strncpy(buf[tmpcount], pTmp, p - pTmp); buf[tmpcount][p - pTmp] = '\0'; //printf("%s\n",buf[tmpcount]); tmpcount++; pTmp = p = p + 1; len = strlen(p);//用来保存最后一个字符串的长度 } } else { //拷贝最后一个分割的字符串包括\0 strncpy(buf[tmpcount], pTmp, len + 1); break; } } while (*p != '\0'); *count = tmpcount + 1; return 0;}void printArr(char **a, int n){ int i; for (i = 0; i<n; i++) { printf("%s\n", *(a + i)); //printf("%s\n", a[i]);//与上面效果一样,注意理解 }}int main(){ char *input = "abcdefg,hjkln,sssss,kkk,hhh,j"; char ctemp = ','; char **p = NULL; int ret; int n, i; p = (char**)malloc(10 * sizeof(char*));//主调函数分配内存 if (p == NULL) { return; } for (i = 0; i<10; i++) { p[i] = (char *)malloc(20 * sizeof(char)); } ret = splitStr(input, ctemp, p, &n); if (ret != 0) { printf("error\n"); } printArr(p, n); //释放内存 for (i = 0; i<10; i++) { if (p[i] != NULL) { free(p[i]); p[i] = NULL; } } if (p != NULL) { free(p); p = NULL; } system("pause"); return 0;}
3)使用第三种内存模型,被调函数分配内存,通过return返回
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> /*第三种内存模型 被调函数分配内存 通过return返回*/char** splitStr(char *str, char c, int *count){ char* p = NULL, *pTmp = NULL;//两个辅助指针变量 int tmpcount = 0, len, len2; char**buf; p = str; pTmp = str; //第一遍扫描 开辟第一维空间 do { p = strchr(p, c); if (p != NULL) { if (p - pTmp>0) { tmpcount++; pTmp = p = p + 1; } } else { break; } } while (*p != '\0'); *count = tmpcount + 1; buf = (char**)malloc((tmpcount + 1)*sizeof(char*)); //printf("tmpcount:%d\n",tmpcount); if (buf == NULL) { return NULL; } //第二遍扫描 根据分割的字符串的长度,开辟第二维空间并拷贝字符串 tmpcount = 0; p = str; pTmp = str; do { p = strchr(p, c); if (p != NULL) { if (p - pTmp>0) { len = p - pTmp + 1; buf[tmpcount] = (char*)malloc(len*sizeof(char)); if (buf[tmpcount] == NULL) { free(buf); return; } strncpy(buf[tmpcount], pTmp, p - pTmp); buf[tmpcount][p - pTmp] = '\0'; tmpcount++; pTmp = p = p + 1; len2 = strlen(p);//用来保存最后一个字符串的长度 } } else { //printf("tmpcount:%d\n",tmpcount); //printf("len2:%d\n",len2); buf[tmpcount] = (char*)malloc((len2 + 1)*sizeof(char)); if (buf[tmpcount] == NULL) { free(buf); return; } //拷贝最后一个分割的字符串包括\0 strncpy(buf[tmpcount], pTmp, len2 + 1); break; } } while (*p != '\0'); return buf;}void freeMem(char **p, int n){ int i; if (p == NULL || n <= 0) return; for (i = 0; i<n; i++) { if (p[i] != NULL) { free(p[i]); p[i] = NULL; } } if (p != NULL) { free(p); p = NULL; }}int main(){ char *input = "abcdefg,hjkln,sssss,kkk,hhh,j"; char ctemp = ','; char **p = NULL; int ret; int n, i; p = splitStr(input, ctemp, &n); printf("n:%d\n", n); for (i = 0; i<n; i++) { printf("%s\n", *(p + i)); } //释放内存空间 freeMem(p, n); system("pause"); return 0;}
4)使用第三种内存模型,被调函数分配内存,通过函数参数返回
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <ctype.h> /*第三种内存模型 被调函数分配内存 通过tmpbuf返回 修改二级指针的指向需要三级指针*/int splitStr(char *str, char c, char*** tmpbuf, int *count){ char* p = NULL, *pTmp = NULL;//两个辅助指针变量 int tmpcount = 0, len, len2; char**buf; p = str; pTmp = str; //第一遍扫描 开辟第一维空间 do { p = strchr(p, c); if (p != NULL) { if (p - pTmp>0) { tmpcount++; pTmp = p = p + 1; } } else { break; } } while (*p != '\0'); *count = tmpcount + 1; buf = (char**)malloc((tmpcount + 1)*sizeof(char*)); //printf("tmpcount:%d\n",tmpcount); if (buf == NULL) { return -1; } //第二遍扫描 根据分割的字符串的长度,开辟第二维空间并拷贝字符串 tmpcount = 0; p = str; pTmp = str; do { p = strchr(p, c); if (p != NULL) { if (p - pTmp>0) { len = p - pTmp + 1; buf[tmpcount] = (char*)malloc(len*sizeof(char)); if (buf[tmpcount] == NULL) { free(buf); return -2; } strncpy(buf[tmpcount], pTmp, p - pTmp); buf[tmpcount][p - pTmp] = '\0'; tmpcount++; pTmp = p = p + 1; len2 = strlen(p);//用来保存最后一个字符串的长度 } } else { //printf("tmpcount:%d\n",tmpcount); //printf("len2:%d\n",len2); buf[tmpcount] = (char*)malloc((len2 + 1)*sizeof(char)); if (buf[tmpcount] == NULL) { free(buf); return -2; } //拷贝最后一个分割的字符串包括\0 strncpy(buf[tmpcount], pTmp, len2 + 1); break; } } while (*p != '\0'); *tmpbuf = buf; return 0;}//释放内存空间 void freeMem(char**p, int count){ int i = 0; if (p == NULL || count <=0 ) { return; } for (i = 0; i<count; i++) { if (p[i] != NULL) { free(p[i]); p[i] = NULL; } } if (p != NULL) { free(p); p = NULL; }}int main(){ char *input = "abcdefg,hjkln,sssss,kkk,hhh,j"; char ctemp = ','; char **p = NULL; int ret; int n, i; ret = splitStr(input, ctemp, &p, &n); if (ret != 0) { printf("error"); return -1; } //printf("n:%d\n",n); for (i = 0; i<n; i++) { printf("%s\n", *(p + i)); } //释放内存 freeMem(p, n); system("pause"); return 0;}
运行结果
阅读全文
0 0
- 二级指针(作为输入)的3中内存模型
- 二级指针的3种内存模型
- 二级指针的3种内存模型
- 二级指针的内存模型
- C语言中,二级指针的三种内存模型
- 二级指针输入模型(三种内存模型)
- 二级指针做输入的3种模型-3
- 二级指针做输入的3种模型-1
- 二级指针做输入的3种模型-2
- 【C语言提高24】二级指针做输入的第一种内存模型:数组指针
- 二级指针内存模型
- 二级指针内存模型
- 二级指针的第三种内存模型
- 二级指针的三种内存模型
- 二级指针的三种内存模型
- 二级指针的三种内存模型
- day4_二级指针的内存模型
- 二级指针的三种内存模型
- Linux之mv
- 关于微信网页授权开发总结整理
- Linux中设置服务自启动的三种方式
- (2017夏令营CONTEST4)NKOJ 3823 水果怪 (组合数)
- 堆排序
- 二级指针(作为输入)的3中内存模型
- 1036. Boys vs Girls (25)
- 数据通信
- SQL like 模糊查询
- Android 开发之自定义标题栏、状态栏
- Bounding-box Regression深度解析
- Hibernate中的一个对象存在于以下四个状态之中
- Code First Migrations 迁移更新数据库
- 硬齿面减速机比软齿面减速机贵多少?