こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

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

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){

}

投稿日時 - 2012-05-22 08:01:24

QNo.7489315

すぐに回答ほしいです

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

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;

のように。

投稿日時 - 2012-05-22 22:33:35

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(5)

ANo.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;

投稿日時 - 2012-05-23 02:36:12

ANo.3

>質問3
>以下のようにポインタを使うのは間違いでしょうか?

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

投稿日時 - 2012-05-22 22:10:57

ANo.2

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

データそのもので区別できるならその区別を使えばいいし, そうでなければ「データが入っているかどうかを判定する」ためのデータが必要.

投稿日時 - 2012-05-22 11:19:12

ANo.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;
}

でもいいですが。

ポインタを使ったコードは、そもそも、「データの実体となる領域を確保できてない」時点でアウトです。

投稿日時 - 2012-05-22 09:11:06