• ベストアンサー

構造体の配列とメンバの配列

typedef struct _ex_table1 {   int  x[10];   int  y[10]; }ETable1; ETable1 et1; int ans1; for( int a = 0; a < 10; a++ ){   et1.x[a] = a+10;   et1.y[a] = a*2; } for( int b = 0; b < 10; b++ ){   if( et1.x[b] == 15 ){     ans1 = et1.y[b];     break;   }   else{     ans1 = 0;   } } printf( "%d", ans1 ); ///////////////////////////////// typedef struct _ex_table2 {   int xx;   int yy; }ETable2; ETable2 et2[10]; int ans2; for( int aa = 0; aa < 10; aa++ ){   et2[aa].xx = aa+10;   et2[aa].yy = aa*2; } for( int bb = 0; bb < 10; bb++){   if( et2[bb].xx == 15 ){     ans2 = et2[bb].yy;     break;   }   else   {     ans2 = 0;   } } printf("%d", ans2 ); と言う感じに、微妙にソースを書いてみたのですが、 上のメンバ(x,xx)の値が正しいものがあったら、 対応する下のメンバ(y,yy)を出力したいと思っていますが、 構造体を配列にした場合と、構造体メンバを配列にした場合は どのように違うのでしょうか? 私には、同じように思えてしまいます。 どなたか、利点・欠点など教えていただけませんか? よろしくお願い致します。

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

  • ベストアンサー
  • madman
  • ベストアンサー率24% (612/2465)
回答No.2

どちらでも同じですが、 typedef struct _ex_table1 {   int  x[10];   int  y[10]; }ETable1; ETable1 et1; だと、x[0]とy[0]の関連がソースを見て判断できません。 それぞれ個別の配列となってしまい配列番号nに入るxとyに関連があるようには見えないのです。 しかし、 typedef struct _ex_table2 {   int xx;   int yy; }ETable2; ETable2 et2[10]; とすれば、xxとyyに関連が生まれ、配列番号n番目のデータとして識別しやすくなります。 またSUB関数コール時に配列番号nに入っている情報だけを渡したい場合 ETable1では sub(et1.x[n], et1.y[n]); int sub(x, y) {  : } と渡さなければならないですが、 ETable2では sub(et2[n]); int sub(ETable2 et) {  : } で渡せます。 プログラムを作る時に、ひとつの塊としてみたいものをメンバとして並べ、それを必要数だけ用意する。ように作成します。 上記例であれば、xとyは対の情報であると判断できますので、 前者の書き方はよくない書き方で、後者のかきかたはよい書き方となります。

coolguys
質問者

お礼

sub関数を造ったときのことを考えると分かりやすかったです。 値を渡すのがひとつでよくなり、 記述のし忘れが減ってデバックも簡単になりますね。 ありがとうございました。

その他の回答 (1)

  • ranx
  • ベストアンサー率24% (357/1463)
回答No.1

ご質問の二つのプログラムについては、得られる効果は同じだと思います。 どちらが適切かというのは、そのデータが何を示しているかによります。 例えば、5匹のタコの足を扱うプログラムがあったとします。 (変な例えですが、ゲームプログラム等でそんな必要があったと考えて下さい。) 下のどれが適切だと思いますか。(Legは適当に定義された型とします。) (1) typedef struct {  Leg leg[8*5]; } Octpus; Octpus tako; (2) typedef struct {  Leg leg[8]; } Octpus; Octpus tako[5]; (3) typedef struct {  Leg leg; } Octpus; Octpus tako[8*5]; (1)や(3)は不自然だと思いませんか? 要はプログラマが見て理解しやすいコードを書けばよいわけです。

coolguys
質問者

お礼

ありがとうございます。 サンプルなどからコピペばっかりしていたために、 基礎部分が分かりませんでした。 結果は同じなのですね。 見易さの問題ですか、なるほど。

