• ベストアンサー

任意の要素数の二次元配列を渡したい

関数で、各次元の要素を問わず、二次元配列を受け取りたいのですが、下記の方法では失敗しました (要素にアクセスすると落ちる) void func(void *p){ int **v=(int **)p } void func(int p[][3]) 上記のような、指定された数だけを受け取る方法をとるしかないのでしょうか ご存知の方が居ましたら教えてください

  • tukai
  • お礼率57% (102/177)

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

  • ベストアンサー
  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

「二次元配列」を void * で受けているあたりが大いなる謎. 今の ISO C なら void func(int row, int col, int array[row][col]); で OK. 特に悩むこともなし. これがダメだと, よくやる手法は「素直にポインタへのポインタを使う」ことでしょう. 例えば int の「二次元配列」として int **array; を用意して, 次のように malloc で領域を確保します: array = malloc(sizeof array[0] * row); for (i = 0; i < row; ++i) array[i] = malloc(sizeof array[i][0] * col); これで大きさが row×col の「二次元配列」ができました. アクセスは普通に array[i][j] でできますし, 他の関数に渡すときも func(array, row, col) で渡せます. 受ける方は void func(int **array, int row, int col); と宣言すれば OK. 「いっぱい引数があって大変だ」と思ったら, struct にしておくと見通しがよくなります.

その他の回答 (3)

  • asuncion
  • ベストアンサー率33% (2126/6288)
回答No.3

コードの断片でなく、当該プログラム全体を載せていただくことは可能ですか?

回答No.2

 状況が、もう1つよくわからないけど、こういうこと? #include <stdio.h> void func(int *a, int y, int x) { int i, j; for(i = 0; i < y; i ++){ for(j = 0; j < x; j ++) printf("%2d ", a[x * i + j]); putchar('\n'); } } int main(void) { int a1[2][3] = {{1, 2, 3}, {4, 5, 6}}; int a2[3][2] = {{7, 8}, {9, 10}, {11, 12}}; func(&a1[0][0], 2, 3); func(&a2[0][0], 3, 2); return 0; }

  • Tasuke22
  • ベストアンサー率33% (1799/5383)
回答No.1

p[][] とし任意の要素数での受取りは出来ますが、 これだけでは要素数が分かりません。 別途、要素数を1次元、2次元の分を送ってやる必要 があります。 void func(int x, int y, p[][]); このような形になるでしょう。

