• ベストアンサー

配列を書き換える関数を作成してみたいのですが、

配列を書き換える関数を作成してみたいのですが、 int a[10]={3,5,7,6,7,8,10,2,3,11}; 上記のような配列があるとして、 0~9のうち特定の添字を指定して、a[]の中身を書き換える関数を作る場合は、 どのような方法があるのでしょうか?

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

  • ベストアンサー
  • koi1234
  • ベストアンサー率53% (1866/3459)
回答No.5

#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; } もありかな(同じくコンパイルなどはしてません)

okwave_q_a
質問者

お礼

いつの日かポインタを攻略したいものです。 回答ありがとうございました。 皆様良いお年を!!

okwave_q_a
質問者

補足

配列の添字はポインタで置き換えが利いてさらに応用的な定義の仕方があるということですね。 今の段階ではまだよくわかりませんが、もう少しポインタが分かるようになったら、再度この関数が 理解できるようになるかもしれません。 C言語の参考書にもポインタと配列は密接な関係があるということですので、C言語を覚えるうえでは押さえておきたい重要な項目のようですね。

その他の回答 (5)

  • koi1234
  • ベストアンサー率53% (1866/3459)
回答No.6

>配列にポインタを使うメリットというのはどういうところなのでしょうか。 ポインタは配列限定で使うものではありません (確かに配列イメージが多いのは間違いはありませんし始めは其処からいったほうがわかりやすいです) 例えば構造体のアドレスを求めるなどのこともできます (ポインタとはアドレスを指し示している変数と考えてください) (考え方なので人それぞれですが)私が思うメリットとしては ・延々と配列で操作をするよりソースコードの文字的に少なくなる (↑かなり強引なメリット) ・一般的に配列でアクセスするよりポインタアクセスしたほうが  実行速度が速い(アセンブリコードなどを見比べると分かりやすい) ・関数の引数に構造体のポインタを渡すことなどで大量のデータの引渡しができる デメリットとしては ・慣れるまで難しい ・操作を間違えるとほぼ間違いなく他のメモリを破壊する ぐらいが思いつきます

okwave_q_a
質問者

お礼

丁寧な回答ありがとうございました。 ポインタはできるなら身につけたいと決意を新たにしました。

okwave_q_a
質問者

補足

ポインタというのは玄人好みの機能といえそうですね。 ほかのメモリを破壊するというのは、暴走してしまうというイメージでしょうか。 自分の作成したプログラムの範囲内でのメモリの破壊であればそれほどダメージはなさそうですが、 もしその他のアプリケーションなどに影響が出るのであれば素人には少しハードルが高めの機能ですね。 慣れるまで難しいということなので、理解できなくてもそれほどショックを受けなくてもよいということですね。 アドレスを指す変数ということでが、本日の配列の話に出てきたソースコードを見る限り、配列で使う限りは直接のアドレスを指定するのではないようなので、本日のソースコードの具体例をいじって使ってみてちょっとずつ覚えていくしかないようですね。

  • koi1234
  • ベストアンサー率53% (1866/3459)
回答No.4

>ところで関数側にint dummyというのがありますが、 >コピペしてみてビルドしてみると、dummyが定義されてないとかでエラーになっちゃって。 ネストを似やすくするため全角スペースを入力しています その為エラーになっていることが考えられます (他にも変換ミスで全角が残っているかもしれません) そうでない場合 >int dummy = *addr1; の書き方をBCCが認識してないかもしれません この行を以下の2行に書き換えてみてください int dummy; dummy=*addr1; コンパイルしたコートを転記ではなく直接入力してますので 其処は御勘弁を

okwave_q_a
質問者

お礼

ちなみにVC++ですが無事実行できたようです。 ありがとうございました。

okwave_q_a
質問者

補足

確かにスペースとカンマを半角にしたら無事実行できました。 初歩的なことを聞いてしまい申し訳ありません。 ところで、配列にポインタを使うメリットというのはどういうところなのでしょうか。 C言語を理解する上では重要なところではあるようですが、初心者にはポインタの意義がいまいちわからなかったりしてしまいます。

回答No.3

> change(a[],1,2); > とすると、 「構文エラー : ']'」というエラーが出てしまいますが、 change(a, a, 2); が正解。

okwave_q_a
質問者

お礼

