Warning
This page is located in archive.

4 - Řídicí struktury, vstupy, výstupy

Cílem cvičení je seznámit se se zadáváním základních typů, textovým vstupem a výstupem spolu s větvením programu. Cvičení se skládá ze čtyř hlavní částí, které jsou zaměřeny na procvičení jednotlivých programových konstruktů.

  • pro vyučující: 04

Výchozí program v Javě

V tomto cvičení již přejdeme od Karla k čisté Javě. Podobně jako v předchozích úlohách využijeme poskytnuté zdrojové soubory, pro které si založte ve vývojovém prostředí nový projekt. Výchozí zdrojové soubory pro toto cvičení si stáhněte z archívu: pr1-lab04.zip, který rozbalte do svého domovského adresáře (složky), např. ~/pr1/pr1-lab04 .

  • V NetBeans vytvořte nový projekt “pr1-lab04” z existujících zdrojových souborů z poskytnutého archivu.
    • Třída Start obsahuje pouze metodu public static void main(String[] args), která zajistí volání metody ze

     public static void main(String[] args) {
        Lab04 lab = new Lab04();
        lab.start(args);
     }

  • třídy Lab04, konkrétně metodu start(). Tato metoda tvoří hlavní vstup do vašeho programu.

     final int PART = 1;
 
     if (PART == 1) {
           part1();
     } else if (PART == 2) {
           part2();
     } else {
           System.out.println("part1 nor part2 has been specified");
     }

  • Z této metody se volají jednotlivé části cvičení pojmenované part1(), part2(), atd., které v průběhu cvičení doplníme o další části.

Informace k procvičovanému tématu

Formátovaný textový vstup

Pro vstup dat z klávesnice se s výhodou používá třída Scanner:

        Scanner scan = new Scanner(System.in);
        System.out.println("Enter a number:");
        int cislo = scan.nextInt();
        System.out.println("Enter a floating point number:");
        double d = scan.nextDouble();
        System.out.println("Enter a word:");
        String s = scan.next();
        System.out.println("Enter a whole line:");
        String r = scan.nextLine();

Poznámky:

  • Desetinné číslo se zadává s oddělovačem desetinné části podle zvoleného národního prostředí. Například v prostředí anglické lokalizace MS Windows je nutné zadávat desetinnou tečku. V případě českého prostředí se naopak používá desetinná čárka.
  • Načítání textového vstupu prostřednictvím standardního vstupu System.in je zpravidla konfigurováno pro zadání kompletního příkazu / vstupu počítače, historicky to odpovídá potvrzení vstupu klávesou Enter, proto je nutné předat vstup stiskem Enter.
  • Nicméně dílčí volání nextInt(), nextDouble() a next() zpracovávají takzvaný token, tj. textový řetězec oddělený definovaných znakem, např. mezerou nebo obecně takzvanou bílou mezerou z anglického “white space”.
  • Zkuste si proto při testování zadávání vstupu například zadat jediný řádek obsahující všechny očekávané vstupy 10 1023,44 slovo a zbytek celeho radku
Nepoužívejte více instancí třídy Scanner - test na odevzdávacím serveru pravděpodobně skončí s chybou!

