二级指针(作为输入)的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、二级指针技术推演

数组参数 等效的指针参数 一维数组char a[5]; 指针 char *a; 指针数组char *a[5]; 指针的指针char **a; 二维数组char a[2][3]; 数组指针 char (*a)[3];

指针演变
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;}

运行结果
这里写图片描述

原创粉丝点击