C言語でオリンピック開催年を判定するプログラムの添削

このQ&Aのポイント
  • C言語入門者のためのオリンピック開催年判定プログラムの添削をお願いします。
  • プログラムでは、任意の西暦年を入力して、その年がオリンピックの開催年であるかを判定します。
  • しかし、現在のコードでは、どの数値を入力しても夏季五輪と表示される問題があります。どこが間違っているのでしょうか?
回答を見る
  • ベストアンサー

C言語入門者です。プログラムの添削をお願いします。

 任意の西暦年を入力し、その年がオリンピックの開催年(夏季・冬季問わず)かどうかを判定するプログラムを作ろうと思っています。  #include<stdio.h> int main(void) {     int year, rest;     rest = year % 4;     printf("オリンピック(夏季・冬季問わず)が開催される年(西暦)を一つ答えなさい。");     scanf("%d", year);     if(rest == 0) printf("正解!夏季五輪!");     if(rest == 2) printf("正解!冬季五輪!");     if(!(rest == 0 || rest == 2)) printf("不正解!");     return 0; } 夏季五輪開催年を入力した場合、「正解!夏季五輪!」 冬季五輪開催年を入力した場合、「正解!冬季五輪!」 それ以外の場合、「不正解!」 と画面に表示されるようにしたいのです。    しかし、year にどんな数値を入力しても、「正解!夏季五輪!」としか表示されません。どこが間違っているのでしょうか?添削よろしくお願いします。

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

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

プログラムは、基本的に書いてある順番に実行され、値が変化します。 > rest = year % 4; C言語では、変数を宣言しただけでは、その中にどんな値が入っているかは不明です。 この時点で、変数yearに何も代入していないので、なんだかよくわからない値が入っています。 その「よくわからない値」を4で割った余りが変数restに代入されます。 /* 「デバグモードで実行すると、0でクリアされる」といった、限定された状況で初期化されることはあります */ /* ですが、常に0になることを期待してはいけません */ このように書いたら、「プログラム中のどこでもrest=year %4」で「yearが変化したらrestも変化する」と考えているなら、大きな考え違いです。 あくまでも、この時点でのyearの値から計算されたrestになるだけです。 > printf("オリンピック(夏季・冬季問わず)が開催される年(西暦)を一つ答えなさい。"); > scanf("%d", year); これで、変数yearに入力した値が入りました。 ですが、変数restは、上で計算した「よくわからない値」のままです。 そのため > if(rest == 0) printf("正解!夏季五輪!"); > if(rest == 2) printf("正解!冬季五輪!"); > if(!(rest == 0 || rest == 2)) printf("不正解!"); のrestは「入力した値 % 4」ではなく「よくわからない値 % 4」のままです。 運よく正解になることもありますが、不正解のことも多いでしょう。 前述のように、「0で初期化される」状況ならば、rest=0%4=0となり、「year にどんな数値を入力しても、「正解!夏季五輪!」としか表示されません」というのは「プログラムに書いた通りの『正しい』動作」ということになります。 期待した通りにするなら、処理の順番を考えて、正しい順番に処理するようにしましょう。 添削ということなら > if(rest == 0) printf("正解!夏季五輪!"); > if(rest == 2) printf("正解!冬季五輪!"); > if(!(rest == 0 || rest == 2)) printf("不正解!"); rest==0とrest==2を2回も書いてますよね。こういう「同じことを何度も書く」というのは、間違いの素です。 この構造は、elseを使えば綺麗にまとめられます。ちょっと考えてみましょう。

noiman_tensai
質問者

補足

教えて頂いた通り処理される順番を考えて下記のように修正しましたが、結果はあいかわらず、どんな数値を入力しても「正解!夏季五輪!」としか出ませんでした。(間違いをはっきりさせるために、あえてelseには直さないでおきました。) #include<stdio.h> int main(void) { int year, rest; printf("オリンピック(夏季・冬季問わず)が開催される年(西暦)を一つ答えなさい。"); scanf("%d", year); rest = year % 4; if(rest == 0) printf("正解!夏季五輪!"); if(rest == 2) printf("正解!冬季五輪!"); if(!(rest == 0 || rest == 2)) printf("不正解!"); return 0; } 他にどこが間違っているのでしょうか?

その他の回答 (3)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.4

