みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

エラー C言語 プログラミングについて

#include<stdio.h>
int leapYear(int);

int main(void){

int year,i;

for(i=2001;i=2999;i++){

year=i;
printf("%d leap = %d \n",i,leapYear(int year));

return 0;
}
}

int leapYear(int year){

if(year%100==0){
return 0;
}
else if(year%400==0){
return 1;
}
else if(year%4==0 && year%100!=0){
return 1;
}
}

をコンパイルすると11行目に式の構文エラーが出るんですが
どうしてでしょうか??
間違ってない気がするんですけど。。

投稿日時 - 2009-05-22 14:56:57

QNo.4980637

すぐに回答ほしいです

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(7)

ANo.7

2400年と2800年の判定もおかしいですよ。

判定してるプログラムを日本語で書いて、
そのネスト構造をインデントして表記すると以下の通りです。

--- start
100で割りきれる // a
 閏年でない // 1
そうでない
 400で割り切れる // b
  閏年である // 2
 そうでない
  4で割り切れてかつ、100で割れない // c
   閏年である // 3
  そうでない
   閏年でない // 4
--- end

まず、400で割り切れる数は必ず100で割り切れます。
たとえば、2400年は閏年のはずですが、aの判定で1に行ってしまうので、閏年になりません。
ここが一つ目の問題ですが、もう一つ問題があります。
aの判定により、100で割り切れる数はcの判定に到達しません。
しかし、どういうわけか100で割り切れないという条件があります。

実は最初のaの判定がいらないのです。

if(year%400==0){
return 1;
}
else if(year%4==0 && year%100!=0){
return 1;
}
else return 0;

どうにもelse ifの動作を正しく理解していないのではないでしょうか。

else if文と通称されるこの書き方ですが、実はCにそんなものはありません。単にif文が再帰的に記述されているだけです。
よくswitchとの関連が説明されますが、両者には大きな違いがあります。

else ifは先頭から順に判定していき、真になったらそのブロックを実行します。そして、残りのブロックは実行されません。
つまり、一番最初に真になったifのブロックのみ実行されます。
このため、順序を入れ替えると動作が変わります。

一方、switch文はcaseに書く整数値は必ずユニークの必要があります。真になるcaseは常に一つです。結果、breakを省略しない限り、順序を入れ替えても動作は同じです。

なお、このプログラムは
return year % 400 == 0 || (year % 4 == 0 && year % 100 != 0);
と書けます。

投稿日時 - 2009-05-23 11:05:24

お礼

iが1になってたのと関数内のelse if文がおかしかったから上手く行かなかったんですね><
else ifは順番に動作していくから先に判定が真になったものから処理を行うということで、2400のときも先に0を返して終了していたということですね。。
最後の条件をまとめられるのも参考になりました。
詳しく教えてくださってありがとうございました^^

投稿日時 - 2009-05-23 18:01:58

ANo.6

>int year,i=1;
i=0; なのでは?

それと、
2400年と2800年が閏年になっていません。

投稿日時 - 2009-05-23 10:57:47

補足

上の方とは別の方とは気づかず、一緒にお礼行っちゃいました><
i=1は凡ミスでほんとに反省っすね。。
どうもありがとうございました!
閏年の件も解決できました^^

投稿日時 - 2009-05-23 18:02:48

ANo.5

相変わらず leapYear がおかしいです. 2000年は閏年ですが, この関数で「閏年」と判定できますか?
あと, 気付かなかったんだけど main で for ループの中に return を入れたらだめ.

投稿日時 - 2009-05-22 17:54:14

補足

でも2001~2999までを判定したいんで2000は除いてて良いんですよね。。
あとreturnの位置がおかしかったので変更しました。
ありがとうございます!
だいぶ上手く行ってもう一歩てとこなんですが、現在のソースは

#include<stdio.h>
int leapYear(int);

int main(void){

int year,i=1;

for(year=2001;year<=2999;year++){

printf("%d leap = %d \n",year,leapYear(year));

if(leapYear(year)==1){

i++;
}
printf("%d 回です\n",i);
}
return 0;

}

int leapYear(int year){

if(year%100==0){
return 0;
}
else if(year%400==0){
return 1;
}
else if(year%4==0 && year%100!=0){
return 1;
}
else return 0;
}
こんな感じでなんですが、結果が「242回です」になるはずなのに241になるんです。。
なんでかわかりますかね??><

投稿日時 - 2009-05-23 02:15:41

ANo.4

#2です。もうひとつ関数の呼び出しがこれでは異常です、独立させましょう。
year = leapyear(i);

printf("%d leap = %d\n", i, year);

どうしてyearにiを代入しているのかわかりません。

投稿日時 - 2009-05-22 16:18:12

補足

あーもうダメダメですいません><

下記の方でも教えてくださってありがとうございます!!

投稿日時 - 2009-05-22 16:53:51

ANo.3

forループの書き方間違えてますね、

for(i=2000; i<=2999; i++) {

が正しいです。i=2000; i=2999;ではiのループ条件ができていません。

投稿日時 - 2009-05-22 16:11:25

補足

#include<stdio.h>
int leapYear(int);

int main(void){

int year;

for(year=2001;year<=2999;year++){

printf("%d leap = %d \n",year,leapYear(year));

return 0;
}
}

int leapYear(int year){

if(year%100==0){
return 0;
}
else if(year%400==0){
return 1;
}
else if(year%4==0 && year%100!=0){
return 1;
}
}

新しくプログラミングしたんですけど、これでも動かないのはなんででしょうか??。

投稿日時 - 2009-05-22 17:01:01

ANo.2

for もおかしいけどね.
ああ, leapYear もおかしい.

投稿日時 - 2009-05-22 15:03:57

補足

指摘ありがとうございました(>_<)
いやーダメダメだぁ。。

投稿日時 - 2009-05-22 16:55:47

ANo.1

> printf("%d leap = %d \n",i,leapYear(int year));
printf("%d leap = %d \n",i,leapYear(year));
intが余計なのでは。

投稿日時 - 2009-05-22 15:00:37

あなたにオススメの質問