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

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

ただいまの
回答率

90.39%

  • C++

    4637questions

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

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

解決済

回答 3

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 409

ham33

score 3

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

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

現在

#define M 
#define N //数を指定

void func(double *a, double *b, int N){
 //ここで複雑な計算をしてるので書き換えるのは厳しい
 //入力がa, 出力をbで受け取るようにしてある
}

int main(void){
double *a = new double[N];
double *b = new double[N];


func(a, b, N);

//ここでbを使ったプログラムが書いてある

delete[] a;
delete[] b;
return 0;
}


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

void func(double *a, double *b, int N){
//関数は書き換えない
}
int main(void){
double **a= new double *a[N];
 for(i=0;i<N;i++){
  a[i] = new double[M];
 }
double **b= new double *b[N];
 for(i=0;i<N;i++){
  b[i] = new double[M];
 }

func( );//ここに配列の1列分を要素として渡したい
//今まではa[N]={1.0,2.0,3.0}を渡してた
//今度は a[N][M]={1.0,2.0,3.0}{4.0,5.0,6.0}の{1.0,2.0,3.0}を渡した

//ここで出力bを使ったプログラムが書いてある

for(i=0;i<N;i++){
 delete a[i];
 delete b[i];
}
delete []a;
delete []b;
return 0;
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 3

checkベストアンサー

0

こんにちは。

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

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

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

void func(double *a, double *b, int N){
 //ここで複雑な計算をしてるので書き換えるのは厳しい
 //入力がa, 出力をbで受け取るようにしてある
}

#include <vector>
constexpr int m=10;
constexpr int n=5;

int main()
{
    std::vector<std::vector<double>> input(m, std::vector<double>(n, 0.0));
    std::vector<std::vector<double>> output(m, std::vector<double>(n, 0.0));

    for (int i=0; i < m; ++i)
    {
        func(&input[i][0], &output[i][0], n);
        // output[i]を使った処理
    }
    // outputを使った処理
}

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/01/12 15:22

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

    キャンセル

  • 2019/01/12 15: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]でアクセスします。

    キャンセル

  • 2019/01/12 15:58

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

    キャンセル

0

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

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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/01/11 22:44

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

    キャンセル

0

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

#include <iostream>

void print(const double* array, int n) {
  while ( n-- ) std::cout << *array++ << ' ';
  std::cout << std::endl;
}

int main() {
  double a[3][3] = {
    1.1, 2.2, 3.3,
    4.4, 5.5, 6.6,
    7.7, 8.8, 9.9,
  };
  print(a[0],3);
  print(a[1],3);
  print(a[2],3);
}

実行結果:

1.1 2.2 3.3
4.4 5.5 6.6
7.7 8.8 9.9

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/01/11 22:48

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

    キャンセル

  • 2019/01/11 22:57

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

    キャンセル

  • 2019/01/11 23:06

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

    キャンセル

  • 2019/01/12 07:06

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

    キャンセル

  • 2019/01/12 11:17

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

    キャンセル

  • 2019/01/12 14:45

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

    キャンセル

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

  • ただいまの回答率 90.39%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • C++

    4637questions

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