Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Diskuze – Lekce 6 - Cykly v Céčku

Zpět

Upozorňujeme, že diskuze pod našimi online kurzy jsou nemoderované a primárně slouží k získávání zpětné vazby pro budoucí vylepšení kurzů. Pro studenty našich rekvalifikačních kurzů nabízíme možnost přímého kontaktu s lektory a studijním referentem pro osobní konzultace a podporu v rámci jejich studia. Toto je exkluzivní služba, která zajišťuje kvalitní a cílenou pomoc v případě jakýchkoli dotazů nebo projektů.

Komentáře
Avatar
Odpovídá na DarkCoder
Lukáš Gardoň:21.11.2019 10:44

Děkuji moc za vysvětlení(do­plnění).

 
Odpovědět
21.11.2019 10:44
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Lukáš Gardoň
DarkCoder:21.11.2019 14:27

Ještě jedna věc. Celý program si rozděl na samostatné části, kde kontrolu jednotlivých úseků programu prováděj ihned kdykoli to jde.

printf("Zadejte prvni cislo: ");
scanf("%lf", &a);
printf("Zadejte druhe cislo: ");
scanf("%lf", &b);

Zde opakuj volbu dokud obě načtení neproběhnou úspěšně. Tedy kontroluješ návratovou hodnotu funkcí scanf() v logickém součinu.

printf("Zvolte si operaci:\n");
printf("1 - scitani \n");
printf("2 - odcitani \n");
printf("3 - nasobeni \n");
printf("4 - deleni \n");
scanf("%d", &volba);

Zde opakuj volbu dokud volba není v rozsahu 1-4 v oboru přirozených čísel. Tedy kontrolu neprovádíš v následujícím kroku u řídícího příkazu switch.

switch(volba) {
        case 1: printf("Vysledek %f\n", a + b); break;
        case 2: printf("Vysledek %f\n", a - b); break;
        case 3: printf("Vysledek %f\n", a * b); break;
        case 4: if(b) printf("Vysledek %f\n", a / b); break;
}

Zde již víš, že volba nabývá hodnot 1,2,3 nebo 4. Nic jiného. Můžeš tak přímo provádět operaci bez sekce default nebo nějaké vyjímky. V tomto příkladě mohu přímo výsledek vypisovat bez přiřazování do proměnné, výraz operace je tenty argumentem funkce printf(). V reálných aplikací a pokročilejší kalkulačce však uložení do proměnné bude vhodnější. Jak jistě víš, dělení nulou není v oboru celých čísel definováno, proto ta podmínka na nenulovou hodnotu ve volbě dělení. Žádná neplatná volba zde nemůže nastat, vše bylo odladěno v předhozí části.

Poslední krok je výzva pro opakování. Zde by bylo bezesporu vhodnější použít znakovou volbu nežli číslicovou. To však není tématem tohoto článku.

printf("Pro pokracovani volba 1,ukoncit volba 0: \n");
scanf("%d", &pokracovani);

Zde opakuj volbu dokud volba není v rozsahu 0 - 1 v oboru přirozených čísel. Pro vyhodnocení se můžeš řídit podmínkou cyklu do-while nebo využít příkazy break a continue v podmínkovém rozhodovacím příkazu (?:).

(pokracovani) ? continue : break;

což odpovídá:

if (pokracovani != 0) continue;
else break;

Když se nad tím vším zamyslíš, zjistíš, že cykly (i cyklus do-while) se používají hojně v C a jejich znalost je bězpodmínečná pro úspěšné programování v C.

Editováno 21.11.2019 14:28
Odpovědět
21.11.2019 14:27
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
Lukáš Gardoň:22.11.2019 14:13

Ahoj, moc děkuji za připomínky a rady. Trošku jsem upravil program podle toho co jsi psal, ale stale nevím jak můžu zkontrolovat to zda jsem zadal číslo a né znak. A to jak u prvních načitání čísel tak i u dalších proměnných jako je volna nebo pokračovaní. Mohl bys mi prosím ukázat příklad nebo mě nasměřovat ?

Děkuji.

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char** argv)
{
double a;
double b;
int volba;
double vysledek;
int pokracovani;
printf("Vitejte v kalkulacce \n");

do
 {
    printf("Zadejte prvni cislo: \n");
    scanf("%lf", &a);
    printf("Zadejte druhe cislo: \n");
    scanf("%lf", &b);
    do
    {
        printf("Zvolte si operaci: \n");
        printf("0 - ukoncit \n");
        printf("1 - scitani \n");
        printf("2 - odcitani \n");
        printf("3 - nasobeni \n");
        printf("4 - deleni \n");
        scanf("%d", &volba);

        if ((volba<0) || (volba>4))
                printf("Opakuj volbu\n");
    }while ((volba<0) || (volba>4));

    switch(volba)
        {
        case 0: pokracovani=0; break;
        case 1: printf("Vysledek je %f\n", a + b); break;
        case 2: printf("Vysledek je %f\n", a - b); break;
        case 3: printf("Vysledek je %f\n", a * b); break;
        case 4:
            {
            if (b!=0)
                printf("Vysledek je %f\n", a / b);
            else printf("Nulou nelze delit");
            break;
            }
        }

        printf("\n");

        if(pokracovani!=0)
            {
            do
            {
                printf("Pro pokracovani volba 1,ukoncit volba 0\n");
                scanf("%d", &pokracovani);
                if ((pokracovani<0) || (pokracovani>1))
                printf("Opakuj volbu\n");
            }while ((pokracovani<0) || (pokracovani>1));
            }

    }while (pokracovani==1);
printf("Dekuji za pouziti kalkulacky");
return (EXIT_SUCCESS);
}
 
