• ベストアンサー

構造体の配列を関数に渡すには

構造体の配列を関数の引数として渡そうとすると エラーになってしまいます ネットで調べてもいまいちわからなかったので ここで質問させてもらいます #include<stdio.h> struct A{   ・    ・    ・ }; void func(struct A *p); int main(void) { struct A x[3][4] = {     ・     ・     ・ }; func(x); return 0; } void func(struct A *p){     ・     ・    ・ } どうすれば渡すことができるのでしょうか? どなたか助言お願いします。

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

  • ベストアンサー
  • aris-wiz
  • ベストアンサー率38% (96/252)
回答No.4

> void func(struct A **p); 型が違いますのでおそらく最近のコンパイラでは コンパイルエラーになると思います。 >> struct A x[3][4] xの型は struct A[3][4]型です。 正しい引数としては、 「void func( struct A[3][4] x )」 となります。 ここで配列の最初の要素を不定数にしたい場合は、 No3さんの「void func(struct A p[][4])」を使うか、 「void func( struct A (*p)[4] )」とする必要があります。 >void func(struct A *p) 多少強引ですが、先頭のポインタ自体は渡されるので、 キャストして呼び出しを行っても動くでしょう。 但し、呼び出された関数内では渡された構造体が、 2次元配列なのか、N次元配列なのか、 1つの構造体のポインタなのか知るすべはありませんので 扱いに注意が必要です。

その他の回答 (4)

noname#130082
noname#130082
回答No.5

すみません。No.4さんの言うとおり、多次元配列では >> void func(struct A **p); >型が違いますのでおそらく最近のコンパイラでは >コンパイルエラーになると思います。 ではコンパイラが通りませんね。 記憶に頼って回答などするから、こういう馬鹿をする<(__)>。 MinGW入れて、gccで念のため確かめました。 一応、 void func(struct A p[][]); はコンパイラは通ることは通るけれど、サイズが不定なので、func内部で要素にアクセスするのは無理か。せめて p[][4] にしないと。

回答No.3

  関数の宣言、定義を void func(struct A p[][4]) とするか、 関数の呼び出しを func((strunct A *)x); とする。  

noname#130082
noname#130082
回答No.2

自信はないですが。 ええと、コンパイルエラーになるのでしょうか? func(x); の引数の型が合っていないような感じがします。 これだと、 void func(struct A **p); のような・・・。

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

「構造体の配列」じゃなくて, 例えば「int 型の配列」ならちゃんと渡すことができる?

