Određivanje broja dana po mesecima – rešenje

Program određuje koliko dana ima mesec na osnovu unete godine i rednog broja meseca. Godina je potrebna zato što februar nema uvek isti broj dana: u običnoj godini ima 28, a u prestupnoj 29 dana.


1. Ideja rešenja

Sa tastature se učitavaju dva cela broja:

  • G – godina;
  • M – redni broj meseca, od 1 do 12.

Promenljiva BD čuva broj dana u izabranom mesecu. Naredbom switch grupišemo mesece prema broju dana:

  • Januar, mart, maj, jul, avgust, oktobar i decembar imaju 31 dan.
  • April, jun, septembar i novembar imaju 30 dana.
  • Februar ima 28 ili 29 dana, u zavisnosti od toga da li je godina prestupna.

U switch naredbi više oznaka case može da vodi do istog bloka naredbi. Pošto između tih oznaka nema naredbe break, izvršavanje se nastavlja do naredbe BD = 31 ili BD = 30. Tako izbegavamo ponavljanje istog koda za svaki mesec.


2. Kada je godina prestupna?

Godina je prestupna ako je deljiva sa 400 ili ako je istovremeno deljiva sa 4 i nije deljiva sa 100. Zato izraz u jeziku C glasi:

(G % 400 == 0) || (G % 4 == 0 && G % 100 != 0)

Operator % izračunava ostatak pri deljenju. Ako je G % 4 == 0, godina je deljiva sa 4. Uslov G % 100 != 0 izuzima godine deljive sa 100, dok izraz G % 400 == 0 ponovo prihvata godine deljive sa 400.

Primeri:

  • 2024. je prestupna godina: deljiva je sa 4, a nije deljiva sa 100.
  • 2023. nije prestupna godina: nije deljiva sa 4.
  • 1900. nije prestupna godina: deljiva je sa 100, ali nije sa 400.
  • 2000. jeste prestupna godina: deljiva je sa 400.

3. C program

#include <stdio.h>

int main(void)
{
    int G, M, BD;

    printf("Unesi godinu i redni broj meseca: ");
    if (scanf("%d%d", &G, &M) != 2) {
        printf("Neispravan unos.\n");
        return 1;
    }

    switch (M) {
        /* Meseci koji imaju 31 dan */
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            BD = 31;
            break;

        /* Meseci koji imaju 30 dana */
        case 4:
        case 6:
        case 9:
        case 11:
            BD = 30;
            break;

        /* Februar: broj dana zavisi od godine */
        case 2:
            if ((G % 400 == 0) || (G % 4 == 0 && G % 100 != 0)) {
                BD = 29;
            } else {
                BD = 28;
            }
            break;

        /* Mesec mora biti u opsegu od 1 do 12 */
        default:
            printf("Neispravan redni broj meseca.\n");
            return 1;
    }

    printf("Broj dana iznosi %d.\n", BD);
    return 0;
}

Napomena: Dodata je provera rezultata funkcije scanf, kako program ne bi nastavio ako nisu uneta oba cela broja. Grana default obrađuje neispravan redni broj meseca. Uključena je samo biblioteka stdio.h, jer je dovoljna za korišćene funkcije printf i scanf.


4. Primeri izvršavanja

Ulaz:

2024 2

Izlaz:

Broj dana iznosi 29.

Pošto je 2024. prestupna godina, februar ima 29 dana. Za unos 2023 2 izlaz bi bio Broj dana iznosi 28., dok bi za unos meseca 13 program prijavio da je redni broj meseca neispravan.


5. Zašto je važna naredba break?

U grupisanim slučajevima za mesece sa 31 ili 30 dana namerno nema naredbe break između oznaka case. Kada se pronađe odgovarajući mesec, izvršavanje prolazi kroz naredne oznake sve dok ne dođe do dodeljivanja vrednosti promenljivoj BD i zatim do break. Ta naredba prekida izvršavanje naredbi unutar switch bloka i sprečava da se nastavi u sledeću grupu meseci.