Odpovědět
22.11.2019 14:13
Avatar
DarkCoder
Člen
Avatar
Odpovídá na Lukáš Gardoň
DarkCoder:22.11.2019 21:29

Správně tušíš, že program bude tvořen několika vnořenými do-while cykly v do-while cyklu. Je to proto, že program by se měl chovat vůči uživateli přátelsky. Tedy při nesprávných vstupech opakovat výzvy a načítání hodnot od uživatele a nikoli okamžitě ukončovat program. Dokonalé odladění programu si vyžaduje znalost vyšších programovacích technik (manipulace se vstupním bufferem) a představu o tom, jak uživatel může třeba i nechtíc nabourat program. Uživatelsky přátelský přístup, robustnost programu, jednoduchost, výkonnost a přehlednost jsou kritéria, na které je třeba při tvorbě aplikace neustále myslet. Abys měl představu jak by taková jednoduchá kalkulačka mohla vypadat, podívej na následující kód.

#include <stdio.h>
#include <stdlib.h>

int main(void){
        double a, b;
        int status, volba;

        printf("Vitejte v kalkulacce\n\n");

        do {
                // Zadani prvniho cisla
                do {
                        printf("Zadejte prvni cislo: ");
                        status = scanf("%lf", &a);
                        fseek(stdin, 0L, SEEK_END);
                        if (!status) printf("Neplatny vstup\n\n");
                } while (!status);

                // Zadani druheho cisla
                do {
                        printf("Zadejte druhe cislo: ");
                        status = scanf("%lf", &b);
                        fseek(stdin, 0L, SEEK_END);
                        if (!status) printf("Neplatny vstup\n\n");
                } while (!status);

                // Volba operace
                do {
                        printf("\nZvolte si operaci: \n");
                        printf("0 - ukoncit \n");
                        printf("1 - scitani \n");
                        printf("2 - odcitani \n");
                        printf("3 - nasobeni \n");
                        printf("4 - deleni \n\n");
                        status = scanf("%d", &volba);
                        fseek(stdin, 0L, SEEK_END);

                        if (status && ((volba >= 0) && (volba <= 4))) break;
                        else printf("Neznama operace\n\n");
                } while (1);

                // Vypis vysledku operace
                switch (volba) {
                        case 0: printf("Dekuji za pouziti kalkulacky\n"); exit(0);
                        case 1: printf("Vysledek je %f\n\n", a + b); break;
                        case 2: printf("Vysledek je %f\n\n", a - b); break;
                        case 3: printf("Vysledek je %f\n\n", a * b); break;
                        case 4: if (b) printf("Vysledek je %f\n\n", a / b);
                                else printf("Nelze delit nulou\n\n");
                                break;
                }

                // Volba pokracovani
                do {
                        printf("Chcete pokracovat? \n");
                        printf("1 - pokracovani, 0 - ukonceni \n\n");
                        status = scanf("%d", &volba);
                        fseek(stdin, 0L, SEEK_END);

                        if (status && ((volba >= 0) && (volba <= 1))) break;
                        else printf("Neznama volba\n\n");
                } while (1);
        } while (volba);

        printf("Dekuji za pouziti kalkulacky\n");

        return 0;
}

Program by šel samozřejmě ještě zefektivnit (přistupovat k dané operaci lze přímo pomocí pole ukazatelů na funkce), použití řídícího příkazu switch je v tomto případě postačující volbou, jak z hlediska výkonu tak z hlediska jednoduchosti. Navíc by nebylo zrovna vhodné do článku týkající se základů vkládat pokročilé techniky o kterých nebyla v předchozích článcích řeč. Jak vidíš, je z důvodu zachování uživatelsky přátelského přístupu práce s cykly (zejména do-while) více než běžná. Věřím, že Ti byla tato prezentace ku prospěchu. Pokud Ti cokoli z toho nebude jasné, ptej se..

Editováno 22.11.2019 21:31
Odpovědět
22.11.2019 21:29
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Avatar
DarkCoder
Člen
Avatar
DarkCoder:26.5.2023 14:17

Kód pro výpočet mocniny (i třeba jen v oboru celých čísel):

vysledek = a;
for (i = 0; i < (n - 1); i++)
    vysledek = vysledek * a;

postrádá ošetření na umocňování na 0.

Chyba se vyskytuje napříč všemi sekcemi o programovacích jazycích.

Odpovědět
26.5.2023 14:17
"I ta nejlepší poučka postrádá na významu, není-li patřičně předána." - DarkCoder
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 5 zpráv z 55.