Faktoriál
| Stránky: | Moodle ZČU |
| Kurz: | KPV/TI Technická informatika ve strojírenství - šablona |
| Kniha: | Faktoriál |
| Vytiskl(a): | Nepřihlášený host |
| Datum: | neděle, 8. listopadu 2026, 17.32 |
1. Faktorial
Úlohou je vytvořit aplikaci na výpočet faktoriálu:
- Pomocí cyklu s podmínkou na začátku (While)
- Pomocí cyklu s podmínkou na konci (Do While)
- Pomocí cyklu s krokem (for)
- Pomocí rekurze
Účel příkladu
- Rekurze
Typ aplikace
- Konzolová aplikace
Popis úkolu
- Výpočet faktoriálu
Funkčnosti
- Po načtení přirozeného čísla v hlavním programu je toto číslo skutečným parametrem předaným 4 podprogramům volaných z hlavního programu:
- Podprogram (funkce s celočíselným návratem) FaktorialWhile - výpočet faktoriálu pomocí cyklu s podmínkou na začátku
- Podprogram (funkce s celočíselným návratem) FaktorialDoWhile - výpočet faktoriálu pomocí cyklu s podmínkou na konci
- Podprogram (funkce s celočíselným návratem) FaktorialFor - výpočet faktoriálu pomocí cyklu s krokem
- Podprogram (funkce s celočíselným návratem) FaktorialVolaniRekurze - výpočet faktoriálu pomocí volání funkce s rekurzí
- Hodnoty vypočtených faktoriálů, předané z podprogramů, budou vypsány bez desetinných míst v hlavním programu
- Po výpisu všech čísel bude aplikace ukončena po stisku klávesy
Výstup programu

Výstup programu: Ukázka výpisu faktoriálu v hlavní metodě programu Faktorial
1.1. Analýza a návrh řešení
Z matematiky víme, že faktoriál čísla n (značeno jako n!) je roven součinu všech přirozených čísel menších nebo rovných n (přičemž platí 0! = 1) např. 3! = 3*2*1 = 1*2*3 = 6. Z předchozí číselné rostoucí řady vidíme, že se jedná o součin hodnot, které postupně stoupají o hodnotu 1 až do konečné prvku této řady představující zadané číslo uživatelem - viz Obrázek 1. Vidíme, že čísla také mohou klesat od čísla n až do 1 - tímto možným přístupem se však nyní nebudeme zabývat.

Obrázek 1: Princip faktoriálu - součin řady zvyšujících se čísel
Matematicky bychom při násobení čísel mezi sebou postupovali např. zleva doprava (lze i opačně), tedy 1*2 = 2 a pak tento výsledek 2 násobíme 3, tedy 2*3 = 6. Jedná se tedy o pravidelný postup, na který lze uplatnit cykly. Součin všech prvků lze rozdělit do jednotlivých iterací, kde v každé iteraci je provedeno násobení hodnoty součinu z předchozí iterace (náš předchozí výsledek součinu uložený v proměnné f) aktuálním číslem (uloženým v proměnné i), tj. f * i. Výsledek tohoto součin budeme ukládat do proměnné f (hodnota v f tedy bude v každé iteraci přepisována), tedy f = f * i. Aktuální číslo uložené v proměnné i je následně zvětšeno o hodnotu 1, tj. i + 1, abychom jej mohli využít v součinu v další iteraci. Myšlenku v předchozí větě aplikujeme na příklad našeho faktoriálu, tj. 3! = 1*2*3.
V první iteraci je v proměnné f a v proměnné i uložena počáteční hodnota 1. V první iteraci je tedy f = f * i = 1*1 = 1. Následně zvedneme hodnotu i o 1, tj. i = i + 1 = 1 + 1 = 2. V další iteraci provedeme součin f = f * i = 1*2 (vidíme že jde o první dva členy v součinu všech čísel v rozepsané rovnici faktoriálu). Hodnotu součinu si uložíme do proměnné f, abychom ji mohli využít v další iteraci. Ještě než přejdeme do další iterace, musíme inkrementovat aktuální číslo z hodnoty 2 na hodnotu 3. V další iteraci tedy násobíme f = 2*3 (hodnota v f * hodnota aktuálního čísla v i). Tato iterace byla poslední, protože aktuální číslo je rovnu číslu, pro něhož jsme chtěli vypočítat faktoriál - viz Obrázek 2.
Všimněte si, že počet iterací je roven 3, což je naše číslo, pro něhož počítáme faktoriál. Všimněte si, že bychom také mohli vynechat první iteraci, pokud bychom inicializovali proměnnou i hodnotou 2. Pak by namísto 3 iterací bylo zapotřebí pouze 2 iterací.

Obrázek 2: Princip výpočtu faktoriálu
Tento princip využijeme ve volaných podprogramech - funkcích, které navracejí do hlavního programu vypočtenou hodnotu faktoriálu. Tyto funkce jsou volány z hlavního programu - viz Obrázek 1.

Obrázek 3: Hlavní program Faktorial pro výpis faktoriálu
První volanou funkcí je FaktorialWhile. Tento podprogram využívá cyklu while, v jehož těle je implementována podstata násobení jednotlivých prvků řady. Počátečním krokem je inicializace obou proměnných i a f na hodnotu 1. V lokální proměnné i je uloženo aktuální číslo, které využíváme v součinu f * i prováděného v každé iteraci. Výsledek tohoto součinu stávající hodnoty f z předchozí iterace a aktuálního čísla i je uložen do proměnné f. V každé iteraci je tedy hodnota v proměnné f přepsána novou hodnotou součinu. Jako následný krok je provedena inkrementace aktuálního čísla i o hodnotu 1 - viz Obrázek 4.

