• 締切済み

構造体を宣言と共に初期化する方法

構造体を宣言と共に初期化する方法はないのでしょうか? もしないのでしたら初期化用の関数を作ってそれを呼び出すしかないのでしょうか? ↓このような感じで ---kudamono.cppの内容 --- #include <stdio.h> struct{ static const char *name[5]; static const char *num[5]; }kudamono; void kuda(void){ kudamono.name[0] = "りんご"; kudamono.name[1] = "みかん"; kudamono.name[2] = "オレンジ"; kudamono.name[3] = "もも"; kudamono.name[4] = "キウイ"; kudamon.num[0] = "1個"; kudamon.num[1] = "3個"; kudamon.num[2] = "5個"; kudamon.num[3] = "2個"; kudamon.num[4] = "4個"; } --- main.cppの内容 --- #include <stdio.h> void kuda( void ); void main( void ){ printf( "%sが%sある" , kudamono.name[0] , kudamon.num[0] ); }

みんなの回答

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

>10のお礼にかかれたものを構造体変数を書かなかった場合です。 >10はコンパイルエラーを全く出さないようにしたものです。 コンパイルエラーが出ないソースを書いて「エラーが出ます」と書いたり コンパイルエラーが出るソースを書いて「エラーは出ません」と書いたりされるのは何故ですか。 >そのため図書館で本を借りるという案は普通の人ならできるのでしょうね。 >案としてはあっていると思いますが実行できずにごめんなさいね。 どんな事情があるにせよ、今の学習方法だとまともに身につかないということは変わらないかと。 あなたは「理解できました」と書かれたりしていますが、 実際のところは「理解できたつもりになりました」のようですし。

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.15

もろもろ指摘はついているので…1つだけ。 >static 型は『値を維持できる』という性質があったのでバグが起きないのですが、 >普通のタイプは関数を抜けると元に戻るためバグが出るのです。 そりゃ、関数内のローカル変数は関数から抜けたら内容は保証されないでしょう。 ソレは変数の寿命を意識して作っていくことで解決する問題ではありませんか? # まぁ、私もそこそこにグローバル変数使ったりはしていますけどね。 static変数を多用するとそれなりに問題が発生することもちゃんと把握しておかないとならないですよ。 スレッドセーフにならない。とか、 ウィンドゥプロシージャでstatic変数使うと複数のウィンドウでプロシージャが使えない。とか…。 規模の大きくないオープンソースのソースコードでも見た方が勉強になるんじゃないですかねぇ。 # 読めるか…は別問題ですが。

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

まず「static型」などというものはない, と指摘しておいて, っと. #13 の「main.cppとkudamono.cppにそれぞれ構造体の定義がありますが、片方修正した時に網片方の修正を忘れたらどうなるでしょうかね?」に対して「修正を忘れたらコンパイルエラーが出てきますよ」と書いてますが, kudamono.cpp の方を static struct kudamono{ const char *name; int num; int price; }kuda; にして本当にエラー出ますか? あと「static 型は『値を維持できる』という性質があったのでバグが起きないのですが、普通のタイプは関数を抜けると元に戻るためバグが出るのです。」の部分は「大本」がどうなってるかわからんのでなんともいいようがない. 「同じ変数で同様の機能だから使いやすーい」と「ヘッダに static な変数を書く」ことって, 実は全く関係ないんだけどな. static な変数をヘッダに書くまでもなく「同じ機能」なら「同じ名前」になるのが本当.

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.13

