簡體   English   中英

(nil)由c中的int指針返回的值

[英](nil) value returned by int pointer in c

當我們聲明一個指針時,它指向內存中的某個隨機位置或地址,除非我們為它明確分配一個特定值(任何變量的地址)。

這是代碼:

int *p;

printf("int is %p\n",p);

float *j;

printf("float is %p\n",j);

double *dp;

printf("double is %p\n",dp);

char   *ch ;

printf("char is %p\n",ch);

j=(float *)p;

printf("cast int to float %p\n",j);

輸出:

int is (nil)

float is 0x400460

double is 0x7fff9f0f1a20

char is (nil)

cast int to float (nil)

而不是打印它隨機打印的位置(無)

這是什么(零)? 我在這里不了解指針的行為??

未初始化的指針變量不會指向隨機地址。 它們指向的位置是不確定的。

實際上,它們具有堆棧中剩余的值,您無法確定該值。 在您的示例中,這幾個指針恰好具有0值,因此它們恰好是空指針,並且顯示為nil

永遠不要依賴這種行為。

如果通過“ gnu”標記表示您正在使用glibc,則原因是當遇到NULL指針時,glibc中的printf實現將打印“(nil)”。

換句話說,您的多個指針恰好具有值NULL(0),因為這恰好是該特定位置在堆棧上的內容。

闡述@yu hao所說的話:

每當調用子例程時,就會將堆棧幀分配給該子例程。 該框架存在直到遇到return語句。

子例程經常需要存儲空間來存儲局部變量的值,這些局部變量僅在活動子例程中是已知的,並且在返回后不會保留值。 為此,編譯器只需簡單地將棧頂移動足夠的空間即可為該用途分配空間。 與使用堆空間的動態內存分配相比,這非常快。 請注意,子例程的每次單獨激活都會在堆棧中為稱為“堆棧框架”的本地變量在堆棧中獲得其自己的單獨空間。

這樣做的主要原因是跟蹤每個活動子例程在完成執行后應返回控制的點。 活動子例程是已被調用但尚未完成執行的子例程,在此之后,應將控制權交還給調用點。 子例程的這種激活可以嵌套到任何級別(在特殊情況下是遞歸的),因此可以是堆棧結構。 例如,如果子例程DrawSquare從四個不同的位置調用子例程DrawLine,則DrawLine必須知道執行完成后要從哪里返回。 為此,調用指令后的地址,即返回地址,也隨每個調用一起被壓入調用堆棧。

調用堆棧調用堆棧2

回到您的問題,在執行過程中,該函數可以更改其堆棧框架,當函數“返回”時,其框架從堆棧中“彈出”。
但是堆棧的內容在此過程中保持不變。 只有堆棧指針被修改為指向前一幀。 因此,當調用新的子例程時,將在前一個子例程的頂部分配新幀,並且如果該子例程具有未初始化的變量,它們將打印存儲在為其分配的內存中的值。 這將取決於該時間點的堆棧狀態。

您所有的指針都是nil / undefiend或者只是堆棧中的隨機值!

請參閱: http//ideone.com/wwiy8F

暫無
暫無

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

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