回答ありがとうございました。

  • koi1234
  • ベストアンサー率53% (1866/3459)
回答No.2

#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; } こんなとこかなと思いますが

okwave_q_a
質問者

お礼

配列の入れ替えのテクを覚えることができました。 ありがとうございます。

okwave_q_a
質問者

補足

とりあえず配列が10までというのはたとえで、 60くらいの数値を入れ替えたり書き換えたりといった感じで 添字も関数で計算で値を出したりしてるので、すっきりとしたソースにしたいと思って 関数を何個か使ってみようと思っています。 関数を使わずに力技でソースを書くと書き間違いや同じような内容の繰り返しでごちゃごちゃしてしまいそうなのも心配です。 詳しい方がすぐに質問に答えてくださるので、質問する初心者としては非常に密度の濃い情報だと思います。 ところで関数側にint dummyというのがありますが、 コピペしてみてビルドしてみると、dummyが定義されてないとかでエラーになっちゃって。 ポインタとかもよくわかっていないレベルなので、もしお時間がありましたらそこも説明していただけると嬉しいです。

回答No.1

普通に a[9]=0;とか書き換える以外の方法ということですか? 何を聞きたいのかがいまいちピンときません・・・ それとも配列を参照として関数に渡す方法ということですか?普通にわたると思いますが? 配列は普通に渡せば参照渡しになりますので。 void change(int a[],int i,int n){ a[i]=n; } こんな感じとか。

okwave_q_a
質問者

お礼

iとnの使い分けに何んとなくこだわりを感じました。 回答ありがとうございます。

okwave_q_a
質問者

補足

確かにあいまいな質問なのですが、回答は的確なようで、恐れ入ります。 ところで、 関数を呼び出す際に change(a[],1,2); とすると、 「構文エラー : ']'」というエラーが出てしまいますが、 定義した関数を呼び出す際は、この方法ではいかんのでしょうか? なにぶん初心者なので、基本的すぎる質問かもしれませんが、 可能であれば答えていただければと思います。