一応確認ですが…… (変数宣言時の)「初期化」をしたいのですか? 何らかの処理をする前に有意な値を「代入」する処理をしたいのですか? # 後者の事を「初期化」という場合もままありますけど…。 # コメントなんかでそう書くこともありますし。 >●私の場合 >同じ変数で同様の機能だから使いやすーい >何で別のファイルだけど、別の変数名つけるんだろう? 使われもしない変数が確保されるのは無駄になりますし、 グローバル変数の管理がなってなくてバグを作り込む初心者が多い中で、 ソースファイル毎に使い方の事なる意味不明な名前の変数が管理できる。 なんて事はまずないでしょう。 先人が苦労したりした点として「そういう使い方はしない方がよい」とされているパターンだってあります。 # まぁ、「私はそんなミスしない」と断言できるのであれば自由に使えばよろしいでしょう。 # 一緒に仕事はしたくありませんが。 >・構造体の変数を宣言しないとstatic 型が使えませんよ といわれたので変数を宣言したのですが全く使わなくてもstatic 型なのでしょうか? 下記の様に書いたのではありませんか? >static struct kudamono{ > const char *name; > int num; >}; 「構造体の定義」だけなのになんでもかんでもstaticをつけてみたりするから怒られたのでしょう。 で、main.cppとkudamono.cppにそれぞれ構造体の定義がありますが、片方修正した時に網片方の修正を忘れたらどうなるでしょうかね? # そういう時の為にヘッダファイルに定義してincludeするモノなのですが……。 >・初期値を代入する方法でのポインタの渡し方がわからなかったために教えていただいた方法とは別の方法でポインタを渡しているのですが問題はありますか? ヘッダファイルで構造体を定義して、初期化(初期値設定)の関数にポインタを渡す。 というのが一般的な使い方です。 # 構造体へのポインタとしてアドレス渡しするのですからグローバル変数使う必要すらありません。 --- kudamono.h の内容(グローバル変数使わないパターン) --- struct kudamono {  const char *name;  int num; }; void syoki(struct kudamono *); --- main.cpp の内容(グローバル変数使わないパターン) --- #include <stdio.h> #include "kudamono.h" void main(void) {  struct kudamono deta[5];  syoki(deta);  printf( "%sが%d個ある\n", deta[1].name , deta[1].num ); } --- kudamono.cpp の内容(グローバル変数使わないパターン) --- #include <stdio.h> #include "kudamono.h" void syoki(struct kudamono *deta) {  struct kudamono {   const char *name;   int num;  } kuda_deta[5]={   { "りんご", 1 },   { "みかん", 3 },   { "オレンジ", 5 },   { "もも", 2 },   { "キウイ", 4 },  };  int i;  for(i=0;i<5;i++,deta++) {   deta->name = kuda_deta[i].name;   deta->num = kuda_deta[i].num;  }  /* または…  for(i=0;i<5;i++) {   deta[i]->name = kuda_deta[i].name;   deta[i]->num = kuda_deta[i].num;  }  */ } グローバル変数使うなら… --- kudamono.h の内容(グローバル変数使うパターン) --- struct kudamono {  const char *name;  int num; }; extern struct kudamono data[5]; void syoki(); --- main.cpp の内容(グローバル変数使うパターン) --- #include <stdio.h> #include "kudamono.h" struct kudamono data[5]; void main(void) {  syoki();  printf( "%sが%d個ある\n", data[1].name , data[1].num ); } --- kudamono.cpp の内容(グローバル変数使うパターン) --- #include <stdio.h> #include "kudamono.h" void syoki() {  struct kudamono {   const char *name;   int num;  } kuda_deta[5]={   { "りんご", 1 },   { "みかん", 3 },   { "オレンジ", 5 },   { "もも", 2 },   { "キウイ", 4 },  };  int i;  for(i=0;i<5;i++) {   data[i].name = kuda_deta[i].name;   data[i].num = kuda_deta[i].num;  } }

nanaka2223
質問者

補足

少々返事が遅くなりました。 #一応確認ですが…… (変数宣言時の)「初期化」をしたいのですか? 何らかの処理をする前に有意な値を「代入」する処理をしたいのですか? 両方ですが代入に近いです 何をしたいかは ●呼び出される側のファイル データーの構造体を作る データーの構造体は宣言と共に初期値を入れる ●呼び出す側 必要な時に呼び出されるファイルから任意のデーターを取得する そのデーターを元に処理を行う こんな流れの物を作りたいと思っているのです。 #使われもしない変数が確保されるのは無駄になりますし、 グローバル変数の管理がなってなくてバグを作り込む初心者が多い中で、 ソースファイル毎に使い方の事なる意味不明な名前の変数が管理できる。 なんて事はまずないでしょう。 確かに使われもしない変数がある事は無駄にはなりますが、全く共通ではないのはソースファイル毎に作ればいいと思っています。 例えば、全ソースファイルで使う背景画像の宣言とか、明度がどのくらいかの宣言はヘッダファイルでやったほうがいいと思うのです。 もし、そこら辺をソース毎に他の変数名に変えたらこのソースでは背景画像の変数名をこう変えろ 明度の変数はこう変えろとかやってたら間違いなくどこでどういう変数だったか混乱するし名前もいちいち考えないといけないので面倒なのです。 どこでも使う変数だから機能としてわかっていればわかりやすいのです。 他にも例えばアイテム関係の処理のヘッダはアイテムの管理する処理のソースに使うとか。 同じアイテムを使う処理の変数でも使い方をあえて異ならせる場合は、ソース毎に変えればいいとは思います。 なぜなら、処理が違うなら変数を変えたほうがどういう処理に使う変数かわからなくなるからです。 #下記の様に書いたのではありませんか? >static struct kudamono{ > const char *name; > int num; >}; そうですそのときにコンパイルエラーになったのです。 #「構造体の定義」だけなのになんでもかんでもstaticをつけてみたりするから怒られたのでしょう。 で、main.cppとkudamono.cppにそれぞれ構造体の定義がありますが、片方修正した時に網片方の修正を忘れたらどうなるでしょうかね? そういう時の為にヘッダファイルに定義してincludeするモノなのですが……。 修正を忘れたらコンパイルエラーが出てきますよ。 そのために両方修正しないといけません。 ヘッダに入れたらstaticが使えないので困ってしまいます。 確かにヘッダに入れたら楽なんですけどね。 #ヘッダファイルで構造体を定義して、初期化(初期値設定)の関数にポインタを渡す。 というのが一般的な使い方です。 # 構造体へのポインタとしてアドレス渡しするのですからグローバル変数使う必要すらありません。 やっぱり関数内に入れてもいいのですね。 グローバルにしているのは全体で参照にするためってことですね。 ソースを教えていただきありがとうございます。 static 型を使わない方法は理解できました。 ただ、見本としてのソースではエラーは起きませんが、この書き方だと大本のプログラムではバグが出るのです。 static 型は『値を維持できる』という性質があったのでバグが起きないのですが、 普通のタイプは関数を抜けると元に戻るためバグが出るのです。 画面がアクティブな時は何も問題はないのですが他の画面をアクティブにして、また画面をアクティブにすると画面が真っ白になったままで困ったーとかのバグが起きたりですね。 そのためどうしても、static 型で構造体を定義したいのです。

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

