簡體   English   中英

通過指針訪問數組

[英]Accessing array by pointers

let int * ptr,array[10]; ptr= array; int * ptr,array[10]; ptr= array; 現在,陣列連續位置中的每個存儲單元都具有固定大小。 如果第一個單元格的地址為1234,則下一個單元格的地址必須為1238。 但是我們使用指針作為*(ptr+1)來訪問它。 我對此感到困惑。 有任何資料或答案嗎? 謝謝。

根據C11 標准: §6.5.2.1

表達式后跟方括號[]是數組對象元素的下標名稱。 下標運算符[]的定義是E1 [E2]與(*((E1)+(E2)))相同。 由於適用於二進制+運算符的轉換規則,如果E1是一個數組對象(相當於一個指向數組對象的初始元素的指針),而E2是一個整數,則E1 [E2]指定E1的第E2個元素E1(從零開始計數)。

EG您在做什么基本上是[]已經在做什么

另外(相同的標准)解釋了為什么指針會如您注意到的那樣遞增:§6.5.6

將具有整數類型的表達式添加到指針或從指針中減去時,結果將具有指針操作數的類型。 如果指針操作數指向數組對象的元素,並且數組足夠大,則結果指向與原始元素偏移的元素,以使結果數組元素和原始數組元素的下標之差等於整數表達式。 換句話說,如果表達式P指向數組對象的第i個元素,則表達式(P)+ N(相當於N +(P))和(P)-N(其中N的值為n)表示到數組對象的第i + n個元素和第i-n個元素(如果存在)。 此外,如果表達式P指向數組對象的最后一個元素,則表達式(P)+1指向數組對象的最后一個元素之后,如果表達式Q指向數組對象的最后一個元素之后,表達式(Q)-1指向數組對象的最后一個元素。 如果指針操作數和結果都指向同一數組對象的元素,或者指向數組對象的最后一個元素之后,則求值不應產生溢出; 否則,行為是不確定的。 如果結果指向數組對象的最后一個元素之后,則不應將其用作被評估的一元*運算符的操作數。

編譯器知道ptr是指向4字節類型的指針,因此它知道ptr+1在內存中還有4個字節。

如果您想一會兒,很顯然這一定是這樣,否則您將無法在不知道(例如)系統中整數大小的情況下編寫可移植代碼。

此外,數組索引是幕后的精確指針算法-也就是說, array[3]*(array + 3)完全相同

在為指針建立索引時,編譯器知道索引應按單元格的大小(在這種情況下為4字節的指針)前進。

指針算術考慮指針類型的大小。 例如,如果ptr值為1234 ,則由於ptr的類型為int* ,則p + 1值為1234 + 1 * sizeof(int) == 1234 + 1 * 4 = 1238 (假設sizeof(int) == 4 )。

+運算符的右側操作數(稱為x)不是您要移動指針的實際量。 因為int是4個字節,所以編譯器知道實際上會跳到x * 4。

指針算術的單位是指向對象,而不是字節。

如果p指向int對象,則p+1p+2p+3指向連續的int對象,而不是連續的字節。 如果p指向大型結構,則它們指向該結構的連續實例。

編譯器在后台進行工作,將指針算法轉換為機器地址算法。 因此,它會根據需要乘以偏移量,以將對象單位轉換為字節單位。

我的猜測是,根據您的意見(ptr + 1)應該會給您1235但顯然沒有。

除了其他人為什么將其加4並給您1238的答案外,請考慮是否給了1235 ,在1235您沒有整數元素(即數組的第二個元素)。 但是您的指針應該指向一個整數。 因此,這種方式行不通。

指針算術是與普通算術不同的運算。 在指針算術中,一個參數必須是指針類型,另一個參數必須是整數類型:

  1. intA + intB :正常算術,結果為和。
  2. intA + pointerB :指針算術,執行的計算為sizeof(*pointerB)*intA + pointerB
  3. pointerA + intB :指針算術,執行的計算為pointerA + sizeof(*pointerA)*intB
  4. pointerA + pointerB :非法

pointerA[intB]只是情況2( pointerA + intB )的簡寫,這就是為什么它等效於intB[pointerA] (解決情況3)的原因,但這僅在IOCCC中使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM