在《C程式設計語言》的第5.7章至第5.9章中,在處理多維陣列、指標陣列等問題時,我想出了以下看法:
如果在下面的代碼中,foo被宣告為一個char陣列的指標,而我后來想給它分配一個char型別的指標。
如果在下面的代碼中,foo被宣告為一個指向char陣列的指標,而我后來想給它分配一個char型別的指標,我必須在字串字面前加上一個&符號。然而,如果我將bar宣告為一個指標,那么無需&符號就可以進行同樣的操作。
char (*foo)[3]; //創建一個指向大小為3的char陣列的單一指標。
char *bar; //創建一個指向char的單指標。
int main()
{
foo = &"AB"/span>。
bar = "AB";
return 0;
反匯編(64位Macho-O)似乎(至少在初學者眼里)對兩個任務都進行了相同的操作:
反匯編部分__TEXT,__text。
0000000100003f80 _main:
100003f80: 55 push rbp
100003f81: 48 89 e5 mov rbp, rsp
100003f84: 31 c0 xor eax, eax
100003f86: 48 8d 0 d 7b 00 00 00 Lea rcx, [rip 123] //'bar'的地址 100003f8d: 48 8d 15 6c 00 00 00 lea rdx, [rip 108] //'foo'的地址
100003f94: c7 45 fc 00 0000 00 mov dword ptr [rbp - 4] 。0 0
100003f9b: 48 8d 35 08 00 00 00 lea rsi, [rip 8] //地址指向'AB'-String
100003fa2: 48 89 32 mov qword ptr [rdx], rsi ///將'AB'的地址存盤在'foo'中
100003fa5: 48 89 31 mov qword ptr [rcx], rsi //span> 存盤'AB'的地址在'bar'中
100003fa8: 5d pop rbp
100003fa9: c3 ret
反匯編部分__TEXT,__cstring。
0000000100003faa __cstring:
100003faa: 41 42 <unknown>
100003fac: 00 <unknown>
反匯編部分__DATA,__common。
0000000100004000 _foo:
...
0000000100004008 _bar:
...
由于我讀的這本書是我第一次接觸C語言,我擔心我在這里錯過了一些明顯的東西。如果我在兩種情況下都需要&符號,這不是更符合邏輯嗎?
uj5u.com熱心網友回復:
在C語言中,一個字串字面的型別是 "char陣列",其大小等于包括結束的空位元組的字符數。 這意味著"AB"的型別是char [3]。
在大多數情況下,當一個陣列被用于運算式中時,它將衰減為指向第一個元素的指標。 這就是發生在bar = "AB"的情況。 右邊的字串常數衰減為char *型別,可以直接分配給bar。
當陣列是&運算子的主體時,這種衰減不會發生的情況之一。 所以從一個char [3]型別的陣列的地址中得到一個char (*)[3]型別的指標,這個指標與foo的型別相符。
uj5u.com熱心網友回復:
好的,讓我們假設每個"AB"的實體都存盤在記憶體位置0xDEADBEEF。運算式"AB"是一個陣列運算式,在大多數情況下將回傳其第一個元素的地址。兩個明顯的例外是&和sizeof運算子。在& "AB"和sizeof "AB"中,陣列將被視為一個陣列,而不是其第一個元素的地址。
char (*foo)[3] = & "AB";將(在大多數架構上)初始化foo的值0xDEADBEEF,這是"AB"的地址。在運算式& "AB"中,陣列"AB"被視為一個陣列,而&回傳其地址。
char *bar = "AB";將初始化bar指向A,你猜怎么著,在大多數架構上這將是與"AB"相同的地址,即0xDEADBEEF。在這里,陣列"AB"被轉換為其第一個元素的指標。
所以foo和bar都指向同一個記憶體位置,但是指向不同的物件。foo指向的是一個由3個位元組組成的序列,但是bar指向的是一個單一的位元組。
由于foo指向一個陣列,運算式*foo就是foo指向的陣列。在大多數情況下,陣列運算式產生一個指向陣列中第一個元素的指標,所以在運算式**foo中,子運算式*foo是陣列"AB"(型別為char[3]),但是被轉換為指向A(型別為char *)的指標。*foo前面的第二個*解除對A指標的參考,并回傳A
總結一下:
。foo是一個指向char[3];的指標,其值為0xDEAFBEEF*foo是foo指向的陣列,它是"AB",其型別是char[3]在大多數情況下,
。*foo被轉換為char *,其值仍為0xDEADBEEF作為上一點的例外,在運算式
&*foo和sizeof *foo中,*foo沒有被轉換,而是保持"AB"。像這樣對
*foo進行遞回**foo,將回傳A(foo==0xDEADBEEF,*foo=="AB"->0xDEADBEEF==bar,**foo==*0xDEADBEEF==*bar='A)
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/315466.html
標籤:
下一篇:我如何獲得指向結構末尾的指標?
