• ベストアンサー

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

こんばんわ。 何度も申し訳ありません。 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回プログラムを実行する   } }

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

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.4

★まとめ ・既に『memset』関数や、『ZeroMemory』関数の回答があるので構造体の全体、1部の  初期化の記述例を紹介します。 ・それと『#include <memory.h>』を記述しないとメモリ関係の関数が利用できません。  『ZeroMemory』関数の場合は『#include <windows.h>』があればそのまま利用できます。 ●構造体全体を初期化 ZeroMemory( rdata, sizeof(rdata) ); または、 memset( rdata, 0, sizeof(rdata) ); です。 ●構造体一部を初期化 ZeroMemory( &rdata[i], sizeof(struct tag) ); または、 memset( &rdata[i], 0, sizeof(struct tag) ); です。 ※rdata[i]の1データだけ初期化します。 余談: ・『ZeroMemory』関数は Win32 API と分類されていますが、実体は『memset』関数に  『#define』されているだけです。でも、戻り値を『VOID』型にキャストされているので  『memset』関数のリターン値を取得できません。→第一引数のアドレスが『memset』関数  ではリターンします。 ・以上。おわり。

参考URL:
http://taka.no32.tk/tips/Win32/ZeroMemory.html
bird0214
質問者

お礼

前回に続きまして返信ありがとうございました。 memset以外にZeroMemory関数を知ることができました。 ありがとうございました。

その他の回答 (4)

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

厳密なことをいうと、構造体のメンバにポインタや浮動小数点数が含まれていると、memset等でゼロクリアすることができません。ただし、VC++.NET 2003に限定するなら、たまたまうまくいきます。 確実にゼロクリアするには、  static const struct tag zero = { 0 }; rdata[i] = zero; のように、ゼロ初期化されたオブジェクトを代入するのが簡単でしょう。 ちなみに、memset関数を使う際にインクルードすべきヘッダは、<memory.h>ではなく、<string.h>です。

bird0214
質問者

お礼

返信ありがとうございます。 2通りの初期化方法を知ることが出来ました。 ありがとうございました。

  • koedame
  • ベストアンサー率33% (10/30)
回答No.3

先の御二方の回答どおり、WinAPI で既に用意されている Zeromemory() 関数を使えば構造体の全メンバは0初期化できます。 使用方法は 第一引数:構造体のアドレスを渡す 第二引数:第一引数で渡した構造体のサイズ(バイト単位なので sizeof() を使用)を渡す 回答例は先の御二方が記述しておられるのでこちらは意味の理解の ための記述です。

bird0214
質問者

お礼

返信ありがとうございます。 せっかくですので、教えていただいたZeromemory関数を用いて記述してみようと思います。 ありがとうございました。

  • PG_RankB
  • ベストアンサー率40% (12/30)
回答No.2

経験論で言うのであれば、構造体の初期化(ゼロクリアなら特に)には、 Win32APIを使用する環境ならばZeroMemory関数が一般的かと思います。 C言語標準ライブラリであれば、memset関数(ないしmemsetで0を渡す事を定義した自作ラップ関数等)を使うのが一番素直なやり方では無いでしょうか? 例)memset( &rdata[i], 0x00, sizeof(tag) );

bird0214
質問者

お礼

返信ありがとうございます。 memset関数は知っていましたが、実際に構造体の初期化を行う際、どのような記述があるのか分かりませんでした。また、Win32APIにZeroMemory関数が存在することを知ることができました。 ありがとうございました。

  • osamuy
  • ベストアンサー率42% (1231/2878)
回答No.1

ZeroMemory( rdata, sizeof rdata ); ――とか。

参考URL:
http://msdn.microsoft.com/library/ja/default.asp?url=/library/ja/jpmemory/html/_win32_zeromemory.asp
bird0214
質問者

お礼

返信ありがとうございます。 このような関数が存在していることを知り、大変勉強になりました。 ありがとうございました。

