構造体を0に初期化する


116

私がこのような構造体を持っている場合:

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

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

myStruct _m1 = {0};

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

myStruct _m2 = {0,0};

回答:


142

最初の方法が最も簡単で(入力の手間が減ります)、機能することが保証されており、すべてのメンバーが0[参照1]に設定されます。
2番目はより読みやすくなっています。

どちらを選択するかは、ユーザーの好み、またはコーディング標準が要求するものによって異なります。

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

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

よく読む:
CおよびC ++:自動構造の部分的な初期化


9
また、私は使用= {};していますが、これが有効かどうかはわかりません。
William Entriken

15
初期化のための@FullDecent空の括弧はGNU拡張です。
a3f

2
@ alias65536質問のタグはC ++ではなくCです。
a3f 2017

3
エラーが発生しました: "初期化子の周りに中括弧がありません[-Werror = missing-braces]"おそらくメンバー配列が原因です:/
DrumM

3
@エデニア。同意しません。私はすでに何をfoo = {0}意味するのか知っています。を見た場合foo = ZERO_FULL、ZERO_FULLの定義をgrepする必要があります。
Andrew Bainbridge

32

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

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

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

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

あなたはおそらく、コーディングができmyStruct m = {};たり myStruct m = {0};(の最初のメンバーがあってもmyStructスカラーではありません)。

memsetローカル構造に使用するのが最善であり、実行時に何かを実行する必要があるという事実をよりよく伝えます(通常、グローバルデータと静的データは、実行時にコストをかけずにコンパイル時に初期化されていると理解できます)。 。


7
ただし、structのすべてのバイトをに設定することが、0すべてのstructメンバーを初期化することと同等であるという保証はありません0。これは多くのプラットフォームで当てはまりますが、普遍的ではありません。
Sander De Dycker

1
サンダーさんの例を教えてください。本物の好奇心。(明らかに、普遍的に真ではない場合でも、必ずしも説明しやすい例外があることを意味するわけではありませんが、例外がある場合は...)
Steven Fisher

2
Cの標準は、すべてゼロのビット以外の何かによってメモリ内で表現されるNULLポインタ(またはゼロ浮動小数点数)を可能にします。非常に少数の奇妙な実装がそれを行っています(名前を付けることはできません)。
バジルStarynkevitch

-1の場合、OPが醜いことを求める初期化が見つかるかもしれませんが、これは標準で予見されているものであり、すべてのコンパイラーで簡単に最適化できます。次に、フォーム{}は有効なCではなく、C ++でのみ使用できます。
イェンスガステッド

7
@Steven:あいまいで古いプラットフォームしか考えられません。CのFAQには、NULLすべての0ビットではないポインタがあったプラットフォームのリストがあります:c-faq.com/null/machexamp.html。そして、プラットフォームが浮動小数点値を表すためにIEEE 754を使用していない可能性がありますが、全0ビット0.0値を持たない他の表現を使用していますが、確かに私はそのようなプラットフォームを知りません。
Sander De Dycker 2012年

19

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

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

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

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

特に、これはすでにC89です:open-std.org/JTC1/SC22/WG14/www/docs/n1124.pdf#page=139(特定の信号処理ターゲットにとって重要)
Tobias
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.