C:如果a[i]等于*(a+;i)。什么是[j][i]的等价物?

C:如果a[i]等于*(a+;i)。什么是[j][i]的等价物?,c,arrays,pointers,multidimensional-array,memory-address,C,Arrays,Pointers,Multidimensional Array,Memory Address,我对C中的这个问题很困惑 如果a[i]等同于*(a+i)。什么是a[j][i]的等价物 我知道(a+I)将数组第一个元素的内存地址增加I的值,然后使用*运算符取消引用该地址以获得值。然而,我对多维数组感到困惑。在内存中,值就像一维数组一样存储,但我不明白如何使用变量I或j来增加内存地址,就像在一维数组示例中一样 出于某种原因,在一维数组中打印*a将打印数组的第一个元素,而在多维数组中打印*a将打印随机数。为什么会这样 非常感谢您的帮助 如果a[i]等于*(a+i)。什么是[j][i]的等价物 类

我对C中的这个问题很困惑

如果
a[i]
等同于
*(a+i)
。什么是
a[j][i]
的等价物

我知道
(a+I)
将数组第一个元素的内存地址增加I的值,然后使用*运算符取消引用该地址以获得值。然而,我对多维数组感到困惑。在内存中,值就像一维数组一样存储,但我不明白如何使用变量I或j来增加内存地址,就像在一维数组示例中一样

出于某种原因,在一维数组中打印
*a
将打印数组的第一个元素,而在多维数组中打印
*a
将打印随机数。为什么会这样

非常感谢您的帮助

如果a[i]等于*(a+i)。什么是[j][i]的等价物

类似于

 *(*(a+ j) + i)
现在如果你想知道它是怎样的

那让我看看

你已经知道了

a[j]=*(a+j)            -------------------------> res 1
现在

然后更换
res2
中的
res1
。所以它变成了

a[j][i] = *(*(a+ j) + i)   ----------------------> res3

通常数组遵循指针的概念。对于1D数组,一次解引用就足以得到值。但是在多维数组中,要得到值,我们在2D数组中要解引用2次,在3D数组中要解引用3次,就像这样


a[j][i]=*(*(a+j)+i)
中,C中的多维数组是连续的。以下是:

a is an array of arrays, so it decays to a pointer to a[0], the first subarray.
a+i is a pointer to the ith subarray of a.
a[i] is equivalent to *(a+i), dereferencing a pointer to the ith subarray of a. Since this is an expression of array type, it decays to a pointer to a[i][0].
a[i][j] is equivalent to *(*(a+i)+j), dereferencing a pointer to the jth element of the ith subarray of a.
INTA[4][5]

由内存中相邻排列的4个int[5]组成

指针数组:

int*a[4]

它是参差不齐的。每个指针都可以指向不同长度的单独数组(的第一个元素)

a[i][j]相当于((a+i)+j)。参见C11标准第6.5.2.1节:

The definition of the subscript operator [] is that E1[E2] is identical to (*((E1)+(E2)))
因此,a[i][j]相当于(*(a+i))[j],后者相当于((a+i)+j)

这种等价性的存在是因为在大多数上下文中,数组类型的表达式衰减到指向其第一个元素的指针(C11标准,6.3.2.1)。a[i][j]解释如下:

a is an array of arrays, so it decays to a pointer to a[0], the first subarray.
a+i is a pointer to the ith subarray of a.
a[i] is equivalent to *(a+i), dereferencing a pointer to the ith subarray of a. Since this is an expression of array type, it decays to a pointer to a[i][0].
a[i][j] is equivalent to *(*(a+i)+j), dereferencing a pointer to the jth element of the ith subarray of a.
请注意,指向数组的指针不同于指向其第一个元素的指针。a+i是指向数组的指针;它不是数组类型的表达式,并且不会衰减,无论是指向指针的指针还是指向任何其他类型的指针

and for some reason printing *a in single dimensional array will print the first element of the array whereas *a in a multidimensional array will print a random number. Why is this so? 
对于二维数组,需要相应地取消对它的引用

printf("\nvalue : %d",**a);

打印数组的第一个元素。

这个问题的字面答案很简单:
a[i]
根据标准定义为始终与
*(a+i)
相同,因此,
a[j][i]
保证始终与
*(*(a+j)+i)
相同,这本身并不能帮助我们理解正在发生的事情;它只是将一个复合表达式转换为另一个

a[j][i]
(扩展而言,
*(*(a+j)+i)
)根据
a
的类型做非常不同的事情。这是因为,根据类型的不同,可能存在不明显的隐式数组到指针转换

在C语言中,数组类型
T[x]
的值在许多上下文中隐式转换为指针类型
T*
的右值,其中一些上下文包括下标运算符的左侧以及操作数。因此,如果执行
a[i]
*(a+i)
,并且
a
是数组类型的表达式,在这两种情况下,它都会转换为指向其第一个元素的指针(如
&a[0]
),并且它是参与操作的指针。因此,您可以看到
*(a+i)
的意义

如果
a
具有类型
T[x][y]
,则它将是一个“真”多维数组,这是一个C数组,其元素本身就是C数组(具有特定的编译时常量大小)。在这种情况下,如果考虑<代码> *(*(a+j)+i)/代码>,发生的事情是1)<代码> a <代码>被转换为指向它的第一个元素的指针(它是指向数组的指针,类型为<代码> t(*)[y] < /代码>),2)该指针被递增和撤销,产生数组类型的值(<代码> j/Cuth>子数组的<代码> A<代码> >3)然后将该数组转换为指向其第一个元素的指针(类型为
T*
的指针),然后对其进行递增和取消引用。这最终生成
a
j
th元素的
i
th元素,您通常认为这是
a[j][i]


但是,
a
也可以有类型,例如,
T**
。这通常用于实现“伪”多维数组,即指针数组,指针数组反过来指向某个数组的第一个元素。这允许您拥有大小不同的“行”(因此多维数组不需要是“矩形”),并且在编译时大小不固定。“行”以及主指针数组不必连续存储。在这种情况下,如果考虑<代码> *(*(a+j)+i)<代码>,发生的事情是1)<代码> a < /C> >递增并取消引用,产生指针类型的值(<代码> j>代码>元素> <代码< < /代码>),2)然后递增和取消指针。这最终生成主指针数组的
j
th元素所引用的数组的
i
th元素。请注意,在这种情况下,没有隐式数组到指针的转换。

谢谢!然而,我在概念上还是不太明白。在圆括号内,先取消引用*(a+i),然后再向其添加int j,然后再次取消引用。如果结果取决于i索引(a[i])的值而不是地址本身,那么这是如何工作的?@Mishy For you declaration see link这个答案将以@newacct below的断言完成。这可能会迅速退化为一个关于指针的全面教程
printf("\nvalue : %d",**a);