年,兮 发表于 2023-4-3 18:49:09

二维数组地址探究

定义一个整型二维数组 代码如下:
#include<stdio.h>
int main()
{
        int i,j;
        int a = {{1},{2},{3}};
        printf("a=%p\n*(a+1)=%p\n*a=%p\na=%p\n*a+1=%p\n",a,*(a+1),*a,a,*a+1);
        printf("a+1=%p\n&a=%p\n",a+1,&a);
        return 0;
}//为什么(a+i)和*(a+i)地址一样;但通过数组索引输出只能*(*(a+i)+j)而不能用*((a+i)+j);

isdkz 发表于 2023-4-3 18:58:02

首先,让我们看一下这段代码中每个指针和地址的含义:


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


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

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

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

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


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


因此,我们应该使用 *(*(a+i)+j) 来表示二维数组中的元素 a[i]。

歌者文明清理员 发表于 2023-4-3 19:22:23

在C语言中,二维数组是以行为主序存储的,也就是说数组的每一行单独成为一个一维数组在内存中连续存储。因此,对于一个二维数组a,a和*(a+i)所表示的地址是一样的,即它们都是指向第i行的首个元素的指针。

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

对于第二个问题,调用*((a+i)+j)等价于a,而((a+i)+j)会把第i行看作一个整体,在其中偏移j个整型长度,这显然是不正确的。因此,必须先解引得到第i行的首个元素,再加上偏移量j才能正确访问到a所对应的元素。

年,兮 发表于 2023-4-4 18:45:31

isdkz 发表于 2023-4-3 18:58
首先,让我们看一下这段代码中每个指针和地址的含义:




1,2,3,4,5都是地址哦,用的都是%p,不过后面的分析的很详细,谢谢
页: [1]
查看完整版本: 二维数组地址探究