>ファイルがひとつの場合は宣言と共に初期値をいれたものはそのまま参照できるのですが >ファイルを二つに分けた場合、 グローバル変数にすれば参照はできますからソースファイルを2つに分けるわけないは関係ありません(グローバル変数にするのをすすめてるわけではありません)。 >I、呼び出し側の構造体には初期値を入れなかったら、呼び出された側も初期値を入れない状態になります。 (略) >っと思ったのです。 呼び出す側で初期化しておく必要があるのかどうかは 呼び出される側の関数が何をするための関数か。でしょ。 ソースファイルの分割は関係ありません。 >\kudamono.cpp(6) : warning C4091: 'static ' : 変数が何も宣言されていないときは、'kudamono' の左辺を無視します。 このメッセージは何をコンパイルしたら出たものですか。 #10のお礼に書かれているkudamono.cppをコンパイルしてもでませんけど。 >こちらの方法で教えていただいた方法が構造体変数を扱うのに対して別の方法はタグ名を使う方法です ポインタの渡し方で、そんな事教えてる人は誰一人いませんが。 >本を買うお金がないのでインターネットで情報を集めて勉強しているのですが書いてある事がばらばら(仕方がないのですが)なのでどうしてもいろいろ混同する事になります。 図書館で借りるという手もあるのですから入門書を熟読してください。 現状のやり方だとおそらくいくらやっても身につかないと思います。 ここでの質問も理解されてないのに、理解したつもりになって締めたりされてるようですし。

nanaka2223
質問者

補足

少々遅くなりました <<このメッセージは何をコンパイルしたら出たものですか。 #10のお礼に書かれているkudamono.cppをコンパイルしてもでませんけど。 10のお礼にかかれたものを構造体変数を書かなかった場合です。 10はコンパイルエラーを全く出さないようにしたものです。 <<ポインタの渡し方で、そんな事教えてる人は誰一人いませんが。 ポインタの渡し方というよりは構造体の値の渡し方ですね 二つの話が混じっているためわかりづらくなってしまってすみません。 <<図書館で借りるという手もあるのですから入門書を熟読してください。 現状のやり方だとおそらくいくらやっても身につかないと思います。 ここでの質問も理解されてないのに、理解したつもりになって締めたりされてるようですし。 あんまり言いたくないのですが私は病気のため、めったに外に出られないのです。 症状とかは詳しくは説明しません。 そのため図書館で本を借りるという案は普通の人ならできるのでしょうね。 案としてはあっていると思いますが実行できずにごめんなさいね。

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

>もしかして構造体をポインタにいれてファイルを2つに分けて表記する場合、宣言と共に初期化しても意味がなかったりしますか? 何を聞きたいのかさっぱりわかりません。 >・構造体の変数を宣言しないとstatic 型が使えませんよ といわれたので変数を宣言したのですが全く使わなくてもstatic 型なのでしょうか? 本当に「構造体の変数を宣言しないとstatic 型が使えませんよ」というメッセージが出てたんですか? エラーメッセージなどを書く際には、そっくりそのまま書くのが質問する上での基本です。 わかりやすく意訳したつもりが間違ってたら害でしかありません。 >・初期値を代入する方法でのポインタの渡し方がわからなかったために教えていただいた方法とは別の方法でポインタを渡しているのですが問題はありますか? あなたのいう「別の方法」って何ですか。 何か色々、混同されたり勘違いされてる気がするんですけど。 ひとまず以下の辺り。 ・構造体の定義と、構造体型の変数の定義 ・宣言と定義 ・変数のスコープとストレージクラス ・ポインタ(と配列) ・#include C言語の入門書最初から読み直した方がいいと思いますよ。