Obrázek 4: Podprogram FaktorialWhile - funkce pro výpočet faktoriálu pomocí cyklu s podmínkou na začátku
Dalším podprogramem (funkcí) využívající cyklus je FaktorialDoWhile, který má svém těle implementován cyklus s podmínkou na konci - viz Obrázek 5. Podstata podprogramu je téměř stejná jako v předchozím podprogramu FaktorialWhile.

Obrázek 5: Podprogram FaktorialDoWhile - funkce pro výpočet faktoriálu pomocí cyklu s podmínkou na konci
Vzhledem k tomu, že víme, kolikrát iterací má proběhnout v cyklu, lze použít v dalším podprogramu FaktorialFor cyklus s krokem - viz Obrázek 6. Inicializace řídící proměnné cyklu probíhá před první iterací cyklu. Inkrementace řídící proměnné cyklu probíhá po proběhnutí iterace, taktéž v bloku for.

Obrázek 6: Podprogram FaktorialDoWhile - funkce pro výpočet faktoriálu pomocí cyklu s krokem
Posledním podprogramem je FaktorialVolaniRekurze. Podprogram je taktéž funkce, která v sobě volá další funkci pro výpočet faktoriálu pomocí rekurze - FaktorialRekurze - viz Obrázek 7.
Obrázek 7: Podprogram FaktorialVolaniRekurze - volání funkce s rekurzí
Pomocí rekurze bychom mohli faktoriál kladného čísla rozepsat jako 3! = 3*2!, kde bychom 2! uvnitř výrazu mohli zase rozepsat 2! = 2*1! a další rozepsání již není zapotřebí, protože 1! je roven 1. Postupným zpětným dosazením nám tedy vznikl výraz 3! = 3*2*1!, tedy 3! = 3*2*1 = 6. Výpočet faktoriálu rekurzivním způsobem, lze zapsat jako n*(n-1)! . Pokud bychom použili metodu pro výpočet faktoriálu, nazvěme ji např. FaktorialRekurze, můžeme náš předchozí zápis výpočtu faktoriálu rekurzivním způsobem zapsat jako n*FaktorialRekurze(n-1). Tohoto principu využijeme v následující funkci využívající princip rekurze - viz Obrázek 8.

