Kurs programování "C" část 4.

©=37,/=92,}=123,(=91,)=93,"=39

i definice znaku procenta, obráceného lomítka, levé složené závorky, levé a pravé lomené závorky, apostrofu.

Podmínky a cykly III.

Základním cyklem pro opakované probíhání je příkaz WHILE. Jeho syntaxe v Céčku:

     while()
    }
       příkaz;
       příkaz;
       příkaz;
    }

Příkaz je možné popsat jako podmínku s opakováním, protože blok příkazů uvedených za WHILE se provádí, dokud není splněna podmínka. Pokud nastane situace, že ke splnění nikdy nedojde, program se "zacyklí" a pomůže jen RESET počítače. Zda studený či jen programově řízený záleží na daném systému.

Již dříve popisovaný příkaz FOR je vlastně rozvedený příkaz WHILE a dalo by se žít i bez něj. Jeho činnost je samozřejmě možné celou popsat jednoduchým WHILE s přidáním řady podmínek a přiřazovacích příkazů.

Podobným příkazem je i DO - WHILE. Jeho syntaxe:

    do }
       příkaz;
       příkaz;
       příkaz;
    } while();

Všiměte si pravidel pro psaní středníku - píše se povinně za posledním řádkem příkazu. Použitý způsob zápisu složených závorek, čili uzavírek bloku příkazů, je doporučený, odliší tak na první pohled příkaz do-while od jednoduchého while.

Zásadním rozdílem je zkoumání podmínky až na konci bloku. Proto proběhne cyklus minimálně jednou.

Oba druhy cyklů jsou řízeny logickým výrazem uvedeným v kulatých závorkách za klíčovým slovem while. Pro první pokusy s cykly je zřejmě nejjednodušší použít čtení z klávesnice a v podmínce testovat výskyt určitého znaku, například:

       while (a != "Q")
         a=getchar();

kde cyklus probíhá, dokud není stistknuta klávesa Q. Uzavření znaku do apostrofů vyjádřuje znakovu konstantu, převede vlastně znak na jeho ASCCI hodnotu, tedy na číslo. Znaková konstanta může být pouze jednomístná a dlále se od řetězce líší tím, že ten je uzavřený v uvozovkách. Pokud uvidíte mezi apostrofy sled dvou znaků jako je obrácené lomítko a malé n, uvědomte si, že jde skutečně jen o jednu znakovou konstantu, zde konkrétně o řídící kód odřádkování (LF).

K této kapitole není přiložen žádný programový výpis s příklady, protože na tvorbu zajímavějších prográmků dosud chybí možnost komunikace.

Vstup a výstup, definice funkcí I.

Pro začátek se podívejme na zdrojový výpis programu X přiloženého na disketě s jazykem "C". Příručka se zmiňuje o nějaké demonstraci vstupu a výstupu.

Po vytištění na papír vidím, že program obsahuje tři části - hlavní funkci main() a dvě další definované uživatelem. S tou definicí to není tak horké - žádné deklarace či snad vytváření hlavičkových souborů, jak se sluší a patří. Je to zato jednoduché, neboť stačí napsat funkce podle obecné syntaxe a už to chodí.

Na druhý pohled je vidět, že zdrojový výpis je napsaný velmi nepřehledně, žádné odrážení mezerami a podobně. Raději uvedu jako prostý fakt, že program simuluje funkci DOSu kopírování z obrazového editoru do souboru a opačně.

Hlavní část programu vypíše jméno programu a v druhé řádce nabídne možné povely. Celý zbytek tvoří cyklus FOR ve zvláštní nekonečné úpravě. Prostým vynecháním parametrů se docílí nekonečného opakování cyklu. Závorky obsahují pouze zbylé oddělovací středníky, které jsou povinné. Takový cyklus se dá ukončit jen násilnými příkazy break a return. Srovnejte si to s BASICem - zde taková divočina není vůbec možná.

Příkaz je z klávesnice čten nám známou funkcí getchar(), jejíž výstup je upraven funkcí tolower(). Tato převádí velká písmena na malá, ostatní nechává beze změny. Program pak může reagovat na povely zadávané malými i velkými písmeny bez nutnosti psát dvojí podmínky. Jistě dobré, pokud nám pro zadávání stačí anglická abeceda.

