用指標給陣列賦值的一個小問題

NO IMAGE

問題是這樣的, 我打算輸入與元素為陣列賦值, 然後反向輸出陣列元素

# 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 的拷貝下執行 * 操作。