関連するQ&A

  • ポインタを使って構造体の配列を戻り値にするには

    関数の戻り値を構造体の配列(アドレスを受け渡しを利用して)にしたいのですがうまくゆきません。 以下のプログラムではコンパイルはできるのですが、 a0 = 2 a1 = 4198512 a2 = 4329332 と表示されてしまいa1,a2がうまくゆきません。 ********************************************* #include<stdio.h> struct test{ int a; }; struct test *func(void); void main(void) { struct test *data;//構造体ポインタ int i; data = func(); //ポインタにtest関数の戻り値(アドレス)を代入 for(i=0;i<=2;i++){   printf("a%d = %d\n",i,(data+i)->a); //構造体要素を表示 } } struct test *func(void) { struct test data[3]={1,2,3}; //構造体配列を定義 return (&data[0]); //構造体配列の先頭アドレスを返す } ************************************************* test関数から受ける取ったアドレス(&data[0])をポインタ(data)に代入して1づつずらして表示させれば a0=1,a1=2,a=3 となると思ったのですがどこが間違っているのでしょうか? よろしくお願いします。

  • 構造体配列の初期化関数をつくる

    C言語での数値プログラミング的な質問です。 例えば, 自作関数で, =========== void shokika(int n, double *x) { int i; for(i=0;i<n;i++) x[i] = 1.0; } =========== とつくり, int main(void) { double x[10]; shokika(10,x); return 0; } とすると, x[0]~x[9]まで1.0を入れることができますが, 配列x[10]を, struct abc { double x, y; } a[10]; というように構造体の配列としてa[i].xとしたときに, 上記のshokika関数の同等の処理をしてくれる (つまり, a[0].x=...=a[9].x=1.0と処理する) 自作関数をつくりたいのですが、どうしたらいいでしょうか。

  • C言語で、他の関数で配列を書き換えられないようにしたい

    下のCのプログラムでは、func関数は配列aの先頭要素へのポインタを返します。 main関数の側では配列aの中身を表示します。 しかし、main関数のfor文の中の★の部分をコメントアウトせずに入れると、この配列の中身が書き換わってしまいます。  私はfunc関数以外では、この配列の中身をいじられたくないのです。  なんとかfunc関数を工夫して作成して、func関数以外では、配列の中身が変わらないようにしたいのですが、どうすればよいでしょうか。    とは言ったものの、多分できないだろうなあ、という気がします。  できないならばできないでも仕方ないのですが、確信が持てないのです。 条件があります。 funcでは表示は行なわない。 配列aの中身を表示できるように、funcから呼び出し元へ、aのアドレスまたはaの先頭要素のアドレスがわかるような情報を返す。 #include <stdio.h> char *func(int i) { static char a[]="AAAA"; a[i]='z'; return a; } int main(void) { int i; for(i=0; i<4; i++) { char *p=func(i); /* p[i]='X'; ★配列の中身を書き換えてしまう。 */ puts(p); } return 0; }

  • 関数先にて配列の長さを取得する方法

    関数にて、引数にて渡された配列(ポインタ)から配列数を調べる方法はないでしょうか? #include <stdio.h> void test(unsigned int *p){ printf ("%d\n", sizeof(*p)/sizeof(p[0])); //結果 1 } int main(){ unsigned int hoge[] = {0x30, 0x31,0x32}; test(hoge); printf("%d", sizeof(hoge)/sizeof(hoge[0])); //結果3 return 1; } 上記コードの関数testの*pから配列の数3が抜き取りたいと思っております。 よろしくお願いします。

  • gcc: incompatible pointer type

    以下のCソースでコンパイルすると、warning: passing arg 1 of `func_b' from incompatible pointer type となります。 void (*p_func)() は、引数を省略しているので int として扱われるということでしょうか? #include <stdio.h> #include <stdlib.h> void func_a( unsigned char x ){ printf( "x=%d\n", x ) ; } void func_b( void (*p_func)() ){ p_func( 1 ) ; } int main(){ func_b( func_a ) ; return 0 ; }

  • 構造体配列

    いつもお世話になっています。 今日構造体配列を勉強した際に下の演習をしていたのですが、いまいち基礎的な関数や配列のことやコマンドライン引数のことが理解できていません。一応自分なりにプログラムを書いてみたのですが、エラーがでます。 どなたかアドバイス・ご指摘・解説・例などをおねがいいたします。 問題はコマンドライン引数で人数を指定し,人数分のデータを標準入力(キーボード)から構造体配列に入力し,標準出力(ディスプレイ)に出力するプログラムです。 #include<stdio.h> typedef struct{ char name[100]; int age; double height; double weight; } PERSONAL_DATA1; typedef struct{ int person[10]; }PERSONAL_DATA2; PERSONAL_DATA1 input_personal_data(int num); void output_personal_data(PERSONAL_DATA2 person[10],int num); int main(int argc, char *argv[]){ PERSONAL_DATA1 x; int num,i; char person[10]; if(argc != 2){ printf("Usage ./test number"); return 0; } num=atoi(argv[1]); for(i=0;i<10&&i<num;i++){ person[i]=input_personal_data(); output_personal_data(person,num); return 0; } } PERSONAL_DATA input_personal_data(void){ PERSONAL_DATA1 x; printf("name>"); scanf("%c" ,&x.name); printf("age>"); scanf("%d" ,&x.age); printf("height>"); scanf("%lf" ,&x.height); printf("weight>"); scanf("%lf" ,&x.weight); return x; } void output_personal_data(PERSONAL_DATA2 person[10],int num){ PERSONAL_DATA1 x; printf("name>>%s\n" ,x.name); printf("age>>%d\n" ,x.age); printf("height>>%lf[cm]\n" ,x.height); printf("weight>>%lf[kg]\n" ,x.weight); } またコマンドライン引数で指定したデータファイルAから入力した個人データ集合を構造体配列に取り込み,標準出力(ディスプレイ)と同じくコマンドライン引数で指定したデータファイルBへファイル出力に出力するプログラムというおまけの問題もあります。 こちらの問題のヒントもいただけませんか?

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

    どうもこんにちは。 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; }

  • ポインタ型配列のポインタを構造体のポインタ変数に格納する方法教えて!_ver2

    int型の配列は構造体のポインタ型のint型変数にはキャストすればうまくコンパイルが通りますが、同じ方法でfloat型の配列は構造体のポインタ型のfloat型変数にはキャストしてポインタの値を入れてもうまくコンパイルできず困っています。ちなみにコンパイルエラーは「互換でない型変換」と表示されます。 返答のほど、よろしくお願いいたします。 #include<stdio.h> #include<malloc.h> float time[] ={2.2, 2.3, 2.4}; int time2[] ={2, 2, 2}; struct timelist{ float *time; int *time2; struct timelist *next; }*head; void main(void) { struct timelist *p; p = (struct timelist *)malloc(sizeof(struct timelist)); p -> time = (float *)time[0]; p -> time2 = (int *)time2[0]; printf("time = %f\n", p -> time); printf("time2 = %d\n", p -> time2); }

  • C言語 ポインタ 関数

    キーボードから文字列”abcdefg”を入力し、main関数で配列aryに格納する。 main関数から配列aryの先頭アドレスを副関数に引き渡す。 副関数で配列aryの最後尾の要素の内容を';'に変更する。 main関数で配列aryの内容を表示する。 この問題が解けません... #include <stdio.h> int main (void) { char ary[]="abcdef"; int *p; int i,x; p=&ary[0]; func(&i); for (x=0;x<=7;x++){ printf("%s",ary[x]); void func (int i) if(i==\0) i=';' else i++ } return 0 } とりあえずこんな感じなんですけど、出来ませんでした...

  • ポインタ配列

    配列をポインタでとって、配列要素を足していこうと思ったのですが、 #include <stdio.h> int main (void) { int p[11]={11,23,43,66,54,67,51,88,22,43,-1}; int *e=p; int x=0; int i=0; while( *e!=-1 ) { x + = ( * (e+i) ); i++; } printf("%d\n",x); return 0; } x = ( * ( e+i ) ); ↑この部分がなぜだめなのか理解できません どなたか教えてくださるとありがたいです

専門家に質問してみよう