2014-05-24 129 views
1
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陣列和指針

+0

你在問爲什麼*(stud + 1),stud + 1打印相同的值? –

+0

是的,stud [0]和&stud [0]也打印相同的值。 – bullseye

+0

究竟是什麼都不打印子數組的實際內容,以防萬一不明顯。如果您要打印地址,請使用'%p'作爲輸出。 – WhozCraig

回答

1

在不使用任何衰減語法可能是更清晰的(這些都是作爲代碼相同的地址;所述第一線是在相反的順序;以及我的括號是多餘的,但希望它提高該實施例的清晰程度):

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]

+0

+1我說的是,但在1/8左右的空間。我真的需要學習何時將其包裝= P – WhozCraig

0

由於您試圖顯示的所有這些值都是指針,因此應該使用%p而不是%u。如果你這樣做,你會看到地址指出:

printf("%p, %p", &stud,stud); 

是不同於:

printf("%p %p",*(stud+1),stud+1); 

,因爲如你所說stud是一個指向數組的數組。

2

對於表達式都是地址結果,您的觀察結果是正確的。但每個標準的那些地址的類型是不同的。你的短語「但是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; 
} 
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數組的地址。因此他們打印相同的地址。

類似的解釋將適用於其他情況。

2
int stud[5][2] = {{1,2},{3,4},{5,6},{7,8},{9,8}}; 

上述語句中定義stud5元素,其中每個元素是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)評估到相同的地址,但它們不是相同的類型。

同樣,&studstud衰減到相同的地址,但它們是不同的類型。 stud的類型爲int[5][2],其中&stud的類型爲int (*)[5][2]

爲什麼這個語句打印相似的值,螺柱[1]或*(螺柱+ 1)實際上是一個數組因此必須得到的基地址即&螺柱[0] [0],但 螺柱本身是一個指向數組數組的指針。

你錯了。 stud[1]*(stud + 1)的基地址是&stud[1][0]而不是&stud[0][0]。另外,stud不是指針,而是數組類型。在某些情況下,它衰減爲指向其第一個元素的指針,但這確實意味着它是一個指針。

另外,您應該使用%p轉換說明符來打印地址。