我想對一些讓我對 C 中的陣列和指標感到困惑的事情有一些進一步的理解,并可能得到澄清。讓我感到困惑的主要事情之一是當您參考陣列的名稱時,它可能是指陣列,或者是指向第一個元素的指標,以及其他一些東西。為了更好地展示我的理解困難來自哪里,我將展示幾行代碼,以及我從每一行中得出的結論。
假設我有
int vals[] = {1,50,3,28,32,500};
int* valptr = vals;
因為 vals 是指向陣列第一個值的指標,所以這意味著 valptr 應該等于 vals 作為一個整體,因為我只是將指標設定為等于指標,例如 1=1。
cout<<vals<<endl;
cout<<&vals<<endl;
cout<<*(&vals)<<endl;
cout<<valptr<<endl;
上面的代碼列印出相同的值,導致我得出兩件事,一件事是 valptr 和 vals 相等,并且可以以相同的方式處理,以及由于某種原因添加 & 和 * 到vals 似乎沒有指代任何不同的東西,這意味著以這種方式使用它們是沒有用的,因為它們都指代相同的值。
cout<<valptr[1]<<endl;//outputs 50
cout<<vals[1]<<endl;//outputs 50
cout<<*vals<<endl;//outputs 1
cout<<*valptr<<endl;//outputs 1
上面的代碼進一步加深了我的心態,即 valptr 和 vals 是相同的,因為每當我對 vals 做某事并對 valptr 做同樣的事情時,它們都會產生相同的結果
cout<<*(&valptr 1)-valptr<<endl;
cout<<endl;
cout<< *(&vals 1) -vals<<endl;
既然我們已經確定了我所知道的,或者我可能有的誤解,現在我們繼續討論我遇到的兩個主要問題,我們現在將討論它們。
我的第一個困惑是cout<< *(&vals 1) -vals<<endl;我知道這會輸出陣列的大小,以及它如何作業的一般概念,但我對幾個部分感到困惑。如前所述,如果
cout<<vals<<endl;
cout<<&vals<<endl;
cout<<*(&vals)<<endl;
所有都列印出相同的值,為什么我需要 * 和 &cout<< *(&vals 1) -vals<<endl;我知道如果我這樣做vals 1只是指陣列中下一個元素的地址,這意味著*(vals 1)回傳 50。這讓我想到了我的第一個問題:為什么 & in*(&vals 1)指的是陣列中的下一個地址?為什么它的輸出(vals 1)與方式不同*(&vals)并且(vals)具有相同的輸出?
現在到我的第二個問題。我們知道這cout<< *(&vals 1) -vals<<endl;是一個有效的陳述句,成功列印了陣列的大小。但是,正如我之前所說,在其他所有情況下,valptr都可以vals互換。然而,在寫作的例子中,cout<<*(&valptr 1)-valptr<<endl;我得到了 0,而不是預期的 6。以前被證明可以互換的東西,怎么可能在這種情況下不再可以互換?
我感謝任何閱讀本文的人可以給我的任何幫助
uj5u.com熱心網友回復:
陣列和指標是 C 中的兩種不同型別,它們之間有足夠的相似性,如果沒有正確理解它們會造成混淆。指標是初學者最難掌握的概念之一這一事實也無濟于事。
所以我覺得快速速成課程是必要的。
速成課程
陣列,簡單
int a[3] = {2, 3, 4};
這將創建一個名為的陣列a,其中包含 3 個元素。
陣列定義了陣列下標運算子:
a[i]
計算為i陣列的第 ' 個元素。
指標,簡單
int val = 24;
int* p = &val;
p是一個指向物件地址的指標val。
指標定義了間接(取消參考)運算子:
*p
計算為 指向的物件的值p。
指標,就像陣列一樣
指標為您提供記憶體中物件的地址。它可以是上面示例中的“獨立物件”,也可以是作為陣列一部分的物件。指標型別和指標值都不能告訴你它是哪一種。只是程式員。這就是為什么
指標還定義了陣列下標運算子:
p[i]
計算.i指向的物件“右側”的第 th 個元素p。這假定物件指標 byp是陣列的一部分(除非p[0]它不需要是陣列的一部分)。
請注意,p[0]等效于 ( 完全相同) *p。
陣列,就像指標一樣
在大多數情況下,陣列名稱衰減為指向陣列中第一個元素的指標。這就是為什么許多初學者認為陣列和指標是一回事。事實上他們不是。它們是不同的型別。
回到您的問題
因為 vals 是指向陣列第一個值的指標
不,這不對。
...那么這意味著 valptr 應該等于整個 vals,因為我只是將指標設定為等于指標,例如 1=1。
因為前提是假的,所以句子的其余部分也是假的。
valptr 和 vals 相等
不,他們不是。
可以用同樣的方法處理
大多數時候是的,因為陣列到指標衰減。然而,情況并非總是如此。例如,作為(地址)運算子的運算式sizeof和運算元。&
為什么 & in
*(&vals 1)指的是陣列中的下一個地址?
&valsvals這是不衰減到指標的少數情況之一。&vals是陣列的地址并且是型別int (*)[6](指向 6 個整數陣列的指標)。這就是為什么&vals 1一個假設的另一個陣列的地址就在陣列的右邊vals。
以前被證明可以互換的東西怎么可能在這種情況下不再可以互換?
簡單來說就是語言。在大多數情況下,陣列的名稱衰減為指向陣列第一個元素的指標。除了我提到的幾種情況。
更多速成課程
指向陣列的指標與指向陣列第一個元素的指標不同。獲取陣列的地址是陣列名稱不會衰減為指向其第一個元素的指標的少數實體之一。
&a指向陣列的指標也是如此,而不是指向陣列第一個元素的指標。陣列和陣列的第一個元素都從相同的地址開始,因此兩者 (&a和&a[0]) 的值相同,但它們的型別不同,當您對它們應用解參考或陣列下標運算子時,這很重要:
| 表達 | 運算式型別 | 解參考/陣列下標 運算式 |
解參考/陣列下標 型別 |
|---|---|---|---|
a |
int[3] |
*a/a[i] |
int |
&a |
int (*) [3] (指向陣列的指標) |
*&a/&a[i] |
int[3] |
&a[0] |
int * |
*&a[0]/(&a[0])[i] |
int |
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/429324.html
上一篇:為什么在將make_unique與陣列一起使用時編譯器會出錯?
下一篇:curl使用摘要標志獲取
