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

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

ただいまの
回答率

87.37%

引数として2次元配列を宣言した関数に、1つの次元のインデックスを固定した3次元配列を実質的な2次元配列として渡したい。

受付中

回答 2

投稿

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

score 12

前提・実現したいこと

タイトルに書いたことを抽象的に書くと、「引数としてn次元配列を宣言した関数に、m次元分のインデックスを固定したn+m次元配列を実質的なn次元配列として渡したい」です。
それが関数の汎用性につながると考えたからです。

発生している問題・エラーメッセージ

エラーメッセージ
error C2059: 構文エラー: ']'

### 該当のソースコード
#include "pch.h"
#include <stdio.h>

void answer(double matrix[3][3])
{
    for (int i = 0; i < 3; i++)
    {
        for (int j = 0; j < 3; j++)
        {
            printf("%lf",matrix[i][j]);
        }

        printf("\n");
    }

}

int main()
{
    static double m[2][3][3] = { {{1,2,3},{4,5,6},{7,8,9}},{{10,11,12},{13,14,15},{16,17,18}} };

    answer(m[1][][]);
}

ここに言語名を入力
C言語
ソースコード
`

試したこと

上記のソースコードを使えば{{10,11,12},{13,14,15},{16,17,18}}が関数answerで出力されてほしかったのですが無理でした。メイン関数で一度2次元配列を用意して以下のようにしてから配列tmpを渡すしかないのでしょうか。代入に時間がかかりそうなのでできればやりたくないので他にいい方法があれば知りたいです。

for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 3; j++)
{
tmp[i][j]=m[1][i][j];
}

}

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

+2

上記のソースコードを使えば{{10,11,12},{13,14,15},{16,17,18}}が関数answerで出力されてほしかったのですが無理でした。

引数に渡すものをm[1]とすれば問題なく動きました(paiza.ioでの動作確認)。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/07/19 14:32

    ありがとうございます!できました!

    ただ一つ気になるのは、左側から連続していくつかしか固定できない感じでしょうか。
    つまり、配列 a[i][j][k][m] があった場合に、インデックスの固定の仕方は以下の4通りしかなくて
    [i]を固定して[j][k][m]からなる疑似的な3次元配列として使う
    [i][j]を固定して[k][m]からなる疑似的な2次元配列として使う
    [i][j][k]を固定して[m]からなる疑似的な1次元配列として使う
    [i][j][k][m]を固定して疑似的な1変数として使う

    [i]と[k]のインデックスだけを固定するというようなやり方はできないのでしょうか?

    キャンセル

  • 2019/07/19 14:57 編集

    > [i]と[k]のインデックスだけを固定するというようなやり方はできないのでしょうか?

    はい。C言語の多次元配列は「a[0]の直後にa[1]が入っている」というようなメモリ配置となっていますので、その一部だけ取り出すようなa[0]やa[0][1]は連続したメモリですが、「0次元目と2次元めだけ取る」ようなものはメモリ上で飛び飛びとなりますので、通常の配列として扱うことはできません。

    キャンセル

  • 2019/07/22 14:11

    回答ありがとうざいます。
    おかげさまで現状したいことをする上では問題なさそうです。
    多次元配列がメモリ上にどう配置されているのかや、ポインタとの関係性を知る必要がありそうです。

    キャンセル

0

Cの配列について、いくつかのお約束があります。

1.「配列」を関数に引数として渡すことは出来ず、配列の先頭要素へのポインタだけを渡して*(p+n)p[n]が等価であるというお約束のもと、順次配列の要素にアクセスできる、という原理で配列を扱います。

2.配列が単独で記述されると、その配列の先頭の要素へのポインタとみなされます。

3.多次元配列というのは一つ下の次元の配列の配列、という定義です(擬似的、なんていうことではありません。配列そのものです)。なので、下位の配列が確定していないままで上位の配列というのは定義されません。

m[1][][]というのは、3.に反します。
double m[2][3][3];
ということであれば、m[1]とだけ記述すればこれは2.によって&m[1][0]の意味になり、double[3][3]の配列そのものへのポインタとなります。

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

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

関連した質問

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

  • トップ
  • Cに関する質問
  • 引数として2次元配列を宣言した関数に、1つの次元のインデックスを固定した3次元配列を実質的な2次元配列として渡したい。