nanaka2223
質問者

お礼

あの時は疲れて思いつかなかったのですが static 型かどうかを調べるのは簡単でした。 関数を数回呼び出して確認したところ static 型になっていました。 手をわずらわせて申し訳ありません。

nanaka2223
質問者

補足

>>何を聞きたいのかさっぱりわかりません。 ファイルがひとつの場合は宣言と共に初期値をいれたものはそのまま参照できるのですが ファイルを二つに分けた場合、 I、呼び出し側の構造体には初期値を入れなかったら、呼び出された側も初期値を入れない状態になります。 II、もし呼び出し側を初期値を入れるなら、呼び出された側も同様の初期値を入れることになります。 Iの場合、結局まとめて初期値を入れることはあきらめて、呼び出された側で全ての初期値を代入すればいいので宣言と共に初期値を入れることは意味はないのでは? IIの場合、わざわざ別ファイルの初期値を入れたものを呼び出さなくても、呼び出し側に同様の初期値があるので宣言と共に初期値を入れることは意味はないのでは? っと思ったのです。 >>本当に「構造体の変数を宣言しないとstatic 型が使えませんよ」というメッセージが出てたんですか? エラーメッセージなどを書く際には、そっくりそのまま書くのが質問する上での基本です。 わかりやすく意訳したつもりが間違ってたら害でしかありません。 申し訳ありません。 ではエラー内容をそのまま転載しますね .\kudamono.cpp(6) : warning C4091: 'static ' : 変数が何も宣言されていないときは、'kudamono' の左辺を無視します。 です。 教えていただいた方法は static struct{ const char *name; int num; }kuda_deta[5]={ { "りんご", 1 }, { "みかん", 3 }, { "オレンジ", 5 }, { "もも", 2 }, { "キウイ", 4 }, }; こちらの方法 別の方法とは static struct kudamono{ const char *name; int num; }kuda; こちらの方法で教えていただいた方法が構造体変数を扱うのに対して別の方法はタグ名を使う方法です 本を買うお金がないのでインターネットで情報を集めて勉強しているのですが書いてある事がばらばら(仕方がないのですが)なのでどうしてもいろいろ混同する事になります。 申し訳ありません。

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.10

>ヘッダに書かれているものは全く同じものが呼び出したcppに書かれるのと同じ事だと思ったのですが違うのでしょうか? あってます。 >それぞれに変数が作られるのは問題はないと思うのですけどね。 >宣言するだけで同じ名前の別の変数ができているのはわかりますし。 >もし、これがWr5さんとしては問題があるのでしたら何が問題なのでしょうか? それぞれが別のものであるという認識を持ってちゃんと区別して使える。なら問題ないでしょう。 同じ型と名前で正しく区別できるか?という問題はありますけどね。 さらに後からそのコードを読む人(数ヶ月後の自分も含む)が混乱する可能性は否定できませんが。 # 前回の質問の時点では「区別できていない」状態でしたから。 きっちりコメントで残す。などしてコードを読んでいる時に誤解を与える書き方はしない方がいいです。 # 「コレ、バグじゃね?」と修正されたら正常に動かなくなった。とかいうイベントが楽しめます。

nanaka2223
質問者

お礼

ついにそれっぽいのができました。 --- main.cpp の内容--- #include <stdio.h> static struct kudamono{ const char *name; int num; }kuda; void syoki( struct kudamono deta[] ); void main(void) { struct kudamono deta[5]; syoki( deta ); printf( "%sが%d個ある\n", deta[1].name , deta[1].num ); } --- kudamono.cpp の内容 --- #include <stdio.h> static struct kudamono{ const char *name; int num; }kuda; static struct{ const char *name; int num; }kuda_deta[5]={ { "りんご", 1 }, { "みかん", 3 }, { "オレンジ", 5 }, { "もも", 2 }, { "キウイ", 4 }, }; void syoki( struct kudamono deta[] ) { int i; for( i=0; i<5; i++ ){ deta[i].name = kuda_deta[i].name; deta[i].num = kuda_deta[i].num; } } 問題となりそうなのは ・構造体の変数を宣言しないとstatic 型が使えませんよ といわれたので変数を宣言したのですが全く使わなくてもstatic 型なのでしょうか? ・初期値を代入する方法でのポインタの渡し方がわからなかったために教えていただいた方法とは別の方法でポインタを渡しているのですが問題はありますか? といった問題ですね 大丈夫なのでしょうか?

nanaka2223
質問者

補足

つまり意見を総合すると ●私の場合 同じ変数で同様の機能だから使いやすーい 何で別のファイルだけど、別の変数名つけるんだろう? ●他の人の場合 同じ変数が宣言されているけれど、何で同じ変数が宣言されてるのかがわからない 機能別に別の変数をつけよ っという差異があるのですね まさか、誤解を与える書き込みになってるとはわかりませんでした。申し訳ありません。 そういう差異があるとは気づきませんでした。

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.9

