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

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

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

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

Q&A

解決済

2回答

1203閲覧

万年カレンダー c言語

ahirumoco

総合スコア9

C

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

0グッド

0クリップ

投稿2018/07/19 13:40

編集2018/07/19 13:50

前提・実現したいこと

万年カレンダーを作成したくてある万年カレンダーを参考にしている時の疑問です
ここに質問の内容を詳しく書いてください。
(例)PHP(CakePHP)で●●なシステムを作っています。
■■な機能を実装中に以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

if ( sw <= ew ){
ew = ew - sw + 28 ;
}else{
ew = 35 - sw + ew ;
}

ここの部分のコードがなんの役割をしているのか。
これは公式なのか。
ew,swはなんのことを表しているのか。

がわからなくて困っています

エラーメッセージ

該当のソースコード

C

1コード 2#include <stdio.h> 3 4int week(int y,int m,int d) 5{ 6 if ( m < 3 ){ //1月を13,2月を14として計算するため 7 m += 12 ; 8 y -- ; 9 } 10 return (y+y/4-y/100+y/400+(m*13+8)/5+d)%7 ; //ツェラーの公式 11} 12 13int main() 14{ 15 int y,m,d,sw,ew ; 16 printf("西暦を入力してください : "); //西暦の入力 17 scanf("%d",&y); 18 printf("月を入力してください : "); //月の入力 19 scanf("%d",&m); 20 sw = week(y,m,1); 21 ew = week(y,m+1,1); 22 23 if ( sw <= ew ){ 24 ew = ew - sw + 28 ; 25 }else{ 26 ew = 35 - sw + ew ; 27 } 28 printf("\n"); 29 printf("%4d / %d\n",y,m); //西暦と月の表示 30 printf("SUM MON TUE WED THU FRI SAT"); //曜日の表示 31 for (d=0 ;d<37 ;d++){ 32 if (d % 7 == 0){ 33 printf("\n"); //(土曜日まで(週の終わり)きたら改行) 34 } 35 if ( d < sw || d >= ew+sw ){ 36 printf(" "); 37 } else { 38 printf("%3d ",d-sw+1); //日にちの表示 39 } 40 } 41 printf("\n"); 42 return 0 ; 43}

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

初めての投稿なので色々間違っていたらすみません。
ここにより詳細な情報を記載してください。

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

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

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

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

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

y_waiwai

2018/07/19 13:44

ソースコードは<code>押して、'''の枠の中に貼り付けてください
guest

回答2

0

ベストアンサー

まずはプログラムのコードの処理を一つずつ見ていきましょう。例えば swewweek() という関数の戻り値で初期化されていますが、この関数内にコメントされている「ツェラーの公式」については調べてみましたか?

何も分からない状態からコードだけを読んで内容を理解するのは至難の技です (特に公式などを使っている場合) 。せっかくコメントにヒントがあるので、まずは細かい単位に分解して、上から順に頭の中で実行していき、そこが何をするためのコードなのか調べていくことが大切です。具体例を考えてみるのもよい手段です。


ツェラーの公式というのはどうやら年月日からその曜日を計算する公式のようですね。

つまり、sw というのは y 年 m 月 1 日の曜日であり、 ew というのは y 年 m + 1 月 1 日の曜日を指すようです。つまり、月の初めの曜日と、その次の月の最初の日の曜日が代入されます。 最初は

ちなみにこれは Wikipedia によると、

0123456

という対応があるらしいです。

つまり 2018 年 7 月のカレンダーを作るなら、7 月 1 日は日曜日ですから sw == 1 となり、 2018 年 8 月 1 日は水曜日ですから ew = 4 となります。

sw <= ew のとき

sw <= ew というのは、 月の最初の曜日が次の月の始まりの曜日より前である ということになりますね。具体的にカレンダーを考えてみればよいのです。つまりたとえば次のようなカレンダーです :

(2018 年 7 月)

123456
78910111213
14151617181920
21222324252627
28293031(1)

上のカレンダーで 1 日は日曜日ですから sw == 1 で、次の月の 1 日は水曜日ですから ew == 4 となります。これを代入してみると ew - sw + 28 == 31 となりますね。なんとなく察せるかと思いますが、これはつまり 2018 年 7 月の 総日数 です。計算式の意味としては、まず日曜日から火曜日までの 3 日間がある + まるまる 4 週間 (28 日) ある、ということでしょうね。上のカレンダー的には、 (1 日から 3 日までの 3 日間) + (4 日から 31 日までのまるまる 4 週間) という感じでしょうか。

つまり「とりあえず 4 週間はまるまるあるよね。後の残りをうまく計算して足そう。」という考えです。

sw <= ew でないとき

sw <= ew でないというのは sw > ew ということなので、 月の最初の曜日が次の月の始まりの曜日より後である ということになりますね。つまりたとえば次のようなカレンダーです :

(実際にこんなカレンダーになるの何年何月か知らないですけど)

12
3456789
10111213141516
17181920212223
24252627282930
31(1)(2)(3)(4)(5)

上のカレンダーで 1 日は木曜日ですから sw == 5 で、次の月の 1 日は日曜日ですから ew == 1 となります。これを代入してみると 35 - sw + ew == 31 となりますね。なんとなく察せるかと思いますが、これもつまりこの月の 総日数 です。計算式の意味としては、まずまるまる 5 週間あって、そこから存在しない日曜日から水曜日までを引く、ということでしょう。上のカレンダー的には、(1 日から次の月の 4 日までのまるまる 5 週間) - (次の月の 1 日から 4 日の 4 日間) ということです。

つまり、「とりあえず 5 週間あるということにしよう。そこから余計に数えている分を引こう。」という考え方です。

書き換え

あまり思い付きませんが、強いていうなら、 ew という変数を異なる意味で使い回していることが気になりますね。ですのでまあ、あえて書くなら...

c

1 // このあと、今表示したい月の総日数をここに入れます。 2int num_of_day; 3if ( sw <= ew ) { 4 int extra = ew - sw; // 足りてない分 5 num_of_day = extra + 28; 6} else { 7 int over = sw - ew; // 余分にカウントした分 8 num_of_day = 35 - over; 9} 10 11// ... 以後、 ew を num_of_day へ変更する

投稿2018/07/19 15:55

Eki

総合スコア429

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

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

0

sw = week(y,m,1);
ew = week(y,m+1,1);

ここで、仮にprintf() で出力してみる(デバッガでも良い)と分かると思いますが、sw: Start Week, ew: End Week じゃないですか?
それぞれが、その月内での第何週か、でしょう。 で、月をまたがる場合に対応するために、

if ( sw <= ew ){

をしていると思われます。
(机上での確認のみ)

投稿2018/07/19 13:54

pepperleaf

総合スコア6383

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

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

ahirumoco

2018/07/19 13:58

自分的にif ( sw <= ew ){ ew = ew - sw + 28 ; }else{ ew = 35 - sw + ew ; } のcordがわかりにくいので代わりとなるcordって思いつきますでしょうか。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問