ページ 1 / 1
配列とポインタについて(初心者です)
Posted: 2009年6月15日(月) 10:20
by たくや
初心者でところどころ伝わりにくい表現があるかと思いますが、その場合はご指摘お願いします。
要素数 3 の int 型の配列 a を定義し, 以下のようにポインタ p, q, r にアドレスを代入して 配列 a の各要素の値とアドレスを p, q, r を使って表示せよ. ただし, ポインタ表現をつかい p などという表現は使ってはいけない。
int *p = &a[0]
int *q = a
int (*r)[3] = &a
という課題が出ました。
①*をつけるとアドレスに格納されている値が返されると習いましたが、
int *p = &a[0]と定義すると*pにa[0]のアドレスが代入される、ということでしょうか?
だとすれば、このa[0]の値をポインタで表示するためにはprintf("a[0]=%d",*(*p))とすればよいということなのでしょうか?
②*q=aと定義すると、配列aの先頭アドレスが*qに代入されるという意味ですか?
だとすればa[1]のアドレスをポインタqを使って表現するためにはprintf("a[1]=%p",*(q+1))とすればよいのでしょうか?
③まず(*r)[3]という表現の意味するところですが、(*r)は(*r)[3]という配列の先頭アドレスと解釈してよいのでしょうか?また、(*r)[3]=&aとは要素数4の配列(*r)の4番目の値に配列aの先頭アドレスを代入するという意味でしょうか?またその場合、a[2]のアドレスと値を表示するためにはどうすればよいのでしょうか?
ヒントがあればお願いいたします。
Re:配列とポインタについて(初心者です)
Posted: 2009年6月15日(月) 10:34
by Mist
まず、変数の宣言とその初期化は分けて考えてください。
int *p = &a[0] ;
これは
int *p;
p = &a[0];
です。
この部分での思い違いがあるため全てにおいて間違った解釈をしています。
上記を念頭においてもう一度課題を見直してください。
追伸
丸囲み数字は機種依存文字です。
表示できない環境もありますのでネット上においては使わないほうがいいです。
Re:配列とポインタについて(初心者です)
Posted: 2009年6月15日(月) 13:47
by たくや
>Mist さん
ありがとうございました。
ということは、
int *q = a;
は
int *q;
q=a;
になるのでしょうか?
また、
int (*r)[3] = &a
の(*r)[3]はどのような意味を持つ表現なのでしょうか?
Re:配列とポインタについて(初心者です)
Posted: 2009年6月15日(月) 13:55
by 御津凪
int (*r)[3] は、「"int 型3個の配列"のポインタ」です。(合ってるかな?)
(ちなみに int *r[3] は「"int のポインタ型"3個の配列」です)
なので、 int (*r)[3] = &a としたら、 (*r)[0] で配列 a の先頭を指します。
(r[0] ではないので注意)
int *q = a; の考え方はそれで正しいです。
Re:配列とポインタについて(初心者です)
Posted: 2009年6月15日(月) 14:15
by たくや
>御津凪 さん
ありがとうございました。プログラミングって難しいですね;;
int (*r)[3] = &a;
は
前のMistさんがおっしゃっていた、定義と初期化ですが、
定義は
int (*r)[3];
としてよいのですか?初期化がわからないのですが
int (*r)[3] =a;
となるのでしょうか??
Re:配列とポインタについて(初心者です)
Posted: 2009年6月15日(月) 14:22
by 御津凪
定義はそれであっています。
初期化はここで言うと、
r = &a;
です。
(定義だけでは値が決まっていないので、初期状態で値を代入することを初期化と言います)
定義と初期化を同時に行うというのは、
int (*r)[3] = &a;
ということです。
Re:配列とポインタについて(初心者です)
Posted: 2009年6月15日(月) 14:34
by たくや
>御津凪 さん
本当にありがとうございました。
お二方の助言に基づき、
とりあえず以下のようなプログラムを作ってみました。
#include <stdio.h>
int main(void){
int a[3];
int *p ;
p=&a[0];
int *q;
q=a;
int (*r)[3];
r=&a;
printf("a[0]の値=%d,a[0]のアドレス=%p\n",*p,p);
printf("a[1]の値=%d,a[1]のアドレス=%p\n",*(q+1),q+1);
printf("a[2]の値=%d,a[2]のアドレス=%p\n",(*r)[2],*(r+2));
return 0;
}
(実行結果)
a[0]の値=1884,a[0]のアドレス=0x22eeb0
a[1]の値=-1,a[1]のアドレス=0x22eeb4
a[2]の値=1628655616,a[2]のアドレス=0x22eec8
aの値がこんな数になるのは少し疑問ですが、
なにか間違っているところがありましたらご指摘いただけるとありがたいです。
Re:配列とポインタについて(初心者です)
Posted: 2009年6月15日(月) 14:46
by 御津凪
配列 a は初期化されていませんので、変な数値になります。
Re:配列とポインタについて(初心者です)
Posted: 2009年6月15日(月) 14:47
by non
配列aには初期値を入れておかないとゴミが出てます。
3番目のrの表現は間違ってます。
Re:配列とポインタについて(初心者です)
Posted: 2009年6月15日(月) 14:53
by たくや
御津凪 さん
ありがとうございました。
Re:配列とポインタについて(初心者です)
Posted: 2009年6月15日(月) 14:54
by たくや
non さん
ご指摘ありがとうございます。
自分なりに訂正してみましたがいかがでしょうか?
#include <stdio.h>
int main(void){
int a[3];
int *p ;
p=&a[0];
int *q;
q=a;
int (*r)[3];
r=&a;
printf("a[0]の値=%d,a[0]のアドレス=%p\n",*p,p);
printf("a[1]の値=%d,a[1]のアドレス=%p\n",*(q+1),(q+1));
printf("a[2]の値=%d,a[2]のアドレス=%p\n",(*r)[2],(r+2));
return 0;
}
実行結果は同じになってしまいましたが・・・
Re:配列とポインタについて(初心者です)
Posted: 2009年6月15日(月) 15:02
by non
課題にこう書いてありました。
>ポインタ表現をつかい p などという表現は使ってはいけない。
Re:配列とポインタについて(初心者です)
Posted: 2009年6月15日(月) 15:03
by toyo
*rはint3個分の大きさがあります
intが4バイトとすると12バイトですね
したがってr + 2はa[2]のアドレスにはなりません
rはa[0]のアドレスと同じですがr + 1はa[3]のアドレスr + 2はa[6]のアドレスになります
Re:配列とポインタについて(初心者です)
Posted: 2009年6月15日(月) 15:05
by ねこ
rに入ってるのは「a配列のポインタ」という意識は持ってるでしょうか?つまり「*r = a」です。
後はこの方程式を割り当てれば良いだけです。
Re:配列とポインタについて(初心者です)
Posted: 2009年6月15日(月) 15:15
by たくや
non さん
ありがとうございました。
そして私が課題について勘違いしていたことに気づきました。
ポインタpとqとrでそれぞれa[0],a[1],a[2]の値とアドレスを3回ずつ表示させるという問題でした。
実行結果は同じになるはずなのですが、どうやってもポインタrを使った場合だけが違ってしまいます。
なぜでしょうか?なにかあればご指摘お願いします。
#include <stdio.h>
int main(void){
int a[3];
int *p ;
p=&a[0];
printf("a[0]の値=%d,a[0]のアドレス=%p\n",*p,p);
printf("a[1]の値=%d,a[1]のアドレス=%p\n",*(p+1),(p+1));
printf("a[2]の値=%d,a[2]のアドレス=%p\n",*(p+2),(p+2));
int *q;
q=a;
printf("a[0]の値=%d,a[0]のアドレス=%p\n",*q,q);
printf("a[1]の値=%d,a[1]のアドレス=%p\n",*(q+1),(q+1));
printf("a[2]の値=%d,a[2]のアドレス=%p\n",*(q+2),(q+2));
int (*r)[3];
r=&a;
printf("a[0]の値=%d,a[0]のアドレス=%p\n",*r,r);
printf("a[1]の値=%d,a[1]のアドレス=%p\n",*(r+1),(r+1));
printf("a[2]の値=%d,a[2]のアドレス=%p\n",*(r+2),(r+2));
return 0;
}
(実行結果)
a[0]の値=1884,a[0]のアドレス=0x22eeb0
a[1]の値=-1,a[1]のアドレス=0x22eeb4
a[2]の値=1628655616,a[2]のアドレス=0x22eeb8
a[0]の値=1884,a[0]のアドレス=0x22eeb0
a[1]の値=-1,a[1]のアドレス=0x22eeb4
a[2]の値=1628655616,a[2]のアドレス=0x22eeb8
a[0]の値=2289328,a[0]のアドレス=0x22eeb0
a[1]の値=2289340,a[1]のアドレス=0x22eebc
a[2]の値=2289352,a[2]のアドレス=0x22eec8
Re:配列とポインタについて(初心者です)
Posted: 2009年6月15日(月) 15:18
by Mist
aの初期化をしないのはなぜ?
不定値の表示じゃ見にくくないですか?
rの値表示はさっきのであってるよ。
アドレス表示はtoyoさんのレスをよく読んで。
追伸
ソースを提示する場合は規約に従いpreタグを使用してください。
Re:配列とポインタについて(初心者です)
Posted: 2009年6月15日(月) 15:26
by non
>rの値表示はさっきのであってるよ。
答えとしてはあっているのですが、[/url]を使ってはいけないと課題に書いてあります。
>int a[3];
を
int a[3]={1,2,3};
などのようにしましょう。
Re:配列とポインタについて(初心者です)
Posted: 2009年6月15日(月) 15:35
by たくや
>toyo さん
とてもわかりやすい解説ありがとうございました。
((*r)+1),((*r)+2)としたところ正しい実行結果が得られました!
toyoさんがおっしゃっていたことは忘れないようにmemoしました。
Re:配列とポインタについて(初心者です)
Posted: 2009年6月15日(月) 15:38
by たくや
>ねこさん
ご指摘ありがとうございます。
ひとつ上のコメントのように直したのですがよいでしょうか?
Re:配列とポインタについて(初心者です)
Posted: 2009年6月15日(月) 15:42
by たくや
>Mistさん、nonさん
ご指摘ありがとうございます。
このように直しました。いかがでしょうか?
#include <stdio.h>
int main(void){
int a[3]={1,2,3};
int *p ;
p=&a[0];
printf("a[0]の値=%d,a[0]のアドレス=%p\n",*p,p);
printf("a[1]の値=%d,a[1]のアドレス=%p\n",*(p+1),(p+1));
printf("a[2]の値=%d,a[2]のアドレス=%p\n",*(p+2),(p+2));
int *q;
q=a;
printf("a[0]の値=%d,a[0]のアドレス=%p\n",*q,q);
printf("a[1]の値=%d,a[1]のアドレス=%p\n",*(q+1),(q+1));
printf("a[2]の値=%d,a[2]のアドレス=%p\n",*(q+2),(q+2));
int (*r)[3];
r=&a;
printf("a[0]の値=%d,a[0]のアドレス=%p\n",*(*r),*r);
printf("a[1]の値=%d,a[1]のアドレス=%p\n",*((*r)+1),((*r)+1));
printf("a[2]の値=%d,a[2]のアドレス=%p\n",*((*r)+2),((*r)+2));
return 0;
}
(実行結果)
a[0]の値=1,a[0]のアドレス=0x22eeb0
a[1]の値=2,a[1]のアドレス=0x22eeb4
a[2]の値=3,a[2]のアドレス=0x22eeb8
a[0]の値=1,a[0]のアドレス=0x22eeb0
a[1]の値=2,a[1]のアドレス=0x22eeb4
a[2]の値=3,a[2]のアドレス=0x22eeb8
a[0]の値=1,a[0]のアドレス=0x22eeb0
a[1]の値=2,a[1]のアドレス=0x22eeb4
a[2]の値=3,a[2]のアドレス=0x22eeb8
Re:配列とポインタについて(初心者です)
Posted: 2009年6月15日(月) 16:06
by non
お疲れ様です。
>*((*r)+2),((*r)+2)
これでいいのですが、()がちょっと無駄です。
*(*r+2),*r+2 でOK