• ベストアンサー

簡素で美しく記述するには・・・・

今与えられた開始日から与えられた終了日までの期間を求めるプログラムを作りました。勿論その中で閏年の計算も行います。 自分の作ったプログラムでは1つだけ気に入らないところがありました。それは閏年の計算部分です。 ■うるう年の判定 ・年が4で割り切れる時はうるう年  従って、2004年はうるう年である ・ただし、100で割り切れる時はうるう年でない  従って、1900年はうるう年ではない ・ただし、400で割り切れる時はうるう年である。  従って、2000年はうるう年である この条件を行うため自分は次のように記述しました for(year = First_Year; year <= End_Year; year++){   if(((year  % 4) == 0) && ((((year % 100) != 0) && ((year % 400) != 0)) || (((year % 100) == 0) && ((year % 400) == 0)))){     閏年の個数を数える    } } for文変数の初期でFirst_Yearを与えていますが、First_Yearが開始年でEnd_Yearが終了年です。 if文がむかつくほど長くなってしまいました。やっていることはyearが4で割り切れかつ100と400で割ったときに両方共に余りが出る、またはyearが4で割り切れかつ100と400で割ったときに両方共に余りが出ない場合に 閏年の個数を数える ようにしています。 かなり強引な質問ではありますが、みなさんならどのように組むでしょうか? 別に自分の考える”美しい”プログラムでなくてもかまいません。色々な考えを聞かせてもらえないでしょうか?

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

  • ベストアンサー
  • thamansa
  • ベストアンサー率40% (95/232)
回答No.3

プログラムを簡素で美しく記述する王道は、 ・何をするのかを日本語で簡潔にまとめる(整理する) → うるう年判定であれば、判定方法を整理します。   (1)4で割れる年をうるう年とする   (2)100で割れる年は平年にする   (3)400で割れる年はうるう年とする ・凝ったことをしようとしない。 → ビット操作とかポインタ操作とかできるのがCの醍醐味ですが、いわゆる「テクニック」を使わないほうが実は簡素で美しくなる傾向にあります。 これを心がけてうるう年判定関数を作ってみました。 bool is_leap(int year){   if(year % 400 == 0) return true;   if(year % 100 == 0) return false;   if(year % 4 == 0) return true;   return false; } 書き方によっては実行速度がはやい方法もあるでしょうけど、うるう年関数なんかチューニングするより、他のアーキテクチャを見直したほうがよっぽど効果的です。 また、この関数であれば、3200年に一度うるう年でないことに対応 させたい(いわゆる仕様追加みたいな場面)ときに   if(year % 3200 == 0) return false; を追加すればよいことが一目瞭然です。 複雑な条件式を書かずに素直に書くと、メンテが楽になりますね。

Mr_tenten
質問者

お礼

返答ありがとうございました。 ・・・・提示してくださったコード、すばらしいと思います。 自分の中では”短いコード”を追求したものが美しいと感じていましたが、そうではないんですよね・・・・・ 提示してくださったコードはプログラムが上から順に実行されていくことをうまく使った方法だと思います。 のちのちのことを考え、他の人が分かりやすく、保守がしやすいコードもまた美しく書く条件の1つになるでしょう。 ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (9)

  • jacta
  • ベストアンサー率26% (845/3158)
回答No.10

> まぁテーブルで使用されるメモリ容量が気になる場合は、単に0,1のみなので、ビット列としてでも表現できますね。 そうなのですが、除算器を持たないような非力なCPUの場合、大抵シフト演算も遅い(ハード的には1ビット単位でしかシフトできない場合が多い)ので、ビット列にしてしまうと結局パフォーマンスが上がらなくなります。

全文を見る
すると、全ての回答が全文表示されます。
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.9

> そして最後の記述ですが、ちょっと自分の経験不足で分からないのですが、表引きにするということは、4桁の西暦を上2桁を行番号、下2桁を列番号とし、それぞれにtrueかfalseを入れるといった方法でしょうか? そんな難しい話ではなく、例えば1970年~2099年までしか扱わないのであれば、西暦から1970を引いた値を添え字とするブール値の配列を作るなどすればよいということです。 具体的には、 int is_leap(int year) {  static const char leap_table[130] = { 0,0,0,1,... };  if (yaer < 1970 || 2099 < year) return -1;  return leap_table[year - 1970]; } のようにします。 返却値は、単にうるう年かどうかだけでなく、引数が不正な場合に報告できるように、少なくとも三値を表現できる必要があります。

