ここから本文です

C言語で2次元配列を戻り値として返したいです。基礎的な質問で申し訳ありません。 ...

lla********さん

2017/10/1617:59:51

C言語で2次元配列を戻り値として返したいです。基礎的な質問で申し訳ありません。
C言語で2次元配列を戻り値として返し、その後違う関数に渡したいです。

今作成中のプログラムが、大体下記みたいな感じになっています。

void main(){
int i, j;

a( i, j ); //?
b( X,H[][] ); //?
}

void a( int i, int j ){

int A[100][200];
int X;

「 iとjを利用しfor 構文でA[][]に値を格納済み。
int XにA[][]の最大値を格納済み。」

}

void b (???){
「ここで配列A[][]の値とXの値を使用したい。」
}

今ここで実現したい事は関数aで求めた配列A[][]とXをmainに戻り値として返し、その後関数bで使用したいです。
Xに関してはポインタを利用すれば、出来そうなのですが配列に関してはどう戻り値として返したらいいか全く分かりません。
???のところを埋めるように教えて頂けるようお願い致します。

閲覧数:
881
回答数:
5
お礼:
250枚

違反報告

ベストアンサーに選ばれた回答

bul********さん

2017/10/1619:05:36

このままでは、どうやっても関数a()のA[][]を関数b()に渡すことはできません。
A[][]はローカル変数なので、関数a()からmain()に戻った時点で、A[][]はもう有効ではありません。単純にポインタを戻しても、実態はなくなっています。xは戻り値として、返せば良いでしょう。

これを実現する方法は幾つかありますが、一番簡単なのはA[][]をmain()で確保して、関数a()に渡して値を格納後、関数b()に渡せば良いでしょう。

int a(int i, int j, int A[100][200])
{
int x;

/* A[][]に値を格納 */

return x; /* xの値を返す */
}

void b(int x, int A[100][200])
{
/* A[][] を使う */
}

int main()
{
int A[100][200];
int i, j;
int x;

x = a(i, j, A);
b(x, A);
}

  • 質問者

    lla********さん

    2017/10/1620:47:13

    回答ありがとうございます。
    今は戻り値がxだけですが、yが増えて複数になった場合に備えて
    なるべくreturnを使用したくないのですが、
    ポインタで返したい場合は以下のソースコードでいけますか?

    int a(int i, int j, int A[100][200],int *x)
    {

    /* A[][]に値を格納 */

    *x = 「整数」;
    }

    void b(int x, int A[100][200])
    {
    /* A[][] を使う */
    }

    int main()
    {
    int A[100][200];
    int i, j;
    int x;

    a(i, j, A,&x);
    b(x, A);
    }


  • その他の返信(1件)を表示

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

質問した人からのコメント

2017/10/21 03:55:26

一番簡単で分かりやすかったです!ありがとうございまして!

ベストアンサー以外の回答

1〜4件/4件中

並び替え:回答日時の
新しい順
|古い順

プロフィール画像

カテゴリマスター

qui********さん

2017/10/1718:39:48

いろいろやり方は考えられますが、Cで一番ふつーにそれを書くとしたら、
関数の呼び出し元で配列の格納領域を確保してそれを(そのポインタを)関数に渡し、書き込ませる
でしょう。

int main(void){//教科書的、というかC規格に登場する普遍的なmainはこれ
int i, j;
int a[100][200];

int X=a( i, j, a );
b(X,a);
return 0;
}

int a( int i, int j, int array[][200] ){
int max;
for(int ii=0;ii<i;ii++){
for(int jj=0;jj<j;j++){
array[ii][j]=func(ii,j);//とかなんとか配列の要素を設定
}
}
//最大値を求めて
return max;
}

付帯する情報が増えたとして、構造体にまとめれば返り値でコピー渡しも出来るのですが、やはりコピーのコストを嫌って呼び出し元で変数領域を確保して

//構造体定義
struct st{
int a[100][200];
int max,min;
};

int main(void){
struct st A;
a( &A);
b( &A);
retrun 0;
}

void a(struct st* arg){
for(int ii=0;ii<i;ii++){
for(int jj=0;jj<j;j++){
arg->a[ii][j]=func(ii,j);
}
}
int max,min;
//最大値を求めて
arg->max=max;
//最小値を求めて
arg->min=min;
}

とかやるかなぁ。

プロフィール画像

カテゴリマスター

hid********さん

2017/10/1623:27:37

a が、return すれば、
その配列、無くなっちゃう!

main から受けて、a と b で
加工を加えた方が、妥当でしょ。

mei********さん

2017/10/1619:22:11

関数から二つの値を戻すことはできません。
解決策は、グローバル変数を使うこと、関数内で値を変更すれば、変更した値を関数外で使えます。
今一つは、関数外で配列を定義しておいて、関数に引数として渡すとアドレスが渡されるので同様なことが出来ます。
詳しいことは、テキストやインターネットで調べてください。

tar********さん

2017/10/1618:55:04

(1)
ひとまとまりとして扱いたいデータは構造体としてまとめるのがよいでしょう。
typedef struct _Data
{
int A[100][200];
} Data;
みたいな形で。
あとは、Data 型を関数の引数にしたり、戻り値にしたり。

(2)
ただ、関数の引数も戻り値もコピー渡しなので、
大きなサイズのデータも全体をコピーします。
それが大きな無駄になる可能性もあります。
それを避けたい場合は、引数に Data のポインター(Data* 型) を渡す。
戻り値の場合もポインターを返す。

(3)
ただ、
一時変数のポインターを戻り値として返す形だと
一時変数が破棄され、無効な領域のポインターを扱うバグが生じます。
なので、
malloc(sizeof(Data));
で割り当てたメモリに Data 型のデータを構築して返すのがいいでしょう。
ただし、malloc したメモリを誰が free するかはきちんと設計する必要があります。
小さいプログラムなら、メモリリークが起こっても気にならないかもしれませんが、
まあ、作法として。

(4)
ひとまとまりのデータを構造体にする考え方になれれば、
自然と class 的な発想、C++的な発想、オブジェクト指向的な発想につながりそうです。
class は構造体に関係する関数もくっつけたようなものですから。
この構造体に、メモリ管理の機能までくっつけたいな、
そういうことを C++ なら実現できます。

返信を取り消しますが
よろしいですか?

  • 取り消す
  • キャンセル

あわせて知りたい

この質問につけられたタグ

みんなで作る知恵袋 悩みや疑問、なんでも気軽にきいちゃおう!

Q&Aをキーワードで検索:

Yahoo! JAPANは、回答に記載された内容の信ぴょう性、正確性を保証しておりません。
お客様自身の責任と判断で、ご利用ください。
本文はここまでです このページの先頭へ

「追加する」ボタンを押してください。

閉じる

※知恵コレクションに追加された質問は選択されたID/ニックネームのMy知恵袋で確認できます。

不適切な投稿でないことを報告しました。

閉じる