我在这里看一个独特的例子,我试图理解为什么他的代码片段的行为方式
// 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
..
答案 0 :(得分:3)
当你考虑数组索引实际上在做什么时,它会变得更加明显。
给定数组test
,您通常会使用n
访问test
的{{1}}元素。但是,这实际上相当于test[n]
。这是因为添加指针会自动将您添加的数量与指向的类型的大小相乘。这意味着如果向指针添加一个指针,则指针将指向数组中的第二个项目,如果添加两个指针则指向第三个项目,依此类推。
您提供的代码然后引用该值,因此您最终得到*(test+n)
。然后,引用(&(*(test+n))
)和取消引用(&
)操作会相互抵消,这意味着您最终只会使用*
。
然后代码对该值执行另一个数组索引,因此您最终得到test+n
,这又可以写为(test+n)[n]
。如果您简化了这一点,则会得到*((test+n)+n)
,可以将其重写为*(test+n+n)
。
显然,如果将其转换回数组索引表示法,最后会得到*(test+2*n)
,它以简单的形式表示您将查询该数组的每个其他元素。
答案 1 :(得分:3)
这是发生的事情: 数组只是一块连续的内存。
&test
获取该数组起点索引的地址。不是价值。
当你添加[某个数字]时,它会将数字大小乘以数据类型的大小,在这种情况下,每个字符都是一个字节。
所以当你这样做时
&test[i]
表示起始地址+ i个字节。
当你做
时(&test[i])[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