いつものようにフォローありがとうございます>#8 >参照URLに書かれているインクルードガードのことですが >#pragma once >をヘッダにつければインクルードガードできますか? とりあえず、VCならインクルードガード出来るでしょう。 # 他のコンパイラについては不明。 で、今回の問題はインクルードガードは無意味ですので念のため。 # 「1つの翻訳単位で同じファイルが複数回インクルードされる」のをカードする為です。 # main.cppとbetu.cppは「別の翻訳単位」ですからインクルードガードは無意味です。 ># 途中からアドレス渡しに興味が移行してそのまま閉じられてしまいましたが。 >結局アドレスを渡さないと参照できないのではないのですか? 普通ならそうです。 が、今回の場合(正確には前回の場合)は「ヘッダファイルに変数の実体が書かれています」から、main.cppとbetu.cppにそれぞれ変数が作られます。 その確認の為に#7で「変数のアドレス」を表示しています。 # 改行指示入れ忘れたので見にくい結果になってますが。 >Wr5さんが書いていただいたソースにもアドレスを渡しているから参照できるように見えるのですが、私の理解部分とWr5さんの違うといってる部分の差がまるでわからないです。 アドレスを渡しているのは「main.cppに取り込まれたbetu.hに宣言されている変数」であって、「betu.cppに取り込まれたbetu.hに宣言されている変数」ではありません。 「別ファイルの変数を~」というのが前回の質問内容でしたから。 # 「main.cppにある変数をbetu.cppで書き換える。」という質問であれば、アドレス渡しでOKとなるのですが。 「betu.hに変数1つしか書いていないのにmain.cppとbetu.cppにある。」というのが判らない。 ってコトかも知れませんけどね……。

nanaka2223
質問者

お礼

後大本の質問に対しての進展がありました --- main.cpp の内容--- #include <stdio.h> typedef struct { const char *neme; int num; }kudamono; void syoki( kudamono kuda[] ); void main(void){ kudamono kuda[5]; syoki(kuda); printf("%sが%d個ある\n", kuda[2].neme , kuda[2].num); } --- kudamono.cppの内容 --- #include <stdio.h> typedef struct { const char *neme; int num; }kudamono; void syoki( kudamono kuda[] ){ kuda[0].neme = "りんご"; kuda[1].neme = "みかん"; kuda[2].neme = "オレンジ"; kuda[3].neme = "もも"; kuda[4].neme = "キウイ"; kuda[0].num = 1; kuda[1].num = 3; kuda[2].num = 5; kuda[3].num = 2; kuda[4].num = 4; } 何とか綺麗に書けるようになったのですが ・static が使えない(困った) ・結局宣言と共に初期化ができていない とできていない事が増えました

nanaka2223
質問者

補足

書いている途中に文章全部消えたTT <<で、今回の問題はインクルードガードは無意味ですので念のため。 # 「1つの翻訳単位で同じファイルが複数回インクルードされる」のをカードする為です。 # main.cppとbetu.cppは「別の翻訳単位」ですからインクルードガードは無意味です。 結局ヘッダをひとつしか書いていませんからね インクルードガードしても仕方ないですね <<が、今回の場合(正確には前回の場合)は「ヘッダファイルに変数の実体が書かれています」から、main.cppとbetu.cppにそれぞれ変数が作られます。 この部分を確認したいのですが、実体は私は関数の中身の事だと認識しているのですが違ったりしますか? 確かにヘッダファイルに関数の中身まで書いてしまうとコンパイルエラーになると思います。 それぞれに変数が作られるのは問題はないと思うのですけどね。 宣言するだけで同じ名前の別の変数ができているのはわかりますし。 もし、これがWr5さんとしては問題があるのでしたら何が問題なのでしょうか? # 改行指示入れ忘れたので見にくい結果になってますが。 改行の事でしたら何とかしました <<アドレスを渡しているのは「main.cppに取り込まれたbetu.hに宣言されている変数」であって、「betu.cppに取り込まれたbetu.hに宣言されている変数」ではありません。 「別ファイルの変数を~」というのが前回の質問内容でしたから。 # 「main.cppにある変数をbetu.cppで書き換える。」という質問であれば、アドレス渡しでOKとなるのですが。 すみませんおそらくこの部分が私は混同している気がします。 私にとってはどちらも同じように見えているのですが、Wr5さん達にとっては何かの差があるのだと思いました。 そしてその差が私にもわかれば質問の仕方がWr5さん達にも伝わるように伝えれたのかもしれません。 文章能力が未熟で申し訳ありません。 <<「betu.hに変数1つしか書いていないのにmain.cppとbetu.cppにある。」というのが判らない。 ってコトかも知れませんけどね……。 ヘッダに書かれているものは全く同じものが呼び出したcppに書かれるのと同じ事だと思ったのですが違うのでしょうか?

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

