1. 程式人生 > >用指標給陣列賦值的一個小問題

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

問題是這樣的, 我打算輸入與元素為陣列賦值, 然後反向輸出陣列元素
# 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 的拷貝下執行 * 操作。