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

时间:2014-09-19 06:18:08

标签: c arrays pointers multidimensional-array memory-address

我对C中的这个问题非常困惑。

如果a[i]等同于*(a+i)。等同于a[j][i]

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

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

非常感谢任何帮助。

4 个答案:

答案 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);

打印数组的第一个元素。