数据结构 | 二维数组的元素地址。【按行或按列存储】时,行列对换坐标,元素的起始地址保持不变

定义一个二维数组a[10][5]:

#include <stdio.h>
#include <math.h>
int main()
{
	char a[100][100];
	printf("%d\n", &a[0][0]);
	printf("%d\n", &a[5][5]);
	return 0;
}

运行结果为:

因为是char数组,单个元素占1个字节,两者相减,易得a[5][5]的起始地址比a[0][0]高505个字节。

由此,可以得出二维数组的元素a[5][5]的起始地址的计算公式:

        ADDRESS( a[5][5] )= A + ( 5 * 100 + 5 )* 1

那么通用公式就是,对于数组 a[ m ][ n ] 中的元素 a[ i ][ j ] 有:

        ADDRESS( a[ i ][ j ] )= A + ( i * n + j )* sizeof(int)

其中A是数组a[0][0]的起始地址,也就是数组a的首地址。

简单解释一下:因为数组的坐标都是从0开始计算的,所以元素 a[ i ][ j ]前面有0到 i - 1行(也就是共 i 行)是完整的一行,可以直接乘以列数 n ,然后元素所在行(也就是 i 行)有0到 j - 1个元素,直接加上就好了。最后再乘以字节,加上首地址。

有人可能问你为什么不算到元素本身。你可以这样想,因为你已经算了a[0][0]的大小了,假如你想得到a[0][1]的起始地址,你直接拿a[0][0]的字节大小加上数组的首地址不就得了。所以,计算元素的地址,算到它前一个就够了,因为要的是元素的起始地址嘛!

上面说的是最常用的按行为主序存储的二维数组,要是按列为主序存储咋办?

因为数组是连续存储元素的,是在你不管咋个存储,每个元素都是前后元素挨着的,这个逻辑顺序不会变。

对于行列相等的二维数组,将 i 和 j 互换就可以保证地址不变的情况下,得到两种主序存储的元素坐标。也即:&a[ i ][ j ] (行主序) == &a[ j ][ i ](列主序)

对于行列不相等的二维数组,按照以下公式:

        ADDRESS( a[ i ][ j ] )= A + ( j * n + i )* sizeof(int)

也就是把上面的公式 i 和 j 互换了一下。

如果已知按行主序的元素坐标,先求出其地址,然后代入上面的式子,就能得出按列主序的元素坐标了。至于你问我一个式子咋求俩未知数,我只能说, i 和 j 都有最大值限制,从这一点上规定了 i 和 j 的值是唯一值。

举个例子:

对于字符型二维数组a[10][8],首地址是1000,有按行为主序的元素a[4][7],通过求出它的地址然后求出按列为主序时,该地址对应的元素是哪个?

元素地址A = 1000 + ( 4 * 8 + 7 ) * 1 = 1039 = 1000 + ( j * 10 + i ) * 1

得出i = 9, j = 3,即a[9][3],不信用excel比划比划试试。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值