二维数组和指针_二维数组与指针

二维数组和指针_二维数组与指针二维数组和指针⑴用指针表示二维数组元素。要用指针处理二维数组,首先要解决从存储的角度对二维数组的认识问题。我们知道,一个二维数组在计算机中存储时,是按照先行后列的顺序依次存储的,当把每一行看作一个整体,即视为一个大的数组元素时,这个存储的二维数组也就变成了一个一维数组了。而每个大数组元素对应二维数组的一行,我们就称之为行数组元素,显然每个行数组元素都是一个一维数组下面我们讨论指针和二维数组元

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全家桶1年46,售后保障稳定

二维数组和指针⑴ 用指针表示二维数组元素。
要用指针处理二维数组,首先要解决从存储的角度对二维数组的认识问题。我们知道,一个二维数组在计算机中存储时,是按照先行后列的顺序依次存储的,当把每一行看作一个整体,即视为一个大的数组元素时,这个存储的二维数组也就变成了一个一维数组了。而每个大数组元素对应二维数组的一行,我们就称之为行数组元素,显然每个行数组元素都是一个一维数组

下面我们讨论指针和二维数组元素的对应关系,清楚了二者之间的关系,就能用指针处理二维数组了。
设p是指向数组a的指针变量,若有:
p=a[0];
则p+j将指向a[0]数组中的元素a[0][j]。
由于a[0]、a[1]┅a[M-1]等各个行数组依次连续存储,则对于a数组中的任一元素a[i][j],指针的一般形式如下:
p+i*N+j
元素a[i][j]相应的指针表示为:
*( p+i*N+j)
同样,a[i][j]也可使用指针下标法表示,如下:
p[i*N+j]
例如,有如下定义:
int a[3][4]={
{10,20,30,40,},{50,60,70,80},{90,91,92,93}};
则数组a有3个元素,分别为a[0]、a[1]、a[2]。而每个元素都是一个一维数组,各包含4个元素,如a[1]的4个元素是a[1][0]、a[1][1]、a[1]2]、a[1][3]。
若有:
int *p=a[0];
则数组a的元素a[1][2]对应的指针为:p+1*4+2
元素a[1][2]也就可以表示为:*( p+1*4+2)
用下标表示法,a[1][2]表示为:p[1*4+2]
特别说明:
对上述二维数组a,虽然a[0]、a都是数组首地址,但二者指向的对象不同,a[0]是一维数组的名字,它指向的是a[0]数组的首元素,对其进行“*”运算,得到的是一个数组元素值,即a[0]数组首元素值,因此,*a[0]与a[0][0]是同一个值;而a是一个二维数组的名字,它指向的是它所属元素的首元素,它的每一个元素都是一个行数组,因此,它的指针移动单位是“行”,所以a+i指向的是第i个行数组,即指向a[i]。对a进行“*”运算,得到的是一维数组a[0]的首地址,即*a与a[0]是同一个值。当用int *p;定义指针p时,p的指向是一个int型数据,而不是一个地址,因此,用a[0]对p赋值是正确的,而用a对p赋值是错误的。这一点请读者务必注意。
⑵ 用二维数组名作地址表示数组元素。
另外,由上述说明,我们还可以得到二维数组元素的一种表示方法:
对于二维数组a,其a[0]数组由a指向,a[1]数组则由a+1指向,a[2]数组由a+2指向,以此类推。因此,*a与a[0]等价、*(a+1)与a[1]等价、*(a+2)与a[2]等价,┅,即对于a[i]数组,由*(a+i)指向。由此,对于数组元素a[i][j],用数组名a的表示形式为:
*(*(a+i)+j)
指向该元素的指针为:
*(a+i)+j
数组名虽然是数组的地址,但它和指向数组的指针变量不完全相同。指针变量的值可以改变,即它可以随时指向不同的数组或同类型变量,而数组名自它定义时起就确定下来,不能通过赋值的方式使该数组名指向另外一个数组。
例4 求二维数组元素的最大值。

