• ベストアンサー

C++ 構造体の一括初期化 {0}

構造体変数に {0} を代入すると、CString は空文字、 intは0に一括で初期化されるようです。 なんでこんなことが出来るのでしょう? {0}は何? 仕組みを教えて下さい!!

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

  • ベストアンサー
  • hidebun
  • ベストアンサー率50% (92/181)
回答No.3

> 一括初期化関数でも作るしかなさそうですね static変数を初期化用に用意しておくのはいかが? http://okwave.jp/qa/q2658268.htmlより >静的記憶域期間をもつオブジェクトを明示的に初期化しない場合、 >次の規定に従う。 >a) そのオブジェクトの型がポインタ型の場合、空ポインタに初期化する。 >b) そのオブジェクトの型が算術型の場合、(正または符号なしの)0に初期化する。 >c) そのオブジェクトが集成体の場合、各メンバにa)~d)の規定を(再帰的に) >適用し初期化する。 >d) そのオブジェクトが共用体の場合、最初の名前つきメンバにa)~d)の規定を >(再帰的に)適用し初期化する。 なので、zero初期化されていることが、規格で保証されます。 typedef struct hoge_struct {  int a;  int b; } hoge_struct; static hoge_struct initializer; //初期化用変数。値は変えない。 int main(void) {  hoge_struct hoge;  hoge = initializer;  return 0; } 真っ白に何度も初期化したいなら、こんな感じでどうでしょう? 関数を用意して初期化すると、構造体のメンバが増えると関数も修正しないといけない ですが、これだと関数を変更しなくてすむし。

nevertheless
質問者

お礼

なるほど!2個用意するんですね!

その他の回答 (5)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.6

> 構造体変数に {0} を代入すると {0}を代入することは原則としてできませんが、initializer_listということなら可能です。 std::vector<int> v; v = {0}; といったことができますから。 ただし、代入後は1要素だけになってしまいます。 (その構造体とやらをどんな仕様にするかにもよりますが...)

  • jjk65536
  • ベストアンサー率59% (66/111)
回答No.5

> {0}は何? {0}で初期化というのは、C言語の時からある手法ですね。 なにやら予約語のようにも見えますが、ただのカッコ0です。 例えば、初期化済み配列を宣言するとします。 int a[2] = {1,2}; これはa[0]=1,a[1]=2で初期化されるのは分かりますよね。 では、数が合わないとき int a[2] = {1}; こんなとき、不足分は0で初期化されることが規格で保証されています。 つまり、a[0]=1,a[1]=0ですね。 ですから、全て0で初期化する場合は、 int a[2] = {0}; とすれば良いわけです。 数が多くても、型が違っても同様です。 char buf[128] = {0}; // ゼロで初期化 このことを知っていると理解しやすいと思いますがいかがでしょう。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

#3 をもうちょっと進めて struct hoge_struct {  int a;  int b;  static const hoge_struct initializer; }; static const hoge_struct hoge_struct::initializer; //初期化用変数。値は変えない。 のようにすると, グローバル名前空間の名前が 1つ減る.

nevertheless
質問者

お礼

これは・・・? どう使うんでしょう?

  • wormhole
  • ベストアンサー率28% (1622/5658)
回答No.2

初期化のときにしか使えなくても こういうこともできるけど。 構造体変数 = (構造体の型){0};

nevertheless
質問者

お礼

なるほど! コピーしてしまうわけですね。賢いです!

回答No.1

> 構造体変数に {0} を代入すると 代入の右辺に {0} はかけないと思うけど。少なくとも私の環境ではコンパイルエラーになる。 初期化なら右辺に {0} を書くことができる。 この違いは分かるかな? > なんでこんなことが出来るのでしょう? 規格で決まっているから。 規格そのものの文章は知らないけど以下に説明があります。 http://www.kijineko.co.jp/node/681

nevertheless
質問者

お礼

有難うございます。初期化の時だけでしたね。 ループの中で一括で初期化できれば便利だと思ったのですが、 一括で初期値に戻すのは無理みたいです。 一括初期化関数でも作るしかなさそうですね。

