目录

嗨,这里是狐狸~~

首先,先声明一些常识,如果你对这些常识还不理解,请先去弥补一下基础知识:

一、一维数组与数组指针​

二、二维数组与数组指针​

三、三维数组与数组指针​

四:多级指针​

总结​


青春,在嘲笑着我们。

嗨,这里是狐狸~~

今天是2022年1月18日,突然发现我们也快放假了,想想都开心,放假的时候文章的更新就会放缓很多了,趁现在有时间,多给大家分享点知识,好了,今天继续给大家讲指针以及数组的知识。

指针与数组是C/C++编程中非常重要的元素,同时也是较难以理解的。其中,多级指针与“多维”数组更是让很多人云里雾里,其实,只要掌握一定的方法,理解多级指针和“多维”数组完全可以像理解一级指针和一维数组那样简单。

首先,先声明一些常识,如果你对这些常识还不理解,请先去弥补一下基础知识:

1、实际上并不存在多维数组,所谓的多维数组本质上是用一维数组模拟的。
2、数组名是一个常量(意味着不允许对其进行赋值操作),其代表数组首元素的首地址。
3、数组与指针的关系是因为数组下标操作符[],比如,int a[3][2]相当于*(*(a+3)+2) 。
4、指针是一种变量,也具有类型,其占用内存空间大小和系统有关,一般32位系统下,sizeof(指         针变量)=4。
5、指针可以进行加减算术运算,加减的基本单位是sizeof(指针所指向的数据类型)。
6、对数组的数组名进行取地址(&)操作,其类型为整个数组类型。
7、对数组的数组名进行sizeof运算符操作,其值为整个数组的大小(以字节为单位)。
8、数组作为函数形参时会退化为指针。

 一、一维数组与数组指针

假如有一维数组如下:

  char a[3];

该数组一共有3个元素,元素的类型为char,如果想定义一个指针指向该数组,也就是如果想把数组名a赋值给一个指针变量,那么该指针变量的类型应该是什么呢?前文说过,一个数组的数组名代表其首元素的首地址,也就是相当于&a[0],而a[0]的类型为char,因此&a[0]类型为char *,因此,可以定义如下的指针变量:

 char * p = a;//相当于char * p = &a[0]

以上文字可用如下内存模型图表示。

大家都应该知道,a和&a[0]代表的都是数组首元素的首地址,而如果你将&a的值打印出来,会发现该值也等于数组首元素的首地址。请注意我这里的措辞,也就是说,&a虽然在数值上也等于数组首元素首地址的值,但是其类型并不是数组首元素首地址类型,也就是char *p = &a是错误的。

前文第6条常识已经说过,对数组名进行取地址操作,其类型为整个数组,因此,&a的类型是char (*)[3],所以正确的赋值方式如下:

  char (*p)[3] = &a;

 注:很多人对类似于a+1,&a+1,&a[0]+1,sizeof(a),sizeof(&a)等感到迷惑,其实只要搞清楚指针的类型就可以迎刃而解。比如在面对a+1和&a+1的区别时,由于a表示数组首元素首地址,其类型为char *,因此a+1相当于数组首地址值+sizeof(char);而&a的类型为char (*)[3],代表整个数组,因此&a+1相当于数组首地址值+sizeof(a)。(sizeof(a)代表整个数组大小,前文第7条说明,但是无论数组大小如何,sizeof(&a)永远等于一个指针变量占用空间的大小,具体与系统平台有关)

二、二维数组与数组指针

      假如有如下二维数组:

 char a[3][2];

由于实际上并不存在多维数组,因此,可以将a[3][2]看成是一个具有3个元素的一维数组,只是这三个元素分别又是一个一维数组。实际上,在内存中,该数组的确是按照一维数组的形式存储的,存储顺序为(低地址在前):a[0][0]、a[0][1]、a[1][0]、a[1][1]、a[2][0]、a[2][1]。(此种方式也不是绝对,也有按列优先存储的模式)

为了方便理解,我画了一张逻辑上的内存图,之所以说是逻辑上的,是因为该图只是便于理解,并不是数组在内存中实际的存储模型(实际模型为前文所述)。