该问题只需对数组元素遍历,即可求解。因此,可以通过顺序移动数组指针的方法实现。
main()
{

int a[3][4]={
{3,17,8,11},{66,7,8,19},{12,88,7,16}};
int *p,max;
for(p=a[0],max=*p;p<a[0]+12;p++)
   if(*p>max)
      max=*p;
printf(“MAX=%d/n”,max);
}
执行结果:
MAX=88
这个程序的主要算法都是在for语句中实现的:p是一个int型指针变量;p=a[0]是置数组的首元素地址为指针初值;max=*p将数组的首元素值a[0][0]作为最大值初值;p<a[0]+12是将指针的变化范围限制在12个元素的位置内;p++使得每比较一个元素后,指针后移一个元素位置。
例5 求二维数组元素的最大值,并确定最大值元素所在的行和列。
本例较之上例有更进一步的要求,需要在比较的过程中,把较大值元素的位置记录下来,显然仅用上述指针移动方法是不行的,需要使用能提供行列数据的指针表示方法。
main()
{

int a[3][4]={
{3,17,8,11},{66,7,8,19},{12,88,7,16}};
int *p=a[0],max,i,j,row,col;
max=a[0][0];
row=col=0;
for(i=0;i<3;i++)
   for(j=0;j<4;j++)
     if(*(p+i*4+j)>max)
      {

        max=*(p+i*4+j);
        row=i;
        col=j;
      }
printf(“a[%d][%d]=%d/n”,row,col,max);
}
程序运行结果:
a[2][1]=88
⑶ 行数组指针
在上面的说明中我们已经知道,二维数组名是指向行的,它不能对如下说明的指针变量p直接赋值:
int a[3][4]={
{10,11,12,13},{20,21,22,23},{30,31,32,33}},*p;
其原因就是p与a的对象性质不同,或者说二者不是同一级指针。C语言可以通过定义行数组指针的方法,使得一个指针变量与二维数组名具有相同的性质。行数组指针的定义方法如下:
数据类型 (*指针变量名)[二维数组列数];
例如,对上述a数组,行数组指针定义如下:
int (*p)[4];
它表示,数组*p有4个int型元素,分别为(*p)[0]、(*p)[1]、(*p)[2]、(*p)[3] ,亦即p指向的是有4个int型元素的一维数组,即p为行指针

此时,可用如下方式对指针p赋值:
p=a;

 

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/213489.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 计算机网络协议(三)——UDP、TCP、Socket[通俗易懂]

    计算机网络协议(三)——UDP、TCP、Socket[通俗易懂]底层网络知识详解:最重要的传输层概述一、UDP协议二、TCP协议2.1TCP的三次握手概述这个专栏的计算机网络协议,我是在极客时间上学习已经有三万多人购买的刘超老师的趣谈网络协议专栏,讲的特别好,像看小说一样学习到了平时很枯燥的知识点,计算机网络的书籍太枯燥,感兴趣的同学可以去付费购买,绝对物超所值,本文就是对自己学习专栏的总结,评论区可以留下你的问题,咱们一起讨论!传输层中有两…

    2022年6月7日
    52
  • mpvue flyio「建议收藏」

    mpvue flyio「建议收藏」https://blog.csdn.net/qq_34239734/article/details/88836320不用改这个,如果改第一个,那么就自动改第二个了在main.js中代码如下importflyfrom’./utils/request’//将fly挂载在全局Vue.prototype.$fly=flyutil…

    2025年10月8日
    5
  • PHP递归算法_php递归函数详解

    PHP递归算法_php递归函数详解先设置数据在本地数据库,设置前要先了解pid字段的关系。如果做成菜单还需添加一个路由字段,自行定义。第一种方式先将数据提取出转换成数组。重点是Yarray方法里的递归方式。接下来进行解析方式。重点:一定要在进行递归之前声明一个静态数组,不然会导致数组覆盖。剩下的就是注释的内容也就是判断父节点与节点来判断等级。这步指来回方法调用本身进行处理递归。最后数据会变成其中关系为pid数值存在与id下的下级关系,level为处于第几级;我们来输出一下看看结.

    2022年8月11日
    10
  • 时间序列预测——双向LSTM(Bi-LSTM)「建议收藏」

    时间序列预测——双向LSTM(Bi-LSTM)「建议收藏」  本文展示了使用双向LSTM(Bi-LSTM)进行时间序列预测的全过程,包含详细的注释。整个过程主要包括:数据导入、数据清洗、结构转化、建立Bi-LSTM模型、训练模型(包括动态调整学习率和earlystopping的设置)、预测、结果展示、误差评估等完整的时间序列预测流程。  本文使用的数据集在本人上传的资源中,链接为mock_kaggle.csv代码如下:importpandasaspdimportnumpyasnpimportmathimportkerasfromma

    2022年6月25日
    194
  • CGLIB中BeanCopier源码实现

    CGLIB中BeanCopier源码实现转载:CGLIB中BeanCopier源码实现CGLIB代码包结构1.core2.beans3.reflect4.proxyBeanCopier实现机制1.BeanCopier的使用2.性能分析3.一次调用流程(1)CGLIB做了什么(2)从BeanCopier#create开始(3)KEY_FACTORY的由来(4)AbstractClassGene…

    2025年9月13日
    6
  • 50个多线程面试题,你会多少?(一)[通俗易懂]

    50个多线程面试题,你会多少?(一)[通俗易懂]下面是Java线程相关的热门面试题,你可以用它来好好准备面试。什么是线程? 什么是线程安全和线程不安全? 什么是自旋锁? 什么是Java内存模型? 什么是CAS? 什么是乐观锁和悲观锁? 什么是AQS? 什么是原子操作?在JavaConcurrencyAPI中有哪些原子类(atomicclasses)? 什么是Executors框架? 什么是阻塞队列?如何使用阻塞队列来…

    2022年5月2日
    39

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号