C言語初心者のための関数への多重配列の値の送り方

このQ&Aのポイント
  • C言語初心者のため、関数へ多重配列の値を送る方法を教えてください。
  • 現在は別の1次元配列を作り、そこに一旦コピーしてから関数に送っていますが、他にもっと良い方法はありますか?
  • 配列の左と右に値を指定して、その中の配列を関数に送りたいです。具体的な方法を教えてください。
回答を見る
  • ベストアンサー

C言語について

C言語初心者です。 今、プログラミングをしていてわからない箇所があるので質問させていただきます。 自作の関数へ配列を送る際、多重配列の途中の配列の値を関数に送りたい場合どのようにすれば よいのでしょうか? 文ではわかりづらいと思うので、例を書きます。↓ /* 関数 */ int sum(int data[],int N){ int i,temp=0; for(i=0;i<N;i++){ temp=temp+data[i]; } return(temp); } /* 本文 */ int output; int a[10][20][30]={適当な数字が入ってるとします。} // この時、配列の左と右に値を指定して、真ん中の配列を関数に送りたいです。 output=sum(???,20); //ちなみに現在はもう一つ1次元配列を作り、そこに一旦コピーしてから関数に送っています。 //なにか良い方法があればご教授ください。

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

  • ベストアンサー
  • k_kota
  • ベストアンサー率19% (434/2186)
回答No.1

要するに、3次元配列のうち、1,3番目の要素を固定して1次元配列としたいのですね。 ポインタを使えば、お望みの形式で実現は可能です。 ただ、この書きっぷりだとちょっと早いような気がします。 MATLABだと簡単なんですけどね。 特に事情がなければ2つ目と3つ目を入れ替えれば簡単になります。 要するにint []としてa[x][y]とかとすれば最後の1次元配列だけ渡せます。 それ以外なら、最初から3次元配列として渡すのもありだと思います。 色々ありますが、何回も使うならそれに最適化した関数を作ればいいし、 1回なら気にしないで分かりやすいのを使う。 特定の箇所なら工夫してうまくやるとかですかね。 思いつかないなら、今できる方法で十分とするのもありだと思います。

ringo_072
質問者

お礼