関連するQ&A

  • 構造体を用いた特定数値抽出方法について

    こんばんは。 前回、複数回実行方法および構造体の初期化について質問させていただいた者です。 VC++.NET2003を用いてコンソールプログラミングを行っています。 以下に前回示しました構造体を示します。この構造体は4つの整数型のメンバをもっています。 このNpktメンバ変数には、10から11000まで10ずつカウントアップされた値が格納されています。10,20,30,40・・・100,110・・・・11000ということです。そこで、Npktが100,200,300・・・の時のgettime,rPkt,lossPktメンバの値を抽出しファイル出力させたいと思い、以下に示しますプログラムを記述しました。 しかし、10,20,30,40・・・100,110・・・490,510,520・・・ という仮に500がない場合が存在し、Npktが500の値を取得できずにかつそれ以降の600,700・・・1000などを取得できない状態になってしまいます。 そこで、500がない場合は改行をファイル出力し600を探索しだすという方法を考えたのですが、うまく記述できません。 もしよろしければ、ヒントや記述方法を教えていただけないでしょうか? よろしくお願い致します。 (1)構造体 #define MAX 2000 struct tag{  int Npkt;  int gettime;  int rPkt;  int lossPkt; }rdata[MAX]; (2)プログラム概要 while(rdata[e].Npkt!='\0'){  if(rdata[e].Npkt==sa){   de=100;   sa+=de;   fprintf(fp9,"%d\t%d\t%d\t%d\n",rdata[e].Npkt,rdata [e].gettime,rdata[e].rPkt,rdata[e].lossPkt);  }  e++; }

  • 構造体の静的な初期化

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

  • 動的配列の構造体の受け渡しについて

    動的配列の構造体の受け渡しについて教えていただきたいです。 typedef struct{ int class; int **matrix; }pattern_struct; という構造体を用意しました。 メイン側で int main(){ pattern_struct *sample,*prototype; 省略 for(k=0;k<9;i++){ for(i=0;i<height;i++){ for(j=0;j<width;j++){ prototype[0].matrix[i][j]=sample[k].matrix[i][j]+prototype[0].matrix[i][j]; } } for(i=0;i<height;i++){ for(j=0;j<width;j++){ prototype[1].matrix[i][j]=sample[k].matrix[i][j]+prototype[1].matrix[i][j]; } }     ~9まで続きます~ } 省略 } 少し変えていますが、このようなプログラムを記述しました。 記述を省略するためにmallocで作成した構造体配列の足し算をする関数を作りたいのですが、どのように記述するべきなのでしょうか。

  • 構造体の構造体の構造体をまとめて初期化したい

    gnuplotをCで吐くためのプログラムを作成していますが、 構造体の構造体の構造体をまとめて初期化することができません。 以下がコードそのコードです。 #define MAX_PLOT_DATA_NUM 8 #define MAX_GRAPH_SET_NUM 35 //child -------------------------------------------------- typedef struct { char *fileName; int column[2]; char *caption; } Col; //child -------------------------------------------------- typedef struct { char *category; char *subCategory; char *xLabel, *yLabel; char *saveFileName; Col col[MAX_PLOT_DATA_NUM]; } GraphSet; //child -------------------------------------------------- typedef struct { char *lineFormat; int lineWidth; } Common; //mother ------------------------------------------------- typedef struct { GraphSet gs[MAX_GRAPH_SET_NUM]; Common common; } PlotFormats; int main(){ PlotFormats pF = { {"Motor angle","right","Time [s]","Angle [rad]","ang_R", {"motor.dat",1,2,"ang #1 "}, {"motor.dat",1,3,"ang #2 "}, {"motor.dat",1,4,"ang #3 "}, {"motor.dat",1,5,"ang #4 "}, {"motor.dat",1,6,"ang #5 "}, {"motor.dat",1,7,"ang #6 "}, }, //ここから下のコメントアウトしてる部分をはずすとコンパイルが通らなくなります。 //{"Motor angle","left","Time [s]","Angle [rad]","ang_L", // {"motor.dat",1,12,"ang #1 "}, // {"motor.dat",1,13,"ang #2 "}, // {"motor.dat",1,14,"ang #3 "}, // {"motor.dat",1,15,"ang #4 "}, // {"motor.dat",1,16,"ang #5 "}, // {"motor.dat",1,17,"ang #6 "}, //}, {"w l", 5}}; return 0; } エラーは ・間接参照のレベルが 'char *' と 'int' で異なっています。(複数) ・初期化子の数が多すぎます。 と出ます。 長くなりましたが、わかる方がいましたら、よろしくお願いします。

  • 構造体

    下記プログラムの2次元配列を構造体の配列に作り変え,構造体を利用して生年月日の項目を追加し,形式は日を除いたYYYY/MMで持ち,生年月日の入出力は,YYYY/MM形式で行い,西暦が数字4桁で,西暦と月の間に'/'があり,月が01~12の範囲の数字の2桁になっている7文字の入力のみ受け付け,正しく入力されるまでそれ以外は再入力させたい。あとdo-while文をつかっている箇所をwhile文に直したいです.自力でやったのですが,わかりませんでした. どのようにしたらよいか教えてください. お願いします. include <stdio.h> #define BUFFERSIZE 11 #define MAX_PERSON 10 #define MAX_CHARS 10 int main(void) { char name[10][BUFFERSIZE]; int c; int count = 0; int i; int j; for (i = 0; i < MAX_PERSON; i++) { printf("氏名入力 : "); j = 0; /* 氏名の1文字目が'0'なら入力を終了 */ if ((c= getchar()) == '0'){ break; } if (c == '\n') { /* 改行のみの入力は再入力 */ do { printf( "再入力\n" ); /*再入力*/ printf("氏名入力 : "); } while ((c = getchar()) == '\n'); } name[i][j++] = c; /*1文字目を格納*/ if (name[i][0] == '0') { break; } while ((c = getchar()) != '\n' && c != EOF) { if (j < BUFFERSIZE - 1) { name[i][j++] = c; } } name[i][j] = '\0'; count++; /* 実際に入力した人数を記録*/ printf("累計 : %d \n", count); } /* 氏名と生年月日を出力したいです */ for (i = 0; i < count; i++) { for (j = 0; j < MAX_CHARS; j++) { if (name[i][j] == '\0'){ break; } putchar(name[i][j]); } putchar('\n'); } return 0; }

  • 構造体のポインタ参照

    構造体のプログラムを作成しており、コンパイルを行った際にエラーが起きてしまいました。 以下に構造体宣言とメイン関数のプログラムをとエラーが出てしまった部分を記述します。 エラー表示の内容として「不完全型ポインタへの間接参照」と出ました。 自分なりに考えた結果、ポインタの参照部分に間違いがあるためエラーが起こったと思います。そのエラーが生じた部分のプログラムをどのように修正すればコンパイルが成功するか、ご教授のほうお願いします。 /* 構造体宣言 */ typedef struct { int m; double *a; double *alpha; }PREDICTOR; int main(){ struct PREDICTOR *pred; int i; /* ここでエラーが起きました */ pred -> a[0] = pred -> a[1] =0; pred -> m = 0; pred -> alpha = r(0);  /* ここまで */ for(i = 0; i < M; i++){ pred = levin(pred); } return 0; }

  • テキストデータから構造体にデータを保存する方法

    C言語初心者です。 大きなテキストデータ(730MB)からデータを取得して、構造体に保存し表示するというプログラムを作成しています。テキストのサイズが大きいため構造体のサイズを400000とし、 残りをftellとfseekを使用してファイルポインタをずらして全データを順次読み込んで表示しようとしているのですが、実行すると400000行目以降(最初の構造体のMAX時点)がうまく読み込めません。 詳しい方がいましたら、ご教授願います。 #define MAX_SIZE 400000 char filename[] = ″test.txt"; struct ALL_DATA{ char cmd[10]; int addr; int bsize; }; for (int lp = 0; lp < 100; lp++){ FILE *fp; struct ALL_DATA ADATA[MAX_SIZE]; // 構造体配列の宣言 if (lp > 0){ fseek(fp, LP, SEEK_SET); } if ((fp = fopen(filename, "r")) == NULL){ printf("%s open error !\n", filename); exit(1); } for (fc = 0; fc < MAX_SIZE; fc++) { if (feof(fp)){ break; } else{ fscanf(fp, "%s %d %d\n", ADATA[fc].cmd, &ADATA[fc].addr, &ADATA[fc].bsize); } } LP = ftell(fp); //現在のFPの取得 printf("********** FP-> %ld *********\n", LP); fclose(fp); while (i < MAX_SIZE){ if (loopcnt == 0){ printf("ADATA[i].cmd -> %s, ADATA[i].addr -> %d, ADATA[i].bsize -> %s\n",ADATA[i].cmd, ADATA[i].addr, ADATA[i].bsize); // i++; } } 上記のような形で作成しています(一部抜粋)。 読み込むテキストデータは testA 123456 20 testA 23415 2 testB 12114567 678 のように「文字列 スペース 数字 スペース 数字」と並んでおり 値はランダムになっています。 初めて質問するため、わかりにくい記述があるかと思いますが、よろしくお願いします。

  • C言語 構造体でつまずいています

    以下、番号と点数を入力して構造体配列に入力し、番号に0が入力されたら、入力処理をやめ、平均点を表示するプログラムです。  今のコードでは、最初から番号に0を入力すると、0除算になりエラーになります。どうすれば良いのでしょうか? #include <stdio.h> #define MAX 50 //配列の要素数を定義 int count=0; //グローバル変数 struct data { //構造体の定義 int num; //メンバの宣言 int ten; }; void nyuryoku(struct data *); //プロトタイプ宣言 float heikin(struct data *); //プロトタイプ宣言 void main() { struct data score[MAX]; //構造体の宣言 printf("**学生番号/点数入力**\n"); printf("\n"); nyuryoku(score); //nyuryoku関数呼び出し printf("\n**以上%d名の平均点:%0.1f点**\n",count,heikin(score)); //heikin関数の戻り値表示 } //nyuryoku関数 //機能:構造体配列にデータを入力する void nyuryoku(struct data *pd) //仮引数pdに構造体ポインタが渡る { int i; for(i=0;i<MAX;i++){ printf("学生番号>>"); scanf("%d",&pd->num); if(pd->num==0){ //学生番号に0を入力するとループを抜ける break; } printf("点  数>>"); scanf("%d",&pd->ten); count++; //人数のカウント pd++; //構造体配列を一つずらす } } //heikin関数 //機能:構造体配列の点数の平均を計算、戻り値として返す float heikin(struct data *pd) //仮引数pdに構造体ポインタが渡る { int i; int sum=0; float ave=0; for(i=0;i<MAX;i++){ if(pd->num==0){ break; } else{ sum+=pd->ten; //点数を加算 pd++; } } ave=(float)sum/count; //平均値を求める return(ave); //平均値を戻り値として返す }

  • CStringを含むconst構造体

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

  • 構造体の配列について

    構造体配列を使った簡単なプログラムを組んでいるのですが、以下のソースコードをコンパイルし、実行したのですが、うまくいきません。 どなたかお力をお貸しください。 ・やりたい事 配列に以下のようにデータをscanf関数を使って入れたいです。 ----[0]---[1]---[2]--- [0] 1 | "あ" | "猫" | [1] 2 | "い" | "亀" | [2] 3 | "う" | "狐" | -登録する内容 番号、名前、好きなもの動物 ■ソース #include <stdio.h> struct hyou { int box[3][3]; }; int main(){ struct hyou *da; int i; for(i=0;i<2;i++){ printf("番号:\n");   scanf("%d",&da->box[i][0]); printf("名前:\n");   scanf("%s",&da->box[i][1]); printf("好きなもの:\n");   scanf("%s",&da->box[i][2]); } //テスト(2件表示) for(i=0;i<2){ printf("番号:\n"); printf("%d",a->box[i][0]); printf("名前:\n"); printf("%s",a->box[i][1]); printf("好きなもの:\n"); printf("%s",a->box[i][2]); } } //構造体配列の意味が違っていたらすみません。 以上、宜しくお願いします。

専門家に質問してみよう