簡體   English   中英

重新初始化C語言的指針

[英]Reinitializing Pointers for C Language

我目前正在通過Dan Gookin的書《 Begining C Programming for Dummies》學習C編程。

我當前正在閱讀的主題之一是數組實際上是指針。 Dan嘗試使用以下代碼證明這一點:

#include <stdio.h>

int main()
{
    int numbers[10];
    int x;
    int *pn;

    pn = numbers;       /* initialize pointer */

/* Fill array */
    for(x=0;x<10;x++)
    {
        *pn=x+1;
        pn++;
    }

    pn = numbers;

/* Display array */
    for(x=0;x<10;x++)
    {
        printf("numbers[%d] = %d, address %p\n",
                x+1,*pn,pn);
        pn++;
    }

    return(0);
}

我的問題確實在第17行。我意識到,如果不再次像第17行那樣重新初始化指針,則在第二個for循環序列中顯示的指針pn的peek值就是一堆毫無意義的垃圾。 因此,我想知道為什么需要重新初始化指針pn才能使代碼按預期工作?

數組不是指針,但是C允許您將數組分配給數組變量類型的指針,其結果是該指針將指向數組的第一項。 這就是pn = numbers作用。

pn是指向int而不是數組的指針。 它指向一個整數。 當您增加指針時,它僅移至下一個存儲位置。 它進行的移位是指針類型的大小,因此在這種情況下為int

那么這證明了什么呢? 並不是數組是指針,而是數組是連續的內存塊,由N倍於數組項類型的大小組成。

當您運行第二個循環時,指針將到達一塊不再屬於該數組的內存,因此您將獲得“垃圾”,而這恰好是該位置上存在的信息。

如果要通過增加指針來再次遍歷數組,則必須重新初始化指向第一項的指針。 for循環只做一件事,計數為10。它不知道數組,也不知道指針,因此循環不會自動為您重置指針。

由於pn在第一個循環中遞增,因此在第一個循環結束后, pn將指向numbers數組之外的地址。 因此,您必須在第二個循環之前將pn初始化為數組的開頭,因為您使用相同的指針來打印內容。

因為您在以下代碼段中更改了pn++語句中pn中包含的地址。

for(x=0;x<10;x++)
    {
        *pn=x+1;
        pn++;
    }

pn指針用於指向numbers數組。

第一個for循環使用pn設置值,逐個數據地逐個遍歷pn 循環結束后, pn指向numbers的末尾(在未分配的第11個元素處)。

對於第二個for -loop工作,即利用pn通過回路numbers再次通過數組步進, pn需要移動到前面numbers數組,否則你會訪問內存,你不應該尋找在(未分配的內存)。

第一個數組不是指針。 當在函數調用中使用它們時,它們會衰減為指針,並且可以(幾乎)相同使用。

一些細微的差異

int a[5];      /* array */
int *pa = a;   /* pointer */

pa[0] = 5;
printf("%d\n", a[0]);   /* ok it is the same here */
printf("address of array %p - address of pointer %p, value of pointer\n",
    &a, &pa, pa); /* &a is the same as pa not &pa */
printf("size of array %d - size of pointer %d\n", sizeof(a), sizeof(pa));

sizeof(a)在這里是5 * sizeof(int)sizeof(pa)是指針的大小。

現在為您的問題:

在第一個循環之后, pn指向p[10]而不再指向p[0] 這就是為什么您必須重置它的原因。

只是為了指出要點,數組不是指針。 當您將numbers聲明為int numbers[10] ,您將在內存中得到以下內容:

         +---+
numbers: |   | numbers[0] 
         +---+
         |   | numbers[1]
         +---+
          ...
         +---+
         |   | numbers[9]
         +---+

沒有為單獨的指向numbers的第一個元素的指針留出空間。 發生的情況是,當表達式numbers出現在任何地方,並且不是 sizeof或一元&運算符的操作數時,它將被轉換(“衰減”)為“ pointer to int ”類型的表達式,並且expression是數組第一個元素的地址。

使用pn是將其設置為指向numbers的第一個元素,然后“遍歷”數組:

         +---+ 
numbers: |   | <------+ 
         +---+        |
         |   |        |
         +---+        |
          ...         |
         +---+        |
         |   |        |
         +---+        |
          ...         |
                      |
         +---+        |
     pn: |   | -------+ 
         +---+

表達式pn++ pn指向下一個整數對象,在這種情況下,它是數組的下一個元素:

         +---+ 
numbers: |   | 
         +---+ 
         |   | <------+
         +---+        |
          ...         |
         +---+        |
         |   |        |
         +---+        |
          ...         |
                      |
         +---+        |
     pn: |   | -------+ 
         +---+

每個pn++前進指針,直到在第一個循環結束時您具有以下內容:

         +---+ 
numbers: |   | 
         +---+ 
         |   | 
         +---+ 
          ...  
         +---+ 
         |   | 
         +---+ 
          ...  <------+
                      |
         +---+        |
     pn: |   | -------+ 
         +---+

此時, pn指向數組末尾之后的對象。 這就是為什么在下一個循環之前必須重置pn原因。 否則,您將緊隨numbers遍歷內存,該numbers可能包含任何內容,包括陷阱表示(即,與給定類型的合法值不對應的位模式)。

嘗試在數組末尾訪問多個內存會導致未定義的行為 ,這可能意味着您的代碼徹底崩潰,顯示垃圾再到正常工作都可能發生。

在填充數組期間,指針pn遞增,數據放置在數組上。 用於打印數組內容的指針變量相同。 由於此重新初始化已完成。

暫無
暫無

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

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