> 今までint型でも問題なく取り込めていたのですが…。 そのときは scanf("%d", &n ) ; と言った具合に & が付いてなかったですか? 学習を進めていくと必ず「ポインタ」というものが出てくるはずです。 詳細はその項目で。 なお、多くの人がC言語を挫折する理由が「ポインタが理解できない」ことです。 > 僕が使用しているのは純正のCではなくC++で、コンパイラはbcc32 この程度の内容なら、CとC++とで違いはありません。

noiman_tensai
質問者

お礼

ありがとうございます。ウッカリしていました。

  • jjon-com
  • ベストアンサー率61% (1599/2592)
回答No.3

>> %dに対応する引数はint *型です。 > int*型とはどういう型なのでしょうか? int型データを指すアドレス値(ポインタ)ということです。 誤× scanf("%d", year); 正○ scanf("%d", &year);

noiman_tensai
質問者

お礼

あ、忘れてました! 今度こそ上手くいきました。ありがとうございます! こういう単純ミスにも自分で気付けるようになりたいですね。

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.2

失礼。見落していました。 > scanf("%d", year); scanfの使い方を確認してください。 ここで間違えているため、変数yearに値が取り込めていません。 %dに対応する引数はint *型です。yearはint型なので型が不一致です。 この不一致は、C言語の仕様上、エラーにはなりません。コンパイラによっては警告を出してくれることはあります。 警告レベルは高めに設定するのがよいでしょう。 (gccなら -Wall、VisualStudioなら「警告レベル」を3以上に)

noiman_tensai
質問者

お礼

kmee様 色々とご丁寧にありがとうございました。自分では間違いに気付けませんでしたが、他の回答者様のご指摘により解決しました。 こういったケアレスミスにも自分で気付けるようになりたいものです。

noiman_tensai
質問者

補足

> %dに対応する引数はint *型です。yearはint型なので型が不一致です。 今までint型でも問題なく取り込めていたのですが…。 そもそもint*型とはどういう型なのでしょうか?変数設定でintの後ろに*をつければいいのでしょうか? ちなみに(ここまできて今更ですが)、僕が使用しているのは純正のCではなくC++で、コンパイラはbcc32、プログラムはコマンドプロンプトで実行しています。

