這個聲明
char (*p_arr)[1] = &arr;
不正確,因爲聲明的指針和初始值設定項具有不兼容的類型。沒有從類型char (*)[5]
(初始化程序的類型)到類型char (*)[1]
(已聲明指針的類型)的隱式轉換。所以你需要一個明確鑄造,重新詮釋一個類型的指針作爲另一種類型的指針,例如
char (*p_arr)[1] = (char (*)[1])&arr;
至於那麼你的問題,如果你有T
類型的對象,其中T
是某種類型的
T obj;
和一個指向對象像
T *ptr = &obj;
然後表達*ptr
或ptr[0]
產生T
類型的參考對象。
因此,讓我們假設你有下面的聲明
char arr[5] = {'A', 'E', 'I', 'O', 'U'};
char (*p_arr)[5] = &arr;
對於類型char[5]
即變量arr
你可以引入一個typedef名稱的類型。
typedef char T[5];
然後聲明將看起來像
T arr = {'A', 'E', 'I', 'O', 'U'};
T *p_arr = &arr;
,因爲它是表達*p_arr
或p_arr[0]
產生類型T
即類型char[5]
的被引用對象如上所述。
來自C標準(6.5.3。2地址和間接運算符)
4一元*運算符表示間接。如果操作數指向一個 函數,則結果是一個函數指示符;如果它指向一個 對象,則結果是指定該對象的左值。如果操作數 的類型爲''指向類型'',則結果的類型爲''type''。如果 無效值已分配給指針,則一元運算符*的操作未定義。
和(6.5.2.1數組下標)
2後綴表達式,隨後在方括號表達式[]是一個數組對象的元素的下標指定。 下標運算符[]的定義是E1 [E2]等於(*((E1)+(E2)))。由於適用於二元運算符的轉換規則,如果E1是一個數組對象(等同於一個指向數組對象的初始元素的指針)並且E2是一個整數,則E1 [E2]指定第E2個元素的E1(從零開始計數)。
,最後(6.5.6加法運算符)
7對於這些操作符的目的,的指針的對象 不是數組的元素的行爲相同的指針 長度爲1的數組的第一個元素與對象的類型爲 其元素類型爲。
所以在此聲明
char arr[5] = {'A', 'E', 'I', 'O', 'U'};
char (*p_arr)[5] = &arr;
指針p_arr
不指向的數組元素。然而,它可以表現爲它指向長度1的陣列的第一個元素可以想像它通過以下方式
char arr[1][5] = { {'A', 'E', 'I', 'O', 'U'} };
char (*p_arr)[5] = arr;
所以表達式p_arr[0]
給出了設想的二維數組,它是一個的第一個元素char[5]
類型的元素。
我的不好,我把原來的問題分成兩部分,忘記把'char(* p_arr)[1] = &arr;'改成'char(* p_arr)[5] = &arr;'這個部分。但是,'char(* p_arr)[1] = &arr;'不會產生任何編譯錯誤(請參閱我的[其他問題](https://stackoverflow.com/questions/46687759/pointer-to-2d-array-with - 不兼容的行長度)),我不明白爲什麼。 –
(C編譯器不會阻止你想做什麼。)用'-Wall'選項編譯它。 – BLUEPIXY
我做了代碼更改的回滾。答案發布後請不要修復你的代碼。通過修復它,你使大多數答案無關緊要。相反,如果您有後續問題,請提出一個新問題(與您一樣)。 – Lundin