2016-07-22 80 views
0

我期待在这里独特的例子,我试图理解为什么他的代码片段的行为方式确实对数组的引用究竟如何工作?

// uninitialized mem 
char test[99999]; 


// 
test[0] = 'a'; 
test[1] = 'b'; 
test[2] = 'c'; 
test[3] = 'd'; 
test[4] = 'e'; 
test[5] = 'f'; 
test[6] = 'g'; 


for (int i = 0; i < 99999; i++) { 
    cout << (&test[i])[i] << endl; 
} 

特别是,什么是在内存中发生的输出跳过一个字符?

output: 
a 
c 
e 
g 
.. 
+1

'&'是这里的地址的运营商。 – LogicStuff

回答

3

这就是发生了什么事情: 一个数组只是一个连续的内存块。

&test 

正在获取该数组起点索引的地址。不是价值。

当您添加[某个数字]时,它将数字乘以数据类型的大小,在这种情况下,每个字符都是一个字节。

所以,当你做

&test[i] 

这意味着起始地址+ I字节。

当你做

(&test[i])[i] 

您是从起始地址做我字节,然后把它看成起始地址和上我更多的字节。

因此,在你迭代:

(&test[0])[0] // index 0 + 0 = 0 
(&test[1])[1] // index 1 + 1 = 2 
(&test[2])[2] // index 2 + 2 = 4 
(&test[3])[3] // index 3 + 3 = 6 
+2

这个答案表明'&test [i]'表示'(&test)[i]'。它没有。它意味着'&(test [i])'。没有'[我]'适用的'测试'。 – hvd

+0

它可以让你用圆括号包装整个数组的取消引用,并将其作为起始指针。 (&(test [i])[i])[0]和(&(&test [i])[i])[0])[0]给你相同的结果 – brianxautumn

+0

@brianxautumn在你的最后一段你有'1 + 1 = 1'。我确实尝试过编辑,但编辑必须至少有6个字符.....你可能可以修复它。 – Andrew

3

当你考虑一下数组索引实际上是在做它应该成为更明显一点。

给定一个数组test,您通常会使用test[n]访问testn th元素。但是,这实际上相当于*(test+n)。这是因为添加指针会自动将您添加的数量与指向的类型的大小相乘。这意味着指针将指向数组中的第二个项目,如果您将指针添加到第二个项目,则第三个项目添加两个,依此类推。

您提供的代码然后引用该值,所以最终以​​3210结束。然后参考文献(&)和取消引用(*)的操作相互抵消,这意味着最终只有test+n

然后代码会对该值执行另一个数组索引,因此您最终得到的结果为(test+n)[n],这可能会写为*((test+n)+n)。如果你简化它,你会得到*(test+n+n),它可能被重写为*(test+2*n)。很显然,如果你将它转换回数组索引表示法,最后会得到test[2*n],这表明你将以简单的形式表示你将查询数组中的每一个元素。