簡體   English   中英

在 printf 中給出不同結果的指針

[英]Pointers giving different results in printf

我正在學習一些 C 並且我正在測試簡單的指針事物以便我可以更多地理解它們。 我想我沒有得到正確的東西。 給出下面的簡單代碼:

#include <stdio.h>

void main() {
    long n = 1;
    long *y = &n;
    n = 2;
    printf("n: %d\n",&n);
    printf("y: %d\n",y);
}

結果是:

n: 6422296
y: 6422296

我猜是 memory 中的 position。

如果我將打印行更改為:

printf("n: %d\n",&n);
printf("y: %d\n",&y);

結果是:

n: 6422300
y: 6422296

我猜n在 memory 中存儲在y之后 4 個字節,但不明白為什么。 我沒有更改 output 中的n並且我要離開&但是當將&添加到y時 output 值會發生變化。

如果我這樣離開:

printf("n: %d\n",n);
printf("y: %d\n",&y);

output 是:

n: 2
y: 6422296

這個結果是我所期待的。

為什么會有這種行為? 我缺少一些東西。

別無禮。 我閱讀了有關指針的教程和解釋,但沒有人為我解釋這些。

y為您提供值,即n的地址。

&y給你y y什么類型。

  • &是地址運算符。 它給你變量的地址。
  • *在表達式中使用時,是取消引用運算符。 它為您提供指針指向的值。 在您的示例中, *y將為您提供n的值。
  • *在聲明中使用時(例如您的long *y )指定該變量將包含一個地址/指針。

要學習和理解 C,閱讀著名的C FAQ的相應部分會有所幫助。

我認為您的問題歸結為“當我添加y地址的打印時,為什么n的地址會發生變化”。 答案歸結為編譯器和優化器如何工作以及它們如何為事物分配存儲的細節。

當您像這樣聲明一個 function 的局部變量時,編譯器在如何處理它方面有很大的自由度。 它可以在它為 function 創建的堆棧幀中分配空間,或者它可以將變量保存在寄存器中,或者它可以兩者都做,或者它甚至可以做其他事情。 唯一的要求是它最終生成的代碼與程序的執行語義相匹配。

對於像這樣的局部變量,如果它們的地址從未被占用(就像y的情況),那么一個好的編譯器通常會嘗試將變量保存在寄存器中並且永遠不會為其分配 memory。 因此,在第一個程序中,它只需要堆棧幀中一個變量( n )的空間( n已占用其地址,因此必須駐留在 memory 中才能獲得地址)。

在第二個程序中, yn都使用了它們的地址,因此它們都必須在 memory 中。碰巧編譯器決定將y放在較低的地址, n放在較大的地址,但並不能保證這一點。 在任何意義上也沒有要求它們彼此“相鄰”。

n是 long, y是指向long的指針。 都占用自己的memory

我稍微修改了你的代碼:

#include <stdio.h>

void main() {
    long n = 1;
    long *y = &n;
    n = 2;
    printf("&n: %p\n",&n); //Please change format specifier to %p for pointer
    printf("y: %p\n",y);
}

在第一個printf()調用中打印n的地址,在第二個printf()調用中打印存儲在y中的值。 由於您使用n的地址初始化y ,因此它們必須相同。

在您的下一組printf()中(再次稍作修改):

printf("n: %ld\n",n); //Please change format specifier to %ld for long int
printf("&y: %p\n",&y); //This one is still a pointer though (long**)

您正在打印n的值和y的地址。

第一個printf()必須打印2因為它是存儲在n中的最新值。 第二個printf()將打印y的地址,即存儲n地址的 memory 地址。 &y是一個指向 long 的指針。

printf("&y: %p\n",&y);

永遠無法打印n的地址,因為yn存儲在不同的 memory 位置

暫無
暫無

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

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