• ベストアンサー

C言語初心者なんですが

はじめまして、最近C言語を勉強している初心者です。 グレゴリウス暦の定義を利用して入力した日は何曜日かという問題なのですがいまいちよくわかりません。 4、400で割り切れる年は閏年 100で割り切れる年は閏年ではない 西暦1年1月は月曜日 今のところわかっているのは前年までの日数と前月までの日数と今月の日数を足して一週間(7日)で割るといったところです。 おそらく私の勉強不足だと思うのですがなかなか進めません 備考 ツェラーの公式は使わないこと 途中でexit returnは使わない 外部変数は使わない

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

  • ベストアンサー
  • fonera
  • ベストアンサー率52% (38/72)
回答No.5

恐れ入ります。 No.4で回答したものです。 とっかかりが無く、結構厳しそうなので補足します。 先ほど自分でも作ってみたのですが、いくつかハマリそうなポイントがあるので先に解説しておきます。参考になさって下さい。 >int WhatsToday(int year, int month, int day) { > int m_array[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; > int today, i; > today = 0; > > if ((monthが3月以降) && (yearが閏年)) { > m_array[2月] += 1; /* 閏年を追加 */ > } > today += yearの前の年を7で割った余り; > today += (yearの前の年 / 4) - (yearの前の年 / 100) + (yearの前の年 / 400); > for (i = 0; monthの前の月まで; i++) { > today += m_array[i]; > } > today += dayの前日; > > return (todayを7で割った余り); >} > >int main (int argc, char* argv[]) { > char *week[7] = {"月", "火", "水", "木", "金", "土", "日"}; > int today = 0; > 年月日を入力してもらう; > today = WhatsToday(入力された年, 入力された月, 入力された日); > printf("%d/%d/%d(%s)", 入力された年, 入力された月, 入力された日, week[today]); > > return 0; >} わかりやすく書いたので、↑を逐次コーディングするだけで解けると思います。 入力前年までの曜日は割合すんなりでると思います。 入力した年が閏年だった場合は、2月末までは閏日を足さず、3月からは閏日を足す必要があります。そこでハマりがちかな、と思います。 とりあえずできることを増やしていくことをお勧めします。 入力(scanf)は理解されているようなので、出力(printf)もしてみましょう。 後は、~回繰り返し(for)・もし~だったら(if)を使えるようになると、大抵のことはできます。 詰まったときは、日本語でも良いのでやることを書き出して行くと結構あっさり解けると思います。 今回は質問に対する回答をほぼ書いてしまいましたが、次からは設計の部分はご自分でできるようになってから質問すると、他の方も答えやすいかと思います:-) では、頑張って下さい。

noname#53915
質問者

お礼

なるほど、まずは自分でやってみないとですね これなら理解できるかもしれません 早速やってみたいと思います ホント、ありがとうございました。

その他の回答 (4)

  • fonera
  • ベストアンサー率52% (38/72)
回答No.4

