• ベストアンサー

配列と変数について

練習のため家庭の収入、支出のバランスを計算するプログラミングを作っています。その為変数宣言についてなのですが以下のようにすると配列をcoutした時にint の変数に代入した値と一致しません。意味不明な数字が表示されます。この時何が起きているのでしょうか(この数字はどこから?各配列には何が入っているのでしょうか?)。 #include <iostream.h> int main (){ int income, loan, expenditure, saving; int cluster []={income, loan, expenditure, saving}; income=100, loan=200, expenditure =300, saving = 500; cout << cluster [0]<<endl<<cluster [2]<<endl<<income<<endl<<expenditure; return 0; } しかしながら以下のように変数の初期化を配列への代入の前に行うと各配列と変数の値が一致します。何故ですか? #include <iostream.h> int main (){ int income, loan, expenditure, saving;      income=100, loan=200, expenditure =300, saving = 500; int cluster []={income, loan, expenditure, saving}; cout << cluster [0]<<endl<<cluster [2]<<endl<<income<<endl<<expenditure; return 0; } 2.今回配列を使ったのはこれらの変数をまとまりとして取り扱ったほうが便利だと思ったからです。この様な場合クラスを作ったほうが良いのでしょうか?メモリ的に配列の方がまとまりが良いように感じましたが、そんな考慮は必要ないのでしょうか? 3.変数名を表示することは出来ますか?上記のincome、savingなどです。

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

  • ベストアンサー
回答No.6

No.4 補足です。 おっしゃっているような、配列にタグをつけるという使い方は、できなくはありません。 1)#define または、const を使う #define incomm 0 #define loan 1 などとして、cluster[incomm] や cluster[loan] C++では、#define の代わりに const int incomm = 0; const int loan = 1; などを使うのが吉。 2.列挙型を使う enum {incomm = 0, loan, expediture, saving}; という宣言をつけておけば、 cluster[incomm], cluster[loan], cluster[expediture], cluster[saving] は、それぞれ、cluster[0], cluser[1], cluser[2], cluster[3] をさします。 3.STL というライブラリにある、map を使う(連想配列) #include <map> #include <string> として、 map <int, std::string> cluster; とすれば、[] の中を string で指定できる整数配列が作れます。 cluster["incomm"] = 100; など。 こういう方法もあります。

その他の回答 (7)

  • Werner
  • ベストアンサー率53% (395/735)
回答No.8

> 今回配列を使ったのは変数を表示できると仮定したときに、 > coutとcinを使うときにループを使い簡単に表示できると考えたからです。 構造体を引数にとって、一括表示するような関数を作るのではだめでしょうか。 ※以下はその一例。 ---------------------------------------------------- #include <iostream> struct clusterType{ int income; int loan; int expenditure; int saving; }; //clusterType出力関数(<<演算子をオーバーロード) std::ostream &operator<<(std::ostream &os, const struct clusterType &cluster){ os << "income=" << cluster.income << std::endl << "loan=" << cluster.loan << std::endl << "expenditure=" << cluster.expenditure << std::endl << "saving=" << cluster.saving << std::endl; return os; } int main(){ struct clusterType cruster = {100, 200, 300, 500}; std::cout << cruster; //incomeだけ変更 cruster.income = 150; std::cout << cruster; return 0; }

  • lv4u
  • ベストアンサー率27% (1862/6715)
回答No.7

>>C++のみでCはやっていません。基礎をマスターするのは重々承知ですが、本に書いてあることは簡単で読み飽きたので自分で組みながら学びたいと思いました。  確かに、C言語入門書の中には、入り口を入らずに、ドアの表面をながめただけで終わっちゃうようなものがありますからね。(私もCの入門書を読んだとき、「簡単!」と思いましたから。もちろん、あとで認識の甘さを思い知ったのですが・・)カーニハン&リッチ著の「プログラミング言語C」はC++抜きのC言語だけの書籍ですが、例題の実行結果の記載も無いくせに343ページもあります。ちゃんとC言語の規格を学ぼうとすると学ぶべきことのボリュームはありますよ。  あと、自分で組むというか「手を使う」のは、覚える方法として、いいと思いますよ。  で、良書を紹介と思ったんですが、「F-16等の兵器システム開発は私の良心が許さない」と雑誌DDJ紙面で「ドロップアウト宣言」を行って最終的には勤め先の会社を辞めたアレン・ホラブ著の「Cの宝箱」をはじめとして、私がお世話になったC言語の良書は、事例のOSがCP/MとかMS-DOSだったり故か、もう絶版になった書籍ばかり・・・。  しかたないので、「詳説C++(第2版)」ソフトバンクを上げておきます。この本は「第0章」として、簡潔にC言語のおさらいをしてC++につないでいます。この第0章を読んで理解できない部分があれば、そこがC++を学ぶ上でネックになると思います。 パラパラと立ち読みでもしてみてください。

wachacha2
質問者

お礼

