2012-12-02 74 views
2

可有人請解釋如何陣列被它的名字所引用,在下面的代碼前面加上指針,雙指針到它的名字一樣:瞭解指針和數組

#include<stdio.h> 

main() 
{ 
    int a[3][2]; 
    a[0][0]=15; 
    a[0][1]=150; 
    a[1][0]=115; 
    a[1][1]=165; 
    a[2][0]=135; 
    a[2][1]=139; 
    printf("%u\n", a); 
    printf("%u\n", *a); 
    printf("%u\n", **a); 
} 
+0

請更好地解釋你的問題。我只看到代碼是無效的(前兩個'printf'語句)。 –

+0

可能重複的[是數組名稱中的一個指針?](http://stackoverflow.com/questions/1641957/is-array-name-a-pointer-in-c) – WhozCraig

回答

5

第一個

printf("%u\n",a); 

打印的地址爲a,與第一個元素的地址相同。

第二個

printf("%u\n",*a); 

解除引用a並給出a

第一 「行」 和地址的第三個

printf("%u\n",**a); 

取消引用指針到第一「行「a,並給出了這個二維數組中的第一個元素的值。

當您編譯您的示例並打開警告時,編譯器已經發出抱怨,因此請告訴您一些您使用的類型。當你指點作爲參數傳遞給printf,你應該使用的格式說明%p

printf("%p\n",a); 
printf("%p\n",*a); 

格式說明%uunsigned int,如果你有int,最好使用符%d

printf("%d\n",**a); 
+0

請注意,它是不正確的使用' %1「和」2「。 –

+0

在前兩種情況下,printf(」%u \ n「,a/* a)應該是'printf(」%p \ n「,a/* a)'。它應該是'printf(「%d \ n」,** a);'在最後一種情況下。請考慮更新答案以添加此內容。 – axiom

+1

而且,爲了學習,指針應該被轉換爲「void *」。在指向不同類型的指針具有不同大小的平臺上,這實際上很重要(但這些平臺可能是假設的)。 –

3

兩個a*a是指針,因此將其打印在格式化輸出中,如printf()使用%p作爲格式說明符。

否則你將得到警告你的編譯器的消息說

warning: format ‘%x’ expects type ‘unsigned int’, but argument 2 has type ‘int (*)[2]’ warning: format ‘%x’ expects type ‘unsigned int’, but argument 2 has type ‘int *’

所以試試這個:

printf("%p\n",a); 
printf("%p\n",*a); 

對於第三種情況**aint型的,因此最好使用%d%i

printf("%d\n",**a); 

根據C標準,

ISO c99 standard : 7.19.6 Formatted input/output functions 

9 If a conversion specification is invalid, the behavior is undefined. 

    If any argument is not the correct type for the corresponding conversion 

    specification, the behavior is undefined. 
0

它像如果是地址比* a是一個

enter image description here

0

值除了當它是的sizeof_Alignof操作數,或一元&運算符,或者是在聲明中用於初始化另一個數組的字符串文本,則類型爲「T」的「N元素數組」的表達式將轉換(「衰減」)爲「指向T的指針」類型的表達式,並且表達式的值將是該數組的第一個元素的地址。

在第一個printf調用中,表達式a具有類型爲「3元素數組的2元素數組int」;通過上面的規則,表達式將被轉換爲「指向2元素數組的012指針」(int (*)[2]),其值與&a[0]相同。

在第二個printf調用中,表達式*a具有類型「int」的2元素數組;通過上述規則,表達式轉換爲類型「指向int」(int *)的指針,其值將與&a[0][0]相同(與&a[0]相同 - 數組的第一個元素的地址相同作爲數組本身的地址)。

在第三printf呼叫時,表達**a具有類型int,並且它的值是什麼存儲在a[0][0](15在這種情況下)。

0

檢查類型是有啓發性的。

a具有類型int [3][2],即具有2個整數的3個陣列的陣列。但是,數組類型不能在C中分配或傳遞。當通過aprintf時,發生什麼情況是降級爲指向其第一個參數的指針,即&a[0],其類型爲int (*)[2],即指向數組2個整數。這是你看到的地址。 (當然,數組的第一個參數的地址也與數組本身的地址相同,所以如果你做了printf("%u", &a);,你會看到相同的地址值(但是類型會有所不同 - - &a將具有類型int (*)[3][2])。)

接下來,*a。您只能取消引用指針,因此a首先被降級爲指針(&a[0]),然後取消引用(*&a[0])。結果是a[0],第一個元素aa[0]具有類型int [2],即2個整數的數組。再次如上所述,數組無法傳遞,所以當您將它傳遞給printf時,這會降級爲指向其第一個參數的指針,即&a[0][0],其類型爲int *,指向int的指針。這是你看到的第二個地址。同樣地,它將與上述地址相同,因爲a[0]的地址與其第一個元素地址a[0][0](但類型不同)相同。

最後,你有**a。如上所述,*aa,退化,然後解除引用。請記住,*a的數組類型爲int [2]。與a一樣,當您解引用它時,它會在將其解除引用之前隱式降級爲指針。所以**aa,退化,解除引用,退化和解除引用。對發生的事情更明確的描述是*&(*&a[0])[0]。最終結果爲a[0][0],其類型爲int