質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

3回答

7798閲覧

c++ 2次元配列の1列を要素として関数に渡したい

ham33

総合スコア15

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

0クリップ

投稿2019/01/11 12:52

編集2019/01/12 06:08

2次元配列があり、その配列の一列分を
要素として関数に渡したいです。

関数は1次元でかかれていて、かなり複雑なので
それを2次元に書き換えるより、2次元の配列の1次元を
要素として関数に渡せることができればと考えました。

現在

c++

1#define M 2#define N //数を指定 3 4void func(double *a, double *b, int N){ 5 //ここで複雑な計算をしてるので書き換えるのは厳しい 6 //入力がa, 出力をbで受け取るようにしてある 7} 8 9int main(void){ 10double *a = new double[N]; 11double *b = new double[N]; 12 13 14func(a, b, N); 15 16//ここでbを使ったプログラムが書いてある 17 18delete[] a; 19delete[] b; 20return 0; 21}

のようにしてあります。かなり端的に書いたので、不十分な点がありましたら
申し訳ございません。これを多次元にしてある配列を用意し、
その一列分を渡したいです。

c++

1void func(double *a, double *b, int N){ 2//関数は書き換えない 3} 4int main(void){ 5double **a= new double *a[N]; 6 for(i=0;i<N;i++){ 7 a[i] = new double[M]; 8 } 9double **b= new double *b[N]; 10 for(i=0;i<N;i++){ 11 b[i] = new double[M]; 12 } 13 14func( );//ここに配列の1列分を要素として渡したい 15//今まではa[N]={1.0,2.0,3.0}を渡してた 16//今度は a[N][M]={1.0,2.0,3.0}{4.0,5.0,6.0}の{1.0,2.0,3.0}を渡した 17 18//ここで出力bを使ったプログラムが書いてある 19 20for(i=0;i<N;i++){ 21 delete a[i]; 22 delete b[i]; 23} 24delete []a; 25delete []b; 26return 0; 27} 28 29 30 31

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答3

0

ベストアンサー

こんにちは。

えっと、まずご提示のプログラムはリークしてますよ。

C++

1int main(void){ 2 double *a = new double; // 次の行でリーク 3 a = new double[N]; 4 double *b = new double; // 次の行でリーク 5 b = new double[N];

次に、2次元配列のとり方はなんでもよいのでしょうか?
であれば、不慣れな内はstd::vectorを使うのがお薦めです。
m x nの2次元と仮定します。

C++

1void func(double *a, double *b, int N){ 2 //ここで複雑な計算をしてるので書き換えるのは厳しい 3 //入力がa, 出力をbで受け取るようにしてある 4} 5 6#include <vector> 7constexpr int m=10; 8constexpr int n=5; 9 10int main() 11{ 12 std::vector<std::vector<double>> input(m, std::vector<double>(n, 0.0)); 13 std::vector<std::vector<double>> output(m, std::vector<double>(n, 0.0)); 14 15 for (int i=0; i < m; ++i) 16 { 17 func(&input[i][0], &output[i][0], n); 18 // output[i]を使った処理 19 } 20 // outputを使った処理 21}

投稿2019/01/11 15:13

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ham33

2019/01/12 06:22

ご指摘、ご回答ありがとうございます。 m×nを0.0で初期化して、funcに1列目をループで渡してるように 見られました。このようにして、すべての列を渡していくことはできるのでしょうか。 元々は1次元配列を渡してそのまま1次元で出力を返してもらっていたのですが、Chironianさんのを参考にfor文をもう1個つかって列を次の列、次の列にしようとするとセグメントエラーを吐きます。
Chironian

2019/01/12 06:48

> funcに1列目をループで渡してるように見られました 違いますよ。&input[i][0]はi行目先頭へのポインタですので、i行目全体を渡すのと同義です。 > for文をもう1個つかって列を次の列、次の列にしようとするとセグメントエラーを吐きます。 当たり前ですね。 あああ、渡したいのは行と思い込んでました。渡したいのは列なのですね。 C/C++では行が連続領域に格納されます。従って列は連続しませんので単純に渡すのは不可能です。 入力側の2次元配列の列を連続領域へコピー後、funcを呼び出し、出力を2次元配列の列へ戻すしかないです。 ですが、2次元配列側の解釈を変えて、行と列を入れ替えればそのような編集処理が不要になりますよ。 以下のイメージです。 double **a= new double *a[M];  for(i=0;i<M;i++){   a[i] = new double[N];  } 今までa[i][j]でアクセスしていた場合、a[j][i]でアクセスします。
ham33

2019/01/12 06:58

ご回答ありがとうございました。 大変勉強になりました。 行列の扱いをもう少し自分で勉強したいと思います。
guest

0

こーゆーことですかいのぅ...

C++

1#include <iostream> 2 3void print(const double* array, int n) { 4 while ( n-- ) std::cout << *array++ << ' '; 5 std::cout << std::endl; 6} 7 8int main() { 9 double a[3][3] = { 10 1.1, 2.2, 3.3, 11 4.4, 5.5, 6.6, 12 7.7, 8.8, 9.9, 13 }; 14 print(a[0],3); 15 print(a[1],3); 16 print(a[2],3); 17}

実行結果:

1.1 2.2 3.3 4.4 5.5 6.6 7.7 8.8 9.9

投稿2019/01/11 13:35

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ham33

2019/01/11 13:48

回答有り難うございます。funcには配列の先頭のポインタを渡して、複雑な計算を行った出力も同じようにポインタで渡して書き換えるようにしています。 2次元配列の1列を渡して、ループを回して残りの列も渡すような書き方はできるのでしょうか。お答えいただけると幸いです。
pepperleaf

2019/01/11 13:57

epistemeさんの回答、そのまま、一列を渡してると思いますが、、、、。
ham33

2019/01/11 14:06

私の書き方だとおもうのですが、 funcに0行目を渡そうとするとエラーをはきます 短文で書きましたが、実際の要素がかなり膨大ですので、 それを1個ずつ渡さず、ループを回すことができるかお聞きしたかったです。
episteme

2019/01/11 22:06

aの0,1,2行目をprintに渡してるんだけど、これじゃダメなん?
fana

2019/01/12 02:17

ああ… 質問文から「列」だと思ってたのですが,質問文のコード内注釈を見たら普通に「行」で良いんですね.
ham33

2019/01/12 05:45

私の質問文の説明の仕方が誤っていました。失礼いたしました。
guest

0

funcの中身次第ですが,仮に,配列要素を[]で参照しているようなものであれば,
「ある2次元配列の特定の列のi番目の要素」へのアクセス手段をoperator[]あたりで提供するクラスを作れば,
funcの引数の型の変更くらいで,中身は変えずにいけるかもしれません.

そんなのでは無理で必ず配列の頭を指すポインタをfuncに渡さないとまずいようであれば,
別の配列に列要素をコピーしてそれをfunc渡すヘルパ関数みたいなのを書けば良いかも.

投稿2019/01/11 13:10

fana

総合スコア11654

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ham33

2019/01/11 13:44

配列要素を[]で参照しているわけではなく、配列の頭のポインタを渡しているので、ヘルパ関数を作るというのを参考にさせていただきたいと思います。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問