多次元配列とポインタ渡しについて

このQ&Aのポイント
  • 多次元配列のポインタ渡しについて,自作の関数がエラーとなる原因を解説してください。
  • 具体的には、自作の関数で配列の先頭アドレスを示すポインタを指定する際にエラーが発生しています。
  • 質問者は間違いがないと思っているが、エラーの原因について詳しく知りたいとのことです。
回答を見る
  • ベストアンサー

多次元配列とポインタ渡しについて

多次元配列のポインタ渡しについて,自分で検索したのですがあまりにも様々で具体的な記述が無く質問させていただきました. 検索力不足もあるのでソースの提示だけでも結構ですので,ご回答お願いいたします. OS:Windows XP ソフト:VisualStudio.net2003(C++) C++プログラミング暦2ヶ月弱です. データを変換して多次元配列にデータを入れる自作の関数をつくりたいと考えています. 具体的には,a1からa2,b1からb2を10区間に分けてたデータを配列にしたいといったものです. 自分で記述した関数は以下の通りです. void Convert(float a1,float a2,float b1,float b2,unsigned short *Data){ int k; float a; float b; for(k=0;k<11;k++){ a = a1 + (a2 - a1) / 10; b = b1 + (b2 - b1) / 10; Data[k][1] = ( powf(2.0,16) * (a + 10.0) / 20; Data[k][1] = ( powf(2.0,16) * (b + 10.0) / 20; } } void main(){ float a = 10; float b = 20; unsigned short Data[11][2]; Convert(a1,a2,b1,b2,Data); ... } としています. ここでコンパイルすると, "5番目の引数をunsigned shortからunsigned short *に変換できません" となってしまいます. 配列の名前のみの部分はその配列の先頭アドレスを示すポインタであることから,自分では間違いがないと思っているのですが….

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

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

Data の型は unsigned short [11][2] で, これをポインタに変換すると unsigned short (*)[2]. これは unsigned short * とは違う型ですから, 当然文句を言ってきます. 考えるのが面倒なら Convert の最後の引数を unsigned short Data[][2] にすればコンパイルは通ります.

llringoll
質問者

お礼

ご回答ありがとうございます. とりあえず,表記のようにしたら通りました♪ やはり,ポインタや配列はまだまだ奥が深いです. もう少し勉強して,きちんと意味が分かるようにしたいと思います. 本当にありがとうございました! 一層の精進をしてまいります!!!!

関連するQ&A

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

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

  • 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]’ このような書き方はやはりやめたいいのでしょうか。 また、その際はサイズ別に関数を作るしかないのでしょうか。 他にいい方法があれば教えていただけると助かります。

  • ポインタと二次元配列

    二次元配列a[ ][ ]の第1行の要素以後を0にするプログラムで動きます。 疑問なんですが、4行目のa[ ][4]は、なぜ[ ]のように空欄になっているんでしょうか。 また、8行目のpa=a[1];は、なぜpa=a[0];ではだめなんでしょうか。第1行は先頭行で0行目を意味しているのではないでしょうか。 #include <stdio.h> void main(void) /*ポインタと二次元配列*/ { static int a[ ][4]={{1,2,3,0}, {4,5,6,0}, {7,8,9,-999}}; int j,k,*pa; pa=a[1]; while(*pa!=-999){ *pa=0; pa++; } for(j=0;j<3;j++){ for(k=0;k<4;k++) printf("%5d",a[j][k]); printf("\n"); } }

  • 配列のポインタ配列のポインタから元の配列を参照する方法について

    C初心者です。下記の様に配列のポインタ配列を作って、そのポインタ配列のポインタを返すコードを書いて、main関数で元の配列の値を参照したいのですが、上手く参照できずに困っています。下記のコードの問題点も含めて、配列のポインタ配列のポインタから、元の配列の値を参照する方法を教えてください。お願い致します。 short int *motion_data(void) { short int data1[5][7] = { {2377,2174,0,0,0,0,0}, {2377,2377,2784,2648,2648,2648,2377}, {2377,2377,2784,2648,2648,2648,2377}, {2377,2377,2377,2377,2377,0,0}, {2377,2377,2377,2377,2377,0,0}, }; short int data2[5][7] = { {2377,2174,0,0,0,0,0}, {2377,2377,2919,2784,2784,2784,2377}, {2377,2377,2919,2784,2784,2784,2377}, {2377,2377,2377,2377,2377,0,0}, {2377,2377,2377,2377,2377,0,0}, }; short int *po_data[2]; po_data[0] = data1[0]; po_data[1] = data2[0]; return *po_data; }

  • ポインタと二次元配列

    ポインタを習ったんですが、二次元配列を指定する場合はどのようにすればいいのでしょうか? また、別関数でそのポインタを呼びたいのですが。 (例) main関数 char retsu[2][2] = {{2,4},{6,8}}; char *ptr; next関数 上記でいくと「main関数内のchar retsuの二次元配列を*ptrで指定」、「next関数でmain関数で指定した*ptr(retsu[2][2])を参照したい」 という事をしたいのですが、教えて下さい。

  • ポインタと多次元配列についての質問です

    私の使っている本に、 『ポインタを使って多次元配列にアクセスするには、コンパイラが自動で行っていることを手作業で 行わなければなりません。たとえば、次の配列には各列に5つの要素があります。 float balance[10][5]; したがって、ポインタを使ってbalance[3][1]にアクセスするには、次のようなコードを使用 しなければなりません。 float *p; p = (float *) balance; *(p + (3*5) +1) 目的の要素に到達するには、行番号に行の要素数を掛けてから、その要素の行内での番号を 加えなければなりません。上記の例では、balanceをfloat* にキャストする必要がありました。 配列要素を手作業で指定する都合上、ポインタ演算をfloatポインタに基づいて行わなければなりません。 しかし、balanceによって生成されるポインタの型はfloatの2次元配列です。そこでキャストが 必要になるわけです。』 とあります。 【質問1】なぜ、p = (float *) balance; なのか。p = (float) *balance; ではないのか? 【質問2】本文「上記の例では………必要になるわけです。」の意味がわかりません。 未熟者の私ですがどうか教えてください。

  • 配列のポインタについて

    C言語で処理が下記のような処理を作成したいと思っております。 関数の引数によって、データを代入する配列を切り替えたいと考えております。 下記のような処理を考えた場合、if文の中・for文のbuffをどのように処理すれば よいでしょうか? アドバイスよろしくお願い致します。 int a[100][150]; int b[100][150]; void sample(int flg) { int i,j; unsigned short *buff; if(flg == 0){ buff = &a; }else{ buff = &b; } for( j=0 ; j<100 ; j++ ){ for( i=0 ; i<150 ; i++ ){ buff[y][x] = data; x++; } x = 0; y++; } }

  • 二次元配列のポインタについて教えて下さい

    今日はCの配列のポインタについて質問いたします、宜しくお願いします。 1次元の配列からは、 =================================== int *p , a={1,2,3}; p = &a; printf("%d\n" , p[1] ) ; printf("%d\n" , *p[1] ) ; ===================================== でaの値がとれますが、 二次元の配列では下のような書き方ではエラーになります。 何故でしょうか、どう書いてやればいいのでしょう。 ===============================================  printf("%d\n" , pbb[1][1] ) ;  printf("%d\n" , *pbb[1][1] ) ; =============================================== 宜しくお願いします。

  • void*型の配列について

    void* a[2]; void* b = a; void* c[2] = (void *[2])b; error C2440: '型キャスト' : 'void *' から 'void *[2]' に変換できません。 配列型への変換はありませんが、参照またはポインタから配列への変換があります。 void*型にした a を再度void*型の配列に戻すにはどのように記述すればよいでしょうか? 環境はXP(SP3)のVS2008 MFC です。 宜しくお願いいたします。

  • 3次元配列でのポインタ

    唐突ですみません。 サイズが640*480の画像を180枚読み込むプログラムをポインタを使って作成しようと考えています。 以下で示すプログラムは画像を読み込むための作成したものですが、エラーが出てしまい実行することができません。 間違えている箇所があればご指摘お願いします。 また、そのほかに効率の良いやり方などがありましたらご教授願います。 #include <stdio.h> #include <stdlib.h> #include <math.h> #define xsize 640 #define ysize 480 #define round 180 #include "Input.h" void Input_task(unsigned char ***In); void main() {   static unsigned char ***In;   int i,j;   In=(unsigned char***)malloc(sizeof(unsigned char)*round);   for(i=0;i<round;i++)   {     In[i]=(unsigned char**)malloc(sizeof(unsigned char)*ysize);     for(j=0;j<ysize;j++)     {       In[i][j]=(unsigned char*)malloc(sizeof(unsigned char)*xsize);     }   }   Input_task(In); } Input.hの中身 void Input_task(unsigned char ***In) {   char filename[30];   int i,j,k;   FILE *fp;   for(i=0;i<round;i++)   {     sprintf(filename,"b20_%04d.raw",i);     fp=fopen(filename,"rb");    for(j=0;j<ysize;j++)     {       for(k=0;k<xsize;k++)       {         *(*(*(In+i)+j)+k)=(unsigned char)getc(fp);       }     }    fclose(fp);   } }

専門家に質問してみよう