配列のメンバを持つ構造体の扱い

このQ&Aのポイント
  • グローバルなデータの初期化方法と要素の判定方法
  • 配列のメンバにデータを代入する方法とデータの判定方法
  • ポインタを使った配列のメンバの初期化とデータの判定方法
回答を見る
  • ベストアンサー

構造体のメンバが配列の場合の扱い

typedef struct _info_t{ int xxx; int yyy; int zzz; } info_t; typedef struct _gData{ int aaa;  int bbb; info_t infoData[100]; } gData_t; gData_t gMainData; 質問1 C言語で上記のようなグローバルのデータを作成しようとしています。 gMainDataの中身を初期化するにはどうするのがベストでしょうか? (特にinfoData[100]の初期化) 質問2 gMainData.infoData[XXX]には info_t型のtmpDataを代入しようとしていますが gMainData.infoData[XXX] = tmpData; データがはいっているかどうかはどう判定するべきでしょうか? 質問3 以下のようにポインタを使うのは間違いでしょうか? typedef struct _gData{ int aaa;  int bbb; info_t *infoData[100]; } gData_t; 初期化 memset(gMainData.infoData,NULL, 100); データの代入 *gMainData.infoData[XXX] = tmpData; データの有無判定 if( gMainData.infoData[XXX] == NULL){ }

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

  • ベストアンサー
noname#208507
noname#208507
回答No.4

1.初期化 ループでもmemsetでもよいと思います。どれがベストかはケース・バイ・ケースでしょう。 ただしmemsetの第2引数はint型、第3引数はバイト数なので、次のようにするべきです。 memset(gMainData.infoData, 0, 100 * sizeof(info_t)); また、C言語の規格により static 変数を明示的に初期化しなければ全て 0 になるので static gData_t iniData; gData_t data; と定義しておいて data = iniData; のように初期化する方法も(一応)あります。 2.データの代入 info_t *infoData[100] は構造体の配列ではなく、ポインタの配列です。 infoData をポインタにするなら、構造体を下のようにすれば typedef struct _gData {  int aaa;  int bbb;  info_t *infoData[100];  info_t _infoData[100]; } gData_t; 次のように代入することができます。 data._infoData[XXX] = tmpData; data.infoData[XXX] = &(data._infoData[XXX]); 3.データの有無判定 前述の2のようにすれば if( gMainData.infoData[XXX] == NULL){ } でデータを代入済みかどうか判定できます。 もちろんデータを代入していないポインタがNULLであることが前提ですが。 ・余談ですが、構造体のタグ名とtypedefする型名は同じでも大丈夫です。例えば typedef struct info_t{ ... } info_t; のように。

その他の回答 (4)

  • wormhole
  • ベストアンサー率28% (1619/5653)
回答No.5

#3です。 >「データの有無判定」は・・・これはどっちの判定だろう・・・ 「データの有無判定」は・・・これはどっちの判定のつもりだろう・・・ です・・・ 初期化は私だと次のように書くかな。 static const info_t initialize_data = { .xxx = 1, .yyy = 2, .zzz = 3, }; for (int i = 0; i < sizeof(gMainData.infoData) / sizeof(gMainData.infoData[0]); i++) gMainData.infoData[i] = initialize_data;

  • wormhole
  • ベストアンサー率28% (1619/5653)
回答No.3

>質問3 >以下のようにポインタを使うのは間違いでしょうか? ポインタを使うことはいいのですが「初期化」はmemset()の使い方を間違ってますし、「データの代入」はメモリが確保されていません。 「データの有無判定」は・・・これはどっちの判定だろう・・・

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

「データが入っているかどうかを判定する」ためには, 「データが『入っているとき』と『入っていないとき』とで何かが違う」という状況を作らなければなりません. データそのもので区別できるならその区別を使えばいいし, そうでなければ「データが入っているかどうかを判定する」ためのデータが必要.

回答No.1

まずは、「普通に」初期化しましょう。 多くの場合、そんなに悪い結果にはなりませんから。 gMainData.aaa = 初期値; gMainData.bbb = 初期値; for(i = 0; i < 100; i++) { gMainData.infoData[i].xxx = 初期値; gMainData.infoData[i].yyy = 初期値; gMainData.infoData[i].zzz = 初期値; } あと、 info_t intial_data = {xxx の初期値, yyy の初期値, zzz の初期値}; で、 for(i = 0; i < 100; i++) { gMainData.infoData[i] = initial_data; } でもいいですが。 ポインタを使ったコードは、そもそも、「データの実体となる領域を確保できてない」時点でアウトです。

