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

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

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

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

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

4回答

5094閲覧

【C言語の質問です】西暦年を引数とし、閏年かどうか判定する関数について

退会済みユーザー

退会済みユーザー

総合スコア0

C

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

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

0グッド

1クリップ

投稿2016/02/26 06:53

編集2016/02/26 07:21

*たくさんの方よりご指摘をいただけてとてもありたいです。
引き続き、よろしくお願い致します。

C言語を勉強している初心者のものです。

今課題をいただき、その作成をしております。
先日提出(全18問)したのですが、大部分が間違っているので、
再度問題を見なおした上で提出してくれと言われてしまいました。

今回は課題なので、間違っている点を教えていただけませんでした。
個人的には、どの辺りが間違っているのかわからないため、
客観的な視点が欲しく、今回ご相談させていただきました。

18問の中の1つですが、
ソースが問題文との趣旨と外れているようでしたら
ご指摘いただけますと幸いです。

【問題】
西暦年を引数とし、閏年かどうか判定する関数を作成せよ。

【閏年の条件】
・年が400の倍数なら閏年である
・年が400の倍数でない、100の倍数でなければ閏年ではない
・年が100の倍数でない、4の倍数であれば閏年である
・年が4の倍数でなければ閏年ではない

【回答】

#include <stdio.h> int uruu(int year); int main(void) { int year,hold; printf("西暦を入力してください\n"); scanf("%d",&year); hold = uruu(year); switch (hold) { case 0: printf("閏年ではありません。\n"); break; case 1: printf("閏年です。\n"); break; case 2: printf("数値がマイナスです。再度入力しなおしてください。\n"); break; }; return 0; } int uruu(int year) { if(year <= 0) { return 2; } if (year % 400 == 0) { return 1; } if (year % 4 == 0) { return 1; } if (year % 100 != 0) { return 0; } if (year % 4 != 0) { return 0; } return 0; }

皆様いつもご回答ありがとうございます。

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

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

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

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

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

WoodenHamlet

2016/02/26 07:39

そもそも西暦元年の扱い(西暦0年を許すか)、紀元前の入力を許すか、の問題がありますね。
退会済みユーザー

退会済みユーザー

2016/02/26 07:44

ご回答ありがとうございます。 今、0年と打つと、 >printf("数値がマイナスです。再度入力しなおしてください。\n"); こちらの回答が返ってくるようになってはいます・・ 紀元前400年などは、条件面に沿っていれば閏年と出ますが、 ここの判断は難しいですね。。。 入力を許さない場合は、do-whileを使う形でしょうか。
WoodenHamlet

2016/02/26 07:46

ん?紀元前だとたとえば-400が入力になるからエラーでないの?
退会済みユーザー

退会済みユーザー

2016/02/26 07:58

すいません、間違えました。。。 マイナス入力は >数値がマイナスです。再度入力しなおしてください。\n"); このように再度入力をお願いする形してしています。
WoodenHamlet

2016/02/26 08:08

まあ紀元前をエラーとするなら今のままでいいと思うけど、入力していいなら紀元年は存在しない(数直線上の0がなくて―1の次が1になってるよね、年表じゃ)のを留意する必要があるね
退会済みユーザー

退会済みユーザー

2016/02/26 08:11

なるほど。。。 たしかにそのとおりですね! ちょっと考えてみます! ありがとうございました!!
guest

回答4

0

enum は習われましたか?関数の返り値が数通りで、その返り値で分岐を行う場合、enum を用いると可読性が上がります

C

1#include <stdio.h> 2 3typedef enum {NOT_URUU, IS_URUU, ERROR_URUU} urRet; 4urRet uruu(int year); 5 6int main(void) 7{ 8 int year; 9 10 printf("西暦を入力してください\n"); 11 scanf("%d",&year); 12 13 switch (uruu(year)) 14 { 15 case NOT_URUU: 16 printf("閏年ではありません。\n"); 17 break; 18 case IS_URUU: 19 printf("閏年です。\n"); 20 break; 21 case ERROR_URUU: 22 printf("数値がマイナスです。再度入力しなおしてください。\n"); 23 break; 24 default: // たとえ絶対に入らないような場合でも default はつけましょう 25 break; 26 }; 27 28 return 0; 29} 30 31urRet uruu(int year) 32{ 33 if(year <= 0) 34 { 35 return ERROR_URUU; 36 } 37 38 if ( (year % 400 == 0) 39 ||(year % 4 == 0 && year % 100 != 0) ) 40 { 41 return IS_URUU; 42 } else { 43 return NOT_URUU; 44 } 45}

投稿2016/02/26 07:32

WoodenHamlet

