此 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];
在任何情况下,循环都会尝试读取数组边界,因为数组的每个元素中只有5
个整数a
,而您的内部循环试图一直到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("%ldn", &(i[array])-&(array[i]));
return 0;
}
输出:
0
- 运行同一解决方案的另一个项目的项目
- CMake-按正确顺序将项目与C运行时对象文件链接
- 如何运行位于boost/libs/python/example/tutorial目录中的hello.cpp和Jamfil
- 代码在main()中运行,但在函数中出现错误
- 我在c++代码中生成了一个运行时#3异常
- 如何在linux终端中同时编译和运行c++代码
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 如何在运行中期切换GTK CSS style_context
- 如何在MS Visual Studio 2019中运行QT UI
- 如何通过cpp程序运行shell脚本
- IPC使用多个管道和分支进程来运行Python程序
- 删除指向指针的指针是运行时错误吗
- 如何用参数值调用函数(仅在运行时已知)
- 为什么即使使用-cudart-static进行编译,库用户仍然需要链接到cuda运行时
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 无法在 VS Code 上使用代码运行程序运行C++文件
- 将简单的 exe 运行到运行 Microsoft/WindowsServerCore 的 docker 容器中
- CUDA 内核在第二次运行时运行得更快 - 为什么?
- cl 生成的可执行文件在第一次运行时运行速度非常慢
- 如何在一个.travis中同时测试Python和c++.无需多次运行c++即可运行yml