int stud[5][2] = {{1,2},{3,4},{5,6},{7,8},{9,8}};
printf("%u %u",*(stud+1),stud+1);
printf("%u, %u", &stud,stud);
爲什麼這個語句打印相似的值,螺柱[1]或*(螺柱+ 1)實際上是一個數組因此必須得到的基地址即&螺柱[0] [0],但螺柱本身是一個指向數組數組的指針。第三條語句也輸出相同的值。2D陣列和指針
int stud[5][2] = {{1,2},{3,4},{5,6},{7,8},{9,8}};
printf("%u %u",*(stud+1),stud+1);
printf("%u, %u", &stud,stud);
爲什麼這個語句打印相似的值,螺柱[1]或*(螺柱+ 1)實際上是一個數組因此必須得到的基地址即&螺柱[0] [0],但螺柱本身是一個指向數組數組的指針。第三條語句也輸出相同的值。2D陣列和指針
在不使用任何衰減語法可能是更清晰的(這些都是作爲代碼相同的地址;所述第一線是在相反的順序;以及我的括號是多餘的,但希望它提高該實施例的清晰程度):
printf("%p %p\n", &(stud[1]), &(stud[1][0]));
printf("%p %p\n", &(stud), &(stud[0]));
在這兩種情況下,行上的第一個地址都與第二個地址匹配,因爲數組的第一個元素與數組位於同一地址。數組不能有初始填充,而在C中,對象的地址是其第一個字節的地址。
stud
的第一個元素是stud[0]
,並且stud[1]
的第一個元素是stud[1][0]
。
+1我說的是,但在1/8左右的空間。我真的需要學習何時將其包裝= P – WhozCraig
由於您試圖顯示的所有這些值都是指針,因此應該使用%p
而不是%u
。如果你這樣做,你會看到地址指出:
printf("%p, %p", &stud,stud);
是不同於:
printf("%p %p",*(stud+1),stud+1);
,因爲如你所說stud
是一個指向數組的數組。
對於表達式都是地址結果,您的觀察結果是正確的。但每個標準的那些地址的類型是不同的。你的短語「但是stud本身是一個指向數組數組的指針」。不準確。 stud
是一組數組。指針是而不是陣列。經過幾十年的努力想出一個堅實的白話來描述它是如何工作的,並且堅決拒絕走「衰退」板(在C標準中恰好出現一個一個次,甚至在那裏它被用作動詞-footnote),我能想到的最好的是:
指針不是數組。指針保存了的地址。數組是的地址。
每個表達式如下所示鑑於int stud[5][2];
stud int (*)[2]
stud+1 int (*)[2]
*(stud+1) int *
&stud int (*)[5][2]
記住的是,根據標準中,陣列的表達值是它的第一個元件的地址,和指針到元件型是所述地址的類型。在兩個輸出中,每對錶達式都有相同的地址,但它們是不同的類型。這是可驗證與原始代碼的一些擴展:
#include <stdio.h>
int main()
{
int stud[5][2] = {{1,2},{3,4},{5,6},{7,8},{9,8}};
printf("%p %p\n", *(stud+1), stud+1);
printf("%p %p\n", &stud,stud);
int (*p1)[2] = stud+1; // OK
// int (*p2)[2] = *(stud+1); // incompatible types
int *p3 = *(stud+1); // OK
int (*p4)[5][2] = &stud; // OK
return 0;
}
允許分析程序
int stud[5][2] = {{1,2},{3,4},{5,6},{7,8},{9,8}};
查閱地址將是這樣的(假設2字節整數)。括號表示數組中的相應元素。
1 element of 2-D array ---> 4001(1) 4003(2)
2 element of 2-D array ---> 4005(3) 4007(4)
3 element of 2-D array ---> 4009(5) 4011(6)
4 element of 2-D array ---> 4013(7) 4015(8)
5 element of 2-D array ---> 4017(9) 4019(8)
我們知道arr [i]給出數組的第i個元素。所以當我們說stud [0]時,我們期望數組stud[5][2]
的第0個元素。我們可以假設二維數組作爲一維數組的集合。所以像printf("%u",stud[0])
這樣的聲明,我們將顯示第0個要打印的元素,以及這個數組的第0個元素是什麼。它是一維數組。我們知道,只提一維數組給出了其基地址。因此,printf
將打印第0個一維數組的基地址,依此類推。
有了這些信息,我們可以分析您的問題。
記住螺柱是二維陣列。 stud
被視爲指向二維數組的第零個元素的指針。所以(stud + 1)
會給出二維數組的第二個元素的地址。因而打印(stud+1)
會打印柱陣列第二元素的地址。它是什麼。從上面的地址將是4005。
現在讓我們看看爲什麼*(stud +1)也給出相同的值。我們知道*(stud +1)
相當於stud[1]
。從上面我們知道stud [1]會打印第二個一維數組的基地址。什麼是一維數組在第二個位置是(3,4)的地址是(4005,4007)。那麼基地址是什麼?它是4005.因此*(stud+1)
也打印4005.
現在你說stud[0] and &stud[0]
打印相同的值。
從上面的stud [0]是一維數組並打印出它的基地址。現在所以& stud [0]應該給出與其基地址相同的1-D數組的地址。因此他們打印相同的地址。
類似的解釋將適用於其他情況。
int stud[5][2] = {{1,2},{3,4},{5,6},{7,8},{9,8}};
上述語句中定義stud
爲5
元素,其中每個元素是int[2]
類型,即,2
整數數組的數組。它還使用初始化程序列表初始化數組。
現在,在表達式stud + 1
中,數組stud
衰減爲指向其第一個元素的指針。因此,stud + 1
評估爲&stud[1]
並且是int (*)[2]
類型,即指向整數的數組的指針。 *(stud + 1)
然後是*(&stud[1])
,即,stud[1]
。 stud[1]
又是一個數組類型,即int[2]
,所以它再次衰減到printf
調用中的第一個元素,即&stud[1][0]
(它是數組stud[1]
的第二元素的基地址)的指針。
請注意stud + 1
和*(stud + 1)
評估到相同的地址,但它們不是相同的類型。
同樣,&stud
和stud
衰減到相同的地址,但它們是不同的類型。 stud
的類型爲int[5][2]
,其中&stud
的類型爲int (*)[5][2]
。
爲什麼這個語句打印相似的值,螺柱[1]或*(螺柱+ 1)實際上是一個數組因此必須得到的基地址即&螺柱[0] [0],但 螺柱本身是一個指向數組數組的指針。
你錯了。 stud[1]
或*(stud + 1)
的基地址是&stud[1][0]
而不是&stud[0][0]
。另外,stud
不是指針,而是數組類型。在某些情況下,它衰減爲指向其第一個元素的指針,但這確實意味着它是一個指針。
另外,您應該使用%p
轉換說明符來打印地址。
你在問爲什麼*(stud + 1),stud + 1打印相同的值? –
是的,stud [0]和&stud [0]也打印相同的值。 – bullseye
究竟是什麼都不打印子數組的實際內容,以防萬一不明顯。如果您要打印地址,請使用'%p'作爲輸出。 – WhozCraig