Mr_tenten
質問者

お礼

返答ありがとうございました。 なるほど・・・基準値を決め、そこから閏年の時だけフラグを立てるという方法ですね。 "少なくとも三値を表現できる必要があります" TRUE、FALSE、-1ということで返り値がintなのですね。 まぁテーブルで使用されるメモリ容量が気になる場合は、単に0,1のみなので、ビット列としてでも表現できますね。 また違った考え方が聞けてよかったと思います。ありがとうございました^^

全文を見る
すると、全ての回答が全文表示されます。
  • jacta
  • ベストアンサー率26% (845/3158)
回答No.8

3200年や80000年に関しては、シミュレーションなどでは必要になる可能性がありますし、遠未来を扱ったSFのゲームなどでも関係してくるかもしれませんね。逆に、グレゴリオ暦ができる(1582年)以前を、または国によって扱うべき暦法を変える必要があるなら、それも考慮する必要があります。 ここ100年か200年だけを扱う場合でも、#3の回答だけでは不十分で、引数の有効範囲をチェックする必要があるかと思います。最低限、assertを仕込んでおくぐらいは必要でしょう。 ところで、ここ100年か200年を扱う場合で、かつCPUが非力な環境(特に除算器を持たないCPU)であれば、表引きにするのが一番効率がよいかと思います。ただし、その分メモリを食いますので、どうするかは総合的に判断する必要があります。

Mr_tenten
質問者

お礼

返答ありがとうございました。 確かに有効範囲をチェックする場合は#3の回答では不十分です。 問題は有効範囲までif文を追加するか、または有効範囲をチェックするかの方法ですが、それに関してもメンテはしやすいと思います。 まぁassertを仕込むだけでも一行で終わりですからね。 そして最後の記述ですが、ちょっと自分の経験不足で分からないのですが、表引きにするということは、4桁の西暦を上2桁を行番号、下2桁を列番号とし、それぞれにtrueかfalseを入れるといった方法でしょうか?

全文を見る
すると、全ての回答が全文表示されます。
  • thamansa
  • ベストアンサー率40% (95/232)
回答No.7

> ところで、3200で割れる年が平年と言うのははじめて聞きましたが、 私も気になったのでgoogleしてみたら、 http://www.water.sannet.ne.jp/kazuya-ai/14/week.html によると、3200で平年、また80000年でうるう年だそうです。 原理的には、その先も何百万年とか何億年単位で例外があると思いますが、3200年後がうるう年かどうかは実用上問題ないので、一般には無視されるという話を聞いたことがあります。 でも、3200年後がうるう年かどうかがシステムに無関係であることを確認したうえで無視するべきで、盲目的に無視したら2000年問題と同じですね。

Mr_tenten
質問者

お礼

返答ありがとうございました。 そしてわざわざ調べていただきありがとうございます。 80000年でうるう年ですか・・・・・・天文学的な数字になってきましたね。 たしかにそこまでがシステムに関係なかったら無視するべきで、関係するシステムもそんなにあるわけではないだろうし、無視してもよいでしょうね。

全文を見る
すると、全ての回答が全文表示されます。
回答No.6

aに年数が入っているときに、 閏年なら0、そうでないとき0以外を返す処理 if (!(a % 100)) a = a /100; return a % 4; これは、閏年を論理和、論理積を使わずに判定せよと言う課題の 解答です。 ところで、3200で割れる年が平年と言うのははじめて聞きましたが、 本当かしら。

Mr_tenten
質問者

お礼

返答ありがとうございました。 そしてすばらしいコードを提示していただきありがとうございます。 自分は論理和、論理積 と このような計算により算出する場合とで、どちらのほうが速度が速いか分かりませんが、このコードも理解しやすいと思います。 つまり100年がいくつ含まれているかを判定し、その個数が4の倍数かどうかを判定していますね。 しかし最後におっしゃられた3200年ももし閏年であっても if(!(a % 3200)) a = a/3200; if(!(a % 100)) a = a/100; return a % 4; 一応上のように条件をただ付け足すだけですよね。 ありがとうございました

全文を見る
すると、全ての回答が全文表示されます。
  • MrBan
  • ベストアンサー率53% (331/615)
回答No.5

