• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:c言語のプログラミングでこまってます)

C言語のプログラミングで月齢と月相を計算する方法

このQ&Aのポイント
  • C言語で月齢と月相を計算するプログラムを作成しましたが、月相が表示されません。
  • for文が正しく動作せず、suuumが0から3.75の範囲でしか反応しません。
  • 月齢の計算には正しい方法を使用し、月齢に基づいて月相を表示するためのfor文を修正したいです。

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

  • ベストアンサー
回答No.4

とりあえず、 i<=suuum &&suuum<i+3.75 と (i<=suuum) &&(suuum<i+3.75) はちゃんと同じ意味になります。 Cのトークン解析は、意味が通じる「最も長い」文字を切り取りますから、スペースがないからと言って、 i<=suuum &&suuum<i+3.75 を i<=suuum & &suuum<i+3.75 と解釈したりはしません。 と、それだけでは何なので、問題についても含めて、周辺を少々。 > •日付チェック以外でも、if文やswitch-case文の数はなるべく少なくするよう工夫せよ。今回は、if文の7行並列も、12行並列も禁止。 とわざわざ指定するなら、月齢の計算も、 int offset[] = {1, 2, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0}; sum = (2011-1740)*210; suuum = sum/19 + month + day + offset[month - 1] - 2; か、最後の -2 も offset に取り込むなら、 int offset[] = {-1, 0, -3, -2, -3, -2, -2, -2, -2, -2, -2, -2}; sum = (2011-1740)*210; suuum = sum/19 + month + day + offset[month - 1]; あと、ひとつ計算をするたびに、sum suum suuum なんていう変数を使うのも、間違いの元なので、お断りしたいところ。 こんな変数を使わなくても、 int offset[] = {-1, 0, -3, -2, -3, -2, -2, -2, -2, -2, -2, -2}; getsurei = (2011-1740)*210; getsurei = getsurei/19 + month + day + offset[month - 1]; で十分だし、 offset[month - 1] がいやなら、(daynum とおなじようにして) int offset[] = {0, -1, 0, -3, -2, -3, -2, -2, -2, -2, -2, -2, -2}; getsurei = (2011-1740)*210; getsurei = getsurei/19 + month + day + offset[month]; でも。 あと、もうひとつ大きな間違いは、この時点で、30に正規化していない点。 それを含めれば、最後に、 getsurei %= 30; が必要です。 質問のソースの中で、これも引っかかってますね。 月齢の表示は、suuum % 30 を表示しているので、それらしい数字が表示できてきますが、月相の判定は、suuum をそのまま使ってしまっているから、ここでも、正解から遠ざかっています。 あと、入力された日付の判定で、「有効な月か」の判定がないですし(問題の指定にもないけど) マイナスの日付に対するチェックもないですね。 複数のチェックをする場合には、関数を使って int dayIsOK(int month, int day) { if (month <= 0) return 0; if (month > 12) return 0; if (day <= 0) return 0; if (day > daynum[month]) return 0; return 1; } として、main() で、 if (! dayIsOK(month, day) { printf("2011年にそんな日はありません"); return(-1); } などとすれば、チェックの条件が複雑になっても見かけを単純にすることができます。

その他の回答 (3)

  • ysawave
  • ベストアンサー率50% (2/4)
回答No.3

for文の 「 i<=suuum &&suuum<i+3.75 ; 」 ですが、実際のソースもこのままの状態ですか? きちんと空白を挟むか、試しに「 (i<=suuum) &&(suuum<i+3.75) ; 」 としてみてはどうでしょうか? (&& と & の優先順のような気がします...) あと、「 printf("月相は",moonphasename[j][15]); 」 ですが、 「 printf("月相は",moonphasename[j]); 」 なのでは?

参考URL:
http://www.bohyoh.com/CandCPP/C/operator.html
回答No.2

> 月相が表示されません(月相は という文字も非表示) と > 最後のfor文ではsuuumが0から3.75のときしか反応しません というのは、矛盾するような気がしますがどうなのでしょう? 「最後の for で、suuum が、0 から 3.75のときには『反応する』」 というのは、どういう状況なのかなと。 ソースを見ると、suuum が、0以上 3.75未満の時には、「月相は」だけ表示。 それ以外の時には、何も表示されないというのだとは思いますが。 まず、月齢計算は、int で良いのじゃないかなと思います。 簡易的な月齢の計算式で、あえて、切り捨てをしている気がしますが。 それ以前に、いろいろな問題があります。 printf("月相は",moonphasename[j][15]); これでは、(表示されたとしても)「月相は」しか表示されません。 文字(列)の表示方法を復習しましょう。 (少なくとも、2つ間違いがあります) あと、たとえば、suuum が、20 の時に、 for(i=0; i<=suuum &&suuum<i+3.75 ; i=i+3.75) { printf("月相は",moonphasename[j][15]); j++ ; } が、どういう風に実行されるのか、ひとつずつ確かめましょう。 (i が int なのは問題ですが、それ以外にも大きな間違いをしています) 前にやった似たような(と思う)課題から、ひっぱってくるのではなく、 どう動くはずなのか、suuum が、0のとき、10のとき、20のとき、くらいは 手作業で確認しましょう。

  • u-bot
  • ベストアンサー率58% (1736/2988)
回答No.1

アルゴリズムが合っているのならsuum変数の宣言の問題かと思います。 suumは整数でないからfloat宣言して  float suum;  float f;  suum=((sum/19.)-2.)+(float)month+(float)day;    :  if(month==1)  suuum=suum+1.;    :  for(f=0; f<=suuum && suuum<f+3.75 ; f=f+3.75){ のようにキャストした変数を代入して、整数値の後ろは念のためドットをつけたらどうでしょう? もしくはsuumが小数点2桁まで有効にしたいのであれば1000倍して整数のまま計算するとか  suum=((sum*1000/19)-2*1000)+(month+day)*1000;    :  if(month==1)  suuum=suum+1000;    :  for(i=0; i<=suuum &&suuum<i+3750 ; i=i+3750){ この場合は問題無いと思いますが、suumがオーバーフローしないように注意して下さい。 ------------ ともかく小数を扱うならfloatかdouble変数を利用して しないのなら整数の範囲で扱えるように値を常数倍しましょう。