プロが教える店舗&オフィスのセキュリティ対策術

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

}

A 回答 (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;
    • good
    • 0

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;

のように。
    • good
    • 0

>質問3


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

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

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



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

まずは、「普通に」初期化しましょう。


多くの場合、そんなに悪い結果にはなりませんから。

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

でもいいですが。

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

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!