如果我想初始化一個指向陣列的 int 指標,我需要使用這個表示法:
int data[] = {34,35,36};
int *ptr = &data[0];
因為變數的型別data是int[],這就是下一個宣告給出警告的原因:
int *ptr = &data;
在上面的例子中,我將一個“陣列型別”分配給一個 int 指標,這是一個錯誤并且沒關系。那么,為什么可以使用下一個代碼在陣列中進行迭代:
for(int i=0;i<3;i )
*(data i);
上面這行應該做的是在每次迭代中添加完整陣列的大小,正確的代碼應該如下所示:
for(int i=0;i<3;i )
*(&data[0] i);
但是如果我們測驗它們,它們都是相等且正確的,可以在陣列中迭代。
那么,變數資料的型別(單獨,不帶[])應該認為是int[]還是int?我怎么知道一個變數什么時候會有一種或另一種型別來做正確的指標演算法。
uj5u.com熱心網友回復:
來自 C 標準(6.5.2.1 陣列下標)
2 后綴運算式后跟方括號 [] 中的運算式是陣列物件元素的下標名稱。下標運算子[]的定義是E1[E2]等同于(*((E1) (E2)))。由于適用于二元 運算子的轉換規則,如果 E1 是陣列物件(等效地,指向陣列物件的初始元素的指標)并且 E2 是整數,則 E1[E2] 指定第 E2 個元素E1(從零開始計數)。
和(6.3.2.1 左值、陣列和函式指示符)
3 除非它是 sizeof 運算子或一元 & 運算子的運算元,或者是用于初始化陣列的字串字面量,否則型別為 ''array of type'' 的運算式將轉換為型別為 ''pointer 的運算式鍵入指向陣列物件的初始元素且不是左值的''。如果陣列物件具有暫存器存盤類,則行為未定義。
因此在這個運算式中
*(data i)
該陣列data被隱式轉換為指向其第一個元素的指標。并且運算式等價于data[i]or i[data]。
所以運算式
*(&data[0] i);
可以重寫為
*(&*( data 0 ) i);
那是一樣的
*( data 0 i);
反過來作為
*( data i);
同樣在指標的宣告中
int *ptr = &data[0];
你可以寫
int *ptr = data;
uj5u.com熱心網友回復:
行。閱讀您的評論后,我發現了“陣列衰減”的概念。陣列名自然衰減為指向陣列型別的指標;例如,如果我宣告int data[5],大多數時候的型別data將是int*,但這種衰減也有一些例外。這里有更多資訊:陣列衰減的例外
我的困惑由此而來:有時當我使用陣列時,它會衰減,而其他時候則不會。
uj5u.com熱心網友回復:
在大多數情況下,只要在運算式中使用陣列名稱,它就會衰減為指向其第一個元素的指標。因此int *ptr = &data[0];100% 等于int *ptr = data;。
至于訪問陣列的單個專案,或者通過指向第一個元素的指標指向的陣列,arr[i]100% 等同于*(arr i),后者只是不必要地難以閱讀。請參閱指標是否支持“陣列樣式索引”?
但是,提到的陣列衰減規則的一個例外是當陣列名稱用作運算&符的運算元時。在這種情況下,它不會衰減——相反,我們得到一個指向“整個陣列”的指標。在你的情況下int *ptr = &data;是一個無效的指標轉換,因為&data它的型別int(*)[3]是指向陣列的指標。
但是請注意,在運算式&data[i]中,運算子優先級表示與運算元相比[]“系結更緊密” 。所以它等價于。前面提到的陣列衰減例外不適用,因為它從不應用于陣列名稱,而是應用于陣列中的一個專案。當我們到達 時,陣列衰減到指向第一個元素的指標已經發生,因為它發生在遇到的點。data&&(data[i])&&[]
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/417724.html
標籤:
