web-dev-qa-db-ja.com

構造体をゼロ/ヌルに初期化/リセットします

struct x {
    char a[10];
    char b[20];
    int i;
    char *c;
    char *d[10];
};

この構造体を埋めてから値を使用しています。次の繰り返しで、再利用を開始する前に、すべてのフィールドを0またはnullにリセットします。

どうやってやるの? memsetを使用できますか、それともすべてのメンバーを調べてから個別に行う必要がありますか?

82
hari

初期値を使用して構造体のconst静的インスタンスを定義し、リセットしたいときにいつでもこの値を変数に割り当てます。

例えば:

static const struct x EmptyStruct;

ここでは、初期値を設定するために 静的初期化 に依存していますが、異なる初期値が必要な場合は、構造体初期化子を使用できます。

次に、ループを回るたびに次のように記述できます。

myStructVariable = EmptyStruct;
98
David Heffernan

最新のC(C99)を使用しているときにこのようなことを行う方法は、複合リテラルを使用することです。

a = (const struct x){ 0 };

これは、Davidのソリューションに多少似ていますが、空の構造体を宣言したり、staticを宣言するかどうかを心配する必要はありません。 constを使用した場合、コンパイラは、必要に応じて読み取り専用ストレージに複合リテラルを静的に自由に割り当てます。

78
Jens Gustedt

上記のすべてよりも優れているのは、構造体の初期化に標準C仕様を使用することです。

struct StructType structVar = {0};

すべてのビットがゼロ(これまで)です。

51
user411313

Cでは、structを使用してmemsetのメモリをゼロにするのが一般的なイディオムです。

struct x myStruct;
memset(&myStruct, 0, sizeof(myStruct));

技術的に言えば、マシン上のNULLポインターが整数値0で表されることを前提としているため、これは移植性があるとは思いませんが、ほとんどのマシンでこれが当てはまるため広く使用されています。

CからC++に移行する場合、すべてのオブジェクトでこの手法を使用しないように注意してください。 C++は、メンバー関数と継承のないオブジェクトでのみこれを有効にします。

33
templatetypedef

C99準拠のコンパイラがある場合は、次を使用できます。

mystruct = (struct x){0};

そうでない場合は、David Heffernanが書いたことを実行する必要があります。

struct x empty = {0};

そしてループ内:

mystruct = empty;
14
Rudy Velthuis

memsetを構造体のサイズで使用できます。

struct x x_instance;
memset (&x_instance, 0, sizeof(x_instance));
5
Diego Sevilla

空のセット({})を変数に割り当てることができると思います。

struct x instance;

for(i = 0; i < n; i++) {
    instance = {};
    /* Do Calculations */
}
3
Archmede

または、構造体にAPIを追加したい場合は、次のようにします。

struct Register {
    ..
    ..
    void reset() { *this = {}; }
    ..
}

後でこれを行うことができます:

Register reg;
// do some work
reg.reset()
0
gatis paeglis
 struct x myX;
 ...
 memset(&x, 0, sizeof(myX));
0
Josh Matthews