関連するQ&A

  • 構造体の中の構造体

    typedef struct number{ int x; struct number *next; }Num; 初心者な質問で申し訳ないんですが、構造体の中に構造体があるのはどう解釈していいんでしょうか? typedef struct number{ int x; int y; }Num; の場合はNum a,b;がint a.x,a.y,b.x,b.yとなるのは分かるんですが・・・

  • 構造体のメンバをfor文で回したい

    次のようなソースで typedef struct test{ int a; int b; int c; }TEST; TEST xx; xx.a=xx.a+3; xx.b=xx.b+3; xx.c=xx.c+3; printf("%d %d %d\n",xx.a,xx.b,xx.c); のようなことをしたいんですが、 xx.a=xx.a+3; xx.b=xx.b+3; xx.c=xx.c+3; の処理の部分をfor文で回せるようにしたいです。 構造体の宣言のところで配列をつかって struct test{ int abc[3]; } とすれば簡単にいくのは分かるんですが、a,b,cそれぞれに分かりやすい名前をつけたいので、配列で確保したくないです。 何かいい方法はないでしょうか? 実際計算に使うんですが、メンバはすべてdouble型で30個程度になると思います。

  • 構造体について

    私は今プログラミング(C++)を勉強しているのですが、構造体に苦戦しています。分からないことがいくつかあります。もし知っていたらどれでもいいですので、よろしければ教えてください。 1、たとえば構造体を宣言するときに struct abc{ int s; struct abc xx; struct abc yy; }; と宣言するときがあります。でも上記の例と下記の例との違いが分かりません。 struct abc{ int s; struct abc xx; struct abc yy; }abc; 2、たとえばメインの最初にこのように宣言されているとします。 int j, i; struct abc *kk, *nn, *mm; これはここに宣言したものがローカルで、1のときに宣言したものがグローバルと考えていいのでしょうか? 3、メインの中に次のようなプログラムがあったとします。 kk->xx = j; kk->yy = j; nn->yy = NULL; i = kk->xx; i = kk; これらがそれぞれどのような意味があるのでしょうか。 これらでわかることがあればぜひ教えてください。よろしくお願いいたします。

  • 構造体のメンバーの静的なサイズ取得

    構造体のメンバーをヘッダーファイル中で得たい場合、 以下のような方法以外になにか方法はないでしょうか? 単純に XXXX x;と宣言してそれを sizeof(x.chwk)と 使うというような方法以外で なにかあれば教えてください。 ---------------------------------------- typedef struct { char chwk[100]; } XXXX; typedef struct { char chwk[ sizeof(( (XXXX*)0)->chwk ) ]; } YYYY; main(int arc, char *arg[] ){ YYYY y; printf( " YYYY chwk size = %d\n", sizeof(y.chwk)); }

  • ポインタを使った構造体のプログラム

    ポインタを使ってメンバに値を入力して表示するプログラムを作ったのですが、mainのstruct XYZ aというオブジェクトと*bというそれを指すポインタを使ってプログラムを表示するにはどうすればいいのでしょうか。 これがプログラムです。 #include <stdio.h> struct XYZ { int x; long int y; double z; }; void set_xyz(struct XYZ *p,int x,long int y,double z) { p->x=x; p->y=y; p->z=z; } //void set_xyz(struct XYZ *,int,long int,double); int main() { struct XYZ a = {12,999999,1.41421356},*b; //ここのポインタ変数bでエラーが表示されます。 set_xyz(b,a.x,a.y,a.z); printf("a.x = %d\na.y = %d\na.z = %lf\n",b->x,b->y,b->z); return 0; } エラーの内容は「初期化されていないローカル変数 'b' が使用されます」となっています。 初歩的な質問ですみません・・・。

  • 入れ子の構造体について

    例えば、入れ子の構造体を1つ使いたい場合、 struct bbb{ int b; }; typedef struct aaa{ struct bbb a; }AAA; AAA dt; と書くと、「dt.a.b = 10」とやれば、値等を設定できると思いますが、 入れ子の構造体を2つ使いたい場合も、同じように書けるのでしょうか? struct ccc{ int c; }; struct bbb{ struct ccc b; }; typedef struct aaa{ struct bbb a; }AAA; AAA dt; dt.a.b.c = 10; と書けるのでしょうか?こんがらがってしまって、どう書いていいのか・・。 2つでも出来るのであれば、コードの書き方を教えて頂けませんか?

  • 構造体のメンバ変数が途中で変化してしまう

    下にあるプログラムでコメントが書いてある部分の"Tmp->x"の値が途中で期待していない変化をします。何回も見ても特に操作していないと見てしまいますが、構造体変数の扱い方がおかしいのでしょうか? struct zahyo *MpCalculate(struct zahyo *P,int a,int multiple,int prime) { struct zahyo *kp,*Tmp; int i,u,r; kp=(struct zahyo*)malloc(sizeof(struct zahyo)); kp->x=P->x; kp->y=P->y; if(multiple == 1) return kp; u=myu(P,a,prime); kp->x=x3_PequalQ(P->x,u,prime); kp->y=y3(P,kp,u,prime); if(multiple == 2) return kp; printf("2Py(%d,%d)\n",kp->x,kp->y); //P≠Q for(i=3; i<=multiple; i++){ /*Tmp->xを表示させているDの部分で値が期待しない変化をします*/ Tmp=kp; A: printf("A:Tmp->x=%d\n",Tmp->x); r=rmd(Tmp,P,prime); B: printf("B:Tmp->x=%d\n",Tmp->x); kp->x=x3_PnotQ(Tmp,P,r,prime); D: printf("D:Tmp->x=%d\n",Tmp->x); kp->y=y3(Tmp,kp,r,prime); printf("%dPy(%d,%d)\n",i,kp->x,kp->y); } return kp; } int rmd(struct zahyo *P,struct zahyo *Q,int prime) { unsigned int m,n; m=mod(Q->x - P->x,prime); n=mod(Q->y - P->y,prime); exeuclid(m,prime,1,0,0,1); return mod(aa*n,prime); } int x3_PnotQ(struct zahyo *P,struct zahyo *Q,int rmd,int p) { /*ここでもTmp->x(P->x)の値は操作されていません*/ C:printf("C:Tmp->x = %d\n",P->x); return mod((int)pow(rmd,2) - P->x - Q->x,p); } 実行結果 A:Tmp->x=10 B:Tmp->x=10 C:Tmp->x=10 D:Tmp->x=5 常にDの部分で変わってしまいます。 このように変化する原因が分かる方、回答よろしくお願いします。

  • 配列の数を途中で増やすには?

    はじめまして。 この度、以下のようなプログラムを作りました。 が、途中で配列の数を増やすことになってしまいました。 ------------------------------------------------ struct a{ int int_a; long int_b; }; struct b{ a *aa; }; void main(void){ b *bb; bb = new b[3]; bb[0].aa = new a[5]; bb[1].aa = new a[4]; . . . } ------------------------------------------------ 具体的には、'bb'の配列を3から5に増やすようなやり方を探しています。 元の配列より大きい配列をつくり、そこにコピーすればいいと考えたのですが、 'bb'内の'aa'の配列も動的に作成しているため、それも出来ない状況です。 どなたかやり方を知っている方がいましたら、教えていただきたいです。 下手な説明ですいません。

  • 構造体メンバへの代入

    とても初歩的なことなのですが、 typedef struct _X{ int x; }X[50]; と構造体を定義して X[0].x = 0; と0を代入しようとすると、「宣言が正しく終了していない」とエラーが出てしまいます。 これはなぜでしょうか? ちなみにMicrosoft Visual C++ 2005 Express Editionを使っています。

  • プログラミング 構造体に関する質問です

    4人を個別で平均点を求めるプログラミングを作りたいのですが外部関数にする方法がいまいちわかりません。あとこのプログラムもなぜかエラーがでてしまいます。どなたかご教授お願いします #include<stdio.h> typedef struct{ char name[4]; int point[4]; }tokutenn; int main(void) { int x, y; int sum[5] = {0}; double ave[5] = {0.0}; tokutenn sd[5] = {{"kou", {55, 44, 33,34}}, {"mei", {34, 74, 67,56}}, {"sai", {72, 36, 68,35}}, {"kai",{34, 82, 73,56}}, for(x = 0; x < 4; x++){ for(y = 0; y < 3; y++){ sum[x] += sd[x].point[y]; } } for(y = 0; y < 4; y++){ ave[y] = sum[y] / 3.0; } for(y = 0; y < 4; y++){ printf( "%sの平均は%.10f点\n",&sd[y].name[0], ave[y]); } return 0; }

専門家に質問してみよう