如上图所示,我们可以将数组分成两个维度来看,首先是第一维,将a[3][2]看成一个具有三个元素的一维数组,元素分别为:a[0]、a[1]、a[2],其中,a[0]、a[1]、a[2]又分别是一个具有两个元素的一维数组(元素类型为char)。从第二个维度看,此处可以将a[0]、a[1]、a[2]看成自己代表”第二维”数组的数组名,以a[0]为例,a[0](数组名)代表的一维数组是一个具有两个char类型元素的数组,而a[0]是这个数组的数组名(代表数组首元素首地址),因此a[0]类型为char *,同理a[1]和a[2]类型都是char *。而a是第一维数组的数组名,代表首元素首地址,而首元素是一个具有两个char类型元素的一维数组,因此a就是一个指向具有两个char类型元素数组的数组指针,也就是char(*)[2]。

也就是说,如下的赋值是正确的:

  char (*p)[2]  = a;//a为第一维数组的数组名,类型为char (*)[2]char * p = a[0];//a[0]维第二维数组的数组名,类型为char *

同样,对a取地址操作代表整个数组的首地址,类型为数组类型(请允许我暂且这么称呼),也就是char (*)[3][2],所以如下赋值是正确的:

  char (*p)[3][2] = &a;

三、三维数组与数组指针

假设有三维数组:

 char a[3][2][2];

同样,为了便于理解,特意画了如下的逻辑内存图。分析方法和二维数组类似,首先,从第一维角度看过去,a[3][2][2]是一个具有三个元素a[0]、a[1]、a[2]的一维数组,只是这三个元素分别又是一个"二维"数组,a作为第一维数组的数组名,代表数组首元素的首地址,也就是一个指向一个二维数组的数组指针,其类型为char (*)[2][2]。从第二维角度看过去,a[0]、a[1]、a[2]分别是第二维数组的数组名,代表第二维数组的首元素的首地址,也就是一个指向一维数组的数组指针,类型为char(*)[2];同理,从第三维角度看过去,a[0][0]、a[0][1]、a[1][0]、a[1][1]、a[2][0]、a[2][1]又分别是第三维数组的数组名,代表第三维数组的首元素的首地址,也就是一个指向char类型的指针,类型为char *。

由上可知,以下的赋值是正确的:

      char (*p)[3][2][2] = &a;//对数组名取地址类型为整个数组char (*p)[2][2]  = a;char (*p) [2]  = a[0];//或者a[1]、a[2]char *p = a[0][0];//或者a[0][1]、a[1][0]...

四:多级指针

      所谓的多级指针,就是一个指向指针的指针,比如:

      char *p = "my name is chenyang.";char **pp = &p;//二级指针char ***ppp = &pp;//三级指针

假设以上语句都位于函数体内,则可以使用下面的简化图来表达多级指针之间的指向关系。

多级指针通常用来作为函数的形参,比如常见的main函数声明如下:

    int main(int argc,char ** argv)

因为当数组用作函数的形参的时候,会退化为指针来处理,所以上面的形式和下面是一样的。

    int mian(int argc,char* argv[]) 

argv用于接收用户输入的命令参数,这些参数会以字符串数组的形式传入,类似于:

    char * parm[] = {"parm1","parm2","parm3","parm4"};//模拟用户传入的参数main(sizeof(parm)/sizeof(char *),parm);//模拟调用main函数,实际中main函数是由入口函数调用的(glibc中的入口函数默认为_start)

多级指针的另一种常见用法是,假设用户想调用一个函数分配一段内存,那么分配的内存地址可以有两种方式拿到:第一种是通过函数的返回值,该种方式的函数声明如下:

    void * get_memery(int size){void *p = malloc(size);return p;}

第二种获取地址的方法是使用二级指针,代码如下:

 int get_memery(int** buf,int size){ *buf = (int *)malloc(size);if(*buf == NULL)return -1;elsereturn 0;}int *p = NULL;get_memery(&p,10);

关于多级指针的用法很多,尤其以二级指针应用最为广泛,后续的有时间再进行补充。

总结

简单总结一下,综上就是我们今天向大家分享的指针的知识了,C/C++最难的无非就是指针了,希望这篇文章可以给予大家一定的帮助,也感谢大家的支持,后续我还会发布更多的项目源或者学习资料,希望大家可以持续关注,有什么问题可以回帖留言。领取C/C++学习资料以及其他项目的源码的可以加群【1083227756】了解。想要对程序员的未来发展有兴趣的可以关注微信公众号:【狐狸的编码时光】,希望和大家一起学习进步!

