繁体   English   中英

此cout语句将如何运行

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM