2017-10-21 77 views
0

我有以下的(貌似無辜的)代碼:爲什麼我不能將一個指針的地址傳遞給一個固定大小的數組,而是將一個指針指向C中的一個指針?

void singleLeftPadZero(char**); 
int main() { 
    char foo[10] = "0"; 

    singleLeftPadZero(foo); // <-- causes warning 
    singleLeftPadZero(&foo); // <-- same exact warning, but different "note" 
} 

我從GCC得到警告是:

警告:從不相容 指針類型

過客 'singleLeftZeroPad' 的參數1

而對於第一種情況需要注意的是:

注:應爲「字符**」,但參數的類型「字符*」

的,我明白這意味着我需要一個指針傳遞給一個指針,但我只是路過的指針。因此,我添加了「&」我的說法,這導致了同樣的警告,但這注:

注:應爲「字符**」,但參數的類型爲「CHAR(*)[10]」

我做這看上去好像是固定的,是創建一個額外的變量: char* fooPntr = foo; 然後到該地址傳遞作爲函數參數: singleLeftPadZero(&fooPntr);但我不知道爲什麼這個作品!

+3

所以一個數組不是一個指針。然後,指向數組的指針不是指向指針的指針。 –

回答

1

你犯的錯誤是相信指針和數組是相同的東西。他們不是。在某些情況下,它們可以以相同的方式使用(與「他們是同一事物」完全不同),但不能用於其他情況。你的例子是在上下文中指針和數組是不同的東西,並且不能像使用相同的東西那樣使用。

在你的第一種情況下,通過首先執行「陣列到指針轉換」傳遞到foo作品singleLeftPadZero() - foo是10 char的陣列,並且被轉換爲char *類型的指針具有值等於&foo[0]。A char *不是char **,因此警告不兼容的類型和音符。

在第二種情況下,通過&foosingleLeftPadZero()不會執行轉換。相反,&foo的類型是「指向10 char的數組的指針」,或者(與來自編譯器的註釋一致)char (*)[10],它與「指向指向char的指針的指針」(這是char **。類型 - char (*)[10]char ** - 不是隱式轉換爲彼此

最後一種情況char* fooPntr = foo實際上相當於(多虧了陣列的foo指針轉換)char *fooPntr = &foo[0]換句話說,fooPntrchar *型的(因爲你。已經這樣聲明)並且包含單個地址char - 數組中的第一個字符foo。由於fooPntrchar *類型的變量,因此可以評估其地址&fooPntr,並且類型爲char **。這正是singleLeftPadZero()接受的功能,所以singleLeftPadZero(&fooPntr)有效。

1

陣列名稱foo衰減到char *,這是一個指向foo的第一個元素的字符指針。它不是char **這是一個指向指向內存位置的字符指針的字符指針。

您的數組是單維的。所以這是char *修改你的函數原型

void singleLeftPadZero(char*); 

由於數組名衰減的指針數組的第一個元素,foo本身是給出了一個地址。所以&foo意味着指向10個元素陣列的指針的地址,因此消息argument is of type ‘char (*)[10]’

char (*)[10]表示指向10個元素數組的字符指針。儘管數組名稱衰變爲指針,但指針和數組並不相同。看看here

相關問題