質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

解決済

2回答

1138閲覧

教科書の説明がよくわかりません。

退会済みユーザー

退会済みユーザー

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2016/12/04 11:26

/*--- y年m月のカレンダーを2次元配列sに格納 ---*/ void make_calendar(int y, int m, char s[7][22]) // 1ヶ月分のカレンダー用の文字列を作る関数 { // 7行22列の2次元配列sに格納する。タイトル1行+本体6行 int i, k; int wd = dayofweek(y, m, 1); // y年m月1日の曜日 int mdays = monthdays(y, m); // y年m月の日数 char tmp[4]; // sprintf(s[0], "%10d / %02d ", y, m); // 0行目(s[0])にタイトル用の年月を格納する // タイトル(年/月),10桁の年を表示してその後に空白1個が // 入ってしる。2桁の月の前に1個の空白が入れてある。 // 02というのは月が1桁の時その前の0を入れるということ for (k = 1; k < 7; k++) // タイトル以外のバッファをクリア // 先頭文字にナル文字を代入すると文字列 // 全体が空になる。k = 1~ k = 6まで変化する s[k][0] = '\0'; // 日付の1行目の要素0から6行目までNULLを代入する。 // 先頭文字になる文字を代入すると文字列sは空になる k = 1; // 日付の1行目を表す。1日が入っている行である sprintf(s[k], "%*s", 3 * wd, ""); // 第1日の左側を空白文字で埋める // 第1日が金曜日であれば15個、曜日に応じて // 適当な個数の空白文字で埋める for (i = 1; i <= mdays; i++) { sprintf(tmp, "%3d", i); // 日付を表す3桁の文字列を配列tmpに作る strcat(s[k], tmp); // i日の日付を追加, strcat:文字列の連結 if (++wd % 7 == 0) // 土曜日の日付を格納して1行分の文字を k++; // 使い切るとkをインクリメントして次の // 行へ進む、++wd % 7 == 0はwdが土曜日である // 次の行へ進む } if (wd % 7 == 0) // wd % 7 == 0はwdが日曜日である時 k--; else { for (wd %= 7; wd < 7; wd++) // 最終日の右側に空白文字を追加 // 11月はwd % 7-->wd,k==5のとき,wd %= 7はwd==2 strcat(s[k], " "); // 最終日の右側に3個の空白文字を追加,strcat:文字列の連結 // s[5][0]==29,s[5][1]==30これに空白文字" "をつないでいく // wd < 7の間3個の空白文字を前の空白に繋いでいく } while (++k < 7){ // 日付が格納されていない未使用行を sprintf(s[k], "%21s", ""); // 空白文字で埋めつくす。最後にNULL文字を //入れるので、22個の枠が埋まる } }コード

wd %= 7 は丁寧な説明をいただき、わかりました。ありがとうございます。
ここのところですfor (wd %= 7; wd < 7; wd++) 。K==5で日付が30日(月)で終わっています。火曜日から土曜日までを空白で埋めるところで、教科書のせつめいがいまいちわかりません。
「教科書の解説は、最終日の右側は空白文字で埋め尽くさなければなりません。この図の例では、30日の日付を格納した直後のwdの値は29となっています。
その値をインクリメントした値30を7で割った余りは、その翌日の曜日(火曜日)を示す2となります。」
となっていますが、wdは0から6までしか変化しないと思うのですが、
どうしてwd==29なのでしょうか?
よろしくお願いいたします

編集

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

1日が何曜日という設定なのでしょうか

30 日が月曜日ということなので、1日は日曜日(wd == 0)なのだとして進めます。
また、 mdays についても mdays == 30 として考えますね

wd はループしていない。

まず、この例では、wd は質問者さんのおっしゃるような 0 〜 6 までの変数ではありません。
というのは、if (++wd % 7 == 0) の部分で wdを7で割った余りを求めてはいるけれどもそれを wd には代入していないからです。処理を追っていくと、

初めて for の中を実行するとき

この月は日曜始まりということなので、この時点で wd == 0 です。
for (i = 1; i <= mdays; i++) { なので i は 1 〜 30 まで変化しますね。
この中で if (++wd % 7 == 0) という部分がありますが、これは上にも書いた通り割った余りを求めているだけで、計算結果の余りを実際に wd に代入しているわけではありません(つまり、wd自体はループに伴って 1,2,3,...,6,7,8,9,... と単純に増えつづけます)。

for 最後の回(30回目)の strcat() 時点

最後の strcat(s[k], tmp); の部分では、ループは 30 回目ですが、wd は最初 0 から始まって strcat() の後でインクリメントされているので、 wd == 29 なのです。教科書の「30日の日付を格納した直後のwdの値は29」とはこのことです。

for の処理が終わるとき

このとき k == 5 になっています (k == 1 から初まり、i == 7,14,21,28 のときに 1 ずつ増えているからです)。そして wd の値は 30 になっています。ループ最後の if でインクリメントされたからです。
教科書の「その値をインクリメントした値30を...」はこういう意味で、これが最後の wd %= 7; によって 2 になります。

投稿2016/12/04 15:20

Eki

総合スコア429

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/12/05 01:19

Ekiさん丁寧な説明でモヤモヤしていたものがすきりしました。ありがとうございます。
guest

0

ベストアンサー

まずwdの内容がどのように取り扱われているか?を整理して考えましょう。

投稿2016/12/04 11:31

編集2016/12/04 15:26
MasahikoHirata

総合スコア3747

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2016/12/04 11:40

あとからまた読み直してみます、プログラムは正常動作しています。ありがとうございました
MasahikoHirata

2016/12/04 11:46

あわてて回答を'ベストアンサー’にしなくても。このサイトを利用される方、’質問をする相手が居ない’との解釈での回答をしています。まあ’老婆心’ながら。。チャンスを生かして聞けるときに恥も外聞も無く質問されれば。’聞くは一度の恥’、’聞かぬは一生の損’ですから。間違っていても最後に知識になれば。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問