こんにちは､ お帰りなさい｡
今回の講義デモでは､ 前回のチャレンジでお話したお天気プログラムの解決策を提供したいと思います｡
では､ コードブロックを立ち上げて､ プロジェクトを作成してみましょう｡
このプロジェクトの名前をweatherと名付けます｡
また､ このアプリケーションでは､ 降雨量の年間合計と月平均を取得することができます｡
だから､ 一番上に､ このプログラムは何なのか､ というコメントを書きたいのです｡
このプログラムでも､ 数年分の降雨データ（基本的には5年分）について､
年合計､ 年平均､ 月平均を求めることになります｡
まだdefineプリプロセッサディレクティブについて詳しく説明していませんが､
このディレクティブに慣れていれば､ それほど複雑なものではありません｡
だから､ それを含めて､ いい品質のコードを書きたいんです｡
そこで､ months can be equal to 12と呼ばれる定数を定義することにします｡
定数モディファイアも使えるので､ years equal to 5というのも定義しておこうと思います｡
それは､ 私たちがスターになることです｡
そして､ メイン関数で最初に行いたいことは､
2次元の配列を作成し､ データを初期化することです｡
そこで､ 降雨量､ 2010年､ 2011年､ 2015年とかの降雨データを初期化することになります｡
2次元の配列の作り方がわかったので､ データ型名を指定しましたが､
floatには小数点以下があり､ 雨量は10進数になることがあるので､
floatにすべきだと思います｡
ここではfloatとし､ rainという名前を付けて､
5行12列となるように指定します｡
そこで､ 定数であるyearsとmonthsと言い､ それを初期化します｡
その大きさを宣言したので､ 今度はそれを初期化したいと思います｡
そして､ このように括弧で囲んで初期化し､ 各行ごとに括弧の中に入れることができるのです｡
また､ この配列を定数にすることも可能ですが､
ここでは行いません｡
今､ 私はこのデータをすでにやっていて､ これは何だろうと打ち込みたくはない｡
そうすると､ 10×50､ 12×5で60の要素になります｡
今､ 60の要素を入力するのは､ 時間を取られるし､
座って寝てしまうだけなので､ やめましょうね｡
そこで､ 初期化をコピー＆ペーストして､ いくつかのデータを初期化します｡
これはあくまでダミーデータであり､ 正しくない場合があります｡
しかし､ それぞれの行に括弧をつけているので､ 5つの行があることがわかると思います｡
各行をカンマで区切り､ その中に中括弧を入れ､ 各行を記述します｡
そして､ 中括弧の中では､ 各月の値をコンマで区切っています｡
つまり､ 行をカンマで区切り､ 行の中の値もカンマで区切っているわけです｡
ここに年間降水量の束があります｡
例えば､ この最初の行は2011年を表し､ 最初の列は1月となります｡
だから､ 2011年1月には4人になったんです｡ 3インチの雨量｡
この下は､ 仮に6を見た場合です｡ 7､ これは2012年､ 13年の分となる｡
3月は6件でした｡ 7インチの雨量｡
つまり､ これが降雨の年や月を表していることがおわかりいただけると思います｡
これですべてのデータが初期化されたので､ 実際に他のローカル変数を初期化したり作成したりすることができます｡
そこで､ 年と月を作成します｡
こうすることで､ 年と月をまっすぐに保つことができます｡
また､ 小計と合計のフロートも作成するつもりです｡
小計は年間合計､ 合計は年間平均が分かるように総雨量にします｡
そして､ 月次平均の出し方も考えていきます｡
まず最初に､ ある年の降雨量をプリントアウトするループが必要です｡
そこで､ まずは1行でプリントアウトしてみます｡
年号をプリントアウトして､ タブを追加して......｡
タブを追加して､ より良いフォーマットにする｡
タブを2つ追加してみましょう｡ これがどのように見えるかは､ 一度表示してからのお楽しみです｡
そして､ 雨量と､ それをインチで入れて､ 改行を入れるんです｡
そしてまた､ これがどのように見えるか､ テストしてみたいものです｡
そして､ 自分のループに入る｡
各年の小計を計算するためには､ すべての行､
すべての年､ そして各年について､ 月を合計する必要があるため､
すべての月を調べます｡
つまり､ 外側のループは最初の年である2011年から始まりますが､ 配列は0インデックスなので､
実際には配列の内部では0になっています｡
また､ この内部で別のローカル変数を初期化するつもりです｡
forループは非常に柔軟性があることを覚えておいてください｡
実はfor文の中で他の変数を作ることができます｡
19行目や20行目のfor文の外で使われる変数を作る必要はなかったですね｡
ここでは､ totalという変数を作成し､ total変数を初期化します｡
そして､ "年 "が "年 "よりも小さくなるまで続け､ カウンタループ制御変数
"年 "をインクリメントしていくのです｡
つまり､ 19行目で年と月がループ制御変数になっているわけです｡
そして､ これが外側のループを表しています｡
2次元配列なので､ インナーループも必要ですね｡
そして､ 私のインナーループは､ 毎月のように通っています｡
ここでは､ 月は0に等しく､ 各月の小計も0に等しいとして初期化します｡
そして､ 全部の月が終わるまでは通うつもりです｡
そして､ ループ制御変数をインクリメントし､ これが私の内部ループとなります｡
そのため､ インナーループで実際に小計を決定することができ､ 何も表示する必要がありません｡
つまり､ 内部ループで行うのは､
各年の小計に足すだけです｡ 小計は年間の合計です｡
そして､ ここでは配列にアクセスするだけです｡
私の配列名はrainにする予定です｡
つまり､ 最初は2011年の外側のループ､ 次に各月のループというように､
サブイヤーで雨を降らせることができるのです｡
そして､ 追加しています｡
だから､ 小計は小計＋雨＋配列の値に等しいと言っているんです｡
そのため､ 内部ループでは､ その年のすべての月を通過して､
小計を作成します｡
今度は､ 5年分の小計を5回だけ表示したいので､
ループの外に表示したいのです｡
そこで､ データを少し整形し､ 適切に表示するための小さなprintステートメントを用意しました｡
これで､ 年と小計になります｡
だから､ おそらく小計に追加したいでしょう､ 2つのタブと言いたいところですが､ どんな風に見えるか見てみましょう､
だからスラッシュTスラッシュT｡
そしてもうひとつ､ 全年度の合計が必要なので､
合計に足し算をします｡
つまり､ ここでは､ トータルプラスが小計に等しいと言えばいいのです｡
そして､ 小計はインナーループに行くたびに再初期化されるので､
それを設定し直す必要がないことに気づくでしょう｡
そして､ ここではインデントがうまくいっているかどうかを確認したいだけなのです｡
また､ 27と29の括弧は1つの文なので必要ありませんが､
そのままにしておきます｡
今､ 私は年間の降雨量または各年の降雨量をプリントアウトした後にそれを行ったので､
私は十分なデータを持っているので､ 私は各月の降雨量の合計を持っているので､ 年間平均を表示することができます｡
ここでは､ 合計を年数で割った年平均を表示することにします｡
そこで､ ここにもう一つprintステートメントを追加します｡
ここでもまた､ テストに適した場所があります｡
それではビルドしてみましょう｡
そして､ 未申告変額年があります｡
コンパイラのエラーが表示された場合､ 実際のエラーとは異なる表現をしていることがあります｡
この場合､ 19行目でエラーが発生したと表示されましたが､ 実はエラーの原因は直前のステートメントにあり､
最後のセミコロンがなかったのです｡
これを実行して､ 年間降雨量を見ることができるかどうか､ どのようにフォーマットされているかを見てみましょう｡
それでは､ 2010年の降水量（単位：インチ）をご覧ください｡
だから､ 小計を表示した後のタブを増やしすぎているのだろう､ そうすると年平均は39になる｡
4.
そのため､ このタブを削除して修正する必要があります｡
エスケープシーケンスであるスラッシュtを使用すれば､ 出力にタブを追加できることを忘れないでください｡
だから､ 少なくともかなり良さそうだ｡
さて､ 月平均を表示するループをもう一つ用意しなければなりません｡
そこで､ 月平均を表示する前に､ すべてを1行でプリントアウトしたいと思います｡
ということで､ printfを使って情報を出力してみます｡
月別の平均をプリントアウトして､ 2行フィードを追加することで､
書式を整えることができるんだ｡
そして､ 他の情報をプリントアウトする｡
月をスペースで区切って､ 新しい行を追加していくだけです｡
そこで､ forループを通過する際にも同じことをすることにします｡
ここで､ 月平均を得るために､ もう1つのforループが必要です｡
つまり､ このforループでは､ 外側のループはmonthから始まることになります｡
各行で行うのではなく､ ここで行うのは､ 月平均を求める必要があるため､
各列で行うことです｡
それでは､ 1月2月3月の各コラムを順番に見ていきたいと思います｡
そして､ それぞれの列について､ その列のすべての年を調べ､
小計と合計を再び変数として使用することができるのです｡
だからここでは､ 月が0に等しい､ 月が月より小さい､ 月プラスプラスと言うことにしています｡
そして､ 私のインナーループは年を重ねるごとに進んでいくのです｡
だからここでは､ 年号は0に等しいということにしています｡
そして､ 小計を再初期化することも忘れないでください｡
ここでは､ 小計を0とします｡ なぜなら､
新しい年を取得したら0から始めて､ すべての年を調べ､ 年をインクリメントしたいからです｡
そして､ この中に小計を入れたいと思います｡ これは､ 1年と数ヶ月分の配列と同じになります｡
ここで重要なのは､ 配列のIDを切り替えることです｡
そして､ 最初のループでは､ 各行を通過して各列を見て反復しています｡
今回は月平均を計算しているので､
実際に各列を見て､ 特定の行を見ています｡
そこで､ 小計を求め､ その月の小計を年数で割ったものをプリントアウトしたいだけです｡
37行目の出力と一致するように｡
だから､ こんな感じで､ 4でやっていくんです｡
1フォーマット､ 小計を年数で割ったもの｡
そして､ スペースを2つほど追加して､ できるだけ整列させるようにします｡
そして､ すべてをプリントアウトした後､ 読みやすくするために改行を加えれば完了です｡
そして､ 小計をすべて出してから年数で割ったので､ 月平均が出ます｡
では､ これをビルドして､ エラーもなく､ 実行してみましょう｡
そして今度は､ 月別の合計や月別の平均を追加で出力します｡
月次平均とフォーマットがあまり合っていないことがわかります｡
つまり､ キャラクターが出力されるからこそ､ すべてが決まるのです｡
実際には､ スペースを減らして､ そこに1つだけスペースを追加して､ より良い仕事ができるかどうか見てみましょう｡
今､ 実行すると､ 各月を平均値で結ぶことができるので､
少しは見栄えが良くなるかと思います｡
月が3文字､ 整数が2文字なので､ やはり少しずれてしまいます｡
スペースが1つしかないので､ 主に10月から11月にかけてダメ出しされました｡
今なら､ あの手この手で解決できる｡
それで､ フォーマットがすべてきれいになるはずです｡
ただ､ 年ごとの降水量と月平均の降水量をプリントアウトしているだけなのがお分かりいただけると思います｡
これで､ 2次元配列､ 配列の反復処理方法､ 配列の代入方法､ データへのアクセス方法について､
ご理解いただけたと思います｡
ありがとうございます｡