图解c/c++多级指针与“多维”数组,拿捏住了相关推荐

  1. 图解c/c++多级指针与“多维”数组

    2019独角兽企业重金招聘Python工程师标准>>> 前言 指针与数组是C/C++编程中非常重要的元素,同时也是较难以理解的.其中,多级指针与"多维"数组更是让 ...

  2. 二级(多级)指针,二级指针和二维数组的避坑,指针面试考题

    1.二级指针的的认识 2.二级指针的实战 想获得二维数组的某个人的位置,采用的是return的方式 如果把第三行的int * 换成void ,把ppos换成传参的方式做. 结果崩溃了 原因是 是个野指 ...

  3. C语言指针和二维数组

    二维数组在概念上是二维的,有行和列,但在内存中所有的数组元素都是连续排列的,它们之间没有"缝隙".以下面的二维数组 a 为例: int a[3][4] = { {0, 1, 2, ...

  4. C语言中的二级指针和二维数组问题

    关于二级指针和二维数组两者差别很大,不可以直接用二级指针传递二维数组 首先来看看二维数组在内存中是如何组织的呢? 一维数组 T arr1 = new T[9]  二维数组T arr2 = new T[ ...

  5. C语言学习之利用指针输出二维数组任一行任一列元素的值

    利用指针输出二维数组任一行任一列元素的值. int main(){int a[3][4];int i,j,x,y;int (*p)[4];//指针变量p指向包含4个整型元素的一维数组printf(&q ...

  6. c语言指针怎样代替二维数组,c语言 指针和二维数组

    // 指针和二维数组 #include int main(int argc, const char * argv[]) { int a[3][6]; for (int i=0; i<3; i++ ...

  7. C ++ 指针 | 指针与二维数组_5

    指针与二维数组 根据上面的图,我现在写一些语句,我们一起来判断输出值是多少!! int (*p)[3] = B; print B; 这个会打印多少? 思考一下....... ... ... ... 打 ...

  8. C++之指针探究(五):数组指针和二维数组

    前文:C++之指针探究(四):指针和二维数组 回顾:初始化二维数组时可以"偷懒":int array[2][3]={{0,1,2},{3,4,5}}; 可以写成:int array ...

  9. C++之指针探究(四):指针和二维数组

    前文:C++之指针探究(三):指针数组和数组指针 一. 二维数组 二维数组通常也被称为矩阵(matrix). 六种初始化方式:   (1) int a[3][4] = {1,2,3,4,5,6,7,8 ...

最新文章

  1. 【H.264/AVC视频编解码技术详解】十九:熵编码算法(5)——H.264的CABAC(上):语法元素的二值化方法...
  2. 解决java.sql.SQLException: Parameter number X is not an OUT parameter--转
  3. 为企业门户提供问答式检索--------让系统能回答普通用户提出的问题
  4. Convolutional Neural Networks for Visual Recognition 8
  5. php启用openssl,php怎么开启openssl模块
  6. C++基础05-类构造函数与析构函数
  7. SSM框架中的前后端分离
  8. mysql 变量定义和赋值_MySQL变量解析
  9. Sublime Text 3快捷键
  10. 怎样用计算机求成绩平均分,2017年计算机一级WPS辅导:WPS2007中求特定比例成绩的平均分...
  11. 大数据查询怎么优化?
  12. Paper Download Artifact
  13. 8月第4周基金排行榜 | TokenInsight
  14. 生日快乐程序_时光匆匆,爱你不变——祝星广十七岁生日快乐
  15. 深圳“毕业”生灵活就业社保缴纳方式
  16. 我该如何向我的朋友解释“01背包”问题?
  17. 保持应用后台,熄屏状态下继续运行
  18. DSAC、DSAC++、DSAC*
  19. LeetCode--597. 好友申请 I :总体通过率
  20. 快手2020春季实习生及校招补招程序B卷

热门文章

  1. 大一 JAVAOOP-T2 面向 对象 进阶- 实践任务指南(美和易思)
  2. 美和易思再次获得十二项国家版权证书!
  3. mysql 导入sql文件 外键报错_为什么MySQL在导入时会忽略外键?
  4. 假期余额不足,这些并发知识你还记得吗?
  5. Android 9.0 代码切换系统语言
  6. 超外差接收机原理图讲解(四)--音频部分
  7. 木箱包角是做什么用的?
  8. 7.python的基础语法元素_文件、异常和模块
  9. 四核处理器_【购机提问】强处理器机型怎么选?4500元价位办公有啥推荐?
  10. IT软件行业网欣物业收费客服软件单页宣传资料源文件PSD格式