関連するQ&A

  • 構造体の静的な初期化

    構造体の静的な初期化で、初期化が書かれていないメンバーは、 どうなるのでしょうか。。? たとえば・・・ // 構造体の宣言 strcut MY_STRUCT {    int data1 ;    int data2 ;    int data3 ;    int data4 ; } ; // 変数宣言&初期化 static strcut MY_STRUCT st = {    .data1 = 100,    .data3 = 300 } ; ネットで調べると、 初期化で指示されていないメンバーは0に初期化される、 という記述も一つだけ見つけたのですが・・・これはC言語(C99)の仕様でしょうか? それともコンパイラ依存の仕様でしょうか?

  • C言語の構造体について

    構造体を勉強している所なのですが変数をまとめられるのは分かりましたがどのサイトを見てもいまいち使い所がわかりません。 struct test { int a; int b; int c; }testtest; testtest.a = 0; testtest.b = 1; testtest.c = 2; 例えば上記のような構造体を作成するとします。 私の見たサイトでは構造体で宣言はまとめられても初期化する事はできないと書いてありました。 下記のように変数を普通に宣言&初期化するよりも手間がかかってしまっていると思うのですが私の考えが及ばない何か別の使い方または処理が早くなったりする事があるのでしょうか?。 int a = 0; int b = 1; int c = 2;

  • 動的な構造体配列の初期化

    以下のように構造体を new で動的に確保したときに 構造体の中身(char bbb[10], int ccc)をゼロで初期化したいのですが ZeroMemory を使用するとCArrayのAdd()を使用したときにエラーになってしまいました。 何かよい方法がありましたら教えて下さい。お願いいたします。 # 簡単にイメージですが・・・ typedef struct { CString a; CString b; }aaa_t ; struct s_aaa{ char bbb[10]; int ccc; CArray<aaa_t,aaa_t> m_aaaArray ; } s_aaa *StructB; StructB = new s_aaa [10];

  • 多次元配列の構造体の初期化

    タイトル通りです。やり方がわかりません。 構造体変数の初期化や多次元配列の初期化が載ってるページは多いのですが、コレだけは調べても解りませんでした。 typedef struct{ int flag; ~~~~~(略)~~~ }map_t; map_t map[64][64]; の後、map_t型のmap64*64の int flag全てに値を代入したいのですが 詳しいやり方が解りません。 int hensuu[3][3]={   {1,2,3},{4,5,6},{7,8,9} }; 普通の多次元配列みたいにmこんな感じでやりたいんですけど… 初心者でスミマセン。回答いただけたらありがたいです。

  • 【VC++2005 MFC】構造体のコピーについて

    【VC++2005 MFC】構造体のコピーについて 構造体をコピーする時、単純に「=」で代入しているのですが、先輩に 「それじゃコピー出来ないから各メンバごとに代入するような関数作れ」 と言われました。 私自身、C言語の初心者ですが、ネットで調べてみると、単純に「=」で代入出来る ような気がしております。 ただ拝見したサイトに記載されている構造体は型が「int」「char」なのですが、 「CString」を使っていたり、構造体の中に更に構造体が入っていたりする場合も 単純に「=」で代入出来るのでしょうか? (というか、実際にコーディング、デバッグして、コピー出来ている事は確認しているん ですが、先輩いわく、「CStringとかのクラスが含まれている場合はダメだと思う。 メモリが壊れると思う」との事でした。)

  • C++、クラスメンバの構造体配列の初期化について

    クラスのメンバに構造体の配列を持っていて、その構造体はfloat値を4つ持ってます。 私はいつもメンバ変数の初期化はコンストラクタでしています。 クラス生成時に全てのfloatを0で初期化したいのですが、これはコンストラクタでfor文を回すしかないのでしょうか? 一文で初期化することは出来ないのでしょうか? 話は少し変わってしまいますが、今思ったのですがコンストラクタで値を決めるのは初期化じゃなくて代入と呼ぶのですかね? ご助力よろしくお願いします。

  • 構造体

    構造体を受け取って、メンバの値を変数に代入する部分での質問です。 lParamには構造体のアドレスが入っています。 strcpy(buf, ((struct mpoint*)lParam)->r); これによって構造体のrメンバの文字列値をbufにコピーしたいのですが、文法が違うようなので正しく直したものを教えてください。

  • 構造体の初期化方法について

    こんばんわ。 何度も申し訳ありません。 VC++.NET 2003を用いてコンソールプログラミングを行っています。前回この掲示板を利用して複数回実行するプログラムを作成し、そこに構造体を用いたプログラムを作成しました。以下に概要を示します。 グローバルで構造体を宣言しているため、複数回実行を行うプログラムでは前回の値が格納されたままであると思い、毎回実行時に構造体の初期化を行いたいと思っています。 そこで、以下に示します構造体の初期化はどのように記述すればよいのでしょうか?0で初期化したいと思っています。 よろしくお願い致します。 #define MAX 2000 //グローバル struct tag{ int Npkt; int gettime; int rPkt; int lossPkt; }rdata[MAX]; main(){   //for文で複数回実行処理   for(i=0;i<=5;i++){   //ここで構造体の初期化を記述する //例として、5回プログラムを実行する   } }

  • C#の構造体に関して

    C#の構造体に関して C#で構造体で配列を持ちたいと思い、宣言の仕方や使い方を 勉強していますが、どうしてもコンパイルは通るもののエラーと なってしまいます。 《ソース》 単純に構造体で宣言した"a"という配列に、"ABC"という文字列を 代入したいだけですが。。。 namespace テスト環境 { struct test { public string []a; } class Program { static void Main(string[] args) { test aaa = new test(); aaa.a[0] = "ABC"; } } } 配列の初期化等は、ようやく理解したつもりではいますが、構造体 が絡むとどうしてもわかりません。 どこをどのように修正したら良いかを教えて下さい。 初歩的な質問で申し訳ありませんが、よろしくお願いします。

  • CStringを含むconst構造体

    VC++6.0で typedef struct { int i; CString s; } StructTest; という構造体を作ったとして const StructTest m_STest = { 1, "TEST" }; とすると 『error C2552: 'm_STest' : 初期化子リストによる個別の識別子の初期化に誤りがあります。』 と出ます。 このような記述は出来ないのでしょうか?

専門家に質問してみよう