Chcete-li použít Scanner v několika metodách, použijte ho takto:

    public class Lab {
        Scanner scan = new Scanner(System.in);
 
        public void method1() {
            System.out.println("Enter a number:");
            int cislo = scan.nextInt();
            System.out.println("Enter a floating point number:");
            double d = scan.nextDouble();
 
            ...
        }
 
        public void method2() {
            System.out.println("Enter a word:");
            String s = scan.next();
            System.out.println("Enter a whole line:");
            String r = scan.nextLine();
 
            ...
        }

Formátovaný textový výstup

Programovací jazyk Java poskytuje nejen základní metody pro formátování číselných typů a výpis řetězců, ale také způsob pro textovou reprezentaci času a data, který se zvláště hodí při unifikace a následné načítání. Předpis způsobu formátování je realizován textovým řetězcem obsahující vyhrazené formátovací znaky.

        String str = "Pepa";
        char ch = 'x';
        int i = 12;
        float f = 4.5F;
        Date date = new Date();
        System.out.printf("%b%n", str);
        System.out.printf("%c%n", ch);
        System.out.printf("%03d%n", i);
        System.out.printf("%e%n", f);
        System.out.printf("%03f%n", f);
        System.out.printf("%.2f%n", f);
        System.out.printf("{%07.3f}%n", f);
        System.out.printf("%f%n", f);
        System.out.printf("%g%n", f);
        System.out.printf("%h%n", f);
        System.out.printf("%s%n", 5);
        System.out.printf("%s://%s/%s%n", str, str, str);
        System.out.printf("%1$s...%n", str);
        System.out.printf("%5s%n", str);
        System.out.printf("%-5s%n", str);
        System.out.printf("%-10.10s %s%n", str, 3);
        System.out.printf("%.5s%n", str);
        System.out.printf("%s%n", date);
        System.out.printf("%tc%n", date); //(lowercase t, lowercase c)
        System.out.printf("%tC%n", date); //(lowercase t, uppercase C)
        System.out.printf("%tD%n", date);
        System.out.printf("%tF%n", date);
        System.out.printf("%tr%n", date);
        System.out.printf("%tR%n", date);
        System.out.printf("%tT%n", date);
        System.out.printf("%tz%n", date);
        System.out.printf("%Tc%n", date);
        System.out.printf("%1$x, %1$X%n", 0xCAFE);
        System.out.printf(Locale.CHINA, "%tc%n", date);
        System.out.printf(Locale.ITALIAN, "%tc%n", date);
        System.out.printf(Locale.getDefault(), "%tc%n", date);

Podívejte se na přehled formátových specifikátorů a speciálních znaků.

Řídicí struktury

Podmíněný příkaz

Příkaz if (podmíněný příkaz) umožňuje větvení na základě podmínky. Má dva tvary:

  1. if ( podmínka ) příkaz1 else příkaz2
  2. if ( podmínka ) příkaz1

Podmínka je logický výraz (výraz, jehož hodnota je typu boolean, tj. true nebo false).

Přestože lze tuto podmínku zapsat na jeden řádek volíme pro přehlednost spíše zápis se složenými závorkami

if ( podmínka ) {
  příkaz1
} else {
  příkaz2
}
Podmínky můžeme také řetězit:
if ( podmínka1 ) {
  příkaz1
} else if ( podmínka2 ) {
  příkaz2 
} else {
  příkaz3
}

Operátor ?

Tento operátor nazýváme ternárním, neboť má tři argumenty. Umožňuje zapsat úplnou podmínku stručnějším, avšak v některých případech méně přehledným způsobem, zvláště pokud je těchto operátorů vnořeno více do sebe. Jeho syntax je:

Podmínka ? Výraz1 : Výraz2;

Je-li podmínka vyhodnocena jako pravdivá, bere se hodnota výraz1, v opačném případě výraz2. Podmínku

if (a<b) { 
  c = a++;
} else {
  c = b++;
}

lze tedy zapsat jako

c = a < b ? a++ : b++;

Příkaz switch

Na rozdíl od konstrukce if-then a if-then-else, příkaz switch povoluje více cest větvení programu na základě hodnoty celočíselné proměnné, která je argumentem příkazu switch. Příkaz switch pracuje s primitivními typy: byte, short, char, int a s instancemi třídy String. Taktéž pracuje s výčtovými typy a se speciálními třídami obalujícími primitivní datové typy: Character, Byte, Short a Integer. Strukturu příkazu switch lze zapsat:

switch(vyraz){
   case konstanta1: 
      Prikaz1;
      break;
   case konstanta2:
      Prikaz2;
      break;
   ...
   default: 
      PrikazX;
      break;
}

Kódovací styl

Dobrý program nejen funguje podle očekávání, ale je také snadno čitelný a to jak pro jeho autora, tak pro další programátory. Čitelnost programu lze zvýšit komentáři nicméně dobrý zdrojový kód zpravidla komentáře nepotřebuje a jeho pochopení je intuitivní a pochopitelné z vhodně zvolených jmen proměnných a funkcí. Čitelnost a přehlednost lze také zvýšit dodržováním správných návyků (kódovacích konvencí) a formátovacího stylu zápisu programu.

V tomto cvičení si proto povšimněte, jak jsou zapisovány proměnné, konstanty a jména funkcí.

  • Proměnné by měly pokud možno co nejlépe vystihovat podstatu proměnné a její použití. Pro jméno proměnné volíme podstatná jména a nebojíme se použít delšího názvu. Čím specifičtější a jednoznačnější jméno proměnné je, tím lépe. Z názvu bychom měli být schopni intuitivně odvodit její použití a co vyjadřuje.
  • V programech jste se již setkali s voláním funkcí. Všiměte si, že jména funkcí jsou slovesa, která vyjadřují činnost, kterou funkce realizuje.

Příklad kódovacích stylů lze najít například na

Při práci na větším projektu nebo ve firemním prostředí je zpravidla použit vlastní styl a kódovací konvence, která však téměř vždy vychází ze zažitých zvyklostí pro konkrétní programovací jazyk. To je dáno především faktem, že dodržování kódovacího stylu usnadňuje porozumění a orientaci v kódu. Zdá-li se vám dodržování pravidel, zejména formátovacích zvyklostí náročné, tak nezoufejte, většina moderních vývojových prostředí nabízí kontrolu stylu a také podporu pro automatické formátování dle definovaných pravidel. Nejinak je tomu v prostředí Netbeans, kde základní formátování naleznete v menu Source→Format (nebo pod zkratkou Alt+Shift+F v základní konfiguraci).

Průběh cvičení

Část 1

V první části part1() poskytnutého projektu jsou uvedeny ukázky formátovaného výstupu celočíselné proměnné a výpis čísla s desetinnou částí. Podívejte se na přehled formátových specifikátorů a vyzkoušejte si různé výpisy celých a desetinných čísel.

Část 2

Ve druhé části je využito standardní třídy Scanner pro načítání hodnot proměnných ze standardního vstupu programu. Upravte hodnotu konstanty PART v metodě start tak, aby byla volána právě část dvě, tj. metoda part2().

Část 3

V další části part3() se seznamte s úskalím reprezentace desetinného čísla. Zkuste objasnit proč při součtu velmi velkého a velmi malého čísla dochází ke ztratě numerické přesnosti. Pro volání tohoto kódu upravte obsah metody start s využitím větvení programu příkazem switch / case a nastavte hodnotu proměnné PART tak, aby byla volána metoda part3().

Část 4

V části part4() jsou uvedeny způsoby načítání vstupu do různých proměnných. Pro volání tohoto kódu přidejte do metody start další větev case 4: a nastavte hodnotu proměnné PART tak, aby byla volána metoda part4(). Ověřte chování programu při zadání jiného než očekávaného vstupu, tj. například místo čísla zadejte slovo nebo použijte jiný než očekávaný vstup. Také si vyzkoušejte zadání očekávaných vstupu na jeden nebo více řádků.

Část 5

V části part5() je uveden kód pro porovnání hodnot dvou textových řetězců. Seznamte se s kódem, upravte metodu start pro jeho volání a vyzkoušejte si chování programu pro různé vstupy.

Úkoly na cvičení

  1. Využijte řídicí konstrukci switch / case a přepište volání if/else podle hodnoty proměnné PART.
  2. Rozšiřte program o volání části part3() a ověřte ztrátu přesnosti reprezentace desetinných míst.
  3. Seznamte se s možnostmi načítání standardního vstupu v části part4() a použitím metod třídy Scanner a vyzkoušejte si chování programu pro různé vstupy.
  4. Rozšiřte program o volání části part5() a seznamte se se způsobem porovnání hodnot dvou textových řetězců.
  5. Napište kód, který zjistí, zda je zadané číslo sudé či liché. Realizujte tuto funkcionalitu jako novou část part6().
  6. Napište program, který načte číslo v rozsahu 1 - 7 a slovně vypíše odpovídající den v týdnu (1 .. Mon, 2 .. Tue, …, 7 .. Sun ). V opačném případě vypíše chybu. Realizujte jako část part7(). Pro větvení programu využijte konstruci switch / case.
  7. Určete, jakých hodnot bude nabývat proměnná “a” po provedení následujících výrazů. Svůj výpočet ověřte implementací (jako část part8() ).
    1. b = 1;
      c = 2;
      a = ++b + c++;
    2. b = 1;
      c = b += 2;
      a = b / c;

Další úlohy na procvičení

  1. Napište program, který vypíše cenu letenky v závislosti na destinaci: do Vídně a Bratislavy stojí letenka 12000 (lépe jet autem), do Londýna 2000 Kč, do Paříže za 3500 Kč a jinam nelétájí. Využijte větvení příkazem switch podle 1. písmene destinace, které zjistítem metodou charAt().
  2. Napište program, který pro dané číslo < 100 000 vypíše slovně počet míst v jeho desítkovém zápise. Použijte funkci Math.log10() a příkaz switch.
  3. Vypište zda zadaný rok je přestupný. Použijte Gregoriánský kalendář platný od září 1752, ve kterém platí: je-li rok dělitelný 4, pak je přestupný. Je-li rok dělitelný 100, pak není přestupný a je-li rok dělitelný 400, pak je přestupný.
  4. Napište program, který vypíše počet dní v měsíci (30 či 31, nezapomeňte na přestupný rok u únoru).

Domácí úkol

courses/a0b36pr1/labs/lab04.txt · Last modified: 2015/10/25 22:34 by mrvajaku