深入理解C语言-二级指针三种内存模型
二级指针相对于一级指针,显得更难,难在于指针和数组的混合,定义不同类型的二级指针,在使用的时候有着很大的区别
第一种内存模型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语言-二级指针三种内存模型的更多相关文章
- C++二级指针第二种内存模型(二维数组)
C++二级指针第二种内存模型(二维数组) 二维数组 二维数组本质上是以数组作为数组元素的数组,即“数组的数组”. 定义 类型说明符 数组名[常量表达式][常量表达式] 例如: float a[3][4 ...
- C++二级指针第一种内存模型(指针数组)
二级指针第一种内存模型(指针数组) 指针的输入特性:在主调函数里面分配内存,在被调用函数里面使用指针的输出特性:在被调用函数里面分配内存,主要是把运算结果甩出来 指针数组 在C语言和C++语言中,数组 ...
- C++二级指针第三种内存模型
#include "stdio.h" #include "stdlib.h" #include "string.h" void main() ...
- C语言 二级指针内存模型①
//二级指针第一种内存模型 #include<stdio.h> #include<stdlib.h> //说明:①:类似于int a[5]={0},数组名a是一维数组a中首元素 ...
- C语言 二级指针内存模型②
//二级指针第二种内存模型 #define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<stdlib.h> #incl ...
- C语言 二级指针内存模型混合实战
//二级指针内存模型混合实战 #define _CRT_SECURE_NO_WARNINGS #include <stdio.h> #include <stdlib.h> #i ...
- c语言二级指针内存模型
第一种: 指针数组作为输入参数 char *myArray[] = {"aaaaaa", "ccccc", "bbbbbb", " ...
- 这样子来理解C语言中指针的指针
友情提示:阅读本文前,请先参考我的之前的文章<从四个属性的角度来理解C语言的指针也许会更好理解>,若已阅读,请继续往下看. 我从4个属性的角度来总结了C语言中的指针概念.对于C语言的一个指 ...
- C语言二级指针底层实现
C语言中,Pointers to Pointers,即二级指针. 一级指针和二级指针的值都是指向一个内存单元: 一级指针指向的内存单元存放的是源变量的值, 二级指针指向的内存单元存放的是一级指针的地址 ...
随机推荐
- find(expr|obj|ele)搜索所有与指定表达式匹配的元素。
find(expr|obj|ele) 概述 搜索所有与指定表达式匹配的元素.这个函数是找出正在处理的元素的后代元素的好方法. 所有搜索都依靠jQuery表达式来完成.这个表达式可以使用CSS1-3的选 ...
- Towers of Hanoi Strike Back (URAL 2029)
Problem The Tower of Hanoi puzzle was invented by French mathematician Édouard Lucas in the second h ...
- deepin linux安装为知笔记
sudo apt-get install wiznote
- Oracle用户被锁解决方法
.查看用户的proifle是哪个,一般是default: sql>SELECT username,PROFILE FROM dba_users; .查看指定概要文件(如default)的密码有效 ...
- spring boot打包以及centos下部署
spring boot打包以及部署 一.打包 springboot的打包方式有很多种.有打成war的,有打成jar的,也有直接提交到github,通过jekins进行打包部署的.这里主要介绍如何打成j ...
- Leetcode题目198.打家劫舍(动态规划-简单)
题目描述: 你是一个专业的小偷,计划偷窃沿街的房屋.每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警. 给 ...
- Mybatis传递多个参数进行SQL查询的用法
当只向xxxMapper.xml文件中传递一个参数时,可以简单的用“_parameter”来接收xxxMapper.java传递进来的参数,并代入查询. 但是,如果在xxxMapper.java文件中 ...
- js 给元素绑定回车事件
经常会看到登录页面输入完账户密码,回车就登录了.实现方法: JQuery方法: $("#focus")为获取id为focus的元素 $("#focus").ke ...
- vuejs2从入门到精通与项目开发实战
vuejs2从入门到精通:一.基础部分0.课件1.介绍2.vue实例3.模板语法4.计算属性和观察者5.Class与Style绑定6.条件渲染7.列表渲染8.事件处理9.表单输入绑定10.1.组件(1 ...
- linux系统中的一些典型问题汇总
一.文件系统破坏导致系统无法启动:Checking root filesystem/dev/sda6 contains a file system with errors,check forcedAn ...