回答ありがとうございます。 >色々ありますが、何回も使うならそれに最適化した関数を作ればいいし、 さっそくやってみたいと思います。 ポインタは、何度か試したのですが、ポインタの理解が浅いために上手く扱えません。(汗 実際は同じような演算を繰り返し行わないといけないので、なるべく処理が少なくなる方法を考えてみたいと思います。

その他の回答 (3)

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.4

>int data[6000] と int data[10][20][30]が等価 すこし語弊があるので訂正。 int data[6000] = { ... . };と int data[10][20][30] = { { {...}} , ... };です。 また、「等価値」なのであって、 「同じ」ではないので注意してください。 それぞれの、型は異なります。

ringo_072
質問者

お礼

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

  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.3

「真ん中の配列」ということですが、 計算結果はどのようなものを望んでいるのでしょうか。。。? 関数に対し、コンパイルエラーのない、 引数を渡す事は簡単ですが期待する計算結果が 間違っている可能性があります。 int data[6000] と int data[10][20][30]が等価であることが 理解できれば、それほど難しくないと思うのですが、 どのような結果を期待しているのか補足して貰えないでしょうか? #numが20と指定されていますが、渡した配列の位置から開始して #20個の合計でいいのでしょうか?

ringo_072
質問者

お礼

回答ありがとうございます。 試行錯誤の結果、メモリ等に問題は残りますが解決できました。 お手数をおかけしました。

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.2

配列のサイズが固定なら、こんな書き方もできますが。 int sum(int data[10][20][30],int N,int index1,int index2){ int i,temp=0; for(i=0;i<N;i++){ temp=temp+data[index1][i][index2]; } return(temp); } 呼ぶほうは int output; int a[10][20][30]={適当な数字が入ってるとします。} // この時、配列の左と右に値を指定して、真ん中の配列を関数に送りたいです。 output=sum(a,20,???,???); こんな感じ。

ringo_072
質問者

お礼

回答ありがとうございます。 実際には配列のサイズは場合によって異なります…。 少しメモリがもったいないかもしれませんが、関数内に大きめの配列を用意して、多重配列をすべて送ることで、演算は上手くいきました^^

関連するQ&A

  • C言語から質問です。

    C言語から質問です。 /* main関数の中で初期化した配列 data[10]={60,30,70,25,20,9,92,55,20,10}; を関数 keisan() に引数として渡して、関数keisan()内で 平均値、最大値,最小値 を求め、その結果をmain関数に戻し、main関数内で 平均値、最大値,最小値を表示させるプログラムを作成せよ。 int keisan(const int data[], int data_kosuu, double answer[]) { return 0; } とする。 (注) プロトタイプ宣言を用いよ。 ヒント:平均値,最大値,最小値の3つの値を main関数に戻すやり方として、配列answer[]を使うとよい。 data_kosuu は、配列の要素数を与えるものです。 ヒント: (int型の変数)/(int型の変数)=int型の値です。 int型同士の割り算の答えANSWERをdoubleにしたい場合は、  ANSWER=(double)(int型の変数)/(int型の変数);    と(double) キャストという操作をする必要がある */ #include <stdio.h> int keisan(const int data[], int data_kosuu, double answer[]); int main(void) { int i; int a[10]={60,30,70,25,20,9,92,55,20,10}; // この値を使ってください double ans[3]; keisan(a,10); /* keisan関数に配列と配列要素数を引数で与える */ for(i=0; i<10 ; i++) printf("a[%d]=%d\n",i,a[i]); printf("平均=%lf 最小値=%d 最大値=%d\n",ans[0],ans[1],ans[2]); return 0; } /* 合計・最大値・最小値を求める関数 */ int keisan(const int data[], int data_kosuu, double answer[]) { int i; int sum; int min,max; min=10; /* min の初期化 */ max=10; /* max の初期化 */ sum=0; /* 合計値の初期化 */ for (i=0; i<10 ; i++){ sum = sum+data[i]; if(data[i] > max) max=data[i]; if(data[i] < min) min=data[i]; } sum=sum/10; answer[0]=sum; answer[1]=min; answer[2]=max; } エラー error C2198: 'keisan' : 呼び出しに対する引数が少なすぎます。 とでて先に進めません。 教科書などを見ても間違いがわかりません; 虫食いになってるところを自分なりにやってみたため、 根本的に間違ってるかもしれませんが、 どうかアドバイスや指摘などをお願いします。

  • C言語の配列について

    配列を20 定義し値を入力して合計値を出したいのですがどうすればよいのでしょうか 下のソースでエラーはおこりませんでした 何がちがうのでしょうか #include <stdio.h> int main() { int a[20]={}; int i, sum; printf("整数を入力してください:"); scanf("%d",&a); printf("\n"); for (i = 0; i < 10; i++) { sum += a[i]; } printf("sum= %d\n", sum); return 0; }

  • C言語のプログラムについて。

    C言語のプログラミングについて質問です。 入力されたデータの配列とデータ数を渡すと配列に格納された値を逆順にして、格納し直す関数reverse関数を書き結果を出力せよ、というものなのですが下のように書いたのですが、うまく作動しません。どこがいけないのでしょうか...?教えていただきたいです。 #include <stdio.h> void reverse(int *data[], int n); #define MAX 100 int main() { int data[MAX]; int n, i; scanf("%d", &n); if (n >= MAX) n = MAX; for (i = 0; i < n; i ++){ scanf("%d", &data[i]); } reverse(data, n); for (i = 0; i < n; i ++) { printf("%d\n", data[i]); } return 0; } void reverse(int *data[], int n) { int c, i; for (i = 0; i < n; i ++) { c = *data[i]; *data[i] = *data[n - (i + 1)]; *data[n - (i + 1)] = c; } }

  • C言語をお願いします

    何が違うのか教えてください。 segmentation faultになります。 よく分からないので、プログラムを作っていただければ、助かります。 問 整数を入力し、降順並び変えてに表示。 ・入力した整数は配列に入れ、その配列を使って並び変える(入力終りの印は 1000 とする)。 ・入力する整数の個数は #define NUM 100 を使いなさい。 ・使うデータは、下記の例のように、キーボードから入力すること。 #include<stdio.h> #define NUM 100 int main(void){ int d[NUM]; int temp; int i,j,n; printf("Input scores.\n"); for(i=0; i<NUM && d[i]!=1000; i++){ scanf("%d",&d[i]); } n = i; for(i = 0; i < n; i++){ for(j = i + 1; j < n;j++){ if(d[j] > d[i]){ temp = d[i]; d[j] = d[i]; d[i] = temp; } } } printf("After sort."); for(i=0; i < n; i++){ printf("%d\n",d[i]); } return 0; } 実行例 Input scores. 60 30 45 90 100 0 1000 After sort. 100 90 60 45 30 0 よろしければ 問2 並び変えをする部分を mysort 関数にしたプログラムを作ってください。 main 関数から mysort 関数には点数の個数と sort 前の配列を渡し、並び変え結果の表示はmain 関数でお願いします。 (問題の意味が分かりません) 関数はさっぱり分かりません。 では、お願い致します。

  • C言語

    昇順にソートしたいのですけど、このソースだと実行しても、最後に入力した文字が、表示されます。分からないので宜しくお願いします。(例21,34 55を入力すると、55,55,55と表示されます) #include <stdio.h> void sort1(int *dt, int n) { int i,temp,exchg=0; while (exchg<n) { for (i=1; i<n; i++) { if (dt[i-1] > dt[i]) { temp=dt[i-1]; dt[i-1]=dt[i]; dt[i]=temp; } } exchg++; } }int main(void) { int data[10]; int no=3; int i,*p_data; p_data =data; printf("%d個の整数を入力してください。\n",no); for (i=0; i<no; i++) { printf("data[%d]:",i); scanf("%d", p_data); } sort1(data,no); puts("これからの値を昇順に並び替えました。"); for (i=0; i <no; i++) printf("data[%d]=%d\n", i,*p_data); return(0); }

  • c言語つくってみました

    #include<stdio.h> #define N 5 struct MEMBER{ int no; char name[8+1]; int run; int jump; int power; int sum; double avg; }; void Calc_Sum(struct MEMBER *data) { data->sum=data->run+data->jump+data->power; return(0); } void Calc_Avg(struct MEMBER *data) { data->avg=data->sum/3.0; return(0); } void Display_Data(struct MEMBER data) { printf("---判定---\n"); printf("背番号:%5d\n",data.no); printf("名前:%5s\n",data.name); printf("走力 :%5d 点数\n",data.run); printf("跳躍力:%5d 点数\n", data.jump); printf("筋力 :%5d 点数\n", data.power); printf("総計 :%5d 点数\n", data.sum); printf("平均 :%5.1f 点数\n", data.avg); return(0); } int main(void) { int i; struct MEMBER member[N] ={{51,"イチロー",95,95,80,0,0}, {55,"松井秀喜",70,80,90,0,0}, {18,"松坂大輔",75,75,80,0,0}, {18,"黒田博樹",80,85,85,0,0}, {19,"上原浩治",85,85,85,0,0}, }; struct MEMBER *p=member; /*総計の算出*/ for(i=0;i<N;i++) Calc_Sum(p+i); /*平均の算出*/ for(i=0;i<N;i++) Calc_Avg(p+i); /*結果の出力:*/ for(i=0;i<N;i++) Display_Data(member[i]); return(0); } 以上のようなのc言語をつくりました。 他に関数を2つ使用しなければならないのですが アドバイスよろしくお願い致します。

  • データのカウント方法について(C言語初心者です)

     二次元配列(10×10)の中のある特定のデータx[i][j][1]の総数を出力するというプログラムを作っています。  しかし、これだとデータがうまくカウントされません。x[i][j][1]は他の関数内で計算するようにしています。 int t, sum=0; for(t=0;t<=1000;t++){ for(i=0;i<N;i++){ for(j=0;j<N;j++){ sum=sum+x[i][j][1];      } } } printf("%d ?n", sum);  何が悪いのでしょうか?教えて頂けたら幸いです。

  • C言語 クイックソートについて

    クイックソートでわからない点があるため、 質問させていただきます。 ----------------------------------------------------- ~省略~ data = [5, 3, 4, 2, 6, 1]; no = 6; //データの個数 ~省略~ dqsort(data, 0, no-1); ~省略~ void dqsort(double data[], int lower, int upper) {   int i, boundary; //boundaryは配列の前半と後半の境界を示す   if(lower >= upper) { return; }   //基準値となる値(データの中央に位置する値)とデータの先頭の値を入れ替える   swapdata(&data[lower], &data[(lower + upper)/2]);   boundary = lower; //boundaryを先頭に移動させる     for(i=lower+1; i<=upper; i++) {       if(data[i] < data[lower]) {         //配列の前半部分に移動し、境界を移動する         swapdata(&data[++boundary], &data[i]);       }     }   //最後に基準値を境界位置にコピー   swapdata(&data[lower], &data[boundary]);   //配列の前半部分をクイックソート   dqsort(data, lower, boundary-1);   //配列の後半部分をクイックソート   dqsort(data, boundary+1, upper); } void swapdata(double *i, double *j) {   int temp;   temp = *i;   *i = *j;   *j = temp; } --------------------------------------------------------- 基準値と配列の先頭のデータを入れ替えた後、 データは、[4, 3, 5, 2, 6, 1]となり、lower = 0であるため、 data[boundary]はdata[0]となります。 for文の最初のループでdata[0]<data[1]なら、 swapdata(&data[++boundary], &data[i]); となっているのですが、 [++boundary]の部分はboundary=0に1を足してから処理するため、 swapdata(&data[1], &data[1]); となると思うのですが、そうすると同じデータを入れ替えることになってしまいます。 何が間違っているのか、教えていただけますでしょうか。

  • C言語課題!C言語初心者です。お願いします。

    課題内容 要素数10の(0~9の順)配列Aの値を2倍して配列Bに格納して  その後配列Aの値を配列Bに、配列Bの逆順を配列Aに格納し  入れ替える前と入れ替えた後の配列A,Bの値を表示するプログラム 書いてみたプログラム #include <stdio.h> int main(void) { int i; int va[10] = {0,1,2,3,4,5,6,7,8,9}; /* 初期化 */ int vb[10]; puts("入れ替え前"); puts("-----------"); for(i=0 , i<10 , i++){ printf("va[%d] = %d\n" , i , va[i]); /* 入れ替え前の配列A */ } for(i=0 , i<10 , i++){ vb[10] = 2*va[10]; } for(i=0 , i<10 , i++){ printf("vb[%d] = %d\n" , i ,vb[i]); /* 入れ替え前の配列B */ } puts("入れ替え後"); puts("-----------"); for(i=0 , i<10 , i++){ vb[10] = va[10]; } for(i=0 , i<10 , i++){ printf("vb[%d] = %d\n" , i ,vb[i]); /* 入れ替え後の配列B */ } for(i = 0 , i < 5 , i++){ /* 配列Bの逆順を配列Aに格納 */ int temp = va[i]; va[i] = vb[4-i]; vb[4-i] = temp; } for(i=0 , i<10 , i++){ printf("va[%d] = %d\n" , i ,va[i]); /* 入れ替え後の配列A */ } return(0); } コンパイルできません。 教えてください。お願いします。

  • C言語 勉強始めた所で、まだ良く解りません、教えてください!

    C言語 勉強始めた所で、まだ良く解りません、教えてください! このプログラムを実行すると、5,5と表示されると思うのですが? /*****************************************************************************/ #include <stdio.h> int average( int *data, int count ) { int i, sum=0; for( i=0; i<count; i++ ) sum+=data[i]; return sum/count; } int main(void) { int numbers [] = { 2, 3, 5, 7, 9, 11, 13, 15, 17,19 }; printf("%d\n",average(numbers,5)); return 0; } /*******************************************************************************/ 5、だけしか表示されません、これでよいのでしょうか?

専門家に質問してみよう