深入理解C/C++二维数组

前言

本来以为自己对二维数组的理解还可以,没感觉有什么,但是今天小伙伴问了一个问题感觉迷惑了好久,于是决定细致的记录一下,一步一步的探究各种关于二维数组的问题,巩固基础。

二维数组的探究之旅(初级)

首先定义二维数组

int a[3][3] = {1, 2, 3, 4, 5, 6, 7, 8, 9};

然后开始研究二维数组名和地址的关系

// 打印a a[0] 和 a[0][0]的地址
cout << "the value of a: " << a << endl;
cout << "the value of a[0]: " << a[0] << endl;
cout << "the address of a[0][0]: " << &a[0][0] << endl;
the value of a: 0x7ffe5b8c1ee0
the value of a[0]: 0x7ffe5b8c1ee0
the address of a[0][0]: 0x7ffe5b8c1ee0

就如各种资料说的那样,可以看出三个表达指向的是一个地址,继续看

这里看一下每一行\(a[i], 0\leq i<3\)

for (int i = 0; i < 3; ++i)cout << "the value of a[" << i << "]" << " is " << a[i] << endl;
the value of a[0]is 0x7ffe5b8c1ee0
the value of a[1]is 0x7ffe5b8c1eec
the value of a[2]is 0x7ffe5b8c1ef8

打印的结果是每一行的首地址,可以看出来每两个地址之间差12个字节,也就是三个int的长度(每个int是四个字节,大部分编译器是这样的)。这与我们预期的是一样的,毕竟是每行的首地址。

继续走,我们看到\(a, a[0], a[0][0]\)的地址是一样的,都是最头上的首地址,那么这里用这个地址推导进而显示其他位置的元素

// 由a[0]推出其他,这里以第1行第1列(0 base)为例
cout << "the address of a[0+1]+1 " << "is " << a[0+1]+1 << endl;
cout << "the value of a[0+1]+1 " << "is " << *(a[0+1]+1) << endl;
cout << "the address of a[0]+4 " << "is " << a[0]+4 << endl;
cout << "the value of a[0]+4 " << "is " << *(a[0]+4) << endl;
the address of a[0+1]+1 is 0x7ffe5b8c1ef0
the value of a[0+1]+1 is 5
the address of a[0]+4 is 0x7ffe5b8c1ef0
the value of a[0]+4 is 5

前两种行是通过加a[0]的索引得到其他行的首地址,然后再加偏移量得到的,后两行是直接计算偏移量得到的。

继续,由\(a[0][0]\)的地址推导

// 由&a[0][0]推出其他, 这里以第1行第1列(0 base)为例cout << "the address of a[0][0]+4 " << "is " << &a[0][0]+4 << endl;
cout << "the value of a[0][0]+1 " << "is " << *(&a[0][0]+4) << endl;
the address of a[0][0]+4 is 0x7ffe5b8c1ef0
the value of a[0][0]+1 is 5

这里和上面的第二中直接加偏移量的情况是一样的。

由数组名得到其他元素

现在是让人有点迷惑的地方,就是数组名a既然和\(a[0], a[0][0]\)指向的地址一样,那么是否用法也一样呢?

我们先来看看如何用a得到\(a[1][1]\)

// 假设要求a[1][1](5)
cout << "a[1][1] inferred from a : " << *(*(a+1)+1) << endl;
a[1][1] inferred from a : 5

a+1指向的是\(a[1]\),这里是第1行(0 base)的首地址,对它解引用得到a[1]的地址,然后+1就得到\(a[1][1]\)的地址了。

前面说a+1是指向地址的,那么是不是意味a是一个二级指针呢?

int *p = a; // 不通过

实验发现报错,说明a不是一个指针类型,继续看

int *p = *a;
cout << "the value of p is: " << p << endl;
cout << "the value of *p is: " << *p << endl;
cout << "the value of p+1 is: " << p+1 << endl;
cout << "the value of *(p+1) is: " << *(p+1) << endl;cout << "a[1][1] inferred from p : " << *(p+1*3+1) << endl;
the value of p is: 0x7ffe5b8c1ee0
the value of *p is: 1
the value of p+1 is: 0x7ffe5b8c1ee4
the value of *(p+1) is: 2
a[1][1] inferred from p : 5

对a解引用后确实是一个地址,所以可以定义指针,并且可以用加偏移量的方式得到\(a[1][1]\)

更为有趣的是

cout << "a[1][1] inferred from p[] : " << p[1*3+1] << endl;
a[1][1] inferred from p[] : 5

指针p表现的竟然像一个一维数组(因为直接按索引就可以得到元素),这里也增加了一种新的取元素方式。这可能和[]的工作方式有关,这部分还是没弄明白,欢迎指导。