関連するQ&A

  • 引数で指定された配列の要素数の取得

    どうもこんにちは。 C言語でプログラムを作成しています。 ある関数に配列を渡すことを考えていますが、渡した配列の要素数を取得する方法は何かありますか? 標準の関数を見ても、配列の先頭アドレスのポインタとともに、配列の要素数を渡しているものばかりで、配列のポインタを渡しているものは見かけません。 要素数があらかじめわかっていれば、それを引数の型に指定できますが、呼び出されるまで不明な場合はうまくいきません。 配列の要素数も引数として一緒に渡す必要がありますか? [作ってみたサンプル] #include <stdio.h> #include <stdlib.h> #include <string.h> // func1 と func2 をまとめられないだろうか。。。 void func1(int (*p)[10]) { ________int n = sizeof(*p) / sizeof((*p)[0]); ________int i; ________for (i = 0; i < n; i++) { ________________printf("%d\n", (*p)[i]); ________} ________printf("\n"); } void func2(int (*p)[5]) { ________int n = sizeof(*p) / sizeof((*p)[0]); ________int i; ________for (i = 0; i < n; i++) { ________________printf("%d\n", (*p)[i]); ________} ________printf("\n"); } int main(int argc, char *argv[]) { ________int ary1[10] = { 2, 4, 6, 8, 0, 1, 3, 5, 7, 9 }; ________int ary2[5] = { 3, 6, 9, 12, 15 }; ________func1(&ary1); ________func2(&ary2); ________return 0; }

  • 配列の要素数を調べる方法

    配列の中にいくつ要素があるか後から調べる方法はあるでしょうか? int test[4][3] = {   {0,1,2},   {0,1,2},   {0,1,2},   {0,1,2}, } ; 上のケースだと、X方向に3、Y方向に4つの 要素があります。しかし、これだとあらかじめいくつ要素があるかを決めて 置かないといけません。 例えば、 int test[] = {0,1,2,3....} みたいに宣言された場合や、 char *test[] = {   "ああああああ",   "いいいいいい",   "うううううう",      ・      ・ //(これは文字列の数を要素数とします) } ; のように宣言された二次元配列などで、後から配列内にいくつ要素があるかを 調べることなどは可能でしょうか?

  • 2次元配列とポインタの引数受け渡しについて

    2次元配列を関数に渡すときは、引数に渡す2次元配列と同じサイズを指定、もしくは2次元目のサイズのみ合わせて渡す方法がありますが、両方とも違うサイズで同じ関数を使いたいです。 最初は中身が同じで引数で受け取る2次元配列のサイズだけ、それぞれに合わせた引数を持つ関数を2つ作っていたのですが、なんだか冗長な気がしました。 そこで、2次元配列の先頭ポインタとサイズを受け取るようにすればいいのかと思い、テストとして次のプログラムを作成してみました。 #include <stdio.h> void func(unsigned char *a, int y, int x); int main(void) { unsigned char a[10][10]; func(a, 10, 10); printf("%d\n", a[7][4]); return 0; } void func(unsigned char *a, int y, int x) { int i, j; for (i = 0; i < y; i++) { for (j = 0; j < x; j++) { *(a + i*y + j) = i * j; } } } もちろんこれでも動くのですが、やはりこういう書き方はルールにはないので、コンパイルで警告が出ます。 a.c: In function ‘main’: a.c:10: warning: passing argument 1 of ‘func’ from incompatible pointer type a.c:4: note: expected ‘unsigned char *’ but argument is of type ‘unsigned char (*)[10]’ このような書き方はやはりやめたいいのでしょうか。 また、その際はサイズ別に関数を作るしかないのでしょうか。 他にいい方法があれば教えていただけると助かります。

  • 多次元配列のポインタ渡し

    C++を使用しています。 多次元配列を関数の引数として渡したいとき、関数側では void A::Func(int a[10][20][30])~ 呼びだし側では Finc(a); とやればいいのはわかります。 お聞きしたいのは、仮引数として呼び出された配列(上でいうa)をクラスのメンバ変数として保持したい場合の方法です。 aは先頭アドレスなのでそこを差すポインタを受ければいい、っていうことはわかりますが、 この方法ですと、受けたメンバ変数が配列みたいに[]を使ってアクセスできません。 (メンバ変数のポインタは配列じゃないから当然ですよね) これを通常の配列みたいに扱えるようにするにはどうしたらいいでしょうか。

  • 配列渡し後の要素数を知るには・・?

    main関数で定義した配列を他の関数で扱う場合にどうすればいいのかいまいちわかりません・・。 微妙に独学したのですが sizeofで要素数を調べたいのですがどうすればmain以外の関数内で要素数を調べる事ができるのでしょうか。私の書いたソースはこれです。 void dis(int *b){ int i, nx; nx = sizeof(b) / sizeof(b[0]); for(i=0;i<nx;i++){ printf("%d\n", *(b+i)); } } main(){ int a[5] = { 10, 20, 5, 1, -1 }; dis(a); return(0); } どうすればいいでしょうか・・・。どなたか教えていただければ光栄です。ご指導お願いします!

  • 配列の要素数に変数を入れたいときには

    よろしくお願いします。 配列の要素数には定数しか入れられないのですが,どうしても変数を入れたいときは,それを引数として関数を呼び出すしか方法はないでしょうか。 具体的には,scanfで手に入れたint型の変数を要素数とする配列を宣言したいのですが,どうすれば良いでしょうか。 ご教授ください。

  • 二次元配列における要素数のはじき出し

    普通、配列の要素数を出すとき $num = @list; で良いですよね? ですが、二次元配列で、 $num = @list[1]; って形にするとエラーになります。 どうすればいいのでしょうか?

    • ベストアンサー
    • Perl
  • 2次元配列を引数とする関数について

    2次元配列を引数とする関数について 私は今、2次元配列を引数とする関数の表を作るという課題に取り組んでいます。 条件として、int a[数字][数字]={{1,2,3...}}という配列の宣言と同時の初期化は使わず、 関数内で表の値を代入し、値を表示する関数を作り、事実上二つの関数を作るというものです。 私は以下のようなプログラムを作り、動かしましたが、[数字][数字]=********のような本来 あるべき実行結果とは異なる数字の羅列が出てきてしまいました。 ↓ #include <stdio.h> void func(int a[][6]); void fund(int b[4][6]); void main(void) { int a[4][6]; fund(a); func(a); } void func(int a[][6]) { int i,j,b[4][6]; fund(b); for(i=0;i<4;i++)        { for(j=0;j<6;j++) { printf("a[%d][%d]=%d\n",i,j,a[i][j]); printf("\n"); } } } void fund(int b[4][6]) { int i,j; for(i=0;i<4;i++) { for(j=0;j<6;j++)          { scanf("b[%d]*[%d]=%d\n",&i,j,b[i][j]); } } } 本来の実行結果 1 2 3 4 5 6 2 4 6 8 10 12 3 6 9 12 15 18 4 8 12 16 20 24 紙にも書いて何回も見直しましたが、どこがおかしいのかわかりませんでした。 どうすれば良いのでしょうか? 何か良いアドバイスをよろしくお願いします。

  • 要素にnullが入った多次元配列の次元数(2回目)

    同様の質問について再度投稿します。 以下、問題集で見掛けたプログラムの抜粋です。 String[][] Array = { {"Sunday", "Monday"}, null, {"Monday", "Tuesday"} }; int count =0; for (String[] A : array){ count += A.length; } System.out.println(count); このプログラムを実行すると、 要素nullのlengthが数えられないため、 NullPointerExceptionが発生する、ということです。 以前に質問した際には、 上記配列に含まれるnullは、大カッコで囲まれていないため、 次元としてカウントされないので、配列の次元数は 2次元となる、という回答を頂きました。 (配列変数も二次元で宣言されている。) 細かいようですが、大カッコで囲まれていないnullは 次元数としてカウントされなくても、要素として 拡張for文の対象にはなるのでしょうか…? 解説をお願いします。

  • 多次元配列

    たとえば  int test[]={1,2,3}; のような場合は、配列の要素数を省略できます。 しかし、多次元配列の場合は左端の添え字しか省略できないのはなざでしょうか? 例  int test[][3]={{1,2,3},{4,5,6},{7,8,9}}; 全部省略できない理由がわかりません。 どなたか教えてれませんか?

専門家に質問してみよう