web-dev-qa-db-ja.com

構造体を0に初期化する

このような構造体がある場合:

typedef struct
{
    unsigned char c1;
    unsigned char c2;
} myStruct;

この構造体を0に初期化する最も簡単な方法は何でしょうか?以下で十分でしょうか?

myStruct _m1 = {0};

または、各メンバーを明示的に0に初期化する必要がありますか?

myStruct _m2 = {0,0};
99
Daan Timmer

最初の方法は最も簡単です(タイピングが少なくなります)、そしてそれは動作することが保証され、すべてのメンバーは0に設定されます[参照1]
2番目の方が読みやすくなっています。

選択は、ユーザーの好みまたはコーディング標準で義務付けられているものによって異なります。

[参照1] 参照C99標準6.7.8.21:

ブレースで囲まれたリストの初期化子が集合体の要素またはメンバーより少ない場合、または既知のサイズの配列を初期化するために使用される文字列リテラルの文字が配列の要素より少ない場合、集合体の残りは静的ストレージ期間を持つオブジェクトと同じように暗黙的に初期化されます。

グッドリード:
CおよびC++:自動構造の部分的な初期化

124
Alok Save

データが静的変数またはグローバル変数である場合、デフォルトでゼロで埋められますので、単にそれを宣言しますmyStruct _m;

データがローカル変数またはヒープに割り当てられたゾーンである場合、次のようにmemsetでクリアします:

memset(&m, 0, sizeof(myStruct));

現在のコンパイラ(たとえば、gccの最近のバージョン)は、実際には非常によく最適化します。これは、すべてのゼロ値(ヌルポインターと浮動小数点ゼロを含む)がすべてゼロビットとして表される場合にのみ機能します。これは、私が知っているすべてのプラットフォームで当てはまります(ただし、C標準では、 false;そのような実装はわかりません)。

myStruct m = {};またはmyStruct m = {0};をコーディングできます(myStructの最初のメンバーがスカラーでない場合でも)。

私の感じでは、ローカル構造にmemsetを使用するのが最善であり、実行時に何かをしなければならないという事実をよりよく伝えます(通常、グローバルおよび静的データはコンパイル時に初期化され、実行時のコスト)。

28

§6.7.9初期化を参照してください:

21括弧で囲まれたリストの初期化子が集合体の要素またはメンバーよりも少ない場合、または既知のサイズの配列を初期化するために使用される文字列リテラルの文字が配列の要素よりも少ない場合、集合体の残り静的ストレージ期間を持つオブジェクトと同じように暗黙的に初期化されます。

はい、両方とも機能します。 C99では、指定された初期化と呼ばれる初期化の新しい方法も使用できることに注意してください。

myStruct _m1 = {.c2 = 0, .c1 = 1};
17
dirkgently