我做了一個小實驗。爲什麼值輸出爲相同A [0],&A,和* A?
#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
int A[5][5];
cout<<A[0]<<" "<<&A<<" "<<*A;
return 0;
}
它爲所有情況打印相同的值。有人可以解釋爲什麼會出現這種情況嗎?
我做了一個小實驗。爲什麼值輸出爲相同A [0],&A,和* A?
#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
int A[5][5];
cout<<A[0]<<" "<<&A<<" "<<*A;
return 0;
}
它爲所有情況打印相同的值。有人可以解釋爲什麼會出現這種情況嗎?
A[0]
,&A
,*A
都是指向不同類型的指針,它們指向相同的內存位置。相同的價值(種類),不同的類型。
Expression Symmetric Type
----------------------------------------------------------------------------
A address of first row. int[5][5]
&A[0][0] address of first element int*
&A address of 2d array int(*)[5][5]
*A = *(A + 0) = A[0] = address of first element int[5] = decays to int*
in a expression
我的5×4尺寸字符數組的例子:
A
+---201---202---203---204---206--+
201 | +-----+-----+-----+-----+-----+|
A[0] = *(A + 0)--►| 'f' | 'o' | 'r' | 'g' | 's' ||
207 | +-----+-----+-----+-----+-----+|
A[1] = *(A + 1)--►| 'd' | 'o' | '\0'| '\0'| '\0'||
213 | +-----+-----+-----+-----+-----+|
A[2] = *(A + 2)--►| 'n' | 'o' | 't' | '\0'| '\0'||
219 | +-----+-----+-----+-----+-----+|
A[3] = *(A + 3)--►| 'd' | 'i' | 'e' | '\0'| '\0'||
| +-----+-----+-----+-----+-----+|
+--------------------------------+
大約圖形例的簡要說明。
- 在圖
A
表示完整的2 d陣列地址201開始,並&A
給出完整的2 d陣列的地址= 201*A = *(A + 0)
=A[0]
點到第一行= 201- 注意值
A[0][0]
是'f'
在我的例子中,&A[0][0]
給出的地址[0][0]
元素= 201- 注
&A[0][0]
是一樣*A
,因爲&A[0][0]
=>&(*(*A))
=>&**A
=>*A
因此,所有A[0]
,&A
,*A
,A
是相同的,但不同的對稱。
觀察A[0]
,&A
,*A
,A
之間的差異。鍵入以打印sizeof()
信息。例如
cout<<sizeof(A[0]) <<" "<<sizeof(&A) <<" "<<sizeof(*A) <<" "<< sizeof(A);
第二個嘗試使用打印下一個位置地址:
cout<<(A[0] + 1)<<" "<<(&A + 1) <<" "<<(*A + 1)<<" "<<(A + 1);
對於更詳細的解釋,一定要讀這answer。
是啊,我不知道爲什麼這個問題有一個[c]標籤。在C中沒有'std :: cout'。 –
對不起編輯我的答案! – haccks
這不是C的問題.C中沒有'std :: cout'。 –
A [0]這相當於*(A + 0),或更簡單地* A。
& A是多一點棘手。 A的類型爲int [5] [5],它由堆棧上的100個字節的連續區域表示。 A的地址是該區域的開始 - 這等於指向第一個元素的指針。第一個元素地址也是* A的存儲位置。
你怎麼知道它是100字節? – 2013-07-12 20:40:02
是的,解釋一下。請....... – haccks
來吧......不是標準的,而是在所有非DSP非嵌入式平臺上存在sizeof(int)== 4'。這些評論會有點用處:*你正在假設一個架構,其中sizeof(int)== 4 * *。順便說一句,Norwæ,你假設32位整數! –
的陣列,在其最基本的水平,是一個指針,指向存儲器中的點。數組中的其他元素是元素之後連續存儲和索引告訴計算機如何很多地方,從第一個元素跳得到所需之一。A[0]
被打印出的第一個元素的地址的第一行中,&A
正在打印是A位於地址,這是在第一行的第一個元素是,和*A
相同A[0]
。
首先要明白的是你要打印的內容:
cout<<A[0]<<" "<<&A<<" "<<*A;
表達A[0]
左值表達式類型int[5]
指內A
第一內部陣列,&A
是int (*)[5][5]
類型的右值,表達式指向數組A
。最後*A
相當於A[0]
,即int[5]
類型的左值表達式。
沒有在語言定義的運營商(你也不能爲他們提供),將轉儲無論是int[5]
或int (*)[5][5]
,所以編譯器將嘗試查找最好匹配它可以和認爲,沒有一個操作符打印一張void*
。 int[5]
可以衰變成一個int*
引用A[0][0]
,那就是本身轉化成void*
。 int (*)[5][5]
是一個指針,因此可轉換爲void*
,所以過載對兩種情況均有效。
該語言定義了內存中數組的佈局,特別是它要求數組和陣列的第一個元素佈局在同一個內存地址中,所以如果要打印地址&A
和&A[0]
它將打印相同的值,並且因爲&A[0]
也是在其第一元件的同一存儲器位置,&A[0][0]
也指相同的地址。
讓我們再回到上面的代碼要打印的是:
cout<< static_cast<void*>(&A[0][0])
<< " " << static_cast<void*>(&A)
<< " " << static_cast<void*>(&A[0][0]);
其按照上述推理必須具有相同的精確值,即使類型不是在第二種情況下是相同的。
什麼是你期待它打印? –
這已經被問過。 'A [0]'是第一個元素,它衰減成要打印的指針,'&A'是地址,它是相同的地址,而'* A'與第一個地址相同。 – chris
那麼A [0]顯示A [0] [0]的地址? –