005 ‐ Součet cifer - zizanek/github-tz-is-2026-sk1 GitHub Wiki

Program: Ciferný součet (matematické řešení)

Tento program demonstruje klasický algoritmický postup rozkladu celého čísla na jednotlivé číslice pomocí celočíselného dělení (/) a zbytku po dělení – modulo (%).

Předlohou pro tento algoritmus je vývojový diagram z učebnice Algoritmizace (strana 80)[cite: 3].


1. Kompletní zdrojový kód programu (Program.cs)

// Řídicí proměnná pro opakování programu
string again = "a";

// Hlavní smyčka programu: běží znovu, pokud uživatel zadá 'a' nebo 'A'
while (again.ToLower() == "a")
{
    Console.Clear();
    Console.WriteLine("***********************************");
    Console.WriteLine("********* Ciferný součet **********");
    Console.WriteLine("***********************************");
    Console.WriteLine("*********** Tomáš Žižka ***********");
    Console.WriteLine("***********************************");
    Console.WriteLine();

    // 1. Bezpečné načtení celého čísla od uživatele
    Console.Write("Zadejte celé číslo: ");
    int number;
    while (!int.TryParse(Console.ReadLine(), out number))
    {
        Console.Write("Nezadali jste celé číslo. Zadejte celé číslo znovu: ");
    }

    // 2. Příprava pomocných proměnných pro výpočet
    int numberBackup = number; // Záloha původního čísla pro závěrečný výpis
    int sum = 0;               // Neutrální prvek pro sčítání je 0
    int digit;                 // Proměnná pro uložení právě oddělené cifry

    // 3. Ošetření záporných čísel (znaménko nemá vliv na cifry)
    if (number < 0)
    {
        number = -number;
    }

    // 4. Zvláštní případ pro nulu
    if (number == 0)
    {
        sum = 0;
    }
    else
    {
        Console.WriteLine();
        Console.WriteLine("Průběh rozkladu čísla na cifry (zprava doleva):");

        // 5. Matematický rozklad čísla pomocí cyklu
        while (number > 0)
        {
            digit = number % 10;            // Modulo 10 získá poslední číslici
            sum = sum + digit;              // Přičtení cifry k celkovému součtu

            Console.WriteLine($"Získána cifra: {digit}");

            number = number / 10;           // Celočíselné dělení 10 odstraní poslední číslici
        }
    }

    // 6. Výpis výsledků
    Console.WriteLine();
    Console.WriteLine("====================================");
    Console.WriteLine($"Původní číslo:  {numberBackup}");
    Console.WriteLine($"Ciferný součet: {sum}");
    Console.WriteLine("====================================");
    Console.WriteLine();

    // 7. Dotaz na opakování programu
    Console.Write("Pro opakování programu stiskněte 'a' a potvrďte klávesou Enter: ");
    again = Console.ReadLine() ?? "";
}

2. Porovnání s vývojovým diagramem (učebnice str. 80)

Ve vývojovém diagramu z učebnice je postup rozdělen na dva kroky[cite: 3]:

  1. POM := A div 10 – celočíselný podíl (číslo 10× zmenšené)[cite: 3].
  2. CIS := A - POM * 10 – výpočet poslední číslice odečtením[cite: 3].

Zápis v C#:

V jazyce C# máme operátor % (modulo), který zbytek po dělení spočítá přímo:

  • digit = number % 10; získá poslední cifru (odpovídá výpočtu CIS)[cite: 3].
  • number = number / 10; zmenší číslo o řád (odpovídá proměnné POM)[cite: 3].

Příklad pro číslo 357:

  • 357 % 10 je 7 (poslední cifra).
  • 357 / 10 je 35 (číslo připravené pro další průchod cyklem).

3. Rozbor klíčových částí programu

3.1. K čemu slouží proměnná numberBackup?

V průběhu cyklu while původní hodnotu v proměnné number postupně dělíme deseti, až v ní zbude 0. Abychom na konci programu mohli uživateli přehledně vypsat původní zadanou hodnotu, musíme si ji hned na začátku zazálohovat.

3.2. Proč je na začátku sum = 0?

Číslo 0 je neutrálním prvkem pro operaci sčítání ($x + 0 = x$). Na začátku je součet prázdný a každou nalezenou cifru k němu postupně přičítáme.

3.3. Proč obracíme záporná čísla?

Pokud uživatel zadá záporné číslo (např. -123), operace -123 % 10 by vracela záporný zbytek -3. Protože samotné číslice chápeme jako nezáporné, převedeme záporné číslo podmínkou if (number < 0) na kladné.


4. Dobré programátorské návyky (Best Practices)

4.1. Nezávislost výpočtu na vstupu

Původní vstup od uživatele uchováváme v neměnné podobě (numberBackup), zatímco pracovní kopii (number) bezpečně modifikujeme v algoritmu.

4.2. Ošetření hraničních stavů (Edge cases)

Pro nulu (number == 0) by cyklus while (number > 0) vůbec neproběhl. Díky samostatné větvi if (number == 0) vrátí program správný výsledek 0 i pro samotnou nulu.


5. Úkoly pro studenty a otázky k obhajobě

  1. Samostatný úkol – Ciferný součin:
    Rozšiřte program tak, aby kromě ciferného součtu počítal a vypisoval i ciferný součin (násobek všech číslic v čísle).
    Nápověda: Jaká musí být počáteční hodnota proměnné pro součin? Co se stane, když číslo obsahuje cifru 0?
  2. Otázka k obhajobě: Proč výraz 357 / 10 v C# vrátí celé číslo 35 a nikoliv 35.7?
  3. Otázka k obhajobě: Co by se stalo, kdybychom v těle cyklu while vynechali řádek number = number / 10;?
  4. Námět na domácí úkol (program002b-soucet-cifer): Šel by tento problém vyřešit bez matematického dělení a zbytku, například tak, že bychom se vstupem pracovali jako s textovým řetězcem (string) a procházeli jednotlivé znaky?