- ベストアンサー
ポインタによる関数への配列渡し
林晴比古さんの「新C言語入門」でC言語を勉強している初心者です。 現在ポインタの勉強をしています。色々教科書の文例等をポインタで書くとどうなるか試しております。 上書P200練習問題2に「配列の最大値を返す(その際配列の長さを渡す)」プログラムがあり、それをポインタで渡すプログラムに直してみました。 仮引数に「maxdata」を設定し、そのアドレスを関数側に渡し、関数側ではポインタとして受け取る(そうすれば関数側からはreturnで値を返す必要がない)、と考え、下記のように書いてみました。 #include <stdio.h> void max_of_array(int n[], int len, int *ans); int main(void) { int dt[6] = {50,20,80,30,10,40}; int maxdata; max_of_array(dt,6,&maxdata); printf("最大値=%d\n", maxdata); return 0; } void max_of_array(int n[], int len, int *ans) { int i; ans = &n[0]; for (i=1; i<len; i++){ if (*ans < n[i]) *ans = n[i]; } } しかしコンパイルすると、何故か「最大値=1」となってしまいます。(正しくは80です) 他にも色々試してみましたがうまくいかず、かなり考えてみたのですがどうしても分かりません。お分かりの方、どうすれば正しくなるのが教えてください、よろしくお願いします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
>ans = &n[0]; でansの参照先がnの先頭番地に変えられてしまいますので、 >if (*ans < n[i]) *ans = n[i]; によって、最大値の答えはn[0]に入れられてしまいます。 呼び出す方では、d[0]に答えが入ってしまうわけです。 maxdataの値は最初の値(初期化されてないので不定)のままです。多分、たまたま1になっただけだと思います。 ans = &n[0]; を *ans = n[0]; にすればよいと思います。
その他の回答 (4)
- asuncion
- ベストアンサー率33% (2127/6289)
>>#1さん 自分に突っ込んでどうするw もちろん、 >#2さん が正しいです。
- asuncion
- ベストアンサー率33% (2127/6289)
>#1さん >どちらでもお好きなほうで。 そうではなく、前者は必須。後者はダメ。 後者がダメな理由は、このプログラムではdt[]をソートしている「のではない」から。
- Quant
- ベストアンサー率18% (23/122)
ans = &n[0];を*ans = n[0];とするか printf("最大値=%d\n", maxdata); をprintf("最大値=%d\n", dt[0]);とする。どちらでもお好きなほうで。 なぜそうなるかはポインタを本当に理解するとわかります。しっかり悩んでね。 みんな悩んで大きくなった。
お礼
「*ans=n[0]」に修正し、うまくいきました!どうもありがとうございました。 主文から関数に引数を渡した時点で、ansがmaxdataを参照できるようになっていたのを、 わざわざまたさらにn[0]のアドレスをansに投入してしまったことで ansはn[0]を参照するようになってしまったのですね。 はい。しっかり悩んでポインタをもっとちゃんと理解したいと思います! ありがとうございました。
- asuncion
- ベストアンサー率33% (2127/6289)
>ans = &n[0]; これは、何をしている文ですか? >if (*ans < n[i]) *ans = n[i]; このif文と書き方に違いがある理由は、何ですか?
お礼
上の「ans=&n[0]」で正しくアドレス設定したつもりになっておりました(*^_^*) 主文から関数に引数を渡した時点で、既にmaxdataを参照するように アドレス設定されていたのですね。 「*ans=n[0]」に書き換え正常にコンパイルできました! 早々にご回答いただきありがとうございました。
お礼
主文から関数に引数を渡した時せっかく、ansがmaxdataを参照できるようになっていたのに、 さらにansにまたn[0]のアドレスを入れてしまったせいで、 maxdataへの参照ができなくなって、 n[0]を参照するようになってしまったのですね。 そうなると確かにmaxdataの方は何もない状態に戻ってしまいますよね(*^_^*) 大変よく理解できました!コンパイルもうまくいきました。 丁寧なご回答どうもありがとうございました。