這是C.我正在學習C,這是一個幻燈片中的例子。爲什麼這個指針減法輸出這個?
int main(int argc, char *argv[]) {
int a = 5, b = 10, c;
int *p = &a, *q = &b;
c = p - q;
printf("%d", c);
return 0;
}
當我運行它的輸出是3,我不明白爲什麼。這似乎是因爲它使用&它會減去內存地址,輸出將是內存地址爲-5。
這是C.我正在學習C,這是一個幻燈片中的例子。爲什麼這個指針減法輸出這個?
int main(int argc, char *argv[]) {
int a = 5, b = 10, c;
int *p = &a, *q = &b;
c = p - q;
printf("%d", c);
return 0;
}
當我運行它的輸出是3,我不明白爲什麼。這似乎是因爲它使用&它會減去內存地址,輸出將是內存地址爲-5。
你正在減去指針的地址,而不是它們指向的地址,你會得到兩個存儲器地址之間的差異,不能保證是任何特定的。如果你在不同的機器或編譯器上運行它,它將很可能是完全不同的值,因爲a
和b
可以分配到各種地址。例如,在我的機器上,它是1.類似的現象稱爲未定義的行爲出於某種原因,因爲您無法保證所有編譯器和機器都有相同的結果。
如果您改爲p
和q
像這樣c = *p - *q;
您將得到-5作爲c
作爲兩組值之間的差異。此外,如果您將p
和q
分配爲int *p = a, *q = b;
,那麼您也會將c
設置爲-5,因爲那樣您就可以將指針設置爲不同的地址,並在嘗試訪問之後嘗試訪問,在任何情況下都會是一個糟糕的主意。
謝謝,但我沒有試圖減去他們指向的東西,這是一個來自老師的例子,我不理解它,我只是在腦海中想到它會是-5。你能解釋爲什麼它是3嗎? –
@BenjaminDagg這正是我在回答中解釋的內存地址的差異。它現在可能是3,但是可以在不同的計算機或編譯器上重新編譯它,它很可能會非常不同,因爲地址會有所不同。 – Dom
@BenjaminDagg沒有什麼特別的原因,它只是3.它碰巧是3.如果你拋硬幣,它可能會出現,但沒有理由出現在頭上。它只是。你爲什麼期望-5?這就是錯誤 - 你沒有理由期待這一點。 –
減去2個不是同一個數組的指針是未定義的行爲。
當兩個指針相減時,它們都應指向同一個數組對象的元素,或者指向數組對象的最後一個元素之後的元素;結果是兩個數組元素的下標差異。 C11§6.5.69
相反,得到一些數字差異,值轉換爲intptr_t
。
int main(int argc, char *argv[]) {
int a = 5, b = 10, c;
int *p = &a, *q = &b;
intptr_t ip = (intptr_t) p;
intptr_t iq = (intptr_t) q;
intptr_t diff = ip -iq;
printf("%lld", (long long) diff);
return 0;
}
當然您打印的值可能不是5. int
的位置從編譯變化進行編譯。
你能解釋爲什麼你期望-5? –
你問爲什麼從另一個減去一個指針而不是從另一個減去一個指針? –