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