Následující část programu je uzavřena do cyklu while, který obsahuje jediný příkaz switch(), proto za ním nejsou použity uzavírky bloku. Smyslem podmínky cyklu je hlídání zadání prázdného znaku RETURN. V takovém případě vnější cyklus for() vrátí průběh programu zpět na nové čtení povelu z klávesnice. Program by fungoval stejně dobře i bez cyklu while(), ale docházelo by ke hroucení tisku chybového hlášení.

Přepínač switch() obsahuje tři možné volby a dále ošetření nesprávných zadání. V takovém případě vypíše zprávu zadání neplatného příkazu a zopakuje možné volby - nyní již s nápovědou jejich významu.

Při volbě čtení je volána funkce rfile(), pro zápis wfile(). Ukončení programu provádí příkaz return. Ten ruší vždy funkci, ve které je obsažen, je-li to právě funkce main(), zruší celý program.

Vlastní operace čtení a zápisu jsou nadefinovány jako samostatné funkce. Došlo tak ke zpřehlednění programu. Volání podprogramů známe samozřejmě i z BASICu, ale v něm by již nebylo možné v kazdé funci zvlášť deklarovat proměnnou c stejného jména, přitom naprosto nezávislé. Říká se tomu lokální proměnná a její obsah je přístupný běžně jen ve funkci, v níž byla deklarována. Všiměme si, že definované funkce čtení a zápisu nepoužívají žádné parametry, takže se píší s prázdnými kulatými závorkami.

V programu je použito několik dosud neprobraných funkcí, proto je nyní stručně popíšu.

Funkce gets(string) by měla být podobná příkazu INPUT z BASICu. Načítá z klávesnice řetězec znaků do proměnné typu char. Podle nejasného popisu v přručce je zřejmě délka vstupního řetězce omezena na 120 znaků.

Pro ošetření zadávaného jména souboru je použita funkce normalize(fname,fext)

kde je jako druhý parametr dosazen řetězec "C". Program je tedy zaměřen na práci se zdrojovými texty v jazyce. Všiměte si rozdílu mezi řetězcem "C" a znakovou konstantou "C", která se ohraničuje apostrofy.

Funkce upravuje zadávaný řetězec do podoby standartní specifikace souboru. Převede tedy malá písmena na velká, dosadí název zařízení jako D: pokud chybí a připojí zadaný extender není-li uveden. V popisu chybí vliv druhého parametru funkce. Podle mých zběžných pokusů je druhý parametr pro extender nepovinný. Pokud se však neuvede, nelze jej funkci předat napsaný do prvního parametru. Jinak má zřejmě prioritu extender zadávaný přímo ve jménu souboru, teprve není-li uveden, dosadí se obsah druhého parametru. (Chce to ještě zkoušet.)

Pro otevření souboru je použita funkce copen(fn,mode). Je to jedna ze dvou možností a to ta podobnější standartním funkcím jazyka. První argument je typu char a slouží k předání specifikace souboru, druhý volí činnost - čtení, zápis a připisování. Použity jsou standartně znaky r a w, ale nejsou uzavřeny do uvozovek, ale do apostrofů. To je odlišné od normy C.

Funkce vrací číslo IOCB, které slouží pro přístup na soubor, nebo záporné číslo chyby při neúspěchu. Proto je nutné volat funkci pomocí proměnné typu int.

Chybu v programu kontroluje běžná podmínka, dojde-li k ní, vypíše zprávu i s jejím číslem.

Soubor se zavírá funkcí cclose(i), kde je jako argument použito číslo IOCB vrácené funkcí copen.

Funkce cgetc(i) a cputc(c,i) jsou opět podobné těm v BASICu, ale podle příručky pracují se znaky, nikoliv s čísly. Parametry je opět číslo IOCB dodané funkcí copen a pro zápis znaková proměnná.

Vzorový příklad.

Jako zadání jsem vybral jednoduchý školní příklad ukládající nalezení největšího a nejmenšího čísla z dané řady čísel. Druzí redaktoři se mi trochu smějí, ale já jsem již skutečně potřeboval zjistit tyto hodnoty při zpracování některých dat.(šlo o samply)

Můžete se sami zamyslet nad vhodným algoritmem řešení. Školní úlohy radí například použít největší a nejmenší zobrazitelné číslo a s těmito porovnávat vstupující data. Já jsem dal přednost algoritmu, který je naprosto univerzální a najde hledané hodnoty na kterémkoliv počítači.

Vlastní program vznikl malou úpravou dříve popisovaného originálního X.C. Hlavní main() slouží i zde jako menu, samostatná funkce extrem() otevře zvolený soubor a najde v něm největší a nejmenší použité číslo.

-ZB-