用指標給陣列賦值的一個小問題
阿新 • • 發佈:2019-01-08
問題是這樣的, 我打算輸入與元素為陣列賦值, 然後反向輸出陣列元素
/*
註釋掉13 行輸出結果:
0 1 2 3 4 5 6 7 8 9
9 9 8 7 6 5 4 3 2 1
註釋掉11, 22行輸出結果:
0 1 2 3 4 5 6 7 8 9
9 9 8 7 6 5 4 3 2 1
註釋掉11, 12, 13行輸出結果:
0 1 2 3 4 5 6 7 8 9
9 8 7 6 5 4 3 2 1 0
*/
因為開始的輸出結果不符合我的期望, 所以我就 用不同的 方法輸出。
結果是: 用陣列方法輸出是正確的, 但是用指標的方法卻是error。
這時候 我有兩個疑惑,
第一: p是個指標。
*p++ 相當於 *p, p++; 這個是我結論剛實驗的。 // 見上面程式。
但是教材上說的是, *p++, 因為 * 運算子與++yu==運算子處於同優先順序,
結合方向自右向左。因此等價於*(p++);
問題就來了, *p++, 到底是先算那個?
第二:我覺得上面三種輸出的方式的結果應該都是一樣的, 但是輸出的卻不一樣。
我用指標輸出時,
for迴圈第一次時, p = &a[9]; 輸出a[9]的值; 然後 p--; 此時 p = &a[8];
第二次時, p = &a[8]; 輸出a[8]的值; 然後p--; 此時p = &a[7];
………………
知道p = &a[0]; 輸出a[0]的值; p--; 此時因為 i 已經不滿足for的條件了, 跳出迴圈。
然而: 事實卻是上面的結果。
輸出結果是:
0x60fee0
0x60fee4
0x60fee8
0x60feec
0x60fef0
0x60fef4
0x60fef8
0x60fefc
0x60ff00
0x60ff04
0x60ff08
可以清晰地看到, 給陣列賦完值之後, p 的值並不是我想象中的 &a[9], 而是 &a[10]。
所以, 問題的根本原因是因為
for (i = 0; i < 10; i++)
scanf("%d", p++);
輸入所有的值之後, p++; 導致 p 指向不是a[9]。
輸出結果如下:# include <stdio.h> int main(void) { int a[10], * p = a, i; for (i = 0; i < 10; i++) scanf("%d", p++); for(i = 9; i >= 0; i--) // 用指標輸出時, i 僅僅用來控制迴圈次數, { // *p-- 相當於 *p, p-- // 10 // printf("%d ", *p); // 11 // p--; // 12 // printf("%d ", *p--);// 13 printf("%d ", a[i]); } return 0; }
/*
註釋掉13 行輸出結果:
0 1 2 3 4 5 6 7 8 9
9 9 8 7 6 5 4 3 2 1
註釋掉11, 22行輸出結果:
0 1 2 3 4 5 6 7 8 9
9 9 8 7 6 5 4 3 2 1
註釋掉11, 12, 13行輸出結果:
0 1 2 3 4 5 6 7 8 9
9 8 7 6 5 4 3 2 1 0
*/
因為開始的輸出結果不符合我的期望, 所以我就 用不同的 方法輸出。
結果是: 用陣列方法輸出是正確的, 但是用指標的方法卻是error。
這時候 我有兩個疑惑,
第一: p是個指標。
*p++ 相當於 *p, p++; 這個是我結論剛實驗的。 // 見上面程式。
但是教材上說的是, *p++, 因為 * 運算子與++yu==運算子處於同優先順序,
結合方向自右向左。因此等價於*(p++);
問題就來了, *p++, 到底是先算那個?
第二:我覺得上面三種輸出的方式的結果應該都是一樣的, 但是輸出的卻不一樣。
我用指標輸出時,
for迴圈第一次時, p = &a[9]; 輸出a[9]的值; 然後 p--; 此時 p = &a[8];
第二次時, p = &a[8]; 輸出a[8]的值; 然後p--; 此時p = &a[7];
………………
知道p = &a[0]; 輸出a[0]的值; p--; 此時因為 i 已經不滿足for的條件了, 跳出迴圈。
然而: 事實卻是上面的結果。
對於第二個問題。 因為是指標輸出的時候結果出錯, 於是我想到是不是指標指向的地址不是我預料中的。我用下面的程式來驗證我的思路。
for (i = 0; i < 10; i++)
{
printf("%#x\n", &a[i]);
}
printf("\n\n%#x\n", p);
輸出結果是:
0x60fee0
0x60fee4
0x60fee8
0x60feec
0x60fef0
0x60fef4
0x60fef8
0x60fefc
0x60ff00
0x60ff04
0x60ff08
可以清晰地看到, 給陣列賦完值之後, p 的值並不是我想象中的 &a[9], 而是 &a[10]。
所以, 問題的根本原因是因為
for (i = 0; i < 10; i++)
scanf("%d", p++);
輸入所有的值之後, p++; 導致 p 指向不是a[9]。
對於第一個問題,優先順序表格顯示字尾++操作符的優先順序高於操作符*, 但是這裡實際上涉及三個步驟:
(1) ++操作符產生 p 的一份拷貝。
(2)然後++操作符增加 p 的值。
(3)最後在 p 的拷貝下執行 * 操作。