年月日をもとに曜日を求めるプログラム
年月日をもとに曜日を求めるプログラム
ツェラーの法則を使って入力した年月日で曜日を表示するプログラムですが、
このプログラムだとビルドエラーがでてしまいます。
おかしな点を教えてください、お願いします。
#include <stdio.h>
int main (void)
{
int year,month,date,day;
printf("西暦,月,日にちを入力してください\n");
printf("西暦:");
scanf("%d", &year);
printf("月:");
scanf("%d", &month);
printf("日にち:");
scanf("%d", &date);
day = (year+year/4-year/100+year/400+(13*month+8)/5+date)%7;
if (day=0)
printf("日曜日です。\n",day);
else if (day=1)
printf("月曜日です。\n",day);
else if (day=2)
printf("火曜日です。\n",day);
else if (day=3)
printf("水曜日です。\n",day);
else if (day=4)
printf("木曜日です。\n",day);
else if (day=5)
printf("金曜日です。\n",day);
else
printf("土曜日です。\n",day);
return 0;
}
このプログラムだとビルドエラーがでてしまいます。
おかしな点を教えてください、お願いします。
#include <stdio.h>
int main (void)
{
int year,month,date,day;
printf("西暦,月,日にちを入力してください\n");
printf("西暦:");
scanf("%d", &year);
printf("月:");
scanf("%d", &month);
printf("日にち:");
scanf("%d", &date);
day = (year+year/4-year/100+year/400+(13*month+8)/5+date)%7;
if (day=0)
printf("日曜日です。\n",day);
else if (day=1)
printf("月曜日です。\n",day);
else if (day=2)
printf("火曜日です。\n",day);
else if (day=3)
printf("水曜日です。\n",day);
else if (day=4)
printf("木曜日です。\n",day);
else if (day=5)
printf("金曜日です。\n",day);
else
printf("土曜日です。\n",day);
return 0;
}
Re:年月日をもとに曜日を求めるプログラム
>>デミチェリスさん
[color=gray>> このプログラムだとビルドエラーがでてしまいます。[/color]
どの様なビルドエラーが出るのでしょうか。
私が見た感じ動きそうな気が致します。
気になった点は day=0 ~ day=5 の部分で、= ではなく == ではないでしょうか。
[color=gray>> このプログラムだとビルドエラーがでてしまいます。[/color]
どの様なビルドエラーが出るのでしょうか。
私が見た感じ動きそうな気が致します。
気になった点は day=0 ~ day=5 の部分で、= ではなく == ではないでしょうか。
Re:年月日をもとに曜日を求めるプログラム
0が日曜日、1が月曜日と固定なのですから、配列を使うとすっきりしますよ。
static const char *Week[/url] = {"日", "月", "火", "水", "木", "金", "土"};
printf("%s曜日です。\n", Week[day]);
DVDMさんのおっしゃっているようなバグが入り込む余地も無くなります。
static const char *Week[/url] = {"日", "月", "火", "水", "木", "金", "土"};
printf("%s曜日です。\n", Week[day]);
DVDMさんのおっしゃっているようなバグが入り込む余地も無くなります。
Re:年月日をもとに曜日を求めるプログラム
文法的な間違いはないのでプログラムにはエラーの原因はありません
DVDMさんの指摘された部分ですべて月曜日となるバグはありますが
以下規約と注意事項から引用です
※回答者が困る質問例※
「コンパイルしたのですが、うまくコンパイルできません」
この手の質問はよく回答に困ります。
使っているOS名・コンパイラ名・ライブラリ名も明記しましょう。
コンパイルエラーの質問時は必ず最低限のエラーメッセージも書きましょう。
DVDMさんの指摘された部分ですべて月曜日となるバグはありますが
以下規約と注意事項から引用です
※回答者が困る質問例※
「コンパイルしたのですが、うまくコンパイルできません」
この手の質問はよく回答に困ります。
使っているOS名・コンパイラ名・ライブラリ名も明記しましょう。
コンパイルエラーの質問時は必ず最低限のエラーメッセージも書きましょう。
Re:年月日をもとに曜日を求めるプログラム
これこのままできちんと入力できます?
>>scanf("%d", &year);
ここを入力、エンター押すと
>>scanf("%d", &month);
とかスルーされていく気が(改行ががが
charの配列を取って、scanfの後に
gets(xxx);
って付けて改行をキャッチしてあげないとまずいと思います。
もしくはscanfを使わない等など
後は好みですが、列挙型を使って0~6 に日~月を割り当てて
最後のif~else文をswitch文にした方が好きかな
ちなみに私の環境でもそのプログラム(コピペ)にビルドエラーは出ませんでしたよ
XP VC++2010 コマンドプロンプト
cl test.cpp
>>scanf("%d", &year);
ここを入力、エンター押すと
>>scanf("%d", &month);
とかスルーされていく気が(改行ががが
charの配列を取って、scanfの後に
gets(xxx);
って付けて改行をキャッチしてあげないとまずいと思います。
もしくはscanfを使わない等など
後は好みですが、列挙型を使って0~6 に日~月を割り当てて
最後のif~else文をswitch文にした方が好きかな
ちなみに私の環境でもそのプログラム(コピペ)にビルドエラーは出ませんでしたよ
XP VC++2010 コマンドプロンプト
cl test.cpp
Re:年月日をもとに曜日を求めるプログラム
>>printf("日曜日です。\n",day);
printfの最後にあるdayは必要ないです。抜いてください。
>>ぜらーちんさん
scanfは問題ありません。
多分そういう問題はscanfの後、getsやgetcharを使うと出ると思います。
printfの最後にあるdayは必要ないです。抜いてください。
>>ぜらーちんさん
scanfは問題ありません。
多分そういう問題はscanfの後、getsやgetcharを使うと出ると思います。
Re:年月日をもとに曜日を求めるプログラム
>>白い時空さん
scanfは問題ないのは分かりますが、そのあとエンター分をキャッチしないとまずくないですか?
試しに今やってみましたが、西暦入力後、何も入力できないでプログラム終わります。
%sならいいでしょうが、数値しか取れない%dだとまずいと思います。
>>多分そういう問題はscanfの後、getsやgetcharを使うと出ると思います。
むしろ、やらないとダメです。
scanfは問題ないのは分かりますが、そのあとエンター分をキャッチしないとまずくないですか?
試しに今やってみましたが、西暦入力後、何も入力できないでプログラム終わります。
%sならいいでしょうが、数値しか取れない%dだとまずいと思います。
>>多分そういう問題はscanfの後、getsやgetcharを使うと出ると思います。
むしろ、やらないとダメです。
Re:年月日をもとに曜日を求めるプログラム
>scanfは問題ないのは分かりますが、そのあとエンター分をキャッチしないとまずくないですか?
>試しに今やってみましたが、西暦入力後、何も入力できないでプログラム終わります。
書式指定子に %d を与えた場合、空白文字は読み飛ばされると思うのですが。
>%sならいいでしょうが、数値しか取れない%dだとまずいと思います。
>>多分そういう問題はscanfの後、getsやgetcharを使うと出ると思います。
>むしろ、やらないとダメです。
最初の scanf("%d", &year); のコードで改行コードは入力バッファに残りますが、続く
scanf("%d", &month); では読み飛ばされますので、問題は無いかと。
scanf("%d", &year); とした後に
scanf("%c", &hoge); とでもしたら変数 hoge には改行コードが入りますが。
>試しに今やってみましたが、西暦入力後、何も入力できないでプログラム終わります。
書式指定子に %d を与えた場合、空白文字は読み飛ばされると思うのですが。
>%sならいいでしょうが、数値しか取れない%dだとまずいと思います。
>>多分そういう問題はscanfの後、getsやgetcharを使うと出ると思います。
>むしろ、やらないとダメです。
最初の scanf("%d", &year); のコードで改行コードは入力バッファに残りますが、続く
scanf("%d", &month); では読み飛ばされますので、問題は無いかと。
scanf("%d", &year); とした後に
scanf("%c", &hoge); とでもしたら変数 hoge には改行コードが入りますが。
Re:年月日をもとに曜日を求めるプログラム
>>へろり
あーなるほど、覚えていたことを勘違いしてましたごめんなさい。
確かに改行読み飛ばされますね
↑の状態が必要なのは、%dであるから例えば[t]とかとかの文字を入力した時でしたね
かなり恥ずかしいことをしてました>>白い時空さん申し訳ない。
whileか何かでループさせて、入力
対応外の文字だと、再入力って形が望ましいですね。思い出しました。
あーなるほど、覚えていたことを勘違いしてましたごめんなさい。
確かに改行読み飛ばされますね
↑の状態が必要なのは、%dであるから例えば[t]とかとかの文字を入力した時でしたね
かなり恥ずかしいことをしてました>>白い時空さん申し訳ない。
whileか何かでループさせて、入力
対応外の文字だと、再入力って形が望ましいですね。思い出しました。
Re:年月日をもとに曜日を求めるプログラム
>使っているOS名・コンパイラ名・ライブラリ名も明記しましょう。
コンパイルエラーの質問時は必ず最低限のエラーメッセージも書きましょう。
・XP,Microsoft Visual C++2010,test.cppです。
・たぶん#include <stdio.h>の付け忘れで識別子見つかりませんでしたと、表示されたのだと思います。
申し訳ないです。いちよ上記のプログラムで表示されました。
ただMicrosoft Visual C++2010のことなのですが、、
・年月日を入力するとコンパイルはされてると思うのですが、画面がすぐに閉じてしまいます。。なので結果がどうなったかはわかりません。
>0が日曜日、1が月曜日と固定なのですから、配列を使うとすっきりしますよ。
charは初めてなので使い方があってるかわかりませんが・・、
#include <stdio.h>
int main (void)
{
int year,month,date,day;
static const char *Week[7] = {"日", "月", "火", "水", "木", "金", "土"};
printf("西暦,月,日にちを入力してください\n");
printf("西暦:");
scanf("%d", &year);
printf("月:");
scanf("%d", &month);
printf("日にち:");
scanf("%d", &date);
day = (year+year/4-year/100+year/400+(13*month+8)/5+date)%7;
printf("%s曜日です。\n", Week[day]);
return 0;
}
コンパイルエラーの質問時は必ず最低限のエラーメッセージも書きましょう。
・XP,Microsoft Visual C++2010,test.cppです。
・たぶん#include <stdio.h>の付け忘れで識別子見つかりませんでしたと、表示されたのだと思います。
申し訳ないです。いちよ上記のプログラムで表示されました。
ただMicrosoft Visual C++2010のことなのですが、、
・年月日を入力するとコンパイルはされてると思うのですが、画面がすぐに閉じてしまいます。。なので結果がどうなったかはわかりません。
>0が日曜日、1が月曜日と固定なのですから、配列を使うとすっきりしますよ。
charは初めてなので使い方があってるかわかりませんが・・、
#include <stdio.h>
int main (void)
{
int year,month,date,day;
static const char *Week[7] = {"日", "月", "火", "水", "木", "金", "土"};
printf("西暦,月,日にちを入力してください\n");
printf("西暦:");
scanf("%d", &year);
printf("月:");
scanf("%d", &month);
printf("日にち:");
scanf("%d", &date);
day = (year+year/4-year/100+year/400+(13*month+8)/5+date)%7;
printf("%s曜日です。\n", Week[day]);
return 0;
}
Re:年月日をもとに曜日を求めるプログラム
いちよへろりさんのやり方ででました。0コンマ、一瞬で表示されて消えたのですが、はっきり見えました。
ありがとうございます^^
ただ、これから今度はその年月のカレンダーを作ります。またわからないことがあったらここに書かせて頂きます。
DVDMさん、へろりさん、toyoさん、ぜらーちんさん、白い時空さん、ありがとうございました^^
ありがとうございます^^
ただ、これから今度はその年月のカレンダーを作ります。またわからないことがあったらここに書かせて頂きます。
DVDMさん、へろりさん、toyoさん、ぜらーちんさん、白い時空さん、ありがとうございました^^
Re:年月日をもとに曜日を求めるプログラム
ツェラーの公式は、1月,2月を前年の13月,14月として扱わないと計算が狂いますよ。
>画面がすぐに閉じてしまいます。
コマンドプロンプトから実行ファイル名を指定して起動するとか、
main関数でリターンする前に getchar(); を書いておけばいいのではないですか?
今のような確認方法ではこの先やってられないと思います。
>画面がすぐに閉じてしまいます。
コマンドプロンプトから実行ファイル名を指定して起動するとか、
main関数でリターンする前に getchar(); を書いておけばいいのではないですか?
今のような確認方法ではこの先やってられないと思います。
Re:年月日をもとに曜日を求めるプログラム
>コマンドプロンプトから実行ファイル名を指定して起動するとか、
main関数でリターンする前に getchar(); を書いておけばいいのではないですか?
今のような確認方法ではこの先やってられないと思います。
・デバックなしでやるようにしたら、とりあえず問題は解決しました^^
>×いちよ ○一応(いちおう)
・そうですね、幼稚言葉というやつですね。一応=いちおう=いちよ、だと思って使ってました。すいません。
・カレンダーの表示は未だ、日にちの表示で迷っています。
printf("---------------------\n");の下からが表示されないです。
#include <stdio.h>
int main (void)
{
int year,month,date,day,i,e;
static char *Week[7] = {"日", "月", "火", "水", "木", "金", "土"};
printf("西暦,月,日にちを入力してください。\n");
printf("西暦:");
scanf("%d", &year);
printf("月:");
scanf("%d", &month);
printf("日:");
scanf("%d", &date);
day = (5 * year / 4 - year / 100 + year / 400 + (26 * month + 16) / 10 + date ) % 7;
printf("%s曜日です。\n", Week[day]);
i = 1;
printf(" ** %d年%d月 **\n", year, month);
printf(" 日 月 火 水 木 金 土\n");
printf("---------------------\n");
while( i <= day )
{
printf(" ");
i = i + 1;
}
if (month == 1 || 3 || 5 || 7 || 8 || 10 || 12)
e <= 31;
else if (month == 4 || 6 || 9 || 11 )
e <= 30;
else
e == 28;
while( i <= e)
{
printf(" %d", i);
if ( (i + e) % 7 == 0)
printf("\n");
}
return 0;
}
main関数でリターンする前に getchar(); を書いておけばいいのではないですか?
今のような確認方法ではこの先やってられないと思います。
・デバックなしでやるようにしたら、とりあえず問題は解決しました^^
>×いちよ ○一応(いちおう)
・そうですね、幼稚言葉というやつですね。一応=いちおう=いちよ、だと思って使ってました。すいません。
・カレンダーの表示は未だ、日にちの表示で迷っています。
printf("---------------------\n");の下からが表示されないです。
#include <stdio.h>
int main (void)
{
int year,month,date,day,i,e;
static char *Week[7] = {"日", "月", "火", "水", "木", "金", "土"};
printf("西暦,月,日にちを入力してください。\n");
printf("西暦:");
scanf("%d", &year);
printf("月:");
scanf("%d", &month);
printf("日:");
scanf("%d", &date);
day = (5 * year / 4 - year / 100 + year / 400 + (26 * month + 16) / 10 + date ) % 7;
printf("%s曜日です。\n", Week[day]);
i = 1;
printf(" ** %d年%d月 **\n", year, month);
printf(" 日 月 火 水 木 金 土\n");
printf("---------------------\n");
while( i <= day )
{
printf(" ");
i = i + 1;
}
if (month == 1 || 3 || 5 || 7 || 8 || 10 || 12)
e <= 31;
else if (month == 4 || 6 || 9 || 11 )
e <= 30;
else
e == 28;
while( i <= e)
{
printf(" %d", i);
if ( (i + e) % 7 == 0)
printf("\n");
}
return 0;
}
Re:年月日をもとに曜日を求めるプログラム
if (month == 1 || 3 || 5 || 7 || 8 || 10 || 12)
上記のコードは
if(month == 1 || 3 != 0 || 5 != 0.....
というコードと等価です。
if(month == 1 || month == 3 || month == 5....
すべてを month と比較する必要があります。
また、閏年の2月は29日までありますよ。
上記のコードは
if(month == 1 || 3 != 0 || 5 != 0.....
というコードと等価です。
if(month == 1 || month == 3 || month == 5....
すべてを month と比較する必要があります。
また、閏年の2月は29日までありますよ。
Re:年月日をもとに曜日を求めるプログラム
>if(month == 1 || 3 != 0 || 5 != 0..... というコードと等価です。
・なるほど勉強になりました。
> また、閏年の2月は29日までありますよ。
・そうですね。一応、式はできてるんですが、printfに表示がうまくいかなくて・・。
if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
>switch caseを使う方法もありますね
・習ってないので使い方はわかりませんが、調べてみます。
・なるほど勉強になりました。
> また、閏年の2月は29日までありますよ。
・そうですね。一応、式はできてるんですが、printfに表示がうまくいかなくて・・。
if (year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
>switch caseを使う方法もありますね
・習ってないので使い方はわかりませんが、調べてみます。
Re:年月日をもとに曜日を求めるプログラム
配列を使えばすっきりしますよ。
static const int Days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
e = Days[month - 1];
2月だけは閏年を判定して+1しなければなりませんが。
static const int Days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
e = Days[month - 1];
2月だけは閏年を判定して+1しなければなりませんが。
Re:年月日をもとに曜日を求めるプログラム
>配列を使えばすっきりしますよ。
こうですか?
printf(" ** %d年%d月 **\n", year, month);
printf(" 日 月 火 水 木 金 土\n");
printf("---------------------\n");
while( i <= day )
{
printf(" ");
i = i + 1;
}
static const int Days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
e = Days[month - 1];
while( i <= e)
{
printf(" %d", i);
if ( (i + day) % 7 == 0)
printf("\n");
}
while( month == 2 )
{
if ( year % 4 == 0 && ( year % 100 != 0 || year % 400 == 0 ))
e == 29;
}
return 0;
}
こうですか?
printf(" ** %d年%d月 **\n", year, month);
printf(" 日 月 火 水 木 金 土\n");
printf("---------------------\n");
while( i <= day )
{
printf(" ");
i = i + 1;
}
static const int Days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
e = Days[month - 1];
while( i <= e)
{
printf(" %d", i);
if ( (i + day) % 7 == 0)
printf("\n");
}
while( month == 2 )
{
if ( year % 4 == 0 && ( year % 100 != 0 || year % 400 == 0 ))
e == 29;
}
return 0;
}
Re:年月日をもとに曜日を求めるプログラム
閏年の求め方が間違っています。
西暦年が4で割り切れて100で割り切れない
または
西暦年が400で割り切れる
とき、閏年です。
今のif文を見直しましょう。
西暦年が4で割り切れて100で割り切れない
または
西暦年が400で割り切れる
とき、閏年です。
今のif文を見直しましょう。
Re:年月日をもとに曜日を求めるプログラム
閏年の求め方は多分あっていると思います。
while(month==2)の内部の意味がよくわからないです。
閏年かつ2月ならeに1を足せばいいので、
static const int Days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
e = Days[month - 1];
//2月で閏年なら1日増やす
if(month==2 && year % 4 == 0 && ( year % 100 != 0 || year % 400 == 0 ))
e++;
こうですかね。
他には
・while(i<=day)の中ではiを加算していますが初期化していません。
・while(i<=e)の中でiもeも変更しないので無限ループになります。またiを初期化してません。
ここではwhileよりforを使うべきだと思います。
あと、
printf(" %d",i);
の%dを%2dに変更してください。こうしないときれいに並びません。
while(month==2)の内部の意味がよくわからないです。
閏年かつ2月ならeに1を足せばいいので、
static const int Days[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
e = Days[month - 1];
//2月で閏年なら1日増やす
if(month==2 && year % 4 == 0 && ( year % 100 != 0 || year % 400 == 0 ))
e++;
こうですかね。
他には
・while(i<=day)の中ではiを加算していますが初期化していません。
・while(i<=e)の中でiもeも変更しないので無限ループになります。またiを初期化してません。
ここではwhileよりforを使うべきだと思います。
あと、
printf(" %d",i);
の%dを%2dに変更してください。こうしないときれいに並びません。
Re:年月日をもとに曜日を求めるプログラム
おかげ様でできました。ありがとうございます。
>ここではwhileよりforを使うべきだと思います。
・while文の限界を感じました。
>ここではwhileよりforを使うべきだと思います。
・while文の限界を感じました。
Re:年月日をもとに曜日を求めるプログラム
> ・while文の限界を感じました。
なぜ?
A;
while (B) {
/* 何かの処理 */
C;
}
と、
for (A; B; C) {
/* 何かの処理 */
}
とは、一部の例外を除いて等価ですよ。
等価である双方を比べて、
whileを使う「べき」とかforを使う「べき」なんてことは言えません。
なぜ?
A;
while (B) {
/* 何かの処理 */
C;
}
と、
for (A; B; C) {
/* 何かの処理 */
}
とは、一部の例外を除いて等価ですよ。
等価である双方を比べて、
whileを使う「べき」とかforを使う「べき」なんてことは言えません。

Re:年月日をもとに曜日を求めるプログラム
閏年の求め方が間違っていると書いたのは正確ではありませんでした。
お詫びいたします。
「間違ってはいないが冗長な部分がある」というのが正確です。
if (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0 ))
というif文は
if ((y % 4 == 0 && y % 100 != 0) || (y % 4 == 0 && y % 400 == 0))
と等価です。ここで、|| 演算子の後ろの部分は
y % 400 == 0
と等価です。4でも400でも割りきれるということは、要するに400で割りきれるってことですからね。
よって、冗長でないif文は
if ((y % 4 == 0 && y % 100 != 0) || (y % 400 == 0))
である、という結論を得ます。
お詫びいたします。
「間違ってはいないが冗長な部分がある」というのが正確です。
if (y % 4 == 0 && (y % 100 != 0 || y % 400 == 0 ))
というif文は
if ((y % 4 == 0 && y % 100 != 0) || (y % 4 == 0 && y % 400 == 0))
と等価です。ここで、|| 演算子の後ろの部分は
y % 400 == 0
と等価です。4でも400でも割りきれるということは、要するに400で割りきれるってことですからね。
よって、冗長でないif文は
if ((y % 4 == 0 && y % 100 != 0) || (y % 400 == 0))
である、という結論を得ます。
Re:年月日をもとに曜日を求めるプログラム
if ( (y % 4 == 0 && y % 100 != 0) || y % 400 == 0 )
これだとyが4の倍数でない場合にも、yが400の倍数かどうかを調べないと
式全体の評価は決まりません。
if ( y % 4 == 0 && (y % 100 != 0 || y % 400 == 0) )
こっちは、yが4の倍数でない場合はそこで評価が終了します。
どちらのケースもyが4の倍数であった場合は100の倍数かどうか調べ、
100の倍数であった場合のみ400の倍数かどうかを調べます。
以上から、下の方法の方が計算効率が良いと言えるのではないでしょうか?
この程度の計算効率の差などあまり気にしなくても良さそうですが。
これだとyが4の倍数でない場合にも、yが400の倍数かどうかを調べないと
式全体の評価は決まりません。
if ( y % 4 == 0 && (y % 100 != 0 || y % 400 == 0) )
こっちは、yが4の倍数でない場合はそこで評価が終了します。
どちらのケースもyが4の倍数であった場合は100の倍数かどうか調べ、
100の倍数であった場合のみ400の倍数かどうかを調べます。
以上から、下の方法の方が計算効率が良いと言えるのではないでしょうか?
この程度の計算効率の差などあまり気にしなくても良さそうですが。
Re:年月日をもとに曜日を求めるプログラム
何億回も閏年の判定をするならごくわずかに実行時間の差が出るかもしれませんが、
先に書いた閏年の定義をもっとも端的に表わすif文は
私が示したものでありましょう。

先に書いた閏年の定義をもっとも端的に表わすif文は
私が示したものでありましょう。

Re:年月日をもとに曜日を求めるプログラム
確かにboxさんが書いた閏年の定義だと
if ( (y % 4 == 0 && y % 100 != 0) || y % 400 == 0 )
の方が分かりやすいですね。
私も閏年の判定とはこのように書くものだと思っていたので、
デミチェリスさんが書いたコードは間違っているのではないかと思いましたが、
よく見ると正しく判定できていていました・・・。
if ( (y % 4 == 0 && y % 100 != 0) || y % 400 == 0 )
の方が分かりやすいですね。
私も閏年の判定とはこのように書くものだと思っていたので、
デミチェリスさんが書いたコードは間違っているのではないかと思いましたが、
よく見ると正しく判定できていていました・・・。