二级指针相对于一级指针,显得更难,难在于指针和数组的混合,定义不同类型的二级指针,在使用的时候有着很大的区别

第一种内存模型char *arr[]

若有如下定义

char *arr[] = {"abc", "def", "ghi"};

这种模型为二级指针的第一种内存模型,在理解的时候应该这样理解:定义了一个指针数组(char * []),数组的每个元素都是一个地址。

在使用的时候,若要使用中间量操作元素,那么此时中间量应该定义为

char *tmp = NULL;

如果要打印这个数组,那么可以使用以下函数

int printAarray(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;
}

第二种内存模型char arr[][]

若有如下定义

char arr[3][5] = {"abc", "def", "ghi"};

这种模型为二级指针的第二种内存模型,在理解的时候应该这样理解:定义了一个二维数组,有3个(5个char)空间的存储变量。

在使用的时候,若要使用中间量操作元素,那么此时中间量应该定义为

char tmp[5] = { 0 };

如果要打印这个数组,那么可以使用以下函数

int printAarray(char pArray[][5], int num)
{
int i = 0;
if (pArray == NULL)
{
return -1;
}
for (i = 0; i < num; i++)
{
printf("%s \n", pArray[i]);
}
return 0;
}

第三种内存模型char **arr

若有如下定义

char **arr = (char *)malloc(100 * sizeof(char *));//char arr[400]
arr[0] = (char *)malloc(100 * sizeof(char));//char buf[100]
arr[1] = (char *)malloc(100 * sizeof(char));
arr[2] = (char *)malloc(100 * sizeof(char));
strcpy(arr[0], "abc");
strcpy(arr[1], "def");
strcpy(arr[2], "ghi");
···
for(int i = 0; i < 3; i++)
if(arr[i] != NULL)
free(arr[i]);
free(arr);

这种模型为二级指针的第二种内存模型,在理解的时候应该这样理解:定义了一个二级指针,二级指针就是指向指针的指针,其实就是开辟了100个指针空间,存放了100个地址。这种写法是第一种的简化写法

在使用的时候,若要使用中间量操作元素,那么此时中间量应该定义为

char *tmp = NULL;

如果要打印这个数组,那么可以使用以下函数

int printAarray(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;
}

例子

把第一种内存模型的数据排序,运算结果放到第三种内存模型中

#include "stdio.h"
#include "string.h"
#include "stdlib.h" char **SortArrayAndGen3Mem(const char ** const myArray1, int num, char *str, int *myNum)
{
char **p = NULL;
p= (char **)malloc(num*sizeof(char *));
if (myArray1==NULL || str==NULL|| myNum==NULL)
{
printf("传入参数错误\n");
p = NULL;
goto END;
}
*myNum = num;
for (int i = 0; i < num;i++)
{
p[i] = NULL;
p[i] = (char)malloc(50 * sizeof(char));
memset(p[i], 0, sizeof(p[i]));
if (p[i]==NULL)
{
printf("内存分配错误!\n");
goto END;
}
strcpy(p[i], myArray1[i]);
}
char *tmp;
for (int i = 0; i < num; i++)
{
for (int j = i + 1; j < num; j++)
{
if (strcmp(p[i],p[j])>0)
{
char *tmp = p[i];
p[i] = p[j];
p[j] = tmp;
}
}
}
for (int i = 0; i < num; i++)
{
printf("%s \n", myArray1[i]);
} END:
return p;
} //释放内存函数 void main()
{
int i = 0;
char **myArray3 = NULL;
int num3 = 0;
//第一种内存模型
char *myArray[] = {"bbbbb", "aaaaa", "cccccc"};
char *myp = "111111111111"; myArray3 = SortArrayAndGen3Mem(myArray, 3, myp, &num3); for (i=0; i<num3; i++)
{
printf("%s \n", myArray3[i]);
} system("pause");
}
#include "stdio.h"
#include "stdlib.h"
#include "string.h" char **SortArrayAndGet3Mem(const char* const myArray1,int num,char *str,int *myNum);
int getArray(char ***newp,int num) ;
int freeArray(char ***newpfree,int num);
int sortTArray(char *p, int num); void main()
{
char **myArray3=NULL;
int num3=0;
char *myArray[]={"bbbb","aaa","cccc"};
char *myp="111111111";
myArray3=SortArrayAndGet3Mem(myArray,3,myp,&num3);
system("pause");
} char **SortArrayAndGet3Mem(const char** const myArray1,int num,char *str,int *myNum)
{
int ret=0;
char **p=NULL;
int i=0;
char **p1=NULL;
p1=(char **)myArray1;
ret=getArray(&p,num +1);
for (i=0;i<num;i++)
{
strcpy(p[i],p1[i]);
}
strcpy(p[i], str);
ret=sortTArray(p,num +1);
for (i=0;i<num +1;i++)
{
printf("%s\n",p[i]);
}
ret=freeArray(&p,num +1);
*myNum = num +1;
return p;
} int getArray(char ***newp,int num)
{
int i=0;
int ret=0;
char **tmp = NULL;
tmp = (char **)malloc(num*sizeof(char *));
for (i=0;i<num;i++)
{
tmp[i]=(char*)malloc(sizeof(char)*100);
}
*newp = tmp; //
return 0;
} //
int freeArray(char ***newpfree,int num)
{
char **p=NULL;
int i=0;
int ret=0;
p=*newpfree;
for (i=0;i<num;i++)
{
free(p[i]);
}
free(p);
*newpfree = NULL; //
return ret;
} //int sortTArray(char ***Arraystr, int num)
int sortTArray(char **Arraystr, int num)
{
int i , j = 0;
for (i=0; i<num; i++)
{
for (j=i+1; j<num; j++)
{
if (strcmp((Arraystr)[i],(Arraystr)[j])>0)
{
char tmp[100];
strcpy(tmp,(Arraystr)[i]);
strcpy((Arraystr)[i],(Arraystr)[j]);
strcpy((Arraystr)[j],tmp);
}
}
}
for (i=0;i<num;i++)
{
printf("%s\n",(Arraystr)[i]);
}
return 0;
}