#7 に関して 2点. まず「えっとソースをみたところ~static のグローバル変数が入っているようですが大丈夫なのですか?」については「staticな関数やグローバル変数の宣言はヘッダファイル内には書かない」を説明するためで, つまりわざとそう書いています. あと, 実はプロトタイプ宣言中では引数の名前を省略してもいいので, void betu(int *); は void betu( int *a ); と同じことになります.

nanaka2223
質問者

お礼

おおおさらに進展しました。 --- main.cpp の内容--- #include <stdio.h> typedef struct { const char *neme; int num; }kudamono; void syoki( kudamono kuda[] ); void main(void){ kudamono kuda[5]; syoki(kuda); printf("%sが%d個ある\n", kuda[3].neme , kuda[3].num); } #include <stdio.h> typedef struct { const char *neme; int num; }kudamono; struct{ const char *neme; int num; }kudamo[5] ={ { "りんご", 1 }, { "みかん", 3 }, { "オレンジ", 5 }, { "もも" , 2 }, { "キウイ" , 4 } }; void syoki( kudamono kuda[] ){ int i; for(i=0;i<5;i++){ kuda[i].neme = kudamo[i].neme; kuda[i].num = kudamo[i].num; } } 初期値を入れた構造体をそのまま入れちゃえばいいんだ。 後はstatic 型を扱えるようになれば問題なしですね。

nanaka2223
質問者

補足

<<まず「えっとソースをみたところ~static のグローバル変数が入っているようですが大丈夫なのですか?」については「staticな関数やグローバル変数の宣言はヘッダファイル内には書かない」を説明するためで, つまりわざとそう書いています. えっと、そうするとstatic なグローバル変数を扱うにはどうしたらいいですか? <<あと, 実はプロトタイプ宣言中では引数の名前を省略してもいいので, void betu(int *); は void betu( int *a ); と同じことになります. ああ、そうなのですか省略可能なのですね びっくりしました。

  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.7

>しかし、ファイルを2つに分ける時がうまくいっていません。 質問に書かれているのは2つに別けた場合…ですよね。 それで回答していたのですが、ココでちゃぶ台返しされるとは……。 あと、複数のファイルにインクルードするヘッダに実体書いてはいけません。 説明が面倒なので参考URLでも見て下さい。 # 「staticな関数やグローバル変数の宣言はヘッダファイル内には書かない」「グローバル変数をextern宣言する」を特に。 それでも理解できない。 というのであれば下記のソースとヘッダで実行してみて下さいな。 # 本題から外れて行ってますが。 --- main.cpp の内容 --- #include <stdio.h> #include "betu.h" void main(void) {  betu(&a);  printf("main():&a = %p:%d", &a, a); } --- betu.h の内容 --- static int a; void betu(int *); --- betu.cpp の内容--- #include <stdio.h> #include "betu.h" void betu(int *p){  *p = 5;  a = 10;  printf("betu():&a = %p:%d\nbetu():p = %p:%d", &a, a, p, *p); } 貴方の意図している変数aが同じもの(プロセス内で1つ)であれば、main()とbetu()で表示される&a=の値は同じになるはずです。 そしてmain()で表示されるaの値は10になるはずです。 1つしかないはずですからね。 実際にどうなっているのか確認して下さい。 # 一応、前回の時の回答に書いているんですけどね… # 途中からアドレス渡しに興味が移行してそのまま閉じられてしまいましたが。

参考URL:
http://d.hatena.ne.jp/saitodevel01/20110321/1300685958
nanaka2223
質問者

補足

<<質問に書かれているのは2つに別けた場合…ですよね。 それで回答していたのですが、ココでちゃぶ台返しされるとは……。 いえ、私としても理想としては別ファイルで宣言と共に初期化してそれを扱えたらいいな と思っているのですが、実際はそれが今できないため、やれるとこからやるしかないかと思いました 確かにやろうとしてることが推移していますね。 参照URLに書かれているインクルードガードのことですが #pragma once をヘッダにつければインクルードガードできますか? # 「staticな関数やグローバル変数の宣言はヘッダファイル内には書かない」「グローバル変数をextern宣言する」を特に。 えっとソースをみたところ --- betu.h の内容 --- static int a; void betu(int *); の中にstatic のグローバル変数が入っているようですが大丈夫なのですか? 後、 void betu(int *); この表記は始めてみます。 どうしてこれで動くのかびっくりです。 こういう書き方をすればWr5さんとしては正解ってことなのですか? # 本題から外れて行ってますが。 本題から外れてしまうため申し訳ありません。 前回のことができないのであれば今回の質問さえまともにできそうにないため蒸し返す事になっていますね。 # 途中からアドレス渡しに興味が移行してそのまま閉じられてしまいましたが。 結局アドレスを渡さないと参照できないのではないのですか? そして全くわからないのですが何故これがWr5さんが違うといってるのかがわからないのです。 Wr5さんが書いていただいたソースにもアドレスを渡しているから参照できるように見えるのですが、私の理解部分とWr5さんの違うといってる部分の差がまるでわからないです。