関連するQ&A

  • 五輪が開催される年の判定

    #include<stdio.h> int main(void){ int year; printf("西暦年を入力してください:"); scanf("%d", &year);      if (year % 4 == 0) printf("夏季五輪\n"); if (year % 2 == 0 && year % 4 != 0) printf("冬季五輪\n"); if (year % 2 != 0) printf("五輪なし\n"); return 0; } この部分は、     if (year % 4 == 0) printf("夏季五輪\n"); if (year % 2 == 0 && year % 4 != 0) printf("冬季五輪\n"); if (year % 2 != 0) printf("五輪なし\n"); なぜこうなるのか説明してください。 五輪が開催されるのは、4年ごとらしいのですが、 レベルの低いかもしれない、質問ですが、どうか解りやすく なぜこうなるのか教えて下さい、よろしくお願いします。

  • 夏季五輪冬季五輪開催と開催しない年の計算

    #include<stdio.h> int main(void) { int year; printf("西暦年を入力して下さい:"); scanf_s("%d", &year); if (year % 4 == 0) printf("夏季五輪\n"); if (year % 2 == 0 && year % 4 != 0)printf("冬季五輪\n"); if (year % 2 != 0) printf("五輪なし\n"); return 0; } まずこれを見ると解る通り、yearに何が入るか解りませんが 適当な西暦の年の数値を入力して2か4で割って余りで計算して0になればいいっていう 例題なんですが、全く意味が解りません。 例えば2018年と入力して冬季五輪と出るのですが、 いったいどういう意味なのかさっぱり解りません。 2018年に冬季五輪がやるという事でしょうか? 適当な数値を入力しているだけだからそんな訳ではないですよね。 if文を使ってやっていたのですが、この例題は何か意味があるのでしょうか?

  • 閏年のプログラム

    C言語(閏年)の質問です。 任意の範囲の年から閏年の表示とその数をカウントして次の実行結果のように表示するプログラムの作成で途中まではわかって修正・追加する箇所があったら一緒に教えてください。(ここでは2つの年をmain関数内で入力し、その範囲の西暦を引数とする関数checkYearを使用するものとする。int型の関数checkYearは、引数に西暦をとり、その西暦が閏年であれば、1を返し、閏年でない場合は0を返す。) なお、閏年の判定方法は以下のとおりである。 条件1 西暦年が4で割り切れる年は閏年である 条件2 条件1を満たしていても、西暦年が100で割り切れるときは閏年でない 条件3 条件2を満たしていても、西暦年が400で割り切れるならば閏年である 実行例1 西暦を入力:2000 西暦を入力:2009 2000年 2004年 2008年 閏年は3回あります。 実行例2 西暦を入力:2100 西暦を入力:2000 2000年 2004年 2008年 2012年 2016年 2020年 (省略) 2096年 閏年は25回あります。 実行例3 西暦を入力:2090 西暦を入力:2110 2092年 2096年 2104年 2108年 閏年は4回あります。 #include <iostream> bool checkYear(int year); int main() { int year; int year2; printf("西暦を入力:"); scanf("%d",year); printf("西暦を入力:"); scanf("%d",year2); int count = 0; for (int i = year; i < year2; i++) { if (checkYear(i)) { printf("%d年\n"); count++; } } printf("閏年は%d回です。\n"); return 0; } bool checkYear(int year) { return (((year % 4) == 0) && ((year % 100) != 0)) || ((year % 400) == 0); }

  • C言語 関数問題

    西暦年yearを引数として受け取り,閏年かどうかの判定結果を戻り値として返す関数leap_year()を作成せよ. ただし,leap_year()は,閏年の場合は1を返し,そうでない場合は0を戻り値として返すものとする. 提出するプログラムは,関数leap_year()だけでなく,メイン関数main()も含む下記プログラムを完成させる形で作成する #include <stdio.h> /* ここに関数leap_year()のプロトタイプ宣言を記述する */ int main() { int i, year[3]; for (i=0; i<3; i++) { printf("西暦年を入力してください"); scanf("%d", &year[i]); if (leap_year(year[i]) == 1) { printf("閏年です.\n"); } else { printf("閏年ではありません.\n"); } } } /* ここに関数leap_year()を定義する */

  • オリンピックが南半球で開催されないわけは?

    オリンピックは2005年12月末までに、夏季冬季合計で戦争中止および特別大会を除くと47回実施されましたが、45回までは北半球で開催されており(日本開催3回を含む)、南半球ではオーストラリアで夏季が2回開催されただけです。 さらに、06年の冬季オリンピック開催地であるトリノはイタリアで、今後予定されているオリンピックも、08年夏季五輪は中国の北京、10年冬季五輪はカナダのバンクーバー、12年夏季五輪はロンドンと、やはり北半球での開催が決定しています。 その国の首都で開催される場合が多いですが、それほど大きいとはいえない都市での開催も冬季を中心にたまに見受けられるだけに、気になります。 その一方で、FIFAワールドカップは南半球開催も少なくはなく、第1回大会は南米のウルグアイでした。 南半球の五輪開催が少ないのには、何か理由があるのでしょうか???

  • C言語について

    こんばんわ。協力お願いします。 2問あります。 1問目です。 西暦年yearを引数として受け取り, 閏年かどうかの判定結果を戻り値として返す関数leap_year()を作成せよ. ただし,leap_year()は,閏年の場合は1を返し, そうでない場合は0を戻り値として返すものとする. 提出するプログラムは,関数leap_year()だけでなく, メイン関数main()も含む下記プログラムを完成させる形で作成する。 #include <stdio.h> /* ここに関数leap_year()のプロトタイプ宣言を記述する */ int main() { int i, year[3]; for (i=0; i<3; i++) { printf("西暦年を入力してください"); scanf("%d", &year[i]); if (leap_year(year[i]) == 1) { printf("閏年です.\n"); } else { printf("閏年ではありません.\n"); } } } /* ここに関数leap_year()を定義する */ 2問目です。 mのn乗を計算する関数power()を作成せよ. ただし,関数power()はm,nを引数とし, 戻り値としてmのn乗の値を返すものとする. m,nは,正整数とする.プログラムには, 関数power()だけでなく,m,nを入力し, mのn乗を出力するメイン関数main()を含むものとする. main()は,power()の前に記述すること. また,power()のプロトタイプ宣言も記述すること。 よろしくお願いします。

  • C言語で分からないところがあるのですが……

    C言語で分からないところがあるのですが…… すみません。C言語を学習していてつまづいたので、皆さんの意見を聞きたいと思います。 現在、カレンダーを表示するプログラムをつくっています。 Yearとmonthをユーザが入力すると、その年その月のカレンダーが出るという算段です。(画像貼っておきます。ソースコードは下) これはできました。 これをいじって、Yearをユーザから受け取ると、その年の1月から12月までのカレンダーがば~っと表示されるようにしろ、と言われました。 Yearとmonthを受け取って書くやつは友人の助けを得ながらなんとかかけましたが、もう無理です。多分、for文を使うんだと思うんですが……助けてください! #include <stdio.h> int dayofweek(int year, int month); int daysinmonth(int year, int month); int daysinyear(int year); void showcal(int dow, int days); int main(void) { int year, month; int dow; int dim; printf ("Year?: "); scanf ("%d", &year); printf ("Month?: "); scanf ("%d", &month); dow = dayofweek(year, month); dim = daysinmonth(year, month); showcal(dow, dim); return 0; } void showcal (int dow, int days) { int i, j, d; printf ("Su Mo Tu We Th Fr Sa\n"); d = 1; for (i = 0; i < dow; i++) { printf (" "); } for (; i < 7; i++) { printf (" %d ", d); d++; } printf("\n"); for (j = 0; d <= days; j++) { for (i = 0; i < 7 && d <= days; i++) { if (d < 10) printf (" %d ", d); else printf ("%d ", d); d++; } printf("\n"); } } int daysinmonth( int year, int month) { int dim; dim = 31; if (month == 4 || month == 6 || month == 9 || month == 11) dim = 30; if (month == 2) { if ( (year % 4 == 0 && year % 100 != 0) || year % 400 == 0) dim = 29; else dim = 28; } return dim; } int daysinyear( int year) { int diy; if ( (year % 4 == 0 && year % 100 != 0) || year % 400 == 0) diy = 366; else diy = 365; return diy; } int dayofweek (int year, int month) { int dow; int days; int y, m; if (year >= 2000) { days = 0; for ( y = 2000; y < year; y++ ) { days = days + daysinyear(y); } for ( m = 1; m < month; m++ ) { days = days + daysinmonth(year, m); } dow = (6 + days) % 7; } else { days = 0; for ( m = month; m <= 12; m++ ) { days = days + daysinmo

  • C言語について

    問題文が表示され、その解答を数字で入力すると正解の場合は「大正解」、不正解の場合は「はずれ」と表示されるプログラムなのですが、?部分がどうしても分りません・・・ 正しいと思えば0、間違ってると思うなら1と入力するプログラムです。 どなたかご教授いただけるとありがたいです>< main() { int i,k; i=0; while(i<5){ printf("次の文章が正しければ0、間違っていれば1を入力してください。\n"); printf("%s",q[i]); scanf("%d",&k); if(a[?]==?) {printf("大正解\n");} else {printf("はずれ\n");} i????; } printf("おしまい\n"); }

  • C言語プログラム

    2つの整数を入力させ、それらが等しい場合hitoshii、異なる場合にはhitoshikunaiと出力するプログラムを作りたいのですが、うまくいきません。間違っているところを教えてください。 #include<stdio.h> #include<conio.h> void main() { printf("整数を入力してください:"); int number1; scanf("%d",number1); printf("整数を入力してください:"); int number2; scanf("%d",number2); if(number1==number2) { printf("hitoshii"); } else { printf("hitoshikunai"); } getch(); }

  • C言語 関数について

    協力お願いします。 2問あります。 1問目です。 西暦年yearを引数として受け取り, 閏年かどうかの判定結果を戻り値として返す関数leap_year()を作成せよ. ただし,leap_year()は,閏年の場合は1を返し, そうでない場合は0を戻り値として返すものとする. 提出するプログラムは,関数leap_year()だけでなく, メイン関数main()も含む下記プログラムを完成させる形で作成する。 #include <stdio.h> /* ここに関数leap_year()のプロトタイプ宣言を記述する */ int main() { int i, year[3]; for (i=0; i<3; i++) { printf("西暦年を入力してください"); scanf("%d", &year[i]); if (leap_year(year[i]) == 1) { printf("閏年です.\n"); } else { printf("閏年ではありません.\n"); } } } /* ここに関数leap_year()を定義する */ 2問目です。 mのn乗を計算する関数power()を作成せよ. ただし,関数power()はm,nを引数とし, 戻り値としてmのn乗の値を返すものとする. m,nは,正整数とする.プログラムには, 関数power()だけでなく,m,nを入力し, mのn乗を出力するメイン関数main()を含むものとする. main()は,power()の前に記述すること. また,power()のプロトタイプ宣言も記述すること。 よろしくお願いします。

専門家に質問してみよう