カリカリに速度チューニングが必要(保守性よりも優先)なケースでもなければ、 ソースレビューしたら私も#3の方の方針を支持します。 「凝ったことをしようとしない。」←これ大事。 「簡素で美しい」コードは、「解説」を必要としないシンプルなコードだと思います。

Mr_tenten
質問者

お礼

返答ありがとうございました。 ”「凝ったことをしようとしない。」←これ大事。” 確かに計算やアルゴリズムに依存して、プログラムのコードも複雑になるケースは沢山ありますが、解釈の仕様によってとてもシンプルなコードになりますよね。 こったことをしようとせず、そのままを頭の中で整理し、コードを作成してみる。すると思ったより分かりやすく、かつシンプルなコードが出来上がることはままあるものですよねw しかし時々あることを重要と考えずに通り過ぎてしまっている。 それはご指摘されたようにこったことをしないことはとても大事だということですね。 そして新しい考え方を聞けてとても感謝しています。 ”簡素で美しい」コードは、「解説」を必要としないシンプルなコード” これもまた簡素で美しいコードの条件の一つに含まれると思いますし、誰もが納得するでしょう。

全文を見る
すると、全ての回答が全文表示されます。
  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.4

全然回答ではありませんが、#3のかたに一票です。 プログラムは、他人がみて最もわかりやすいものが、簡素で美しい記述になります。自分一人で趣味で作る範囲では、どのようなものでもかまいませんが、業務用の場合は、そのプログラムが、次のひとに引き継がれていきます。 従って、 他人がみてわかりやすい。 仕様変更が容易にできる。 ことが必要です。 #3のかたの回答は、その意味で、満点です。

Mr_tenten
質問者

お礼

返答ありがとうございました。 自分も#3様に一票ですw 確かにおっしゃられるとおり、とても分かりやすくシンプルで、保守もしやすいと思います。 ぱっと見、これ以上そぎ落とすものがなく、条件の追加が容易で分かりやすい。 自分もこのようなコードを書けるよう日々努力しようと思います。

全文を見る
すると、全ての回答が全文表示されます。
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.2

★アドバイス ・うるう年の判定はあまり複雑に考えなくても判定できますよ。  そこで昔、作成したマクロ関数と関数を載せておきます。 /* 閏年判定のマクロ関数 */ #define MacroIsLeapYear(n) ((!((n) % 4) && ((n) % 100) && ((n) % 3200)) || !((n) % 400)) /* 西暦から閏年の判定 */ bool FuncIsLeapYear( int year ) {  if ( !(year % 4) && (year % 100) && (year % 3200) ){   return( true );  }  return( !(year % 400) ); } /* ●解説 (1)4で割れる年をうるう年とする (2)ただし、100で割れる年は平年にする (3)ただし、400で割れる年は閏年とする (4)ただし、3200で割れる年は平年とする ※まとめると4年に1回は閏年、でも 400 年に3回は閏年ではない事になる。 */ その他: ・開始日から終了日の期間の計算は西暦1年1月1日からの通算日数を求めた後で引き算をした方が  for 文でうるう年を数えるよりも早く計算できると思います。まずは通算日数を計算する関数を  作成して下さい。もちろん、この計算にもうるう年を含めた計算を追加します。 ・つまり、4 年に1回はうるう年なので『西暦 / 4』を通算日数に加算します。  でも 400 年に3回は平年になるため『西暦 / 400 * 3』を通算日数から引きます。  これで西暦1年1月1日からの通算日数が求まります。 ・その後に『終了日』から『開始日』を単純に引くことで期間の日数が計算できます。  下に1月1日からの通算日数を求める関数を紹介します。 /* 年月日から1月1日からの日数を取得 */ int FuncGetDays( int year, int month, int day ) {  static int table[] = { /* 0 */ 0, /* 1 */ 0, /* 2 */ 31, /* 3 */ 31 + 28, /* 4 */ 31 + 28 + 31, /* 5 */ 31 + 28 + 31 + 30, /* 6 */ 31 + 28 + 31 + 30 + 31, /* 7 */ 31 + 28 + 31 + 30 + 31 + 30, /* 8 */ 31 + 28 + 31 + 30 + 31 + 30 + 31, /* 9 */ 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31, /* 10 */ 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30, /* 11 */ 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31, /* 12 */ 31 + 28 + 31 + 30 + 31 + 30 + 31 + 31 + 30 + 31 + 30,  };    // 2月以降で閏年なら+1日  if ( (month >= 3) && FuncIsLeapYear(year) ){   day++;  }  return (table[month] + day); } /* ●解説 ※1月1日からの日数を返す。(1-366) */ 最後に: ・開始日を Y1/M1/D1、  終了日を Y2/M2/D2 とすると  days1 = ((Y1 * 365) + (Y1 / 4) - (Y1 / 400 * 3)) + FuncGetDays(Y1,M1,D1);  days2 = ((Y2 * 365) + (Y2 / 4) - (Y2 / 400 * 3)) + FuncGetDays(Y2,M2,D2);  diff = (days2 - days1);   ↑  この diff が開始日から終了日の期間の日数です。 ・以上。