恐れ入ります。 おそらく宿題についての質問だと思うので、「考え方」だけお答えします。 自分で調べられるように、必要な情報は盛り込みましたので、参考になさってください。 定義や備考(「ツェラーの公式を使わないこと」「西暦1年1月1日を火曜日とする」)から、 求められているのは、「1年1月1日が月曜日である」事から「入力日の曜日を求める」事であると判ります。 (以下、グレゴリオ歴で解説します) <入力年の1月1日の曜日の出し方> 一年は365日なので、7で割り切れません。閏年でなければ、12月30日で割り切れます。 これは、1月1日が月曜日であれば、12月30日が日曜日である(ちょうど割り切れる)という意味です。 つまり、12月31日は月曜日になって、次の年の1月1日は火曜日になります。 1年過ぎると、曜日が1つ進むわけです。 この単純な事実から、前年までの日数の計算が必要なくなります。 例えば、2008年は(閏年を無視すれば)2008回曜日が進んだと判ります。 2008 / 7 = 286 余り 6 = 月曜日から6回進んだ曜日 = 土曜日 <閏年を考える> さて、先ほどの「2008年1月1日が土曜日」という計算は間違っています。 なぜならば「閏年を無視した」からです。 2008年までに何回閏年があったでしょうか? 2007 / 4 = 501 (余りは無視) 2007 / 100 = 20 (余りは無視) 2007 / 400 = 5 (余りは無視) つまり、501回閏年だけど、そのうち20回は閏年ではなく、でも5回はやっぱり閏年という事が判ります。 501 - 20 + 5 = 486 閏年のせいで、486日余分な日が挿入されているので、その分曜日も進みます。 486 / 7 = 69 余り 3 = 土曜日から3回進んだ曜日 = 火曜日 つまり、「2008年1月1日は火曜日」となります。あっていますね。 <1月1日から何日たったかを考える> さて、明日の日付(2008/01/22)が何曜日かは簡単ですね。 ここでちょっとしたトリックを使います。 「2008年1月1日を火曜日」ではなく、「2008年1月0日を月曜日」とするのです。 22 / 7 = 3 余り 1 = 1月0日から1回進んだ曜日 = 火曜日 (7で割り切れると1月1日の1回前の曜日になる、という事を考えればトリックのタネが判ります) もしも3月21日の曜日が出したいのであれば… 1月の日数(31)と2月の日数(28+閏日=29)を足して、21日を足せばよいのです。 31 + (28 + 1) + 21 = 81 81 / 7 = 11 余り 4 = 1月0日から4回進んだ曜日 = 金曜日 (残念ながら毎月の日数は、歴史的な理由で適当に数字が決まっているので、覚えるしかありません) 以上で、「考え方」の解説は全てです。 どう考えたらよいか、という点については解説しました。 あとは、理解できない点を調べながら、実際にプログラミングしてみてください。 言われたことをこなすだけだと、C言語をはじめとするプログラムって面白くないので、是非頑張ってみてください。

noname#53915
質問者

お礼

情報ありがとうございます。助かりました。 とりあえず途中まで考えてみたんですが #include <stdio.h> int main () { int year, months, day, sum = 0; /*年数,月,日数*/ int m_array[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; char *week[7] = {"日", "月", "火", "水", "木", "金", "土"}; printf("input (e.g. ****/**/**)\n>>"); scanf("%d/%d/%d", &year, &months, &day); いまのとこはここまでです。

  • buriburi3
  • ベストアンサー率44% (353/792)
回答No.3

一週間は7日ですから、基準日からの日数÷7の余りを出せば基準日からのズレが得られます。 基準日は何処でもよくて例えば今年の1月1日(火)を基準に取った場合 ●今年の5月1日は ・今年はうるう年なので3月1日までの日数は  31+29+31+30=121  121÷7=17余り2  基準日とのズレ(余り)で曜日がわかり  余り:0-火 1-水 2-木 3-金 4-土 ・・・  なので5月1日は木曜日である事がわかります。 万年カレンダーに使う場合には基準日は可能な限り過去の日曜日が望ましいというだけで実際に過去の曜日を調べないのであれば 2006年1月1日(日曜日)あたりを基準にしても良いと思います。 カレンダーとにらめっこすれば理屈が分かりますよ。(多分)

noname#53915
質問者

お礼

なるほど、勉強になります! ありがとうございました。

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.2

★アドバイス ・ここのカテゴリの過去の質問にたくさんの回答があります。  私もいくつか回答していた時期があります。  『曜日』キーワードなどで過去の質問を検索してみて下さい。 http://oshiete.goo.ne.jp/search/search.php?status=select&MT=%CD%CB%C6%FC&nsMT=&ct_select=1&ct0=205&ct1=221&ct2=250

noname#53915
質問者

お礼

参考になりました ありがとうございます。

  • sakusaker7
  • ベストアンサー率62% (800/1280)
回答No.1

>西暦1年1月は月曜日 グレゴリオ暦が採用されたのは国にもよりますが、16世紀以後のことですから 1年1月1日が何曜日であるかわかってもどうにもならないのでは? グレゴリオ暦 - Wikipedia http://ja.wikipedia.org/wiki/%E3%82%B0%E3%83%AC%E3%82%B4%E3%83%AA%E3%82%AA%E6%9A%A6

noname#53915
質問者

お礼

わかってもというか私の説明不足でしたね 「西暦1年1月1日は月曜日として」 とゆう設定で解くといった感じです。

関連するQ&A