関連するQ&A

  • 文字列をうまく返してくれない

    数値を文字列として呼び出し元に渡し、呼び出し元で文字列を数値に変えようとしたのですがatoi関数(strtolを使うと最初の文字のみ帰ってくるため2桁以上の数値に対応できない)を使うとうまく行きませんでした。 どのように変更したらatoiが使える文字列になりますか? #include <stdio.h> #include <stdlib.h> static struct{   char *name; }kuda[5]={   { "もも" , "りんご" , "みかん" , "バナナ" , "パイナップル" } } char *re_3( void ){   int a = 3;   char str_h[100];   char *str;   sprintf_s( str_h , 100 , "%d" , a );   *str = *str_h; //原因はおそらくここ   return str; } void main( void ){   printf( "%s" , kuda[ atoi( re_3() ) ].name ); }

  • 構造体とfscanf

    ファイルをfscanfを使って文字列を構造体に格納して読み込みたいのですが読み込み方の記述方法がわか りません。 どのようにしたら読み込めますか? 以下ソース ---ソース--- #include <stdio.h> #include <string.h> #include <stdlib.h> struct info //1回目の呼び出し方法 { char name[20]; char mb[20]; }deta; struct info2 //2回目の呼び出し方法 { char *name; char *mb; }deta2; struct info3 //3回目の呼び出し方法 { char *name[6]; char *mb[6]; }deta3; void main(void){ FILE *fp; fp=fopen("yasa.txt","r+"); while( !feof( fp ) ){ fscanf( fp, "%s %s",deta.name,deta.mb ); printf("%s %s\n",deta.name,deta.mb); } rewind( fp ); //2回目の呼び出し方法での記述の仕方がわからない rewind( fp ); //3回目の呼び出し方法での記述の仕方がわからない fclose(fp); } ---yasa.txtの内容--- オレンジ ● みかん ● いちご × もも ● ぶどう × キウイ ●

  • 構造体メンバ及び、strncpy()について

    /* 構造体のメンバを char name[30]; にした時は実行できますが、char *name; としたときはプログラムを実行できません。 コンパイルエラーはともに出ないのですが、strncpy();の使い方が間違っているのか、先に構造体側でメモリサイズを確保しないと、使えないのか? メンバをポインタで持たせた構造体を初期化する関数の作り方を教えてください。 よろしくお願いします。 */ #include <stdio.h> #include <string.h> typedef struct{ char *name; int no; }ST; void set_name(ST *st, char *name, int no); int main(void) { ST st; set_name(&st, "テスト", 1); printf("%s No%d\n", st.name, st.no); return 0; } void set_name(ST *st, char *name, int no) { strncpy(st->name, name, 30); st->no=no; }

  • 構造体宣言したポインタ変数に値を代入するには?

    strcpy(p -> key ,name);と打ってp -> key に入力した名前を格納したいのですがうまくいきません。 ほかにもp -> key = nameなども試してみましたがコンパイルエラーが出現してダメでした。 うまく格納できるやり方があれば教えてください。よろしくお願いします。 #include<stdio.h> #include<string.h> #define WORD_LENGTH 50 /* 文字列の最大長 */ typedef struct cell{ char key[WORD_LENGTH]; struct cell *next; /* 次のセルへのポインタ */ } CELL; void main(void) { char name[WORD_LENGTH]; CELL *p; printf("名前入力\n"); scanf("%s\n", name); strcpy(p -> key ,name); printf("%s\n", p -> key); }

  • ポインタ型配列のポインタを構造体のポインタ変数に格納する方法教えて!

    問題の箇所を試行錯誤しても「移植性のないポインタ変換(関数 main )」と表示されます。 どうすればエラーが出ないでしょうか? 返答のほどよろしくお願いいたします。 #include<stdio.h> char *name[] = {"AAA", "BBB", "CCC"}; struct namelist{ char *name; struct namelist *next; }*head; void main(void) { printf("name = %s\n", name[1]); head -> name = *name[1];←問題の箇所 printf("head -> name = %s\n", head -> name); }

  • 分割コンパイルの方法がわかりません‥(Studio.NET)

    mainとsubという2つのcppファイルと各ヘッダファイルで分割コンパイルを試みましたがうまくいきません・・。 何が間違っているのでしょう・・。 エラーメッセージ error LNK2005: "char * a" (?a@@3PADA)は既にmain.objで定義されています。 fatal error LNK1169: 1つ以上の複数回定義されているシンボルが見つかりました。 と表示されます。ファイルソースは以下です。どなたか教えてください>< ----------(main.h)---------- char a[100]; ----------(main.cpp)---------- #include<stdio.h> #include "main.h" #include "sub.h" int main(){  sprintf(a,"hello.");  sub_write();  return 0; } -----------(sub.h)----------- void sub_write(); -----------(sub.cpp)------------- #include <stdio.h> #include "main.h" #include "sub.h" void sab(){  printf("%s\n",a); } return; }

  • 配列について

    初歩的な質問ですいませんが、質問よろしくお願いします。 ◎1----------------------------- #include<stdio.h> int main(void) { char ss[10]="AB"; printf("ss=%s\n",ss); return 0; } ------------------------------------ ◎2-------------------------------- #include<stdio.h> int main(void) { char ss[10]; ss[0]='A'; ss[1]='B'; ss[2]=0; printf("ss=%s\n",ss); return 0; } ----------------------------------- ◎3------------------------------- #include<stdio.h> #include<string.h> int main(void) { char ss[10]; strcpy(ss,"AB"); printf("ss=%s\n",ss); return 0; } ----------------------------------- ◎4------------------------------- #include<stdio.h> int main(void) { char ss[10]; ss="AB"; printf("ss=%s\n",ss); return 0; } ---------------------------------- 以上4つのプログラムで、◎2と◎3は正常に動くと理解できたのですが、何故、◎1は正常に動き、◎4は「'const char [3]' から 'char [10]' に変換できません。」といったようなエラーが出てしまうか分かりません。 教えていただければ嬉しいです。

  • 構造体?

    以下は、あるC++のサンプルプログラムの頭の部分なのですが、構造体associateの中に、再びassociateが2回も出てきます。何をしている記述なのか教えてください。 #include <vector> #include <algorithm> #include <functional> #include <iostream> using namespace std; struct associate { int num; char chr; associate(int n, char c) : num(n), chr(c) {};←この業は何? associate() : num(0), chr('\0'){};←この行は何? }; bool operator<(const associate &x, const associate &y) { return x.num < y.num; } ostream& operator<<(ostream &s, const associate &x) { return s << "<" << x.num << ";" << x.chr << ">"; } int main () { vector<associate>::iterator i, j, k; associate arr[20] = {associate(-4, ' '), associate(16, ' '), ・ ・ ・ associate(-3, 'e'), associate(15, ' ')};

  • 構造体とポインタについて教えてください。

    #include <stdio.h> typedef struct ningen { char *name; char *sex; int age; } NINGEN; NINGEN data = {"牧村 五郎",NULL,30}; char mf[2][3] = {"男","女"}; void main(void) { data.sex=mf[0]; printf("%s (%s) %d歳\n", data.name, data.sex, data.age); } このプログラムで実行結果は 牧村 五郎 (男) 30歳 となるのですが、最初の typedef struct ningen { char *name; char *sex; int age; } NINGEN; のところで、nameとsexはアドレスで宣言しているので printf("%s (%s) %d歳\n", data.naem, data.sex, data.age);でのdata.naem, data.sexでの対象もアドレスを示していると思うのですが、 結果は値を表示しているのはなぜでしょうか?

  • 構造体の動的メモリについて

    #include <stdio.h> #include <stdlib.h> #include <string.h> #define NUM 10 /*生徒数*/ typedef struct data { int num; /*従業員番号*/ char name[16]; /*名前*/ int jap; /*国語の点数*/ int math; /*数学の点数*/ }data; int main(void) { data test[NUM]; /*生徒のデータ*/ FILE *fp; /*ファイル操作用*/ int i; /*配列インデックス*/ int count; /*データ分割用*/ char s[100]; /*データ読み込み用*/ char *token; /*データ分割用*/ char *data[6]; /*分割データ保存用*/ fp = fopen ("data1.txt","r");        for (i=0; i<NUM; i++){ fgets (s, sizeof(s), fp); /*dataファイルから1行読み込み*/ token = strtok(s, ","); /*読み込んだデータを","で分割する*/ count=0; while (token != NULL){ data[count] = token; /*分割したデータを配列へ入れる*/ token = strtok(NULL,","); count++; } test[i].num = atoi(data[0]);       strcpy (test[i].name, data[1]); test[i].jap = atoi(data[2]); test[i].math = atoi(data[3]); } fclose(fp);       } このプログラムを構造体へのポインタの配列で管理するように変えたいのですが、どのように変更すればいいのでしょうか。 条件として、個人データを格納するメモリ領域とポインタの配列のメモリ領域は動的に確保します。 初心者でよくわからないので詳しく教えていただけると助かります。よろしくお願いします。