• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:関数に配列を渡す場合のプログラムについて)

関数に配列を渡す場合のプログラムについて

このQ&Aのポイント
  • showint関数の引数の書き方について説明されています。
  • showint関数の引数はポインタでなければならない理由について説明されています。
  • showint関数が正しく動作する理由について説明されています。

質問者が選んだベストアンサー

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.8

「型が違う」ということを意識できているならいいです.

yuukizx
質問者

お礼

何度も回答していただき、本当にありがとうございました。

その他の回答 (7)

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.7

あ, 書き間違えた. #6 最後の「たまたま同じアドレスを持っているけど別のもの」は「たまたま同じ値を持っているけど別のもの」と読んでください. 値は同じであったとしても, 型が違えば「違うもの」として扱わなきゃならない場面が存在する.

yuukizx
質問者

補足

理論的?にいうとaはa[0]のアドレスを表しているが、 構成上により、実際にはa[0][0]のアドレスを指し示している。 故に、たまたま同じ値を持っている ということでしょうか?

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.6

「aはa[0]のアドレスならば、a[0][0]かa[0][1]のどちらのアドレスなのか わからないのではないでしょうか??」 というのは, 「何が」「a[0][0]かa[0][1]のどちらのアドレスなのか わからないのではないでしょうか??」と問うているのですか? int a[4][2]; の場合, a は (その最初の要素である) a[0] のアドレスとなります. 一方 a[0] は (その最初の要素である) a[0][0] のアドレスです. 構成上 a[0] の最下位バイトと a[0][0] の最下位バイトは同じ位置になるので, a と a[0] は「値として」は同じ (つまり (char *)a == (char *)a[0] が成り立つ) ですが, その型は違います. つまり「たまたま同じアドレスを持っているけど別のもの」と考えなければなりません.

  • D-Matsu
  • ベストアンサー率45% (1080/2394)
回答No.5

> aはa[0]のアドレスならば、a[0][0]かa[0][1]のどちらのアドレスなのか > わからないのではないでしょうか?? 実際のアドレス配置はともかくとして、「それがわかるという前提を置いてはいけない」が正解です。 #4の最後の例で考えた場合、aは「a[0]のアドレス」、a[0]は「ポインタaの値=a[0][0]のアドレス」以上の意味を持ちません。 a(=a[0]のアドレス)とa[0](=a[0][0]のアドレス)は別の値を持ちうる、というのがここでのポイントです。 ※配列限定なら大抵同じになっていると思いますが、上記のように憶えておくとポインタの際に役立ちます

yuukizx
質問者

お礼

とても参考になりました。ありがとうございました。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

あ, 確かにいた. しかし「配列名aは、配列の先頭アドレスを示すアドレス定数となります」はいただけないなぁ.... ここは変な方向に考えると混乱するところなので「理屈」をしっかり押さえておかないといけないところ. まず, 「配列名」は本来「配列全体」を表します. ただし, 式の中で「配列名」を使うと, 一定の条件下で「その配列の先頭要素のアドレス」に変換されます. また, この変換で得られる「アドレス」には「要素へのポインタ」という型が付きます. 例えば int x[4]; なら x は「各要素が int である, 要素数 4」の配列であり, これを変換すると x[0] (型は int) のアドレス (型は int *) になりますし, 同様に double y[100]; では y は「各要素が double である, 要素数 100」の配列で, 変換すると先頭要素 y[0] (型は double) のアドレス (型は double *) になります. そして int a[4][2]; では a は「各要素が int [2] である, 要素数 4」の配列なので, 変換すると a[0] (型は int [2]) のアドレス (型は int (*)[2]) となります. あくまで「a[0] のアドレス」であって「a[0][0] のアドレス」ではありません.

yuukizx
質問者

補足

aはa[0]のアドレスならば、a[0][0]かa[0][1]のどちらのアドレスなのか わからないのではないでしょうか?? 理解にいたらずすみません。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.3

え~と, 「アドレス定数」ってどこから出てくるんでしょうか?

yuukizx
質問者

補足

すみません、質問の意味がよくわからないのですが・・・。 「アドレス定数」という言葉がどこから来るという意味でしょうか?? それなら、NO2さんの参考URLから参考にさせていただきました。 間違っていたらすみません。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

関数の引数の場合 int func(int * b) と int func(int b[]) は同じです。 書き方の違いだけで、ポインタで受け取ってます。 int a[N][2] という二次元配列は int [2] の配列(長さN)ですから、関数で受ける場合は int func(int m[][2]) int func(int (* m)[2]) /* mは int [2]へのポインタ */ になります。が int func(int ** m) /* mは int *へのポインタ にはなりません。

参考URL:
http://news.mynavi.jp/articles/2008/04/18/pointer/index.html
yuukizx
質問者

お礼

今回の補足質問のきっかけになりました。ありがとうございました。

yuukizx
質問者

補足

参考URLを拝見させていただきました。少し言葉がおかしいかもしれませんが、 ポインタは変数のアドレス格納で、アドレス定数は定数(中身が決まっている)アドレス格納 ということでしょうか? となると、ポインタ自体にアドレスがあるようにアドレス定数にもアドレスがあるということでしょうか??

  • samtomsan
  • ベストアンサー率55% (1060/1897)
回答No.1

関数の引数を扱うとき、値渡しとポインタ渡し(参照渡し)の二種類がありますので、この辺りが理解できればすぐに分かります。これが理解できないと思った通りに動かないプログラムになってしまいます。(^_^) 「c 値渡し」などで検索してみてください。 下記などが参考になります。 http://www.c-lang.org/argument.html http://ratan.dyndns.info/MicrosoftVisualC++/hairetukansu.html http://www.geekpage.jp/programming/c/func-pointer-arg.php http://www.aerith.net/design/argument-j.html

yuukizx
質問者

お礼

たくさんURLとても参考になりました。ありがとうございました。

関連するQ&A

専門家に質問してみよう