京都産業大学のレポート課題の解き方が分かりません。  
[京都産業大学のレポート課題](http://www.cc.kyoto-
su.ac.jp/~yamada/programming/pointer.html#pointerPointer)  
高校生です。  
今、ポインタを学習しています。  
ネット上にある演習問題を解いているのですが、この問題がさっぱりです。  
whille文の中でbを使わずにこのプログラムを完成させることは可能なのでしょうか?  
皆さんはどのようなコードをかかれますか？

```

    #include <stdio.h>
    
    int main()
    {
     int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
     int b[10];
     int *p, *q;
     int i;
    
     p = ???;
     q = ???;
    
     while( ??? ここでは p と a を使う) {
         ???;
         ???; ここでは p と q を使う
         ???;
     }
    
     for (i = 0; i < 10; i++) {
         printf("%d ", b[i]);
     }
    
     return 0;
    }
    
```

実行例  
10 9 8 7 6 5 4 3 2 1
CC BY-SA 3.0
2018-04-29T14:27:08.373
43656
2021-03-19T17:01:15.530
2018-04-30T03:20:30.277
3060
28359
question
c
ポインタと配列に関して
while 文の外に

```

    p = ???;
    q = ???;
    
```

があって、while 文の中に

```

    ???; ここでは p と q を使う
    
```

があるので、`p` と `q` を使って値をコピーしていくのだろう、と予測できます。

`p`, `q` がそれぞれ `a`, `b` の配列の中を指すようにして、`p`, `q` の指す場所を移動させながらコピーしていくわけです。

`???` を埋めてみました。

```

    #include <stdio.h>
    
    int main()
    {
        int a[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        int b[10];
        int *p, *q;
        int i;
    
        p = a;
        q = b + 10;
    
        while(p < a + 10) {
            q--;
            *q = *p;
            p++;
        }
    
        for (i = 0; i < 10; i++) {
            printf("%d ", b[i]);
        }
    
        return 0;
    }
    
```
CC BY-SA 3.0
2018-04-29T15:26:24.690
43658
2018-04-29T15:26:24.690
5288
43656
answer
たぶん想定されている答えは下記の通りでしょうか。  
僕もポインタは定期的に勉強しているので、腕試しがてらに解いてしまいました。

```

    int main(void) {
        int a[10] = { 1,2,3,4,5,6,7,8,9,10 };
        int b[10];
        int *p, *q;
        int i;
        p = a+10; //or p=&a[10]
        q = b; //or p=&b[0]
        while (p != a){
            p--;
            *q = *p;
            q++;
        }
        for (i = 0; i < 10; i++){
            printf("%d ", b[i]);
        }
        scanf("%d\n", &a);
        return 0;
    }
    
```

考え方  
配列aを逆順に配列bに格納することを求められている。  
そのためにはwhile文の外でbをポインタ参照する必要がある。(でないと与えられた制約でbを変更できない。)  
Cにおいてint a[10];としたときにaはa[0]のメモリアドレス&a[0]を示している。  
アドレスaに対する加算a+10はa[10]のメモリアドレス&a[10]を示している。よってコメント行に記された書き方のほうがわかりやすいかもしれません。  
ここで気を付けてほしいのはa+10は実際には初期化されていないメモリアドレスを指していること、int
a[10]=...;で初期化されるのはa[0]～a[9]までであり、a[10]には何が入っているかわからない。なのでwhile文では先にp--;を行いa[10]にアクセスしないようにする必要がある。  
*q=*p;でaが格納している値をpのポインタを介してアクセスし(derefとか参照剥がしとか呼んだりします。)、qのポインタを介してbに格納している。  
ポインタpに対する加減算は、ポインタの型のサイズだけアドレスをずらすということは理解されているかもしれませんが、再度確認しておきます。  
例えばpに00FF08が格納されているとするとpはint型(4bit)のポインタなので、p--は00FF04、p++は00FF0Cを指します。
CC BY-SA 3.0
2018-04-29T15:47:32.373
43659
2018-04-29T15:47:32.373
25980
43656
answer