関連するQ&A

  • 構造体メンバ 構造体ポインタ 値代入

    typedef struct _test_t{ int aaa; int bbb; } test_t; typedef struct _globalData{ int xxx; test_t* pTestData[256]; } globalData_t; globalData_t globalData; int main(){ test_t testData1 = {1,1}; test_t testData2 = {2,2}; *globalData.pTestData[1] = testData1; /* (1) */ globalData.pTestData[2] = &testData1; /* (2) */ } 上記のようなグローバルデータの構造体globalData のメンバの構造体配列にtest_t型の構造体を格納し保持するには、 (1)、(2)のどちらが正しいでしょうか?

  • 動的な構造体配列の初期化

    以下のように構造体を new で動的に確保したときに 構造体の中身(char bbb[10], int ccc)をゼロで初期化したいのですが ZeroMemory を使用するとCArrayのAdd()を使用したときにエラーになってしまいました。 何かよい方法がありましたら教えて下さい。お願いいたします。 # 簡単にイメージですが・・・ typedef struct { CString a; CString b; }aaa_t ; struct s_aaa{ char bbb[10]; int ccc; CArray<aaa_t,aaa_t> m_aaaArray ; } s_aaa *StructB; StructB = new s_aaa [10];

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

    例えば、入れ子の構造体を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つでも出来るのであれば、コードの書き方を教えて頂けませんか?

  • 構造体の構造体配列初期化

    typedef strunct _test01 { int a; int b; } test01_t; typedef strunct _test { int c; test01_t sTest01[256]; } test_t; test_t sTest; 上記のような構造体がある場合、sTestのメンバのsTest01をNULL初期化する 方法とsTest01に値が入っていないか(初期化されているか)を判定する方法を 教えていただけませんか? よろしくお願い致します。

  • 構造体の引数について

    struct XXX { char *aaa; char *bbb; }; static struct XXX YYY[] = { {NULL, "JJJ"}, ... }; 上記のYYY[]をmainの上で設定し、下記のように使いたいです。 sub()関数でYYYの値を見たいのですが、下記の設定ではコンパイルが通りません。 どうしたらsub()関数で使うことができますか? どなたかご教授ください。 main(){ rtn = sub((struct xxx *)YYY); } int sub(struct xxx *YYY[10]){ for(i=0; YYY[i]->bbb[0]; iii++){ ... } ... }

  • 静的構造体の初期化について

    struct XXX{ MYSQL *MMM; char a[32]; char b[32]; char c[32]; char d[24]; } static struct XXX YYY[] = { {NULL, "AAA", "BBB", "CCC", "DDD"}, {NULL, "AAA", "BBB", "CCC", "DDD"}, {NULL, "", "", "", ""} } main(){ for(i=0; YYY[i].a[0]; i++){ MMM = ... } 上記のように、YYY[]分MMMの値を設定します。 この設定はうまくMMMが取得できるのですが、 実際にはMMMを1つの構造体の中に10個分用意したいです。 つまり、イメージは struct XXX{ MYSQL *MMM[10]; ... } このような形です。 ただし、初期化の仕方がわからずコンパイルが通りません。 またこのようなやり方ができるのかもわかりません。 どなたかご教授ください。 他にいいやり方があるのであればそれも教えて下さい。

  • 多次元配列の構造体の初期化

    タイトル通りです。やり方がわかりません。 構造体変数の初期化や多次元配列の初期化が載ってるページは多いのですが、コレだけは調べても解りませんでした。 typedef struct{ int flag; ~~~~~(略)~~~ }map_t; map_t map[64][64]; の後、map_t型のmap64*64の int flag全てに値を代入したいのですが 詳しいやり方が解りません。 int hensuu[3][3]={   {1,2,3},{4,5,6},{7,8,9} }; 普通の多次元配列みたいにmこんな感じでやりたいんですけど… 初心者でスミマセン。回答いただけたらありがたいです。

  • 構造体へのポインタ

    typedef struct str_tmp_t{ int a; char b; } str_tmp; void main() { str_tmp *str_info; str_info->a = 1; } とした場合、コンパイルエラーは出てはいないのですが、数値を代入している個所で落ちてしまいます。 これを回避するには単純にmallocしてfreeすれば良いのでしょうか? よろしくお願い致します。

  • 構造体の型について

    ある構造体をxxxと名づける以下のプログラムを作成しました。 ーーーーーーーーーーー #include <stdio.h> #include <string.h> main() { typedef struct { char variable[64]; char type[64]; char value[512]; } xxx; xxx aaa; strcpy(aaa.variable,"bbb"); printf("%s\n",aaa.variable); } ーーーーーーーーーーー これは動き、bbbと表示されます。 しかしながら、構造体のポインタを使用した 以下のプログラムではコンパイルはとおりますが実行時にコアダンプして落ち ます。 ーーーーーーーーーーーーーーーーーーーー #include <stdio.h> #include <string.h> main() { typedef struct { char variable[64]; char type[64]; char value[512]; } xxx; xxx* aaa; strcpy(aaa->variable,"bbb"); printf("%s\n",aaa->variable); } ーーーーーーーーーーーーーーーーーーーーーーー 両プログラムの意図はまったく同じなのに何故いけないのでしょうか。

  • 入れ子になっている構造体配列の初期化がうまくいきません。

    入れ子になっている構造体配列の初期化がうまくいきません。 どのようにすればうまくいくでしょうか? #include <stdio.h> typedef struct _item { int no; char name[10]; int price; }ITEM; typedef struct _all_item_info { ITEM ruit[2]; ITEM vegetable[2]; }ALL_ITEM_INFO; ALL_ITEM_INFO all_item_info = { {1, "apple", 100}, {2, "melon", 80}, {3, "tomato", 100}, {4, "radish", 200} }; int main() { ・・・・ } コンパイルすると、以下のようにエラーになってしまいます。 エラー E2225 kouzoutai7.c 20: 初期化子が多すぎる エラー E2141 kouzoutai7.c 22: 宣言の構文エラー エラー E2190 kouzoutai7.c 22: 不要な } エラー E2190 kouzoutai7.c 22: 不要な } OSはwindows、 コンパイラはBorland C++ Compilerです。

専門家に質問してみよう