総合スコア306

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

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

退会済みユーザー

退会済みユーザー

2016/02/26 07:54

ご回答ありがとうございます。 すいません、まだenumは習っておりませんが、 記載頂いた文書を元に勉強してみたいと思います。 ありがとうございました!!
guest

0

こんにちは。

問題文自体がなんか変です。

・年が400の倍数なら閏年である

・年が400の倍数でない、100の倍数でもなければ閏年ではない
・年が100の倍数でない、4の倍数であれば閏年である
・年が4の倍数でなければ閏年ではない

400の倍数でない100の倍数の時を定義してないですね。

誤> ・年が400の倍数でない、100の倍数でもなければ閏年ではない
正> ・年が400の倍数でない、100の倍数であれば閏年ではない

ですね?

次にもう少し厳密に表現すると下記と思います。

・年が400の倍数なら、閏年である

・年が400の倍数でない、かつ、100の倍数であれば、閏年ではない
・年が100の倍数でない、かつ、4の倍数であれば、閏年である
・年が4の倍数でなければ、閏年ではない

この通りに条件判断を作ってみてはどうでしょうか?

そして、試しに-1年くらいから3000年くらいまでfor文で回して、上記のどの条件にも当てはまらないケースがあるのかないのか見てみる必要があるかも。なんか抜けてそうな気がしません?
もし、抜けてこなかったら、必要のない条件判断をしていることになります。それはどれでしょうか?
そして、更に何か不要な条件判断をしているかも知れません。

投稿2016/02/26 07:19

編集2016/02/26 07:21
Chironian

総合スコア23272

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

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

退会済みユーザー

退会済みユーザー

2016/02/26 07:40

ご回答ありがとうございます。 すいません、修正させていただいたのですが、 私に記載に一部誤りがありました。 誤> ・年が400の倍数でない、100の倍数でもなければ閏年ではない 正> ・年が400の倍数でない、100の倍数でなければ閏年ではない とはいえ、 >正> ・年が400の倍数でない、100の倍数であれば閏年ではない こちらの認識にて間違いないです。 ご指摘ありがとうございました。 早速そちらの条件面にて作ってみます。 そして、試しに-1年くらいから3000年くらいまでfor文で回して、上記のどの条件にも当てはまらないケースがあるのかないのか見てみる必要があるかも。なんか抜けてそうな気がしません? もし、抜けてこなかったら、必要のない条件判断をしていることになります。それはどれでしょうか? そして、更に何か不要な条件判断をしているかも知れません。 上記もありがとうございます。 一旦for文を作ってみたいと思いますが、 for文を作ってエラーがなければ問題ないという認識でよろしかったでしょうか。
Chironian

2016/02/26 07:58

プログラムの動作としては問題ないと思います。 プログラムの作りとしては、あまり褒められたプログラムにはなってないと思います。 バグの多くは条件判断で発生します。つまり、無用な条件判断が残っているとバグの元ですし、仕様変更する際、バグを避けるため無駄に苦労しますので。
退会済みユーザー

退会済みユーザー

2016/02/26 08:50

なるほど! 条件判断は難しいですね・・・ 文章を整理してからプログラミングしていきたいと思います。 いつもありがとうございます!
guest

0

ベストアンサー

400で割りきれない、かつ100で割り切れるのはうるう年ではなくなるので、判定順序はこんな感じ。

C言語

1if ( year <= 0 ) { return 2; } 2if ( year % 400 == 0 ) { return 1; } 3if ( year % 100 == 0 ) { return 0; } 4if ( year % 4 == 0 ) { return 1; } 5return 0;

投稿2016/02/26 07:00

tkturbo

総合スコア5572

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

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

0

このままだと、1900年のような「100で割り切れるけど400で割り切れない年」を誤判定してしまいます。「400で割り切れるかチェック」→「100で割り切れるかチェック」→「4で割り切れるかチェック」という順番にする必要があります。

投稿2016/02/26 06:56

maisumakun

総合スコア145184

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

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

退会済みユーザー

退会済みユーザー

2016/02/26 07:17

ご回答ありがとうございます。 すいません、私の認識が間違っていたらぜひ教えていただきたいのですが、 条件の2つ目なのですが、400で割り切れなかった数値でも 100で割り切れれば閏年になりますでしょうか。 100の倍数でなければ閏年ではないでしたので、 100の倍数であれば閏年なのかと思いました。 いかがでしょうか。
退会済みユーザー

退会済みユーザー

2016/02/26 07:26

すいませんでした、私の認識が間違っていたようです。。 400で割り切れなくても100で割り切れたらそれは閏年でないということですね。 ご指摘どおりでした! ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問