深入理解C语言-二级指针三种内存模型的更多相关文章

  1. C++二级指针第二种内存模型(二维数组)

    C++二级指针第二种内存模型(二维数组) 二维数组 二维数组本质上是以数组作为数组元素的数组,即“数组的数组”. 定义 类型说明符 数组名[常量表达式][常量表达式] 例如: float a[3][4 ...

  2. C++二级指针第一种内存模型(指针数组)

    二级指针第一种内存模型(指针数组) 指针的输入特性:在主调函数里面分配内存,在被调用函数里面使用指针的输出特性:在被调用函数里面分配内存,主要是把运算结果甩出来 指针数组 在C语言和C++语言中,数组 ...

  3. C++二级指针第三种内存模型

    #include "stdio.h" #include "stdlib.h" #include "string.h" void main() ...

  4. C语言 二级指针内存模型①

    //二级指针第一种内存模型 #include<stdio.h> #include<stdlib.h> //说明:①:类似于int a[5]={0},数组名a是一维数组a中首元素 ...

  5. C语言 二级指针内存模型②

    //二级指针第二种内存模型 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #incl ...

  6. C语言 二级指针内存模型混合实战

    //二级指针内存模型混合实战 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #i ...

  7. c语言二级指针内存模型

    第一种: 指针数组作为输入参数 char *myArray[] = {"aaaaaa", "ccccc", "bbbbbb", " ...

  8. 这样子来理解C语言中指针的指针

    友情提示:阅读本文前,请先参考我的之前的文章<从四个属性的角度来理解C语言的指针也许会更好理解>,若已阅读,请继续往下看. 我从4个属性的角度来总结了C语言中的指针概念.对于C语言的一个指 ...

  9. C语言二级指针底层实现

    C语言中,Pointers to Pointers,即二级指针. 一级指针和二级指针的值都是指向一个内存单元: 一级指针指向的内存单元存放的是源变量的值, 二级指针指向的内存单元存放的是一级指针的地址 ...

随机推荐

  1. Java8-Stream-No.06

    import java.io.IOException; import java.math.BigDecimal; import java.util.Arrays; import java.util.s ...

  2. Rendering in UE4(Gnomon School UE4 大师课笔记)

    Rendering in UE4 Presented at the Gnomon School of VFX in January 2018, part two of the class offers ...

  3. Spring Framwork Maven dependency

    Spring Framwork 更新时间 2019.12.21 统一版本号 <properties> <!-- spring版本号 --> <spring.version ...

  4. triggerHandler(type, [data])

    triggerHandler(type, [data]) 概述 这个特别的方法将会触发指定的事件类型上所有绑定的处理函数.但不会执行浏览器默认动作,也不会产生事件冒泡. 大理石平台价格 这个方法的行为 ...

  5. 快速弄清JavaScript中undefined和null的区别

    ES6的7大数据类型里面有这俩玩意:undefined和null,让接触不深的学习者常常产生混淆,这俩玩意的区别在哪呢? 字面意思上来看,undefined是未(被我们)阐明的,未说明的,null则意 ...

  6. Java小数中的四舍五入

    1.怎么设置显示小数位数 public static void main(String[] args) { DecimalFormat decimalFormat = new DecimalForma ...

  7. luogu 1169 [ZJOI2007]棋盘制作 悬线dp

    悬线法,虽然得不到局部最优解,但是一定能得到全局最优解的算法,十分神奇~ #include <cstdio> #include <algorithm> #define N 20 ...

  8. conda 激活环境失败解决办法

    https://stackoverflow.com/questions/41746137/conda-environment-is-discoverable-but-not-activateable- ...

  9. 如何检测域名是否被微信屏蔽 微信域名检测接口API是如何实现

    微信域名检测技术的主要用户是微信域名防封,大家知道拼多多这种网站,靠诱导分享方式在微信里面摇身一变已经估值160亿美元,身价仅次于京东了 ,这是何等的速度,简直是惊为天人,but 如果你想玩微信病毒营 ...

  10. IDEA出现Could not autowire. No beans of 'xxx' type found.解决

    Plan A File → Project Structure... Facets → Spring → 右键删除即可 Plan B File → Settings → Editor → Inspec ...