Obrázek 8: Podprogram FaktorialRekurze - funkce pro výpočet faktoriálu pomocí rekurze
V těle této funkce je definována podmínka, která určuje, kdy se vnořování funkce do sebe samé musí zastavit, tzn., že krok, kdy se funkce postupným snižováním parametru na základě výrazu (n – 1), dostane až do stavu, kdy je předávaná hodnota parametru rovna 0 (tehdy je 0! = 1). Je také možností zastavit vnořování funkce již o jednu iteraci dříve, tj. kdy je předávaná hodnota parametru rovna 1 (protože 1! = 1). Uživateli jsme však dali možnost vypočítat faktoriál pro číslo z definičního oboru přirozených čísel, proto povolíme i vložení 0.
Samotnou rekurzi vidíme ve větvi false rozhodovacího bloku uvnitř těla funkce, kdy funkce volá sama sebe (svým jménem FaktorialRekurze) a předává si postupně snižovanou hodnotu parametru o jedna. Až se volaná funkce dostane do stavu, že daný parametr už nejde snížit (splnění podmínky ukončení další rekurze v těle funkce, tj. n == 0), funkce předá hodnotu 1 zpět do funkce, která ji naposledy volala. Pak tato volající metoda vypočte hodnotu svého výrazu a tuto hodnotu zase postupně dosazuje zpět do volající funkce. Tento cyklus probíhá tak dlouho, dokud neobdržíme výsledek příkazu, který odstartoval volání vnořených funkcí.
Použití rekurze je velmi účinný ale často také nebezpečný trik!
1.2. C#
Načtení čísla, pro které bude následně ve statické hlavní metodě vypočten faktoriál, je realizováno pomocí příkazu (metody s výstupními parametry) TryParse. V hlavní statické metodě jsou pomocí jednotlivých výpisů odděleny hodnoty faktoriálu vypočtené pomocí volaných metod s celočíselným návratem, jejichž těla obsahují různé typy cyklu - viz Kód 1. Tyto celočíselné návraty (datového typu long) jsou konvertovány pomocí příkazu ToString vyvolaného pomocí tečkové notace. Datový typ long umožňuje větší rozsah celočíselných hodnot (horní mez až 9,223,372,036,854,775,807). Tím umožníme uživateli zadávat i větší čísla, pro které má být vypočten faktoriál (horní mez datového typu int je 2,147,483,647), aniž bychom způsobili přetečení. Např. 12! = 479,001,600 a faktoriál čísla 13 je již 13! = 6,227,020,800.
Číslice jsou formátovány pomocí formátu "N0", což znamená, že jsou to celá čísla bez desetinných míst ("N" ... Number, "0" ... počet vypsaných desetinných míst).
static void Main(string[] args) { // Výpis textu Console.WriteLine("Výpočet faktoriálu"); // Výzva k zadání čísla pro výpočet faktoriálu Console.Write("Zadejte číslo: "); /* Načtení čísla - 'n' ... číslo, pro které bude vypočten * faktoriál (výstupní parametr TryParse) */ int.TryParse(Console.ReadLine(), out int n); /* Výpis textu a hodnoty faktoriálu, který je výstupem zavolané funkce * s předaným parametrem 'n'; specifikace výstupního formátu * čísla "N0", tj. bez čísel za desetinnou čárkou */ Console.WriteLine("Faktoriál (cyklus while): " + FaktorialWhile(n).ToString("N0")); Console.WriteLine("Faktoriál (cyklus do-while): " + FaktorialDoWhile(n).ToString("N0")); Console.WriteLine("Faktoriál (cyklus for): " + FaktorialFor(n).ToString("N0")); Console.WriteLine("Faktoriál (rekurze): " + FaktorialVolaniRekurze(n).ToString("N0")); // Čekání na stisk klávesy -> ukončení programu Console.ReadKey(); }
Kód 1: Program Faktorial - deklarace hlavní statické metody Main
První volanou metodou pro výpočet faktoriálu pomocí cyklu s podmínkou na začátku je metoda s celočíselným návratem (datový typ long) FaktorialWhile - viz Kód 2. V této metodě jsou použity dvě lokální proměnné i a f. Proměnná i představuje čítač cyklu, ale zároveň představuje aktuální číslo v součinu. Tato proměnná je datového typu int, protože není zapotřebí velký rozsah zadávaných čísel vzhledem k horní mezi datového typu long vybraného pro proměnnou f, která představuje hodnotu vypočteného faktoriálu. Výraz f = f * i; bychom mohli zkrátit pomocí zápisu f *= i; . Dále jsme také zkrátili zápis inkrementace i = i + 1; na i++.
// Metoda s celočíselným návratem (datový typ long) pro výpočet faktoriálu pomocí cyklu while static long FaktorialWhile(int n) { /* Deklarace: 'i' ... čítač (aktuální číslo v součinu); * 'f' ... hodnota faktoriálu */ int i; long f; // Inicializace i = 1; f = 1; // Opakuj, pokud je čítač menší, nebo roven číslu pro výpočet faktoriálu while (i <= n) { // Výpočet faktoriálu f = f * i; // Inkrementace čítače i++; } // Návrat vypočtené hodnoty faktoriálu return f; }
Kód 2: Deklarace statické metody s celočíselným návratem s názvem FaktorialWhile
Další volanou metodu pro výpočet faktoriálu pomocí cyklu s podmínkou na konci je metoda s celočíselným návratem FaktorialDoWhile - viz Kód 3.
// Metoda s celočíselným návratem pro výpočet faktoriálu pomocí cyklu do-while static long FaktorialDoWhile(int n) { /* Deklarace: 'i' ... čítač (aktuální číslo v součinu); * 'f' ... hodnota faktoriálu */ int i; long f; // Inicializace i = 1; f = 1; do { // Výpočet faktoriálu f = f * i; // Inkrementace čítače i++; } // Opakuj, dokud je čítač menší, nebo roven číslu pro výpočet faktoriálu while (i <= n); // Návrat vypočtené hodnoty faktoriálu return f; }
Kód 3: Deklarace statické metody s celočíselným návratem s názvem FaktorialDoWhile
Poslední typem cyklu, použitým při výpočtu faktoriálu, je cyklus s krokem, který je využit v metodě FaktorialFor - viz Kód 4. Na rozdíl od předchozích metod je řídící proměnná deklarována a inicializována přímo v cyklu for.
// Metoda s celočíselným návratem pro výpočet faktoriálu pomocí cyklu for static long FaktorialFor(int n) { // Deklarace: 'f' ... hodnota faktoriálu long f; // Inicializace f = 1; // Cyklus s krokem; deklarace: 'i' ... čítač (aktuální číslo v součinu) for (int i = 1; i <= n; i++) { // Výpočet faktoriálu f = f * i; } // Návrat vypočtené hodnoty faktoriálu return f; }
Kód 4: Deklarace statické metody s celočíselným návratem s názvem FaktorialFor
Metoda s celočíselným návratem pro výpočet faktoriálu pomocí volání funkce využívající rekurzi je metoda FaktorialVolaniRekurze - viz Kód 5. V této metodě je volána rekurzivní metoda FaktorialRekurze.
/* Metoda s celočíselným návratem pro výpočet faktoriálu pomocí * volání funkce využívající rekurzi */ static long FaktorialVolaniRekurze(int n) { /* Návrat vypočtené hodnoty faktoriálu pomocí * volání metody pro výpočet faktoriálu pomocí rekurze */ return FaktorialRekurze(n); }
Kód 5: Deklarace statické metody s celočíselným návratem s názvem FaktorialVolaniRekurze
Metoda FaktorialRekurze využívá principu rekurze, kde metoda volá sama sebe (tím se postupně zanořuje sama do sebe) - viz Kód 6. Při každém takovém zanořování je předán parametr o hodnotu o 1 menší než v předchozím volání. V metodě tedy musí být definována podmínka, kdy je toto vnořování zastaveno, tj. n == 0. Až tato podmínka bude vyhodnocena jako true, nastane postupné předávání vypočtené hodnoty faktoriálu zpět do volajících metod. Tento cyklus postupného předávání zpět probíhá tak dlouho, dokud neobdržíme výsledek příkazu, který odstartoval volání vnořených metod.
// Metoda s celočíselným návratem pro výpočet faktoriálu pomocí rekurze static long FaktorialRekurze(int n) { // Deklarace: 'f' ... hodnota faktoriálu long f; // Pokud je předaná hodnota v parametru rovna nule if (n == 0) { // Faktoriál je 1 f = 1; } else { // Rekurzivní volání metody(metoda volá sama sebe) f = n * FaktorialRekurze(n - 1); } // Přiřazení návratu metody return f; }
Kód 6: Deklarace statické rekurzivní metody s celočíselným návratem s názvem FaktorialRekurze
1.3. Výsledný kód
Následující zdrojový kód je kompletací předešlých kódů programu Faktorial, který je umístěn v souboru Program.cs - viz Kód 1.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Faktorial { class Program { static void Main(string[] args) { // Výpis textu Console.WriteLine("Výpočet faktoriálu"); // Výzva k zadání čísla pro výpočet faktoriálu Console.Write("Zadejte číslo: "); /* Načtení čísla - 'n' ... číslo, pro které bude vypočten * faktoriál (výstupní parametr TryParse) */ int.TryParse(Console.ReadLine(), out int n); /* Výpis textu a hodnoty faktoriálu, který je výstupem zavolané funkce * s předaným parametrem 'n'; specifikace výstupního formátu * čísla "N0", tj. bez čísel za desetinnou čárkou */ Console.WriteLine("Faktoriál (cyklus while): " + FaktorialWhile(n).ToString("N0")); Console.WriteLine("Faktoriál (cyklus do-while): " + FaktorialDoWhile(n).ToString("N0")); Console.WriteLine("Faktoriál (cyklus for): " + FaktorialFor(n).ToString("N0")); Console.WriteLine("Faktoriál (rekurze): " + FaktorialVolaniRekurze(n).ToString("N0")); // Čekání na stisk klávesy -> ukončení programu Console.ReadKey(); } // Metoda s celočíselným návratem (datový typ long) pro výpočet faktoriálu pomocí cyklu while static long FaktorialWhile(int n) { /* Deklarace: 'i' ... čítač (aktuální číslo v součinu); * 'f' ... hodnota faktoriálu */ int i; long f; // Inicializace i = 1; f = 1; // Opakuj, pokud je čítač menší, nebo roven číslu pro výpočet faktoriálu while (i <= n) { // Výpočet faktoriálu f = f * i; // Inkrementace čítače i++; } // Návrat vypočtené hodnoty faktoriálu return f; } // Metoda s celočíselným návratem pro výpočet faktoriálu pomocí cyklu do-while static long FaktorialDoWhile(int n) { /* Deklarace: 'i' ... čítač (aktuální číslo v součinu); * 'f' ... hodnota faktoriálu */ int i; long f; // Inicializace i = 1; f = 1; do { // Výpočet faktoriálu f = f * i; // Inkrementace čítače i++; } // Opakuj, dokud je čítač menší, nebo roven číslu pro výpočet faktoriálu while (i <= n); // Návrat vypočtené hodnoty faktoriálu return f; } // Metoda s celočíselným návratem pro výpočet faktoriálu pomocí cyklu for static long FaktorialFor(int n) { // Deklarace: 'f' ... hodnota faktoriálu long f; // Inicializace f = 1; // Cyklus s krokem; deklarace: 'i' ... čítač (aktuální číslo v součinu) for (int i = 1; i <= n; i++) { // Výpočet faktoriálu f = f * i; } // Návrat vypočtené hodnoty faktoriálu return f; } // Metoda s celočíselným návratem pro výpočet faktoriálu pomocí rekurze static long FaktorialRekurze(int n) { // Deklarace: 'f' ... hodnota faktoriálu long f; // Pokud je předaná hodnota v parametru rovna nule if (n == 0) { // Faktoriál je 1 f = 1; } else { // Rekurzivní volání metody s návratem (metoda volá sama sebe) f = n * FaktorialRekurze(n - 1); } // Návrat vypočtené hodnoty faktoriálu return f; } /* Metoda s celočíselným návratem pro výpočet faktoriálu pomocí * volání metody využívající rekurzi */ static long FaktorialVolaniRekurze(int n) { /* Návrat vypočtené hodnoty faktoriálu pomocí * volání metody pro výpočet faktoriálu pomocí rekurze */ return FaktorialRekurze(n); } } }
Kód 1: Program Faktorial - deklarace hlavní statické metody Main včetně deklarací dalších metod
Výstup programu
Na následujícím výstupu programu vidíme výpis vypočtených hodnot faktoriálu pomocí různých typů cyklu a za použití rekurze - viz Výstup programu - Kód 1.

Výstup programu - Kód 1: Ukázka výpisu vypočtených hodnot faktoriálu v hlavní metodě programu Faktorial
2. FaktorialWPF
Úlohou je vytvořit aplikaci na výpočet faktoriálu:
- s cyklem s krokem (for)
- s cyklem s podmínkou na začátku (while)
- s cyklem s podmínkou na konci (do while)
- pomocí rekurze
Účel příkladu
- Rekurze
Typ aplikace
- WPF aplikace
Popis úkolu
- Výpočet faktoriálu
Funkčnosti
- Při stisku tlačítka For se provede načtení čísla z pole Zadejte číslo. Následně bude vypočten faktoriál tohoto čísla pomocí cyklu s pevným krokem. Vypočtená hodnota faktoriálu bude vypsána do pole Faktoriál
- Při stisku tlačítka While se provede načtení čísla z pole Zadejte číslo. Následně bude vypočten faktoriál tohoto čísla pomocí cyklu s podmínkou na začátku. Vypočtená hodnota faktoriálu bude vypsána do pole Faktoriál
- Při stisku tlačítka Do While se provede načtení čísla z pole Zadejte číslo. Následně bude vypočten faktoriál tohoto čísla pomocí cyklu s podmínkou na konci. Vypočtená hodnota faktoriálu bude vypsána do pole Faktoriál
- Při stisku tlačítka Rekurze se provede načtení čísla z pole Zadejte číslo. Následně bude vypočten faktoriál tohoto čísla pomocí zavolání funkce, která obsahuje rekurzi. Vypočtená hodnota faktoriálu bude vypsána do pole Faktoriál
- Při stisku tlačítka Konec se provede zavření formuláře
Výstup programu
Výstup programu 1: Ukázka GUI při počátečním spuštění programu FaktorialWPF
Výsledek:
Výstup programu 2: Ukázka výpisu vypočteného faktoriálu programu FaktorialWPF
2.1. Analýza a návrh řešení
V příkladu bude využit stejný princip výpočtu faktoriálu jako v příkladu Faktorial, proto již není zapotřebí provádět detailní analýzu.
Formulář bude obsahovat následující prvky - viz Obrázek 1.
Obrázek 1: Návrh GUI pro aplikaci FaktorialWPF
Pro rozložení jednotlivých prvků použijeme Grid, který rozdělíme na 2 řádky a 2 sloupce. Do prvního řádku Grid (s indexem 0) do každého sloupce umístíme objekt typu WrapPanel do nichž budeme pokaždé vkládat 2 objekty. První vložený objekt slouží pro popisek (objekt typu Label ). Za tento objekt umístíme objekt typu TextBox. V TextBox umístěném v prvním sloupci budeme zadávat hodnotu, pro níž budeme počítat faktoriál. V dalším objektu TextBox umístěném ve druhém sloupci budeme vypisovat vypočtenou hodnotu faktoriálu. Do druhého řádku řádku Grid umístíme StackPanel, do něhož umístíme dva objekty typu WrapPanel. Do prvního WrapPanel umístíme tlačítka pro výpočet faktoriálu. Do druhého WrapPanel umístíme tlačítko pro ukončení aplikace.
Obrázek 2: Návrh GUI - rozložení prvků v mřížce formuláře
2.2. XAML
Na základě našich zkušeností s XAML bude již stručně popsán postup tvorby formuláře. Formulář rozdělíme na dva řádky a dva sloupce. Výška prvního řádku se bude přizpůsobovat roztažení okna. Druhý řádek se přizpůsobí obsahu vložených prvků. - viz Kód 1.
<Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions>
Kód 1: Rozdělení Grid na řádky
Šířka obou sloupců se budou přizpůsobovat roztažení okna - viz Kód 2.
<Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions>
Kód 2: Rozdělení Grid na sloupce
Do prvního řádku Grid (s indexem 0) a prvního sloupce umístíme objekt typu WrapPanel. První objekt typu Label je popisek dalšího vloženého objektu typu TextBox. V TextBox budeme zadávat hodnotu, pro níž bude vypočten faktoriál pomocí stisknutí některého z tlačítek. Číslo (číslice) vepsané do TextBox je vystředěno jak v horizontální tak i vertikální ose - viz Kód 3.
<WrapPanel Margin="5,20,5,5" HorizontalAlignment="Center"> <Label Content="Zadejte číslo:" Margin="5" /> <TextBox Name="TxtCislo" Margin="5" TextWrapping="Wrap" Text="0" Width="120" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/> </WrapPanel>
Kód 3: WrapPanel s popiskem (Label) a zadávanou hodnotou (v TextBox), pro níž bude vypočten faktoriál
V dalším WrapPanel v prvním řádku a ve druhém sloupci Grid bude také umístěn popisek (objekt typu Label) a objekt TextBox, do nějž budeme vypsána vypočtená hodnota faktoriálu. Tento TextBox zamkneme pro vkládání dat (vlastnost IsReadOnly) a podbarvíme (Background). Umožníme také zalamování textu do více řádků (vlastnost TextWrapping). Hodnota faktoriálu vypsaného do TextBox bude vystředěna jak v horizontální tak vertikální ose - viz Kód 4.
<WrapPanel Margin="5,20,5,5" Grid.Column="1" HorizontalAlignment="Center"> <Label Content="Faktoriál:" Margin="5" /> <TextBox Name="TxtFaktorial" Margin="5" TextWrapping="Wrap" Text="0" Width="200" IsReadOnly="True" Background="AliceBlue" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/> </WrapPanel>
Kód 4: WrapPanel s popiskem (Label) a vypisovanou hodnotou (v TextBox) vypočteného faktoriálu
Do druhého řádku řádku Grid umístíme StackPanel, do něhož umístíme dva objekty typu WrapPanel. Do prvního WrapPanel umístíme tlačítka pro výpočet faktoriálu. Do druhého WrapPanel umístíme tlačítko pro ukončení aplikace. Pro tlačítka vygenerujeme obsluhu události stisknutí tlačítka (událost Click) pomocí nastavení vlastnosti Click a zvolení položky <New Event Handler> - viz Kód 5.
<StackPanel Grid.Row="1" Grid.ColumnSpan="2"> <WrapPanel HorizontalAlignment="Center"> <Button Name="BtnFor" Content="For" Margin="5" Width="110" Height="30" Click="BtnFor_Click"/> <Button Name="BtnWhile" Content="While" Margin="5" Width="110" Click="BtnWhile_Click"/> <Button Name="BtnDoWhile" Content="Do While" Margin="5" Width="110" Click="BtnDoWhile_Click"/> <Button Name="BtnRekurze" Content="Rekurze" Margin="5" Width="110" Click="BtnRekurze_Click"/> <Button Name="BtnMazat" Content="Mazat" Margin="5" Width="110" Click="BtnMazat_Click"/> </WrapPanel> <WrapPanel HorizontalAlignment="Right"> <Button Name="BtnKonec" Content="Konec" Margin="5" Width="80" Padding="5" Click="BtnKonec_Click"/> </WrapPanel> </StackPanel>
Kód 5: StackPanel - umístění tlačítek v objektech typu WrapPanel v posledním řádku Grid
Výsledný formulář
Navržené rozložení prvků na formuláři, včetně formuláře samotného, je vidět na následujícím obrázku - viz Obrázek 1.
Obrázek 1: Výsledný formulář WPF aplikace
Objekty na formuláři:
Formulář obsahuje následující objekty (kontrolky):
- Grid
- StackPanel
- WrapPanel
- Label
- TextBox
- TxtCislo
- TxtFaktorial
- Button
- BtnFor
- BtnWhile
- BtnDoWhile
- BtnBezCyklu
- BtnMazat
- BtnKonec
Obrázek 2: VS - okno Document Outline - seznam objektů
2.3. XAML - prvky formuláře
Následující XAML kód obsahuje nastavení formuláře - viz Kód 1. Pokud je zapotřebí zkopírujte XAML kód a vložte jej namísto řádky s nastavením vlastností okna (řádek začíná Title=....).
Title="Výpočet faktoriálu" Height="250" Width="800">
Kód 1: Nastavení vlastností formuláře
Grid
Následující zdrojový kód XAML obsahuje potřebné prvky na formuláři pro řešení úlohy, bez nastavení událostí - viz Kód 2. Pokud je zapotřebí, zkopírujte XAML kód a vložte jej mezi počáteční a koncovou značku prvku Grid.<Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <WrapPanel Margin="5,20,5,5" HorizontalAlignment="Center"> <Label Content="Zadejte číslo:" Margin="5" /> <TextBox Name="TxtCislo" Margin="5" TextWrapping="Wrap" Text="0" Width="120" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/> </WrapPanel> <WrapPanel Margin="5,20,5,5" Grid.Column="1" HorizontalAlignment="Center"> <Label Content="Faktoriál:" Margin="5" /> <TextBox Name="TxtFaktorial" Margin="5" TextWrapping="Wrap" Text="0" Width="200" IsReadOnly="True" Background="AliceBlue" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/> </WrapPanel> <StackPanel Grid.Row="1" Grid.ColumnSpan="2"> <WrapPanel HorizontalAlignment="Center"> <Button Name="BtnFor" Content="For" Margin="5" Width="110" Height="30"/> <Button Name="BtnWhile" Content="While" Margin="5" Width="110"/> <Button Name="BtnDoWhile" Content="Do While" Margin="5" Width="110"/> <Button Name="BtnRekurze" Content="Rekurze" Margin="5" Width="110"/> <Button Name="BtnMazat" Content="Mazat" Margin="5" Width="110"/> </WrapPanel> <WrapPanel HorizontalAlignment="Right"> <Button Name="BtnKonec" Content="Konec" Margin="5" Width="80" Padding="5"/> </WrapPanel> </StackPanel>
Kód 2: Prvky v Grid
2.4. C#
V souboru MainWindow.xaml.cs obsahující kód na pozadí (Code Behind) byla vygenerována základní struktura našeho programu v C#. Vedle konstruktoru MainWindow této třídy byly také vygenerovány soukromé (private) metody bez návratu:
- BtnFor_Click
- BtnWhile_Click
- BtnDoWhile_Click
- BtnRekurze_Click
- BtnMazat
- BtnKonec_Click
Tyto metody umístíme do regionu Události, abychom oddělili kódy pro obsluhu události Click jednotlivých tlačítek od regionu Výpočty, do kterého umístíme metodu s rekurzivním volání funkce pro výpočet faktoriálu.
Prvním typem cyklu, použitým při výpočtu faktoriálu, je cyklus s krokem, který je využit v metodě pro obsluhu události tlačítka BtnFor - viz Kód 1. Hodnota pro níž je vypočten faktoriál, je načtena přímo z formuláře. Řídící proměnná cyklu je deklarována a inicializována přímo v cyklu for. Výpis vypočteného faktoriálu (konvertovaného čísla na text ve formátu bez desetinných míst) je vypsán na formulář.
private void BtnFor_Click(object sender, RoutedEventArgs e) { // Deklarace: 'f' ... hodnota faktoriálu - inicializace long f = 1; // Načtení čísla pro výpočet faktoriálu a jeho konverze na číslo int.TryParse(TxtCislo.Text, out int n); // Cyklus s krokem; deklarace: 'i' ... čítač (aktuální číslo v součinu) for (int i = 1; i <= n; i++) { // Výpočet faktoriálu f = f * i; } // Zformátovaný výpis vypočteného faktoriálu (konverze na text) this.TxtFaktorial.Text = f.ToString("N0"); }
Kód 1: Deklarace metody pro výpočet faktoriálu pomocí cyklu s krokem (BtnFor_Click)
Pro výpočet faktoriálu jsme v metodě pro obsluhu události stisknutí tlačítka BtnWhile využili cyklus s podmínkou na začátku - viz Kód 2. V této metodě jsou použity dvě lokální proměnné i a f. Proměnná i představuje čítač cyklu, ale zároveň představuje aktuální číslo v součinu. Tato proměnná je datového typu int, protože není zapotřebí velký rozsah zadávaných čísel vzhledem k horní mezi datového typu long vybraného pro proměnnou f, která představuje hodnotu vypočteného faktoriálu. Výraz f = f * i; bychom mohli zkrátit pomocí zápisu f *= i; . Dále jsme také zkrátili zápis inkrementace i = i + 1; na i++.
private void BtnWhile_Click(object sender, RoutedEventArgs e) { /* Deklarace: 'i' ... čítač (aktuální číslo v součinu) - inicializace; * 'f' ... hodnota faktoriálu - inicializace */ int i = 1; long f = 1; // Načtení čísla pro výpočet faktoriálu a jeho konverze na číslo int.TryParse(TxtCislo.Text, out int n); // Opakuj, pokud je čítač menší, nebo roven číslu pro výpočet faktoriálu while (i <= n) { // Výpočet faktoriálu f = f * i; // Inkrementace čítače i++; } // Zformátovaný výpis vypočteného faktoriálu (konverze na text) this.TxtFaktorial.Text = f.ToString("N0"); }
Kód 2: Deklarace metody pro výpočet faktoriálu pomocí cyklu s podmínkou na začátku (BtnWhile_Click)
Další volanou metodou pro výpočet faktoriálu pomocí cyklu s podmínkou na konci je metoda pro obsluhu události tlačítka BtnDoWhile - viz Kód 3.
private void BtnDoWhile_Click(object sender, RoutedEventArgs e) { /* Deklarace: 'i' ... čítač (aktuální číslo v součinu) - inicializace; * 'f' ... hodnota faktoriálu - inicializace */ int i = 1; long f = 1; // Načtení čísla pro výpočet faktoriálu a jeho konverze na číslo int.TryParse(TxtCislo.Text, out int n); do { // Výpočet faktoriálu f = f * i; // Inkrementace čítače i++; } // Opakuj, dokud je čítač menší, nebo roven číslu pro výpočet faktoriálu while (i <= n); // Zformátovaný výpis vypočteného faktoriálu (konverze na text) this.TxtFaktorial.Text = f.ToString("N0"); }
Kód 3: Deklarace metody pro výpočet faktoriálu pomocí cyklu s podmínkou na konci (BtnDoWhile_Click)
Další metodou pro obsluhu události stisknutí tlačítka BtnRekurze je metoda, kdy je výpočet faktoriálu realizován pomocí volání rekurzivní metody FaktorialRekurze s návratem - viz Kód 4. Tuto metodu umístíme mimo region Události do regionu s názvem Výpočty.
private void BtnRekurze_Click(object sender, RoutedEventArgs e) { // Deklarace: 'f' ... hodnota faktoriálu long f; // Načtení čísla pro výpočet faktoriálu a jeho konverze na číslo int.TryParse(TxtCislo.Text, out int n); // Volání rekurzivní funkce - předání čísla pro výpočet faktoriálu f = FaktorialRekurze(n); // Zformátovaný výpis vypočteného faktoriálu (konverze na text) this.TxtFaktorial.Text = f.ToString("N0"); }
Kód 4: Deklarace metody pro výpočet faktoriálu pomocí rekurze (BtnRekurze_Click)
Soukromá metoda s celočíselným návratem využívá principu rekurze, kde metoda volá sama sebe (tím se postupně zanořuje sama do sebe) - viz Kód 5.
/// <summary> /// Metoda s celočíselným návratem pro výpočet faktoriálu pomocí rekurze /// </summary> /// <param name="n"> číslo pro výpočet faktoriálu </param> /// <returns> vypočtený faktoriál </returns> private long FaktorialRekurze(int n) { // Pokud je předaná hodnota v parametru rovna nule if (n == 0) { // Faktoriál je 1 return 1; } else { // Rekurzivní volání metody(metoda volá sama sebe) return n * FaktorialRekurze(n - 1); } }
Kód 6: Deklarace soukromé rekurzivní metody s celočíselným návratem (FaktorialRekurze)
Předposlední metodou, kterou budeme vytvářet, je metoda pro výmaz vypsané hodnoty faktoriálu na formuláři. Pro vymazání textu v objektu typu TextBox použijeme příkaz (Clear) - viz Kód 7.
private void BtnMazat_Click(object sender, RoutedEventArgs e) { // Vymazání předchozího výpisu faktoriálu this.TxtFaktorial.Clear(); }
Kód 7: Deklarace metody pro výmaz vypočteného faktoriálu vypsaného na formuláři (BtnMazat_Click)
Poslední metodou, kterou musíme upravit je metoda pro obsluhu události Click tlačítka Konec. Tato metoda nám zavře formulář - viz Kód 8.
private void BtnKonec_Click(object sender, RoutedEventArgs e) { // Zavření formuláře this.Close(); }
Kód 8: Deklarace metody bez návratu pro zavření formuláře (BtnKonec_Click)
2.5. Výsledný kód
XAML kód
Výsledný XAML kód formuláře (MainWindow.xaml) - viz Kód 1.
<Window x:Class="FaktorialWPF.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:local="clr-namespace:FaktorialWPF" mc:Ignorable="d" Title="Výpočet faktoriálu" Height="250" Width="800"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="*"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <WrapPanel Margin="5,20,5,5" HorizontalAlignment="Center"> <Label Content="Zadejte číslo:" Margin="5" /> <TextBox Name="TxtCislo" Margin="5" TextWrapping="Wrap" Text="0" Width="120" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/> </WrapPanel> <WrapPanel Margin="5,20,5,5" Grid.Column="1" HorizontalAlignment="Center"> <Label Content="Faktoriál:" Margin="5" /> <TextBox Name="TxtFaktorial" Margin="5" TextWrapping="Wrap" Text="0" Width="200" IsReadOnly="True" Background="AliceBlue" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/> </WrapPanel> <StackPanel Grid.Row="1" Grid.ColumnSpan="2"> <WrapPanel HorizontalAlignment="Center"> <Button Name="BtnFor" Content="For" Margin="5" Width="110" Height="30" Click="BtnFor_Click"/> <Button Name="BtnWhile" Content="While" Margin="5" Width="110" Click="BtnWhile_Click"/> <Button Name="BtnDoWhile" Content="Do While" Margin="5" Width="110" Click="BtnDoWhile_Click"/> <Button Name="BtnRekurze" Content="Rekurze" Margin="5" Width="110" Click="BtnRekurze_Click"/> <Button Name="BtnMazat" Content="Mazat" Margin="5" Width="110" Click="BtnMazat_Click"/> </WrapPanel> <WrapPanel HorizontalAlignment="Right"> <Button Name="BtnKonec" Content="Konec" Margin="5" Width="80" Padding="5" Click="BtnKonec_Click"/> </WrapPanel> </StackPanel> </Grid> </Window>
Kód 1: Výsledný XAML kód vytvořeného formuláře
C# kód
Code Behind - C# kód pro veškeré události vyvolané uživatelem při manipulaci s aplikací (MainWindow.xaml.cs) - viz Kód 2.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace FaktorialWPF { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); } #region Výpočty /// <summary> /// Metoda s celočíselným návratem pro výpočet faktoriálu pomocí rekurze /// </summary> /// <param name="n"> číslo pro výpočet faktoriálu </param> /// <returns> vypočtený faktoriál </returns> private long FaktorialRekurze(int n) { // Pokud je předaná hodnota v parametru rovna nule if (n == 0) { // Faktoriál je 1 return 1; } else { // Rekurzivní volání metody(metoda volá sama sebe) return n * FaktorialRekurze(n - 1); } } #endregion #region Události private void BtnFor_Click(object sender, RoutedEventArgs e) { // Deklarace: 'f' ... hodnota faktoriálu - inicializace long f = 1; // Načtení čísla pro výpočet faktoriálu a jeho konverze na číslo int.TryParse(TxtCislo.Text, out int n); // Cyklus s krokem; deklarace: 'i' ... čítač (aktuální číslo v součinu) for (int i = 1; i <= n; i++) { // Výpočet faktoriálu f = f * i; } // Zformátovaný výpis vypočteného faktoriálu (konverze na text) this.TxtFaktorial.Text = f.ToString("N0"); } private void BtnWhile_Click(object sender, RoutedEventArgs e) { /* Deklarace: 'i' ... čítač (aktuální číslo v součinu) - inicializace; * 'f' ... hodnota faktoriálu - inicializace */ int i = 1; long f = 1; // Načtení čísla pro výpočet faktoriálu a jeho konverze na číslo int.TryParse(TxtCislo.Text, out int n); // Opakuj, pokud je čítač menší, nebo roven číslu pro výpočet faktoriálu while (i <= n) { // Výpočet faktoriálu f = f * i; // Inkrementace čítače i++; } // Zformátovaný výpis vypočteného faktoriálu (konverze na text) this.TxtFaktorial.Text = f.ToString("N0"); } private void BtnDoWhile_Click(object sender, RoutedEventArgs e) { /* Deklarace: 'i' ... čítač (aktuální číslo v součinu) - inicializace; * 'f' ... hodnota faktoriálu - inicializace */ int i = 1; long f = 1; // Načtení čísla pro výpočet faktoriálu a jeho konverze na číslo int.TryParse(TxtCislo.Text, out int n); do { // Výpočet faktoriálu f = f * i; // Inkrementace čítače i++; } // Opakuj, dokud je čítač menší, nebo roven číslu pro výpočet faktoriálu while (i <= n); // Zformátovaný výpis vypočteného faktoriálu (konverze na text) this.TxtFaktorial.Text = f.ToString("N0"); } private void BtnRekurze_Click(object sender, RoutedEventArgs e) { // Deklarace: 'f' ... hodnota faktoriálu long f; // Načtení čísla pro výpočet faktoriálu a jeho konverze na číslo int.TryParse(TxtCislo.Text, out int n); // Volání rekurzivní funkce - předání čísla pro výpočet faktoriálu f = FaktorialRekurze(n); // Zformátovaný výpis vypočteného faktoriálu (konverze na text) this.TxtFaktorial.Text = f.ToString("N0"); } private void BtnMazat_Click(object sender, RoutedEventArgs e) { // Vymazání předchozího výpisu faktoriálu this.TxtFaktorial.Clear(); } private void BtnKonec_Click(object sender, RoutedEventArgs e) { // Zavření formuláře this.Close(); } #endregion } }
Kód 2: Výsledný C# kód vytvořeného formuláře a metod jeho prvků
Výstup programu
Na následujícím obrázku vidíme výstup naší aplikace pro výpočet faktoriálu ze zadaného čísla - viz Výstup programu - Kód 1 a 2. Výpočet faktoriálu s následným výpisem hodnoty faktoriálu je spouštěn pomocí příslušného tlačítka s určitým typem cyklu, nebo rekurze. Aplikaci lze ukončit pomocí tlačítka Konec, nebo pomocí zavíracího tlačítka umístěného v pravém rohu aplikace.
Výstup programu - Kód 1 a 2: Výpis hodnoty vypočteného faktoriálu pomocí cyklu s krokem