1、二级指针的第一种内存模型:指针数组
#include <stdlib.h> #include <string.h> #include <stdio.h> void main21() //不适用二级指针的常规做法 { int i = 0, j = 0; int num = 0; char *tmp = NULL; //数组 数组中的每一个元素是指针 指针数组 char *myArray[] = {"aaaaaa", "ccccc", "bbbbbb", "111111"}; //打印 num = sizeof(myArray)/sizeof(myArray[0]); printf("排序之前\n"); for (i=0; i<num; i++) { //printf("%s \n", myArray[i]); printf("%s \n", *(myArray+i) ); } //排序 for (i=0; i<num; i++) { for (j=i; j<num; j++) { if (strcmp(myArray[i], myArray[j]) > 0 ) { tmp = myArray[i]; //注意 交换的是数组元素 交换的是指针的值 myArray[i] = myArray[j]; myArray[j] = tmp; } } } printf("排序之后\n"); for (i=0; i<num; i++) { //printf("%s \n", myArray[i]); printf("%s \n", *(myArray+i) ); } printf("hello...\n"); system("pause"); return ; } void printMyArray11(char **myArray, int num)//数组中的每一个元素是指针(字符串常量的首地址),所以使用的是二级指针 { int i = 0; for (i=0; i<num; i++) { //printf("%s \n", myArray[i]); printf("%s \n", *(myArray+i) ); } } void sortMyArray11(char **myArray, int num)//数组中的每一个元素是指针(字符串常量的首地址) ,所以使用的是二级指针 { int i =0 , j = 0; char *tmp = NULL; //排序 for (i=0; i<num; i++) { for (j=i; j<num; j++) { if (strcmp(myArray[i], myArray[j]) > 0 ) { tmp = myArray[i]; //注意:交换的是数组元素(字符串常量的首地址),交换的是指针的值 //改变的是指针的指向 myArray[i] = myArray[j]; myArray[j] = tmp; } } } } void main() { int i = 0, j = 0; int num = 0; char *tmp = NULL; //数组 数组中的每一个元素是指针(字符串常量的首地址) 指针数组 char *myArray[] = {"aaaaaa", "ccccc", "bbbbbb", "111111"}; //打印 num = sizeof(myArray)/sizeof(myArray[0]); printf("排序之前\n"); printMyArray11(myArray, num); sortMyArray11(myArray, num); printf("排序之后\n"); printMyArray11(myArray, num); printf("hello...\n"); system("pause"); return ; }
2、二级指针的第二种内存模型:二维数组
#include <stdlib.h> #include <string.h> #include <stdio.h> //打印 排序 //封装成函数 void main31() { int i = 0, j = 0; int num = 4; char myBuf[30]; char tmpBuf[30]; char myArray[10][30] = {"aaaaaa", "ccccc", "bbbbbbb", "1111111111111"}; //打印 printf("排序之前\n"); for (i=0; i<num; i++) { printf("%s\n", myArray[i]); } for (i=0; i<num; i++) { for (j=i+1; j<num; j++) { if (strcmp (myArray[i], myArray[j]) > 0) { strcpy(tmpBuf, myArray[i]); //交换的是内存块 strcpy(myArray[i], myArray[j]); strcpy(myArray[j], tmpBuf); } } } //打印 printf("排序之后\n"); for (i=0; i<num; i++) { printf("%s\n", myArray[i]); } printf("hello...\n"); system("pause"); return ; } //问题的本质是:dm03_二级指针做输入_第2种内存模型(二维数组) 的 myArray + 1 // dm03_二级指针做输入_第1种内存模型(指针数组) myArray + 1 不一样 ; //指针的步长不一样 指针所指向的内存空间的数据类不一样 。 void printMyArray02_err(char **myArray, int num)//错误打印模型,涉及到多维数组退化为指针的细节 { int i = 0; for (i=0; i<num; i++) { //printf("%s \n", myArray[i]); printf("%s \n", *(myArray+i) ); //见问题本质 } } void printMyArray02(char myArray[10][30], int num)//正确打印模型 { int i = 0; for (i=0; i<num; i++) { //printf("%s \n", myArray[i]); printf("%s \n", *(myArray+i) ); //见问题本质 } } //交换的是内存块! void sortMyArray02(char myArray[10][30], int num) { int i, j = 0; char tmpBuf[30]; for (i=0; i<num; i++) { for (j=i+1; j<num; j++) { if (strcmp (myArray[i], myArray[j]) > 0) { strcpy(tmpBuf, myArray[i]); //交换的是内存块 strcpy(myArray[i], myArray[j]); strcpy(myArray[j], tmpBuf); } } } } //打印 排序 //封装成函数 void main333() { int i = 0, j = 0; int num = 4; char myBuf[30]; char tmpBuf[30]; char myArray[10][30] = {"aaaaaa", "ccccc", "bbbbbbb", "1111111111111"}; //myarray:编译器只会关心:有10行 ,每行30列。目的是: //myarray+1:多维数组名的本质,+1以后步长是多少,跳30个单元! { int len1 = sizeof(myarray); // 300 int len2 = sizeof(myarray[0]);//30 int size = len1/len2; //10 ,实际上求出来的是多少行,和一维对比 printf("len1:%d , len2:%d , size:%d \n", len1, len2, size); } //打印 printf("排序之前\n"); printMyArray02(myArray, num); sortMyArray02(myArray, num); //打印 printf("排序之后\n"); printMyArray02(myArray, num); printf("hello...\n"); system("pause"); return ; }
3、二级指针的第三种内存模型:扔开C编译器,手工打造二维内存
#include <stdlib.h> #include <string.h> #include <stdio.h> //直接写 void main41() { int i = 0, j = 0; char **p2 = NULL; int num = 5; char *tmp = NULL;//辅助下面交换指针 char tmpbuf[100];//辅助下面交换内存 //自己打造内存 p2 = (char **)malloc(sizeof(char *) * num);//char **里面装char * for (i=0; i<num; i++) { p2[i] = (char *)malloc(sizeof(char) * 100 ); //char buf[100]; //char *里面装char数据 sprintf(p2[i], "%d%d%d", i+1, i+1, i+1); //以"%d%d%d"的格式打印字符串到p2 } //排序之前 printf("排序之前:\n"); for (i=0; i<num; i++) { printf("%s \n", p2[i]); } //排序 交换的是:指针 /* for (i=0; i<num; i++) { for (j=i+1; j<num; j++) { if (strcmp( p2[i] , p2[j]) < 0) { tmp = p2[i]; p2[i] = p2[j]; p2[j] = tmp; } } } */ //排序 交换的是:内存 for (i=0; i<num; i++) { for (j=i+1; j<num; j++) { if (strcmp( p2[i] , p2[j]) < 0) { strcpy(tmpbuf, p2[i]); strcpy( p2[i], p2[j]); strcpy( p2[j], tmpbuf); } } } //排序之后 printf("排序之后:\n"); for (i=0; i<num; i++) { printf("%s \n", p2[i]); } //释放内存 for(i=0; i<num; i++) { if (p2[i] != NULL) { free(p2[i]); p2[i] = NULL; } } if (p2!=NULL) { free(p2); } printf("hello...\n"); system("pause"); return ; } //改写、封装 //分配内存 char **getMem41(int num) { int i = 0; char **p2 = NULL; p2 = (char **)malloc(sizeof(char *) * num); if (p2 == NULL) { return NULL; } for (i=0; i<num; i++) { p2[i] = (char *)malloc(sizeof(char) * 100 ); //char buf[100]; sprintf(p2[i], "%d%d%d", i+1, i+1, i+1); } return p2; } //打印 void printMyArray03(char **myArray, int num) //二级指针 { int i = 0; for (i=0; i<num; i++) { //printf("%s \n", myArray[i]); printf("%s \n", *(myArray+i) ); } } //排序 void sortMyArray03(char **myArray, int num) //二级指针 { int i =0 , j = 0; char *tmp = NULL; //排序 for (i=0; i<num; i++) { for (j=i; j<num; j++) { if (strcmp(myArray[i], myArray[j]) > 0 ) { tmp = myArray[i]; //注意 交换的是数组元素 交换的是指针的值 //改变指针的指向 myArray[i] = myArray[j]; myArray[j] = tmp; } } } } //释放内存 void getMem41_Free(char **p2, int num) //二级指针 { int i = 0; //释放内存 for(i=0; i<num; i++) { if (p2[i] != NULL) { free(p2[i]); p2[i] = NULL; } } if (p2!=NULL) { free(p2); } } void main() { int i = 0, j = 0; char **p2 = NULL; int num = 5; char *tmp = NULL; char tmpbuf[100]; p2 = getMem41(num); //排序之前 printf("排序之前\n"); printMyArray03(p2, num); sortMyArray03(p2, num); //排序之前 printf("排序之后\n"); printMyArray03(p2, num); getMem41_Free(p2, num); //p2是一个野指针 return ; }
4、总览二级指针的三种内存模型:
#define _CRT_SECURE_NO_WARNINGS #include <stdlib.h> #include <string.h> #include <stdio.h> void main2() { int i = 0; //指针数组 char * p1[] = {"123", "456", "789"}; //二维数组 char p2[3][4] = {"123", "456", "789"}; //手工二维内存 char **p3 = (char **)malloc(3 * sizeof(char *)); //int array[3]; for (i=0; i<3; i++) { p3[i] = (char *)malloc(10*sizeof(char)); //char buf[10] sprintf(p3[i], "%d%d%d", i, i, i); } }
5、三种内存模型综合演练:
/* int sort(char *p[], int count, char **p, int *ncount); int sort(char *p[], int count, char(*p)[30], int *ncount); int sort(char(*p)[30], int ncount, char **p, int *ncount); //把第一种内存模型和第二种内存模型结果copy到第三种内存模型中,并排序、打印 char **sort(char **p1, int num1, char(*p)[30], int num2, int *num3); */ #include"stdio.h" #include"stdlib.h" #include"string.h" int sort(char **myp1, int num1, char (*myp2)[30], int num2, int ***myp3, int *num3) { int i = 0, j = 0, k = 0; int tmplen = 0; char *tmpP = NULL;//辅助指针变量,以便排序使用 //分配内存,以供拷贝 char **p3 = NULL; p3 = (char **)malloc((num1 + num2)*sizeof(char *)); //里面装的是指针 if (p3 == NULL) { return -1; } //拷贝 for (i = 0; i < num1; i++) { tmplen = strlen(myp1[i]) + 1; p3[i] = (char *)malloc(tmplen *sizeof(char));//挂内存,指向内存空间 if (p3[i] == NULL) { return -2; } strcpy(p3[i], myp1[i]);//赋值,拷贝 } for (j = 0; j < num2; j++, i++) { tmplen = strlen(myp2[j]) + 1; p3[i] = (char*)malloc(tmplen*sizeof(char));//挂内存,指向内存空间 if (p3[i] == NULL) { return -3; } strcpy(p3[i], myp2[j]);//赋值,拷贝 } //排序 tmplen = num1 + num2; for (i = 0; i < tmplen; i++) { for (j = i + 1; j < tmplen; j++) { if (strcmp(p3[i], p3[j])>0) { tmpP = p3[i]; p3[i] = p3[j]; p3[j] = tmpP; } } } //间接赋值 *num3 = tmplen; *myp3 = p3; return 0; } void sortFree1(char **p, int len)//第一种释放内存方法,仅释放内存 { int i = 0; if (p == NULL) { return; } for (i = 0; i < len; i++) { free(p[i]); } free(p); } void sortFree2(char ***myp, int len)//第二种释放内存的方法,把二级指针指向的二维内存释放掉的同时间接地修改了实参的值 { int i = 0; char **p = NULL; if (myp == NULL) { return; } p = *myp; //还原成二级指针 if (p == NULL) { return; } for (i = 0; i < len; i++) { free(p[i]); } free(p); *myp = NULL; //myp是实参的地址 //间接赋值是指针存在的最大意义 } int main() { int ret = 0; char *p1[] = { "aaaa", "ssssss", "dddddd" };//指针数组 char buf2[10][30] = { "11111", "2222", "33333333" };//二维数组 char **p3 = NULL; int len1, len2, len3; len1 = sizeof(p1) / sizeof(*p1); len2 = 3; ret = sort(p1, len1, buf2, len2, &p3, &len3); if (ret != 0) { printf("func sort() err!"); } for (int i = 0; i < len3; i++) { printf("%s\n", p3[i]); } //sortFree1(p3, len3); sortFree2(&p3, len3);//释放内存 return ret; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-11-07 00:08:01