[英]how will this cout statement run
int a[10][5];
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
cout << i[j[a]];
cout << j[i[a]];
}
}
编辑 :假设值已经初始化为数组,那么此cout有效吗?
请解释i[j[a]];
不管程序是什么,我只关注该语句!
cout << i[j[a]];
cout << j[i[a]];
在C ++中, X[Y]
符号在词法上等效于*(X+Y)
:
[C++11: 5.2.1/1]:
[..]表达式E1[E2]
(根据定义)与*((E1)+(E2))
[..]相同
这意味着Y[X]
等于*(Y+X)
,与*(X+Y)
相同,因为加法是可交换的 。
由于某种原因,作者决定通过编写此令人困惑的代码来尝试变得“聪明”。
通过可交换性和单独对X[Y]
的定义:
i[j[a]] => i[*(j+a)] => *(i+*(j+a)) => *(*(a+j)+i) => *(a[j] + i) => a[j][i]
j[i[a]] => j[*(i+a)] => *(j+*(i+a)) => *(*(a+i)+j) => *(a[i] + j) => a[i][j]
那么,您的cout
语句等效于:
cout << a[j][i];
cout << a[i][j];
在任何情况下,循环都会尝试读取数组边界,因为数组a
每个元素中只有5
整数,而内部循环则尝试一直上升到10
。
实际结果是不确定的,因此您可能会获得无声成功,无声失败,任意值,分段错误,断电,黑洞,圣诞节小马,脚趾截肢或新自行车。
即使固定了循环条件,也请注意,第一条语句在语义上是不正确的(假设您继续将第一个维度归因于外部循环,将第二个维度归因于内部循环)。
C数组有一个奇怪的怪癖,它允许通过“相反”方向访问它们。 这深深植根于数组的指针运算中。 例如, a[1]
等效于*(a + 1)
。 同样, 1[a]
等效于*(1 + a)
。 由于加法的可交换性质,因此效果很好。 可以在此处找到更多详细信息。
掌握了这些知识之后,表达式i[j[a]]
可以分解为两个不同的部分。 j[a]
等效于*(j + a)
,由于您拥有的数组的多维性质,它会返回另一个数组,出于示例目的,我们将其称为返回的数组p
。 然后,您得到的语句i[p]
相当于*(i + p)
。 将其放回一起将向您显示i[j[a]]
等效于*(i + *(j + a))
。 确实,这意味着i[j[a]]
只是写a[j][i]
一种混淆方式。
在C / C ++中,可以用带下标的指针下标指针,也可以用指针下标的整数索引,其含义(语义)是完全相同的。 我不知道为什么疯狂的语法是有效的,但事实如此,而且显然如此,它将永远存在。
#include <stdio.h>
int main(int argc, char** argv)
{
int i = 1, array[10];
printf("%ld\n", &(i[array])-&(array[i]));
return 0;
}
输出:
0
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.