我的代碼是這樣的我的程序的輸出是混亂
int main()
{
unsigned int x [4] [3] =
{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}};
printf("%u, %u, %u", x + 3, * (x + 3), * (x + 2) + 3);
}
輸出的所有3個值都相同誰能告訴我爲什麼?
我的代碼是這樣的我的程序的輸出是混亂
int main()
{
unsigned int x [4] [3] =
{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}, {10, 11, 12}};
printf("%u, %u, %u", x + 3, * (x + 3), * (x + 2) + 3);
}
輸出的所有3個值都相同誰能告訴我爲什麼?
首先 - 正如其他人所指出的那樣 - 您需要使用正確的格式說明符,並將這些值轉換爲指針。
現在至於爲什麼他們都給出相同的價值。這裏x是一個數組。其元素的類型是unsigned int[3]
。即x
是unsigned int[3]
陣列的陣列 。
首先,x + 3
給出數組中第四個元素的地址。那就是{10, 11, 12}
的 地址。該數組在內存中的地址將是其內存中第一個元素的地址。這是內存中10
的地址。請注意,該值爲int (*) [3]
,即address of an unsigned int[3] array
。
二,* (x + 3)
相當於x [3],它是第四個元素,它是unsigned int[3]
。 它是陣列{10, 11, 12}
。該值指向 數組{10, 11, 12}
的第一個元素。也就是說,這個值指向10
。請注意,此值爲unsigned int[3]
。
三*(x+2) + 3
:這裏*(x + 2)
相當於x[2]
這是一個unsigned int[3]
,這是{7, 8, 9}
陣列, 當你做一個+ 3
你正在又一次的10
地址。請注意,此值爲unsigned int[3]
。
因此,你會發現在所有三種情況下,你的結果都是在內存中的相同地址,即存儲10
的地址 - 即使你在不同的時間表示不同的東西;第一個是unsigned int (*)[3]
,第二個和第三個是unsigned int[3]
。
蒸餾水未定義行爲:
printf("%u, %u, %u", x + 3, * (x + 3), * (x + 2) + 3);
所有額外的參數必須是unsigned int
,但2D是unsigned int (*)[3]
,三維是unsigned int *
,第四是unsigned int *
了。
你得到錯誤的值,因爲你做指針算術錯誤。
x
是unsigned int[4][3]
型,長度爲4的陣列,其中每個部分是本身長度3.
因此,什麼是x+3
的陣列?它是x
中最後一個成員的地址(請記住x
的成員是數組)。
因此*(x+3)
本身就是一個數組。但是當你將它們作爲函數參數傳遞時,數組會發生什麼?他們衰變成指針。所以你看到中第一個元素的地址數組,被printf
中錯誤的類型說明符所篡改。
好吧,讓我們來看看元素x[2][3]
。這將是*(*(x+2)+3)
這種表示,全部相當於*(&x[0][0] + 2*3 + 3)
。
使用錯誤的格式說明符是未定義的行爲。 – mch
錯誤的格式說明符%u是用於unsigned int的。 –
'x + 3'的類型是'unsigned int(*)[3]'(一個指針),'*(x + 3)'和'*(x + 2)+ 3'的類型是'unsigned int *'。所有3個都不是'unsigned int',而是指針,所以你應該使用'%p'並且轉換爲'(void *)'。 – mch