C语言——详解二维数组中元素的地址

在C语言中,二维数组元素的地址认知是一个相对复杂但重要的概念。以下是对二维数组中元素地址认知的详细叙述:

一、二维数组的基本构成

二维数组可以被看作是由多个一维数组组成的数组。例如,定义了一个3行4列的二维数组,

int a[3][4] = { {1,3,5,7},
                {9,11,13,15},
                {17,19,21,23}
               }

其中a[0]a[1]a[2] 分别代表这个二维数组中的三个一维数组(即行),同时也是这三个一维数组的首地址,本身代表的是一个地址,而不是二维数组中一个元素的值,并不能代表对应行的首元素值作为输出。即

printf("%d",a[0]);

是错误的,因为它本身是一个地址,不能作为一个值输出。

printf("%d",*a[0]);

是正确的且输出结果为1,即第一行一维数组首元素的值。

二、二维数组名的含义

  • 二维数组名是一个地址常量:二维数组名(如a)是一个指向其首元素的指针,即指向第一个一维数组(或第一行)的指针。在C语言中,数组名代表数组首元素的地址,因此a的值是二维数组首元素(即第一行)的地址。
  • 二维数组名与行指针:二维数组名也可以被理解为行指针,它指向的是一个一维数组(行)的首地址。
  • 二维数组名 = 第一个一维数组(或第一行)的地址 = 存放的是二维数组第一个元素的值

三、二维数组中元素的地址

  1. 首元素的地址:二维数组的首元素地址是&a[0][0],它同时也是二维数组名a的值。
  2. 行地址
    • a+i(其中i是非负整数)表示二维数组中第i行的首地址。例如,a+1是第二行(即a[1])的首地址。
    • a[i](其中i是非负整数且小于行数)也是第i行的首地址,同时它也是一个一维数组名,代表一个一维数组(即一行)。
  3. 列地址
    • 在二维数组中,我们通常不直接谈论“列地址”的概念,因为列是通过行和列索引来定位的。但是,我们可以说a[i]+j(其中i是行索引,j是列索引)表示第i行第j个元素的地址。例如,a[0]+1是第一行第二个元素的地址(即&a[0][1])。
  4. 元素的值与地址
    • 要获取二维数组中某个元素的值,我们可以使用a[i][j]的形式。
    • 要获取该元素的地址,我们可以使用&a[i][j]

四、二维数组地址的等价表示

在C语言中,二维数组的地址可以通过多种方式等价表示:

(1)a[i] 等价于 *(a+i)等价于a+i,都表示第i行的首地址。

为什么 *(a+i) 可以作为地址使用

       当 a 是一个二维数组时,a 本身是数组名代表首元素地址,等价于一个指向其第一行的指针。因此,a+i 计算出的是指向第 i 行的指针(注意这里的“行”本身也是一个数组或一维数组)。在二维数组中,*(a+i) 或等价地 a[i]他们是一个指向一个一维数组的指针,本身的值就是指向的数组的首元素的地址

  *(a+i) 在这个上下文中通常被视为一个数组名(或行指针),而不是一个具体的值。要访问第 i 行第 j 列的元素,我们需要进一步解引用,即 *(*(a+i)+j) 或 a[i][j]

        总结来说,*(a+i) 可以作为地址使用,因为它通过解引用操作获取了指针所指向的值,而这个值实际上是数组元素的地址。

(2)a[i]+j 等价于 *(a+i)+j,都表示第i行第j个元素的地址,但是等价于(a+i)+j

  a[i]+j :a[i] 表示二维数组 a 的第 i 行的首地址。由于数组是连续存储的,a[i] 实际上指向了第 i 行的第一个元素的内存地址。a[i]+j 表示从第 i 行的首地址开始,向后偏移 j 个整数的位置。这正好是第 i 行第 j 列元素的地址。

  *(a+i)+j :首先通过 (a+i) 获取指向第 i 行的一个指针,通过解引用运算符 * 获得这个指针的值即第 i 行首元素的地址,然后 +j 等同于在内存地址上向后偏移 j 个整数的位置,因此也得到了第 i 行第 j 列元素的地址。

  (a+i)+j:a 是指向二维数组首元素的指针。a+i 表示从 a 开始,按照数组的行数来偏移。如果数组的每行有 N 个元素,那么 a+i 实际上偏移了 i*N 个整数的位置,指向第i行的第一个元素。(a+i)+j 这里再次使用 +j,并不是在内存地址上简单偏移两个整数,而是根据数组的行数来偏移。这意味着 (a+i)+j 实际上相当于 (a + i*N) + j*N,即从第二行的首地址开始,再偏移 j*N 个整数的位置。

五、注意事项

  • 在处理二维数组时,要注意不要越界访问数组元素,这可能会导致未定义行为。
  • 数组名是一个常量指针,不能对其进行赋值操作(如a++是非法的),但可以通过指针算术来访问数组的不同部分。

  • 17
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hardStudy_h

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值