Mr_tenten
質問者

お礼

返答ありがとうございました。 /* ●解説 (1)4で割れる年をうるう年とする (2)ただし、100で割れる年は平年にする (3)ただし、400で割れる年は閏年とする (4)ただし、3200で割れる年は平年とする ※まとめると4年に1回は閏年、でも 400 年に3回は閏年ではない事になる。 */ 3200で割れる年が平年だとは知りませんでした。 そして解釈の仕様によってとてもシンプルなアルゴリズムになりますね。”4年に1回は閏年、でも 400 年に3回は閏年ではない”と解釈の仕方をすることができなかったため、自分のようなソースになってしまいました。 自分が作ったプログラムは配列を13個用意し、添え字が1から12までの各要素を月として、その月の最大日数を格納して計算していました。 しかしOh-Orange様が示されたように、1月を0として、そのつきの前の日数を足して配列に格納していけば、たとえば2月22日といった場合には添え字2の場所には1月分の日数が入っているわけだから、添え字2に格納されている数字と22を足すだけでいいですね。 こういう方法もあるんだと関心です。

全文を見る
すると、全ての回答が全文表示されます。
  • koko_u_
  • ベストアンサー率18% (459/2509)
回答No.1

bool is_leap(int year); みたいな関数にする (End_Year / 4 ) - (First_Year / 4) みたいにすれば、間にある 4の倍数を数えることも易しいけど、関数にした方が意味を把握しやすいでしょう。

Mr_tenten
質問者

お礼

