[英]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.