[英]Can someone explain why this program behaves like this?
我在 C 中有以下程序:
void main() {
int x[3];
int* p = &x;
printf("%d %d \n", p, x);
}
p
和x
那些值似乎是相同的,但我不明白為什么,因為 p 是指針 x 的地址,不應該有像*p = x
而不是p = x
嗎?
最大的問題是p
和&x
是不同的類型。
&x
給出的指針是指向整個數組x
的指針,而不是指向單個元素的指針,其類型是int (*)[3]
,而不是int *
。
如果你想得到一個指向x
的第一個元素的指針,那么使用&x[0]
,或者普通的x
(因為它會衰減到&x[0]
)。
即使&x
和&x[0]
類型不同,它們都指向相同的位置(如您的(無效)打印輸出所示)。 如果您嘗試在內存中可視化數組x
,則可以看到這一點:
+------+------+------+ | x[0] | x[1] | x[2] | +------+------+------+ ^ | &x | &x[0]
正如我在評論中已經提到的,要打印指針,您需要使用%p
格式說明符。 格式說明符和參數類型不匹配會導致未定義的行為。
更重要的是, %p
格式說明符用於void *
指針,因此您需要轉換指針(除非它們當然已經是void *
):
printf("%p %p \n", (void *) p, (void *) x);
您的代碼在編譯時產生一些警告:
warning: initialization from incompatible pointer type [-Wincompatible-pointer-types]
warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]
warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘int *’ [-Wformat=]
並且您編譯的代碼導致未定義的行為,而相同的結果是由於未定義的行為。
提示:您的代碼在概念上是錯誤的,請閱讀有關 C 語言中指針、數組 e 類型的更多信息。
您的程序中有幾個問題會導致未定義的行為。
首先,數組x
未初始化,稍后訪問它會導致 UB。
其次, x
當用作指針時已經是數組x
的第一個元素的地址(相當於&x[0]
); 因此&x
將是指向該指針的指針。 第三, %d
需要一個整數值,而不是一個指向 1 的指針; 所以你需要取消引用p
和x
。
以下程序應按您的預期運行:
int main() {
int x[3] = { 1,2,3 };
int* p = x;
printf("%d %d \n", *p, x[0]);
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.