总结

这篇博客详细的记录了由二维数组名引出的各种细节,虽然还不完善,但是确实让自己巩固了基础,以后估计应该不会倒在二维数组了……吧。

转载于:https://www.cnblogs.com/bobxxxl/p/10438034.html

深入理解C/C++二维数组相关推荐

  1. 理解C语言二维数组名

    欢迎关注我的博客:小鱼的技术博客 最近在研究二维数组,发现如果单独理解数组名的Array的含义,还真不太好理解.比如现在有一个二维数组: int Array[2][2] = { {1, 2}, {3, ...

  2. html页面创建二维数组,二维数组怎么理解

    如何理解Java中的二维数组? 二维数组可以看成是以一维数组为元素的一维数组.通常将最外层的一维数组称为外维数组:而作为元素的内层数组称为内维数组.如下: //声明一个字符串类型的二维数组,其中外维数 ...

  3. 剑指offer_第1题_二维数组中的查找

    题目描述 在一个二维数组中(每个一维数组的长度相同) 每一行都按照从左到右递增的顺序排序 每一列都按照从上到下递增的顺序排序. 请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整 ...

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

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

  5. C语言 二维数组定义和使用 - C语言零基础入门教程

    目录 一.二维数组简介 二.定义二维数组并初始化 1.定义二维数组 2.初始化二维数组 三.访问二维数组 四.修改二维数组 五.猜你喜欢 零基础 C/C++ 学习路线推荐 : C/C++ 学习目录 & ...

  6. (五)C语言之二维数组

    今天的第二个内容单独拿出来讲一下,对于初接触C语言的人来说,这个知识点比较难懂,后面在讲指针的时候我还会提到这部分的内容,看不懂的同学可以看后面的内容. 指针变量可以指向一维数组中的元素,当然也就可以 ...

  7. java二维数组的长度问题

    二维数组的长度 package ArrayTest;public class Array3 {public static void main(String[] args) {//write your ...

  8. 关于定义二维数组时为什么可以省略行,而不可以省略列

    最近在复习c语言,看到二维数组的定义时,有省略行的定义方法,如arr[][10],但为什么没有省略列的定义方法呢? 我个人理解是:将一个二维数组看成若干一维数组,每一行就是一个一维数组,而二维数组的列 ...

  9. 指针 二维数组元素引用

    二维数组元素指针引用 1.定义 2.数组指针和指针数组的区别 1.二维数组可以理解为是一个一维数组,不过每个数组元素又是一个一维数组 int a[2][3]={{1,2,3},{4,5,6}}; 可以 ...

最新文章

  1. checkbox管理
  2. 云路由 vyatta 体验(二)NAT
  3. 【ssi】增删改查六操作小框架(八)
  4. zoj 3841 Cards
  5. lightroom手机版下载_vnc控制手机版下载,vnc控制手机版下载的使用教程
  6. 初窥QuickTest脚本录制
  7. 教你用易语言编写一个简单的电脑病毒
  8. OpenWRT 使用USB 4G上网卡
  9. 苹果手机计算机桌面显示器,《iphone使用技巧》苹果电脑手机必学的几个投屏幕方法分享...
  10. 这是我见过最干净的系统(WIN10 LTSC 2019)
  11. 利用正则截取匹配的字符串前后内容同
  12. 解线性方程组的各种情况
  13. 双色球彩票生成之一用户彩票号码随机生成
  14. linux虚拟机mtr不出去,如何使用MTR诊断网络问题
  15. ogr 缓冲区_OGR入门.pdf
  16. 广和通l610二次开发|广和通l610 CAT.1模组opencpu开发《一》资源介绍
  17. netty报Unknown channel option ‘TCP_NODELAY‘ for channel异常
  18. Samsung automotive v7 cameraCoretest
  19. 【场景化能力包】满足不同场景使用的解决方案
  20. Tomcat9启动闪退

热门文章

  1. H5 小代码(实时更新)
  2. 设置虚拟机和本机时间同步方法
  3. ORM框架之------Dapper,Net下无敌的ORM
  4. 使用wordpress创建自己的博客
  5. 关于性能测试几个名词概念的说明
  6. 【Xamarin开发 Android 系列 5】 Xamarin 的破解
  7. Objective-C 学习笔记15 NSProcessInfo
  8. kibana 更新 索引模式_elasticsearch – 如何在kibana中自动配置索引模式
  9. python函数几个return语句_Python常用函数--return 语句-阿里云开发者社区
  10. cad2020 开始_如何设置CAD2020经典模式,原来这么简单,一起来看看