返信ありがとうございます。 関数にしてみたところ確かにすっきりしました。 すばやい回答に感謝します。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 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()を定義する */

  • C言語習いはじめです

    大学の講義でC言語を習い始めたのですが、if文でコンパイルするとどうしても解決できないエラーが起こってしまいます。 文の意味は 「4で割り切れる年は”閏年”また、400でも割り切れる年も”閏年”と表示する。100で割り切れる年は”平年”と表示する」 というものです。値は2100で指定しています。 #include <stdio.h> main() { int y; printf(" y=2100; "); { if(y%400:0) { printf("a leap year \n"); {/* 閏年 */} } else if(y%100:0) { printf("a common year \n"); {/* 平年 */} } else if(y%40:0) { printf("a leap year \n"); {/* 閏年 */} } else { printf("a common year \n"); {/* 平年 */} } } return 0; } これをコンパイルすると、どうしても 「エラー E2377 ”ファイル名” 5: If文に ) がない(関数 main)」 と出てきてしまいます。 残るこのエラーだけが解決できません。どなたか、間違っている点がわかる方はいませんでしょうか。お願いします。

  • 西暦・月からカレンダーを表示

    問題文 西暦・月を入力してカレンダーを表示するプログラムを作成せよ。 プログラム全体のことを考える。プログラムの流れとしては、つぎのようになるであろう。  (1)変数の宣言: プログラムの中で使う変数や配列等をすべてここに集めておく。          (2)入力: キーボードから、西暦年の値を読み取る ← scanf( ) 関数  1月から12月まで、以下を繰り返す。  (3)カレンダーの年・月の表示: (例えば、2008年1月 と表示)  (4)各曜日名の表示: 「日 月 火 水 木 金 土」と表示  (5)月の日数の算出: 月の最後の日を計算しておく。(*1~12月以外では誤りとすること)  (6)曜日の算出: 月の初めの日(ついたち)の曜日をツェラー公式で計算しておく。  (7)空列の表示: ついたちの前の空白部分を表示する ← for文 を利用。  (8)各日の表示: 月の各日を順に表示していく ← for文を利用          (土曜の後に改行を入れる) #include <stdio.h> int leapYear(int year) { if (year%400==0||(year%4==0 && year%100!=0)) { return 1; } else { return 0; } } int main(void) { int d,year,m,i; int day[12] = {31,28,31,30,31,30,31,31,30,31,30,31}; /*1~12月までの各月の日数*/ printf("西暦を入力してください:"); scanf("%d",&year); printf("月を入力してください:"); scanf("%d",&m); if(m!=1 & m!=2 & m!=3 & m!=4 & m!=5 & m!=6 & m!=7 & m!=8 & m!=9 & m!=10 & m!=11 & m!=12)/*1~12月以外で日数を出そうとした場合*/ { printf("入力が誤っています。やりなおしてください。\n"); } else{ if (leapYear(year)==1)/*閏年の場合*/ { printf("%d年は閏年です。\n",year); day[1] +=1; } else/*閏年でない場合*/ { printf("%d年は閏年ではありません。\n",year); } i = (year+year/4 -year/100 +year/400 + ( 13*m+8 )/5 + 1) % 7; /*西暦~年・1~12月の1日の曜日について考える*/ printf("日 月 火 水 木 金 土\n"); (7)・・・ (8)・・・ } return 0; } 手順に沿ってやっていく課題なのですが(7)、(8)の部分の表現の仕方が良く分かりません。(求めた月の日数をカレンダー形式に表示する方法・1日の前に空白を入れる等) 過去の質問も見たのですが、いまいち理解できず・・・orz どなたかご教授お願いできないでしょうか・・・。

  • 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言語 関数について

    協力お願いします。 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()のプロトタイプ宣言も記述すること。 よろしくお願いします。

  • 関数について

    協力お願いします。 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による基本的な条件分岐(if,else if文)のプログラムです。 西暦年(4けたの整数)を入力し、その年がうるう年かどうかを判断するプログラムを作りなさい。 4で割り切れるときはうるう年であるが、100で割り切れるときはうるう年ではない。 しかし、400で割り切れればうるう年である。 ・・・とゆう問題文です。 #include<stdio.h> int main(void) { int x; printf("西暦を入力して下さい¥n"); scanf("%d",&x); if(x%4==0) printf("うるう年である¥n"); else if(x%400==0) printf("うるう年である¥n"); else if(x%100!==0) printf("うるう年でない¥n"); else printf("うるう年でない¥n"); return 0; } ・・・とりあえず自分で考えてみたのですがどうでしょうか; 間違ってると思いますが頑張って考えました・・・;; 4けたの整数ってゆうのはどう書けばいいんでしょうか? 実際にこのプログラムは動くのでしょうか? もっと省略して書くことができるのでしょうか?  等、色々わからないことばかりです。 プログラミングの授業自体に苦手意識を持っているので得意ではありません。 間違いなど指摘していただけたらと思います!! よろしくお願いします!

  • VBAマクロの記述を教えてください m(__)m 娘から聞かれたのですが主婦の私にはわかりません

    VBAマクロの宿題です。どうもエクセルのことのようですが、それ以上は私にはわからず困っています。    A   B   C   D   E  1  ○  ×  ○  ×  ○ 2  5  5 3 12 12 4  8  8 5 15 15 6 31 31 7  4  4 8  3  3 9 87 87 10  18  18 11 183 87 以上がエクセルのシートだと見てください。 準備:A1セルからE1セルに○あるいは×を入力する。    A2セルからE10のセルに適当な2桁の数値を入力する。 問題:1行目が○なら11行目に2行目から10行目までの    合計を計算・表示する。    1行目が×なら11行目に2行目から10行目までの    最大値を表示する。 ヒント:文字のIF文      プログラム上で文字を扱う場合、ダブル・クォーテー      ションで文字をはさむ。      IF Cells( 、 )="○" Then     プログラムの流れ |     For |       IF |         For |         Next |       Else |         For |         Next |       END IF |     Next 以上です。もう何が何やらちんぷんかんぷんです。どなたか助けてください。

  • 閏年のプログラム

    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); }

  • fortran77のend ifの個数について質問です。

    他人が作ったfortran 77のプログラムを使うことになったのですが、if文の数とend if文の数が合わずに混乱しています。コンパイルも実行も出来るのですが自分の中では納得いきません。具体的に言うと、 =============== if (aa.gt.bb) then  計算 if (cc.gt.dd) then  計算 else  計算 end if  計算 if (ee.gt.ff) then  計算 end if =============== と言った具合です。この場合1つめのif文に対応するend ifがないと思うのですが…なぜコンパイルがうまくいくのか教えてください。