2つの整数(月、日)を入力すると、2007年度があと残り何日かを計算するプログラムが書きたいのですが、できるだけif文(またはswitch文)を少なくして書きたいのですが、12こif文を使うと書けるものの、それ以下に絞ることができません。
2007年度(2007年4月1日~2008年3月31日)のみに適応できればいいので、日付をコンピュータから取得せず、入力された値だけに反応するものを書きたいです。
if文、switch文、printf文、scanf文のみで仕上げるというのが課題なのですが、他の文をつかえばできるとは思うのですが、上記のものだけで作るとなると、難しいです…、どなたか、教えていただけないでしょうか。
No.2ベストアンサー
- 回答日時:
★アドバイス
・if、switch を減らしたいのなら配列のテーブルで残りの日数を用意します。
あとは配列の添え字に『月』を指定すればそのまま残りの日数を得ることが出来ます。
>if文、switch文、printf文、scanf文のみで仕上げるというのが課題なのですが、
>他の文をつかえばできるとは思うのですが、上記のものだけで作るとなると、
>難しいです…、どなたか、教えていただけないでしょうか。
↑
まずは if、switch、printf、scanf で出来ているソースを貼り付けてみて下さい。
ちなみに配列データは次のようにすれば良いです。
static const int table1[] = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
static const int table2[] = {
0,
31 + 29, ←2008年1月
31, ←2008年2月
0, ←2008年3月
31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31, ←2007年4月
31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 30,
31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 31,
31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,
31 + 29 + 31 + 30 + 31 + 30 + 30,
31 + 29 + 31 + 30 + 31 + 31,
31 + 29 + 31 + 30 + 30,
31 + 29 + 31 + 31,
31 + 29 + 31, ←2007年12月
};
テーブルの内容は
>2007年度(2007年4月1日~2008年3月31日)
↑
これに合わせています。
このテーブルの table2[ month ] とすることで残りの日数が簡単に求まります。
この値に入力された day の残りに数を加えれば良いです。
つまり ans = table2[month] + (table1[month] - day); とします。
・このような方法なら if、switch は使いません。
特に2007年度限定ならば。
入力部分と入力値の補正処理はご自分で行って下さい。
ちなみに今日は2007年10月24日なので
table2[10] + (table1[10] - 24);
とすると
151 + (31 - 24)
となって 158 が残り日数となります。
・table1 は各月の日数です。
table2 が 2007 年度(2008/3/31)までの残り日数を記述しています。
極端に if、switch 文を減らそうとするとこのようになります。
普通は西暦1年1月1日(1970/1/1でも良いけど)からの累計数を求めてその数を
引き算するようにします。そうすれば 2007 年度以外にも対応できます。
・以上。テーブルの作り方などを参考にして下さい。
この回答への補足
#include <stdio.h>
int main(void)
{
int month, day, nokori;
printf("Input date : ");
fflush(stdout);
scanf("%d %d", &month, &day);
if( month == 4 && day>=1 && day <=30){
nokori = 11 * 30 + 6 + (30 - day);
}
else if( month == 5 && day >= 1 && day<= 31){
nokori = 10 * 30 + 5 + (31- day);
}
else if( month == 6 && day >= 1 && day<= 30){
nokori = 9 * 30 + 5 + (30- day);
}
else if( month == 7 && day >= 1 && day<= 31){
nokori = 8 * 30 + 4 + (31- day);
}
else if( month == 8 && day >= 1 && day<= 31){
nokori = 7 * 30 + 3 + (31- day);
}
else if( month == 9 && day >= 1 && day<= 30){
nokori = 6 * 30 + 3 + (30- day);
}
else if( month == 10 && day >= 1 && day<= 31){
nokori = 5 * 30 + 2 + (31- day);
}
else if( month == 11 && day >= 1 && day<= 30){
nokori = 4 * 30 + 2 + (30- day);
}
else if( month == 12 && day >= 1 && day<= 31){
nokori = 3 * 30 + 1 + (31- day);
}
else if( month == 1 && day >= 1 && day<= 31){
nokori = 2 * 30 + (31- day);
}
else if( month == 2 && day >= 1 && day<=29){
nokori = 31+ ( 29- day);
}
else if( month == 3 && day >= 1 && day<= 31){
nokori = 31- day;
}
else{
printf("this month or day is not correct");
return (-1);
}
printf("nokori is %d \n", nokori);
return (0);
}
と、私が作ったものはこのような感じに、if文がならんでいます…
入力された値が正しいかどうかのif文はのこしておいて、正しければテーブルを使用した計算をする、というような構成でいいのでしょうか。
No.6
- 回答日時:
>具体的にどういった風に使用すればよいかわからなかったので
3/31だと1(=Month3[31-1])を返せばいいですよね。
if( monthNo == 3 ){
return( Month3[dayNo-1] );
}
No.4
- 回答日時:
★アドバイス
>入力された値が正しいかどうかのif文はのこしておいて、
>正しければテーブルを使用した計算をする、
>というような構成でいいのでしょうか。
↑
そうです。
入力した『年』『月』『日』のチェックをした後にテーブル参照で求めれば良いです。
ただし、日付のチェックはちょっと面倒です。
理由は 28、29、30、31 と4パターンあるからです。
でも前回紹介した table1 を使えば簡単にチェックできます。
つまり
if ( (day >= 1) && (day <= table1[month]) ){
// day入力値は有効
}
else{
// day入力値は無効
}
とすれば良いです。
なお先に month の有効性をチェックしておいて下さい。
・以上。
No.3
- 回答日時:
(3/31で1日と答えると仮定しています)
それが美しいかどかは別として...
if,switchの数を減らせばいいのなら、2変数だからswitch文2個
入れ子にすれば足ります。
数字はプログラムでなくあなたが先に計算しておくこともできます。
switch( monthNo ){
case 1://1月
switch( dayNo ){
case 1://1日
return(91);//1月1日->91日
case 2:
return(90);
...
}
break;
case 2:
...
}
入力値から日数を計算すれば、計算式は使いますがif,switchなどは
全く使わずに作れますよね。
const int Month3[31] = {31,30,29,...2,1};
const int Month2[29] = {60,59,58,...33,32};
と答えのテーブルを作っておくのも一案です。
リソースとしてメモリはあるけど時間は使いたくない時に、
複雑なif文を回避するためにこういうテーブルを使うこと
もありますよ。
この回答への補足
回答ありがとうございます。
const int Month3[31] = {31,30,29,...2,1};
const int Month2[29] = {60,59,58,...33,32};
というテーブルを具体的にどういった風に使用すればよいかわからなかったので、詳しく教えていただけませんか?
なにぶん、授業で2~3時間レクチャーを受けただけで、知識といえば、型があること、if文、switch文、printf文、scanf文くらいまでしか教わっていないので…。
そして補足欄が一度書いてしまうと訂正できませんでしたので、ここからはAno2のOh-Orangeさんへのお返事になります。申し訳ありません、機能を把握していなくて・・・。
Oh-Orangeさんのご回答を参考にしてテーブルを使ってみたのですが...
#include <stdio.h>
int main(void)
{
int month, day, nokori;
static const int table1[] = { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
static const int table2[] = {
0,
31 + 29,
31,
0,
31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 31,
31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 30,
31 + 29 + 31 + 30 + 31 + 30 + 31 + 31 + 31,
31 + 29 + 31 + 30 + 31 + 30 + 31 + 31,
31 + 29 + 31 + 30 + 31 + 30 + 30,
31 + 29 + 31 + 30 + 31 + 31,
31 + 29 + 31 + 30 + 30,
31 + 29 + 31 + 31,
31 + 29 + 31,
};
printf("Input date : ");
fflush(stdout);
scanf("%d %d", &month, &day);
if( month < 1 || month > 12 || day < 1 || day > 31){
printf("this month or day is not correct");
return (-1);
}
else{
nokori = table2[month] + (table1[month] - day);
}
printf("nokori is %d \n", nokori);
return (0);
}
とすると、2 30 (2月30日)など存在しない日を入力しても答えを計算してしまいます。(その場合、3月1日と入力したのと同じ回答が得られます)
一応、最初のif文で、1未満や12より大きい月、1未満や31より大きい日などははじくようにしてあるのですが…。
あと3つくらいif文を追加すれば判別できるのでしょうけど…
条件文のところに、29日の月、30日の月、31日の月であれば計算する…というような条件を書いて。
うまくまとめる方法はないでしょうか…。
No.1
- 回答日時:
#include <stdio.h>
int main(void)
{
int m[12] = {30, 31, 30, 31, 31, 30, 31, 30, 31, 31, 28, 31};
int month, day, sum, i;
scanf("%d %d", &month, &day);
if(month < 1 || 12 < month) return 1;
month = (month + 8) % 12;
if(day < 1 || m[month] < day) return 1;
sum = m[month] - day;
switch(month + 1){
case 1: sum += m[1];
case 2: sum += m[2];
case 3: sum += m[3];
case 4: sum += m[4];
case 5: sum += m[5];
case 6: sum += m[6];
case 7: sum += m[7];
case 8: sum += m[8];
case 9: sum += m[9];
case 10: sum +=m[10];
case 11: sum +=m[11];
default : ;
}
printf("%d\n", sum);
return 0;
}
ご回答本当にありがとうございます。
私の言い方が悪かったのですが、スイッチ文を少なくするというのはスイッチ文の中のケースも少なくする、という意味なので、いただいた回答とは少しずれがありました。せっかくご回答頂いたのに申し訳ないです。
でも私のソースよりもすっきりしていて見やすくって、とても参考になりました。今後プログラムを書くのに参考にさせていただきます。
ありがとうございました。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# 至急教えてください。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分 1 2022/07/19 17:03
- C言語・C++・C# 至急教えてください。プログラミングの問題です。 malloc関数を使ってください!お願いします! 最 1 2022/07/21 09:28
- その他(住宅・住まい) 築15年マンションで発生した玄関扉の不具合を販売主へ契約不適合責任を請求できますか? 3 2023/02/28 10:47
- Visual Basic(VBA) 3つのプロシージャをまとめたら実行時エラー発生で対応不能 6 2022/05/17 01:47
- Excel(エクセル) VBA EOMonthについて 5 2023/02/10 11:51
- C言語・C++・C# C言語のエラーについて 2 2022/07/11 13:56
- 大学受験 娘の大学受験勉強 6 2022/06/30 19:58
- C言語・C++・C# C言語階乗の総和を求める 2 2023/03/04 23:31
- 雇用保険 育児給付金について 1 2022/08/12 10:51
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
構文エラー";"が型の前にあり...
-
c言語プログラミングで1から100...
-
for文の中にswitch文はいれられ...
-
配列を関数に渡す方法
-
c言語for文
-
scanfが実行されません
-
C言語プログラムが理解できなくて…
-
C言語階乗の総和を求める
-
C言語の二分法のプログラムにつ...
-
#if 1 #elseの意味について
-
C言語 数字以外を入力させない...
-
階乗のプログラム!!
-
C言語 マスターマインドゲーム...
-
c言語で平均をだす
-
プログラム 不等式
-
c言語のwhile文を使った計算で...
-
C言語です
-
入力した数値を0~3乗するプロ...
-
C言語でのソースファイル
-
Cプログラムの条件文 if,els...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
構文エラー";"が型の前にあり...
-
#if 1 #elseの意味について
-
for文の中にswitch文はいれられ...
-
C言語階乗の総和を求める
-
配列を使って魔方陣
-
C言語 数字以外を入力させない...
-
C言語プログラムが理解できなくて…
-
配列を関数に渡す方法
-
初心者です。for文、if文を使っ...
-
scanf関数を用いての加減乗除%...
-
c言語プログラミングで1から100...
-
getcの改行判定
-
while文について、c言語...
-
プログラミングで二番目に大き...
-
VHDLで、case文とwhen文のどち...
-
C言語で電卓を作成する。
-
C言語の二分法のプログラムにつ...
-
階乗のプログラム!!
-
プログラミングに関して
-
C言語についてですfor ifをつか...
おすすめ情報