我对C中的这个问题非常困惑。
如果a[i]
等同于*(a+i)
。等同于a[j][i]
?
我知道(a+i)
正在通过i的值递增数组的第一个元素的内存地址,然后使用*运算符取消引用该地址以获取该值。但是,我对多维数组感到困惑。在内存中,值就像一维数组一样存储,但我不知道如何通过使用变量i或j增加内存地址,就像在单维数组示例中一样。
由于某种原因,在单维数组中打印*a
将打印数组的第一个元素,而多维数组中的*a
将打印一个随机数。为什么会这样?
非常感谢任何帮助。
答案 0 :(得分:4)
如果a [i]等于*(a + i)。什么是[j] [i]?
的等价物
a[j][i]
类似于
*(*(a+ j) + i)
现在如果你想知道它是怎么回事?
然后看看
你已经知道了
a[j]=*(a+j) -------------------------> res 1
现在
a[j][i] = *(a[j]+i); --------------------------> res2
之后替换res1
中的res2
。所以它变成了
a[j][i] = *(*(a+ j) + i) ----------------------> res3
答案 1 :(得分:1)
一般来说数组遵循指针概念。对于一维数组,一次取消引用就足以获得值。但是在多维数组中,为了获得值,我们在2D数组中取消引用2次,在3D数组中取消引用3次。
在a[j][i]=*(*(a+j)+i)
答案 2 :(得分:1)
问题的字面答案很简单: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]
,那么它将是" true"多维数组,它是一个C数组,其元素本身是C数组(具有某个编译时常量大小)。在这种情况下,如果考虑*(*(a+j)+i)
,发生的事情是1)a
被转换为指向其第一个元素的指针(它是指向数组的指针,类型为T(*)[y]
) ,2)指针递增和解除引用,产生数组类型的值(j
的{{1}}子数组,3)然后将数组转换为指针到它的第一个元素(类型为a
的指针),然后4)递增和解除引用。这最终产生T*
的{{1}}元素的i
元素,您通常认为是j
。
但是,a
也可以有类型,例如a[j][i]
。这通常用于实现" fake"多维数组,它是一个指针数组,然后指向某个数组的第一个元素。这允许你有"行"可以有不同的大小(因此多维数组不必是"矩形"),并且大小在编译时不固定。 " rows"以及主指针数组不必连续存储。在这种情况下,如果考虑a
,发生的事情是1)T**
递增和解除引用,产生指针类型的值(*(*(a+j)+i)
的{{1}}元素),2) 指针然后递增和解除引用。这最终产生由主指针数组的a
元素引用的数组的j
元素。请注意,在这种情况下,没有隐式的数组到指针转换。
答案 3 :(得分:0)
C中的多维数组是连续的。以下内容:
int a [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);
打印数组的第一个元素。