- ベストアンサー
配列を書き換える関数を作成してみたいのですが、
配列を書き換える関数を作成してみたいのですが、 int a[10]={3,5,7,6,7,8,10,2,3,11}; 上記のような配列があるとして、 0~9のうち特定の添字を指定して、a[]の中身を書き換える関数を作る場合は、 どのような方法があるのでしょうか?
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
#4 訂正 >ネストを似やすくするため全角スペースを入力しています ネストを見やすくするため全角スペースを入力しています どうせなので 多分間違いだとは思いますが#3さんのは >change(a, a, 2); change(a, 1, 2); の打ち間違いだと思われます 更に思いつき#1さんのをちょっと書き方変えてみました >void change(int a[],int i,int n){ >a[i]=n; >} コール側 change(a, 1, 2); //a[1] に2を代入する 関数側 void change(int *addr, int pt, int newdata){ *(addr+pt) = newdata; } もありかな(同じくコンパイルなどはしてません)
その他の回答 (5)
- koi1234
- ベストアンサー率53% (1866/3459)
>配列にポインタを使うメリットというのはどういうところなのでしょうか。 ポインタは配列限定で使うものではありません (確かに配列イメージが多いのは間違いはありませんし始めは其処からいったほうがわかりやすいです) 例えば構造体のアドレスを求めるなどのこともできます (ポインタとはアドレスを指し示している変数と考えてください) (考え方なので人それぞれですが)私が思うメリットとしては ・延々と配列で操作をするよりソースコードの文字的に少なくなる (↑かなり強引なメリット) ・一般的に配列でアクセスするよりポインタアクセスしたほうが 実行速度が速い(アセンブリコードなどを見比べると分かりやすい) ・関数の引数に構造体のポインタを渡すことなどで大量のデータの引渡しができる デメリットとしては ・慣れるまで難しい ・操作を間違えるとほぼ間違いなく他のメモリを破壊する ぐらいが思いつきます
お礼
丁寧な回答ありがとうございました。 ポインタはできるなら身につけたいと決意を新たにしました。
補足
ポインタというのは玄人好みの機能といえそうですね。 ほかのメモリを破壊するというのは、暴走してしまうというイメージでしょうか。 自分の作成したプログラムの範囲内でのメモリの破壊であればそれほどダメージはなさそうですが、 もしその他のアプリケーションなどに影響が出るのであれば素人には少しハードルが高めの機能ですね。 慣れるまで難しいということなので、理解できなくてもそれほどショックを受けなくてもよいということですね。 アドレスを指す変数ということでが、本日の配列の話に出てきたソースコードを見る限り、配列で使う限りは直接のアドレスを指定するのではないようなので、本日のソースコードの具体例をいじって使ってみてちょっとずつ覚えていくしかないようですね。
- koi1234
- ベストアンサー率53% (1866/3459)
>ところで関数側にint dummyというのがありますが、 >コピペしてみてビルドしてみると、dummyが定義されてないとかでエラーになっちゃって。 ネストを似やすくするため全角スペースを入力しています その為エラーになっていることが考えられます (他にも変換ミスで全角が残っているかもしれません) そうでない場合 >int dummy = *addr1; の書き方をBCCが認識してないかもしれません この行を以下の2行に書き換えてみてください int dummy; dummy=*addr1; コンパイルしたコートを転記ではなく直接入力してますので 其処は御勘弁を
お礼
ちなみにVC++ですが無事実行できたようです。 ありがとうございました。
補足
確かにスペースとカンマを半角にしたら無事実行できました。 初歩的なことを聞いてしまい申し訳ありません。 ところで、配列にポインタを使うメリットというのはどういうところなのでしょうか。 C言語を理解する上では重要なところではあるようですが、初心者にはポインタの意義がいまいちわからなかったりしてしまいます。
- επιστημη(@episteme)
- ベストアンサー率46% (546/1184)
> change(a[],1,2); > とすると、 「構文エラー : ']'」というエラーが出てしまいますが、 change(a, a, 2); が正解。
お礼
回答ありがとうございました。
- koi1234
- ベストアンサー率53% (1866/3459)
#1さんと同じで質問の趣旨がよく分かりませんし それだけを関数化してもあまりメリットないような気はしますが (逆にオーバヘッドで速度低下する気がしないでもない) そんなに多数の方法(書き方)があるわけではない思いますが #1さんが書いた2手法と違う書き方で書けば(関数名はパクって同じ名前にします) コール側 change(&a[3],30); //a[3]に30を代入する 関数側 void change(int *addr, int newdata){ *addr = newdata; } もしどこかの配列の中身(要素)を入れ替えたいのであれば (こっちはたまに関数にしたりしてます) コール側 swap(&a[3],&a[5]); //a[3]とa[5]のデータを入れ替える 関数側 void swap(int *addr1, int *addr2){ int dummy = *addr1; *addr1 = *addr2; *addr2 = dummy; } こんなとこかなと思いますが
お礼
配列の入れ替えのテクを覚えることができました。 ありがとうございます。
補足
とりあえず配列が10までというのはたとえで、 60くらいの数値を入れ替えたり書き換えたりといった感じで 添字も関数で計算で値を出したりしてるので、すっきりとしたソースにしたいと思って 関数を何個か使ってみようと思っています。 関数を使わずに力技でソースを書くと書き間違いや同じような内容の繰り返しでごちゃごちゃしてしまいそうなのも心配です。 詳しい方がすぐに質問に答えてくださるので、質問する初心者としては非常に密度の濃い情報だと思います。 ところで関数側にint dummyというのがありますが、 コピペしてみてビルドしてみると、dummyが定義されてないとかでエラーになっちゃって。 ポインタとかもよくわかっていないレベルなので、もしお時間がありましたらそこも説明していただけると嬉しいです。
- wildcat-yp
- ベストアンサー率37% (303/813)
普通に a[9]=0;とか書き換える以外の方法ということですか? 何を聞きたいのかがいまいちピンときません・・・ それとも配列を参照として関数に渡す方法ということですか?普通にわたると思いますが? 配列は普通に渡せば参照渡しになりますので。 void change(int a[],int i,int n){ a[i]=n; } こんな感じとか。
お礼
iとnの使い分けに何んとなくこだわりを感じました。 回答ありがとうございます。
補足
確かにあいまいな質問なのですが、回答は的確なようで、恐れ入ります。 ところで、 関数を呼び出す際に change(a[],1,2); とすると、 「構文エラー : ']'」というエラーが出てしまいますが、 定義した関数を呼び出す際は、この方法ではいかんのでしょうか? なにぶん初心者なので、基本的すぎる質問かもしれませんが、 可能であれば答えていただければと思います。
お礼
いつの日かポインタを攻略したいものです。 回答ありがとうございました。 皆様良いお年を!!
補足
配列の添字はポインタで置き換えが利いてさらに応用的な定義の仕方があるということですね。 今の段階ではまだよくわかりませんが、もう少しポインタが分かるようになったら、再度この関数が 理解できるようになるかもしれません。 C言語の参考書にもポインタと配列は密接な関係があるということですので、C言語を覚えるうえでは押さえておきたい重要な項目のようですね。