C言語関係掲示板

過去ログ

No.274.ポインタと++演算子

[戻る] [ホームページ]


No.1647

ポインタについて
投稿者---RYO(2002/06/03 00:10:37)


初めまして。今日このHPを見つけました。
最近、C言語を勉強しはじめたのでとても参考になります。
ちょっとポインタについていまいちわからないところが
あるので教えてもらえないでしょうか?

<pre>
#include <stdio.h>

void main()
{
int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
int *b,i; //iはループ変数

b=a[0];

for(i=0;i<12;i++)
printf("%d\n",*b++);

}
</pre>
ポインタについてこのようなソースがあったとします。
疑問なのはprintfで*b++としたら最初のa[0][0]をインクリメント
しつづけるような気がするのですが、実行すると配列の
中身をすべて表示してくれます。アスタリスクをつけると
ポインタの指定した先のデータをいじるのではないのですか?
何故、すべての配列を表示できるのでしょうか?


No.1648

Re:ポインタについて
投稿者---ジャスミン茶(2002/06/03 06:09:32)


>ポインタについてこのようなソースがあったとします。
>疑問なのはprintfで*b++としたら最初のa[0][0]をインクリメント
>しつづけるような気がするのですが、実行すると配列の
>中身をすべて表示してくれます。アスタリスクをつけると
>ポインタの指定した先のデータをいじるのではないのですか?
>何故、すべての配列を表示できるのでしょうか?

はじめまして。

これは*と++の優先順位の問題でしょう。
++の方が優先順位が高いので先に評価されます。
よって、*b++はb++の中身を表示することになります。
演算としては*(b++)という事です。
つまり、毎回b++というアドレスの中身を見るわけです。
逆に同じアドレスの中身を増やしたい場合は(*b)++とします。

bに先に関係付けられるのはのはどちらか?と考えるといいと思います。
(*)b++や*b(++)はダメです。
前者はb++を型不明のポインター型にキャストする。
後者は++を引数にとる関数bへのポインター。
という意味になります。
前者は無論エラーになりますが、型が不明なだけなので(int *)のようにすればエラーは出ません。
bはint型のポインターなので中身はアドレスが含まれています。
+1するとint型の分(多分4バイト)だけアドレスが進みます。
後者は関数bの定義がないとかいわれると思います。

No.1649

Re:ポインタについて
投稿者---shelly(2002/06/03 09:55:39)


ジャスミン茶さんがすでに適切な解説を出されているので、脱線しますが。。。


for(i=0;i<12;i++)
    printf("%d\n",*b++);

このような書き方はすべきではないです。
素直に二重ループにすべきです。
(for文内のぶら下がりは好みだと思いますが、個人的には好きではないです)
for (i = 0; i < 3; i++) {
    for (j = 0; j < 4; j++) {
        printf("%d\n",b[i][j]);
    }
}




No.1652

ありがとうございました
投稿者---RYO(2002/06/03 17:25:32)


おかげさまで理解できました。どうもありがとうございました。
確かにこの場合は2重ループにしたほうがわかりやすいですね。
アドバイスどうもでした。

No.1654

Re:ポインタについて
投稿者---かずま(2002/06/03 19:49:21)


> int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};

> 疑問なのはprintfで*b++としたら最初のa[0][0]をインクリメント
> しつづけるような気がするのですが、実行すると配列の
> 中身をすべて表示してくれます。

a[0][0]をインクリメントし続けても、配列の中身をすべて表示しても、
どちらも、1,2,3, ..., 12 となるはずです。どうして後者だと分かったのですか。

No.1656

Re:ポインタについて
投稿者---RYO(2002/06/03 22:47:19)


>> int a[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
>
>> 疑問なのはprintfで*b++としたら最初のa[0][0]をインクリメント
>> しつづけるような気がするのですが、実行すると配列の
>> 中身をすべて表示してくれます。
>
>a[0][0]をインクリメントし続けても、配列の中身をすべて表示しても、
>どちらも、1,2,3, ..., 12 となるはずです。どうして後者だと分かったのですか。

これは同じ時期にCの勉強をはじめた知り合いが
だしてきた問題なんです。同じにa[0][0]をインクリメント
しつづけてるのか、それとも配列の中身を表示してるのかわかる?
ってきかれて、配列の中身変えてみたりしたら配列の中身を
表示してたんです。てっきりインクリメントしてるものだと
思っていたので、考えてみても優先順位まで頭が回りませんでした。
(同時期にはじめた知り合いに聞くのは癪だったんです^^;