実は最近2冊目とおもい何冊かリストアップしていたなかに「詳説C++(第2版)」があります。他には「C++実践プログラミング 」、「Boost C++ Libraryプログラミング 」、「C++ プライマー 第4版 IT Architect’ Archive クラシックモダン・コンピューティング 」があります。やはり詳説C++(第2版)良いですか。真剣に検討してみます。有難うございます。

回答No.5

No.4 です。 > ちなみになぜポインタ、参照を使う方法はお勧めできないのですか? これは、ポインタを使うからおすすめできないのではなくて、配列として扱う必然性が感じられないからという意味です。 配列というのは、各要素への操作が、統一的に扱えるときだけ効果があります。一斉に初期化するとか、一斉に2倍するとか、それぞれの要素の差を別の要素に一括して計算するとか。 こういうオペレーションがループで扱えるのは、非常に良いでしょう。 逆にこういう操作がなければ、必ず、cluster[0] は、incom ? loan ? という混乱が発生します。混乱をなくすために、#define や、enum を駆使して、cluster[loan] などもできますが、これであれば、単独の loan や、cluster.loan という構造体による参照の方がわかりやすいでしょうと思います。 また、関数になどに一括して渡す/関数から返す場合にも、構造体であれば、これが可能なので、おそらく、構造体としての使い方が、妥当なのかなと思います。

wachacha2
質問者

お礼

返信有難うございます。今回配列を使ったのは変数を表示できると仮定したときに、coutとcinを使うときにループを使い簡単に表示できると考えたからです。それだけのことですがデータ数が大きくなるとそれなりに効率性があると思ったのです。 ANo.6は私の参考書には乗ってない方法なので現在さらに調べています。とても参考になりました有難うございます。

回答No.4

ただ単に、変数をまとめて扱うのであれば、構造体というものがあります。 struct clusterType { int income; int loan; int expenditure; int saving; }; struct clusterType cluster; ※ここで、clusterType は、構造体のタグ名と呼ばれ、構造谷つける型の名前のようなものです。ここでは、cluserType としましたが、わかりやすい名前なら何でもいいです。 これで、cluster.income のようにアクセスできます。 「まとめる」というのが、他にも、同じ組み合わせのデータがあるからというのであれば、構造体は struct clusterType lastYear; などがあれば、 lastYear = cluster; のように一括して代入したり、関数の返値にできます。 このデータを操作する関数をセットで定義しようと思えば(というのは、説明としてはちょっと違うのですが)クラスになります。 あと、ご質問の形を使おうと思えば、 int * cluster []={&income, &loan, &expenditure, &saving}; と、それぞれの変数のポインタを配列として持っておくことはできます。 これでh、たとえば、 *cluster[0] は、income と同じものになります。 が、あまりおすすめはできない気がします。

wachacha2
質問者

お礼

ポインタと参照を使う方法は考えてみました、やはり配列と変数を結合させるにはこの方法しかないのですね。各配列にタグ(変数名)をつけ一括して扱えれば楽だなと思ったからやってみたのですが。ちなみになぜポインタ、参照を使う方法はお勧めできないのですか? 構造体は知りませんでした。使ってみます。有難うございます。

  • lv4u
  • ベストアンサー率27% (1862/6715)
回答No.3

>>この様な場合クラスを作ったほうが良いのでしょうか?メモリ的に配列の方がまとまりが良いように感じましたが、そんな考慮は必要ないのでしょうか?  クラスを作るかどうか?という問題も重要でしょうけど、現時点では、配列だけの単純なプログラムにしておいて配列等のC言語の基礎をマスターするほうが先だと思いますけど。 >>変数名を表示することは出来ますか?上記のincome、savingなどです。  PL/Iでは、変数名とデータを組にして表示する機能がありましたが、C/C++ではそういった余分な機能は用意されてないです。そのような機能は言語設計者からみて「余計なもの」でしょうね。必要なら、自分でコーディングしましょう。

wachacha2
質問者

お礼

C++のみでCはやっていません。基礎をマスターするのは重々承知ですが、本に書いてあることは簡単で読み飽きたので自分で組みながら学びたいと思いました。しかし、もう一冊ぐらいは必要みたいですね。 数名とデータを組にして表示する機能はないのですか、残念です。

  • MrBan
  • ベストアンサー率53% (331/615)
回答No.2

もしも#include <iostream>に変更したらコンパイルエラーになる場合は(最近のコンパイラではなるはず)、 coutもstd::cout、endlもstd::endlにするなど、標準のものにはstd::をつけてください。

wachacha2
質問者

お礼

了解しました。

  • BLUEPIXY
  • ベストアンサー率50% (3003/5914)
回答No.1

>int cluster []={income, loan, expenditure, saving}; では、"変数"を配列にしているのではなくて、 その時点での変数の値で配列を初期化しています。 その時点のそれぞれの変数の値は初期化されていませんから(うまく行く場合は初期化されている) 値は、不定(メモリ上のゴミ)です。 あと、 #include <iostream.h> は、 多分参考にされている書物が古いのではないかと存じます。 今どきは #include <iostream> で

wachacha2
質問者

お礼

なるほど、"変数"を配列にしているのではないのですね。やはりポインターを使わなければ無理みたいですね。

関連するQ&A