teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

1

文言追記しました。

2021/01/24 00:23

投稿

tatsu99
tatsu99

スコア5540

answer CHANGED
@@ -94,4 +94,50 @@
94
94
  ```
95
95
  実行結果
96
96
 
97
- ![イメージ説明](ae603abb4059e12fa2ca7a44153dcf52.png)
97
+ ![イメージ説明](ae603abb4059e12fa2ca7a44153dcf52.png)
98
+
99
+ ①getWeekOf1ですが、指定された年月に対応するの1日の週番号を求めています。
100
+ 2021年1月なら5
101
+ 2021年2月なら1
102
+ 2021年3月なら1
103
+ 2021年4月なら4、以下同様
104
+ を返します。
105
+ この値は、getCalenderのwofへ渡す値として使用されます。
106
+ この値をどのようにして算出するかということですが、
107
+ 1案:if 文で判断して直接返す。
108
+ 2案:1月1日は、#define WEEKof1 5 で与えられているので、それを利用して算出する。
109
+ のどちらかになります。
110
+ 1案なら
111
+ if month == 1 return 5;
112
+ if month == 2 return 1;
113
+ if month == 3 return 1;
114
+ if month == 4 return 4;
115
+ のように書きます。
116
+ この案の利点は、深く考える必要がないということです。
117
+ 欠点は、来年のカレンダーを作る場合は、全て書き換えないといけない、ということです。
118
+ 今回は2案を採用しています。
119
+ 2案の場合は、来年になった場合、#define WEEKof1 5のみを書き換えれば、済みます。
120
+ 算出方法は、
121
+ 2021年1月なら、WEEKof1の値を返す。
122
+ 2021年2月なら、WEEKof1に1月分の日付を加算した値(31)を7で割った余りを返す。(5+31)%7=1
123
+ 2021年3月なら、WEEKof1に2月分までの日付を加算した値(31+28)を7で割った余りを返す。(5+31+28)%7=1
124
+ 以降同様です。
125
+
126
+ ②mainについて
127
+ 一か月分のカレンダーは、char calender[8][MON_WIDTH];を確保し、
128
+ getCalender(calender, YEAR, 1, 5);
129
+ で作成しています。
130
+ つまり、getCalenderに作成したい年、月、及び週番号を与えると、calenderにその内容が設定されて
131
+ 返ってきます。そして、それを印字すれば、完了です。
132
+ 縦に1年分のカレンダーを印字する場合は、これを12回繰り返せば、それが実現できます。
133
+ しかしながら、横に4列の場合は、1行を印字するときに、横に4か月ぶんのカレンダーの内容を
134
+ 一度に印字しないといけません。(一度、改行してしまうと、前の行に戻ることはできない為)
135
+ その為、12か月分のカレンダー領域を確保し、12月分のカレンダーをまず作成します。
136
+ 領域はchar calender[12][8][MON_WIDTH];のようになります。
137
+ for (m = 1; m <= 12; m++){のループの部分で、12月分のカレンダーを作成しています。
138
+
139
+ 次にカレンダーの印字です。
140
+ for (row = 0;row < ROW;row++){の部分で、以下の処理(4か月分の印字)3回繰り返します。
141
+ for (int i = 0; i < 8; i++) {の部分で、4か月分のカレンダーの1行目から8行目の印字を繰り返します。
142
+ for (col = 0; col < COL; col++){の部分で各月の印字(4か月分の各月)を4回繰り返します。
143
+ 4か月分の印字が終了後、改行を印字します。