関連するQ&A

  • C言語で、他の関数で配列を書き換えられないようにしたい

    下のCのプログラムでは、func関数は配列aの先頭要素へのポインタを返します。 main関数の側では配列aの中身を表示します。 しかし、main関数のfor文の中の★の部分をコメントアウトせずに入れると、この配列の中身が書き換わってしまいます。  私はfunc関数以外では、この配列の中身をいじられたくないのです。  なんとかfunc関数を工夫して作成して、func関数以外では、配列の中身が変わらないようにしたいのですが、どうすればよいでしょうか。    とは言ったものの、多分できないだろうなあ、という気がします。  できないならばできないでも仕方ないのですが、確信が持てないのです。 条件があります。 funcでは表示は行なわない。 配列aの中身を表示できるように、funcから呼び出し元へ、aのアドレスまたはaの先頭要素のアドレスがわかるような情報を返す。 #include <stdio.h> char *func(int i) { static char a[]="AAAA"; a[i]='z'; return a; } int main(void) { int i; for(i=0; i<4; i++) { char *p=func(i); /* p[i]='X'; ★配列の中身を書き換えてしまう。 */ puts(p); } return 0; }

  • 自作関数の連想配列をreturnしたい。 

    環境:PHP5:WinXP(SP2) 自作関数を作成しているのですが、 不特定多数の添え字を持つ連想配列を全てreturnする 教えて頂けませんか?

    • ベストアンサー
    • PHP
  • C言語の配列について質問です。

    配列の添え字に別の配列を指定するような以下の処理について 質問です。 #include <stdio.h> int main(void) {    int k = 0;    int kn = 0;    char str[256];    char key[] = "ABCD";    kn = strlen(key);    for(k=0; k<kn-1; k++) {    str[key[k]] = kn-k-1;    } } 上記についてですが、for文の中で "str[key[k]]"とありますが、 ループ処理にともなって配列str[] の添え字は、str[A], str[B], str[C] となるのでしょうか?? その場合、結果的に配列str[]の各要素にはどのような値が格納され るのでしょうか? そもそも、配列の添え字に対して別の配列を指定した場合の動きが よくわかりません。 どなたか教えて頂けますか??

  • 関数に配列を渡すときの質問です

    関数に配列を渡したいんですがこのソースが問題ないか見てください。 #include<stdio.h> #define N 10 #define M 20 int sig(int X[],int x); main() { int a[N],b[M],i,x,y; for(i=0 ; i<N ; i++){ a[i]=i; } for(i=0 ; i<M ; i++){ b[i]=i; } x=sig(a,N); y=sig(b,M); } int sig(int Z[],int x){ int i,k; k=0; for(i=0 ; i<x ; i++){ k=k+Z[i]; } return k; } ソースは以上です。 1つのソースの中でa[N]とb[M]のように違う数の 配列があるんですが、その配列全部(0~N-1、0~M-1)とかを足してくれる(シグマ)関数を作りたいんですが、Z[]と配列の数を指定しなくてもちゃんと動いてくれるんでしょうか?関数のほうの int x で配列の数を指定するようにしています。 自分でテストした限りではちゃんと動いているようなんですが、間違ってるようなら指摘お願いします。

  • [C言語] 配列が添字の意味を失う理由

    はじめまして。こんばんは。 早速ですが、下記のソースコードは、 配列aの各要素の内容を先頭から順に調べ、最初に0であった要素の添字番号を表示する。 という内容の、C言語のプログラムです。(C++でコンパイルするためmain()はint型に指定) そこで、このプログラムを実行していて腑に落ちない点として、 プログラムの挙動を見る限り、 タイトルに書いたとおり、 「配列が添字の意味を失っている」という事なんです。 普通に配列の添字と考えれば、 while文の条件式は、 int i=0; while(a[i]) { i++; } なので、a[0]になるはずなので、 普通に考えれば 条件式の中身としては  配列a[0] が 配列a[0] になるまでi++をするとなるはずです。 しかしながら、このプログラムは、 初期値に「0」が入っている要素まで探し続けます。 なぜ、 「配列が添字の意味を失うのか?」 どなたか、この疑問にお答えしていただけますと幸いです。 「プログラムの内容」 配列aの各要素の内容を先頭から順に調べ、最初に0であった要素の添字番号を表示する。 「表示結果」 a[2]= 0 「ソースコード」 #include<stdio.h> int main() { int a[]={3,0,7,8,5,5,8}; int i=0; while(a[i]) { i++; } printf("a[%2d]=%2d \n",i,a[i]); }

  • 関数から配列を返すには?

    return で配列を返すにはどうしたらよいのでしょうか。 例えば以下のような場合です。 int main (){ char Value[] = "999"; int a;  a = test(Value);  printf ("%d", a);   } int test(char *Value) { int nVal[255]; ここで nVal に適当な処理をして・・・  return Value; }  int a を配列とかにしてみましたけど、コンパイラが 通りません。 要は配列数値を main で受け取って表示したいのですが、 本日C言語はじめたところなので、教えていただければありががたいです。

  • 配列の大きさ

    こんにちは、 ちょっとしたことがわからないので、書きこみました。 int a (int hikisuu1, int hikisuu2){ int b[hikisuu1]; } 当然ながら、上のソースは、エラーがでます。 関数内で扱う配列の大きさを引数によって決める方法を 教えてもらえるよう、お願いします。

  • C言語 配列・関数の問題

    下記の問題が解けなくて困っております。 for文をつかった解法をお願いしたいです。 n個の要素からなる整数の配列a[ ]の中から2番目に大きな値を求め、それを戻り値とする関数maxsecを作成しなさい。 int maxsec(int n , int a[ ]) { 宜しくお願いします。

  • 配列に添え字を書かないと・・・

    java初心者です。 配列として宣言した変数(?)に、添え字を書かないとどういう処理をするのでしょうか? 例えば、 int[] n = new int[10]; という書き方をしたのに、使うときに n というのを何の添え字もつけずに使っているようなのですが・・。 よろしくお願いします。

  • ポインタと配列

    配列を複数他の関数に渡す方法を知りたいです。1つの場合は、次でできました。 void sample2(int *a) { printf("%d",a[2]); } int sample1() { int a[]={0,1,2}; sample2(a) return(0); } sample1のなかにもっと多数の配列a1,a2,a3,....,ax,.... が存在する時に、それを他の関数にわたす効率のいい方法はありますか?基本的な質問かもしれませんがCの本が今手元に無かったので質問させていただきました。

専門家に質問してみよう