-5

ポインターと配列を使って練習する C のこの単純なプログラムについて質問があります。

コード:

#include <stdio.h>

fun(int *p, int *v) {
    *p++;
    *(v+2) = p[3];
    *v++ = p[0];
    v[0] = *(p+4);
}

int main() {

    int v[] = {90, 89, 8, 78, 60, 120};
    int k[] = {0, 0, 0, 0, 0, 0};
    int *ptr = k;

    fun(v, ptr);
    for (ptr = k; ptr < k + 6; ptr++)
        printf("%d\n", *ptr);
}

だから私の質問は、なぜそれが印刷されるのかということ89 120 60 0 0 0です。

4

1 に答える 1

2

ポインターと配列で何が起こっているかを (紙に手書きでも!) 描くと便利です。次の関数の場合:

void fun(int *p, int *v) {
    *p++;
    *(v+2) = p[3];
    *v++ = p[0];
    v[0] = *(p+4);
}

これらの配列を渡しました:

[90] [89] [8] [78] [60] [120]
 |
 p

[0]  [0]  [0] [0]  [0]  [0]
 |
 v

で何が起こりfunますか?

*p++

これは、次の 2 つの方法のいずれかで読み取ることができます。p を逆参照してその値を (post) インクリメントするか、p を後からインクリメントして p の古い値を逆参照します。それはどれですか?便利な演算子の優先順位の表によると、++ は * の前にあるので、2 番目です。ポインターを参照しますが、値には何もしないことに注意してください。つまり、書いp++て同じ結果を得ることができたということです。

インクリメントの後、ポインターが変更されました。

[90] [89] [8] [78] [60] [120]
      |
      p

次の行では、 と の両方pを使用していvます。

    *(v+2) = p[3];

これは、「p の右側の 3 番目の値を v の右側の 2 番目のスポットに割り当てる」と読むことができます。p の右側の 3 番目のスポットには があり60、次のようになります。

[0]  [0]  [60] [0]  [0]  [0]
 |
 v

次は:

*v++ = p[0];

前から、*v++ は (ポスト) インクリメント v を意味することがわかっています。++v (プリインクリメント) と v++ (ポストインクリメント) の違いは、返される値です。この場合、v を変更しますが、 p が指しているものを代入して、その古い値。v がインクリメントされていることに注意してください。

[89]  [0]  [60] [0]  [0]  [0]
       |
       v

そして最後に:

v[0] = *(p+4);

これは、「p の右側の 4 番目の値を v の右側の 0 番目のスポットに割り当てる」と読むことができます。p の右にある 4 番目のスポットは 120 で、次のようになります。

[89]  [120]  [60] [0]  [0]  [0]
       |
       v

関数の最後では、ポインタとメモリは次のようになります。

[90] [89] [8] [78] [60] [120]
 |    |
 |    p
main-v

[89]  [120]  [60] [0]  [0]  [0]
 |     |
 |     v
main-k
main-ptr
于 2013-06-14T17:31:28.123 に答える