C言語

【C言語】閏年(うるう年)の判定・一覧表示を行うプログラム


代表的なプログラミング初心者向けの練習問題である閏年(うるうどし)の判定、及び一覧表示を行うプログラムの作成ですが、意外と躓いてしまう人は多いです。

本記事では、そんなプログラミング初心者のために閏年の判定、及び一覧表示を行うプログラムの作成方法について解説します。

そもそも閏年(うるうどし)とは?

まずは閏年について簡単に説明します。

通常の年より日数が一日多い年

閏年とは、季節と暦のズレを補正することを目的に作られた年のことです。閏年は通常の年より日数が一日多くなっています。(通常の年は2月が28日間、閏年では29日間)

どのように判定するのか?

閏年は以下の定義に従って判定することが可能です。

  • 西暦年が4で割り切れる場合は閏年
  • ただし、西暦年が100で割り切れる場合は通常の年
  • ただし、西暦年が400で割り切れる場合は必ず閏年

参考までに閏年、通常の年の例を以下に示します。

例)閏年
1904年、1944年、2000年、2012年、2020年

例)通常の年
1900年、1945年、2001年、2013年、2021年

閏年の判定を行うプログラムの作成

それでは実際に閏年の判定を行うプログラムを作成してみます。

プログラム作成の手順

ここでは、以下の手順で処理を実装します。

  1. ユーザーに任意の西暦年を入力させる
  2. 前述したルールに従い、閏年の判定を行う

実装例 – 通常版

上記の手順に従ってプログラムを作成します。使用する言語はC言語です。

#include <stdio.h>

int main(void){

  /* 判定対象の値を入力させる */
  printf("西暦年を入力して下さい:");
  int year;
  scanf("%d", &year);

  /* 条件式に従い、閏年の判定を行う */
  if (year%4==0) {
    if (year%100==0) {
      if (year%400==0) {
        printf("%d年は閏年です。\n", year);
      } else {
        printf("%d年は閏年ではありません。\n", year);
      }
    } else {
      printf("%d年は閏年です。\n", year);
    }
  } else {
    printf("%d年は閏年ではありません。\n", year);
  }

  return 0;
}

このプログラムを実行すると以下の出力結果が得られます。

西暦年を入力して下さい:2020
2020年は閏年です。
西暦年を入力して下さい:1945
1945年は閏年ではありません。

出力結果から適切に処理を実行できていることがわかります。

実装例 – 改善版

一つ前の実装例でも十分に処理を実行できますが、if文が乱立しているせいで少し可読性の低いプログラムとなってしまっています。

複数の条件式をまとめて一つのif文に圧縮することでプログラムの可読性を改善してみます。

なお、今回も使用する言語はC言語です。

#include <stdio.h>

int main(void){

  /* 判定対象の値を入力させる */
  printf("西暦年を入力して下さい:");
  int year;
  scanf("%d", &year);

  /* 条件式に従い、閏年の判定を行う */
  if (year%400==0 || ( year%4==0 && year%100!=0 )) {
    printf("%d年は閏年です。\n", year);
  } else {
    printf("%d年は閏年ではありません。\n", year);
  }

  return 0;
}

このプログラムを実行すると以下の出力結果が得られます。

西暦年を入力して下さい:2020
2020年は閏年です。
西暦年を入力して下さい:1945
1945年は閏年ではありません。

出力結果からこちらのプログラムも適切に処理を実行できていることがわかります。

処理の中身はそのままにより簡潔な見た目になっているため、個人的にはこのようなプログラムの書き方を推奨します。

閏年を一覧表示するプログラムの作成

先程紹介した閏年の判定プログラムの仕組みを転用し、閏年の一覧表示を行うプログラムを作成してみます。

プログラム作成の手順

ここでは、以下の手順で処理を実装します。

  1. ユーザに西暦年の任意の期間を入力させる
  2. 入力された期間の西暦年を一つずつチェック
  3. 2の手順において閏年と判定された西暦年のみ出力処理を行う

実装例

上記の手順に従ってプログラムを作成します。使用する言語はPythonです。

#include <stdio.h>

int main(void){

  int a, b;

  /* 判定対象の値を入力させる */
  printf("西暦a~b年の期間における閏年を表示します。\n");
  printf("値を入力して下さい:\n");
  printf("a = ");
  scanf("%d", &a);
  printf("b = ");
  scanf("%d", &b);
  printf("---------------------------------------\n");

  /* 指定の期間における閏年の一覧を表示させる */
  if (a<b && (a>0 && b>0)) {
    int flag = 0;
    for (int year=a; year<b; year++) {
      if (year%400==0 || ( year%4==0 && year%100!=0 )) {
        printf("%d ", year);
        flag = 1;
      }
    }
    if (flag==0) {
      printf("西暦%d~%d年の期間中に閏年はありません。", a, b);
    }
  } else {
    printf("入力が不正な値です。");
  }

  return 0;
}

このプログラムを実行すると以下の出力結果が得られます。

西暦a~b年の期間における閏年を表示します。
値を入力して下さい:
a = 2000
b = 2021
---------------------------------------
2000 2004 2008 2012 2016 2020
西暦a~b年の期間における閏年を表示します。
値を入力して下さい:
a = 2001
b = 2002
---------------------------------------
西暦2001~2002年の期間中に閏年はありません。
西暦a~b年の期間における閏年を表示します。
値を入力して下さい:
a = 0
b = 0
---------------------------------------
入力が不正な値です。

出力結果から適切に処理を実行できていることがわかります。