鱼C论坛

 找回密码
 立即注册
查看: 1279|回复: 3

[已解决]二维数组地址探究

[复制链接]
发表于 2023-4-3 18:49:09 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
定义一个整型二维数组 代码如下:
#include<stdio.h>
int main()
{
        int i,j;
        int a[3][4] = {{1},{2},{3}};
        printf("a[1]=%p\n*(a+1)=%p\n*a=%p\na=%p\n*a+1=%p\n",a[1],*(a+1),*a,a,*a+1);
        printf("a+1=%p\n&a[1]=%p\n",a+1,&a[1]);
        return 0;
}//为什么(a+i)和*(a+i)地址一样;但通过数组索引输出只能*(*(a+i)+j)而不能用*((a+i)+j);
最佳答案
2023-4-3 18:58:02
首先,让我们看一下这段代码中每个指针和地址的含义:

  • a 是二维数组的首地址,即数组 a[0] 的首地址,它表示的是第一个一维数组的地址;
  • *a 是第一个一维数组的首元素,即 a[0][0];
  • a+1 是第二个一维数组的地址,即数组 a[1] 的首地址;
  • *(a+1) 是第二个一维数组的首元素,即 a[1][0];
  • *a+1 是第一个一维数组的第二个元素,即 a[0][1];


现在我们来解释为什么 (a+i) 和 *(a+i) 的地址一样。

首先要明确的是,这两者的值是一样的,但类型是不同的。(a+i) 的类型是一个指向一维数组的指针,

而 *(a+i) 的类型是一个指向整型的指针。因为数组名在大多数情况下会被转换为指向其首元素的指针,所以它们的值相等。

然后,让我们解释为什么我们可以使用 *(*(a+i)+j),但不能使用 *((a+i)+j) 来表示数组中的元素。在这里:

  • *(a+i) 是第 i 个一维数组的首元素;
  • *(*(a+i)+j) 是第 i 个一维数组的第 j 个元素,即 a[i][j];
  • (a+i) 是指向第 i 个一维数组的指针;
  • ((a+i)+j) 是试图将整数 j 添加到指向一维数组的指针中,这是不正确的,因为这里的加法没有意义;


因此,我们应该使用 *(*(a+i)+j) 来表示二维数组中的元素 a[i][j]。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-4-3 18:58:02 | 显示全部楼层    本楼为最佳答案   
首先,让我们看一下这段代码中每个指针和地址的含义:

  • a 是二维数组的首地址,即数组 a[0] 的首地址,它表示的是第一个一维数组的地址;
  • *a 是第一个一维数组的首元素,即 a[0][0];
  • a+1 是第二个一维数组的地址,即数组 a[1] 的首地址;
  • *(a+1) 是第二个一维数组的首元素,即 a[1][0];
  • *a+1 是第一个一维数组的第二个元素,即 a[0][1];


现在我们来解释为什么 (a+i) 和 *(a+i) 的地址一样。

首先要明确的是,这两者的值是一样的,但类型是不同的。(a+i) 的类型是一个指向一维数组的指针,

而 *(a+i) 的类型是一个指向整型的指针。因为数组名在大多数情况下会被转换为指向其首元素的指针,所以它们的值相等。

然后,让我们解释为什么我们可以使用 *(*(a+i)+j),但不能使用 *((a+i)+j) 来表示数组中的元素。在这里:

  • *(a+i) 是第 i 个一维数组的首元素;
  • *(*(a+i)+j) 是第 i 个一维数组的第 j 个元素,即 a[i][j];
  • (a+i) 是指向第 i 个一维数组的指针;
  • ((a+i)+j) 是试图将整数 j 添加到指向一维数组的指针中,这是不正确的,因为这里的加法没有意义;


因此,我们应该使用 *(*(a+i)+j) 来表示二维数组中的元素 a[i][j]。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-3 19:22:23 | 显示全部楼层
在C语言中,二维数组是以行为主序存储的,也就是说数组的每一行单独成为一个一维数组在内存中连续存储。因此,对于一个二维数组a,a[i]和*(a+i)所表示的地址是一样的,即它们都是指向第i行的首个元素的指针。

对于第一个问题,表达式(a+i)和*(a+i)都指向第i行的首个元素,并且它们所占用的空间大小相同,因此它们的地址也一样。

对于第二个问题,调用*((a+i)+j)等价于a[i][j],而((a+i)+j)会把第i行看作一个整体,在其中偏移j个整型长度,这显然是不正确的。因此,必须先解引得到第i行的首个元素,再加上偏移量j才能正确访问到a[i][j]所对应的元素。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2023-4-4 18:45:31 | 显示全部楼层
isdkz 发表于 2023-4-3 18:58
首先,让我们看一下这段代码中每个指针和地址的含义:

1,2,3,4,5都是地址哦,用的都是%p,不过后面的分析的很详细,谢谢
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-6-17 08:44

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表