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

©=37,/=92,}=123,(=91,)=93
i definice znaku procenta, obráceného lomítka, levé složené závorky, levé a pravé lomené závorky.

Protože pro účely kursu chybí některé důležité znaky a v Čapkovi již nejsou žádné volné pozice, zvolil jsem po delším přemýšlení jednoduchý způsob dodefinování znaků. Jako náhradu za znak procenta jsem zvolil copyriht, protože má téměř také dvě kolečka (s trochou fantazie), další dva znaky jsou jednoduše vyjádřeny inverzními protějšky, lomené závorky jsou nahrazeny inverzními kulatými.

Tento systém by měl být přehlednější než chaos použitý v první části. Původně jsem si totiž myslel, že pro zobrazování v Hypertextu se nesmí použít inverze. Nejčitelnější ovšem bude vytisknout si text na tiskárně vybavené sadou Kamenických.

Podmínky a cykly.

Pro vytváření složitějších programů jsou potřebné možnosti rozhodování o jeho dalším průběhu na základě okamžitých stavů. Začnu s popisem základní jednoduché a složené podmínky IF, známé podle jména i z jazyka BASIC.

Její tvar, cizím slovem syntaxe, je ale v Céčku podstatně jiná.

 /*  podmínka jednoduchá  */

    if(podmínka)
    }
     příkaz ;
     příkaz ;
     příkaz ;
    }

 /*  podmínka složená   */

    if(podmínka)
     }
      příkaz ;
      příkaz ;
     }
     else
     }
      příkaz ;
      příkaz ;
     }

Ukázky zápisu jsou uvedeny komentářem, nebo-li poznámkou. Tato je ohraničena sekvencí znaků lomítka a hvězdičky. Příručka dosti nejasně tvrdí, že poznámka může být kdekoliv, kde může být normálně mezera. Trpěliví zájemci mohou sami experimentovat s možnostmi jejího umístění.

Důležitější je ale vlastní tvar podmínky. Předně je třeba si zapamatovat, že za podmínkou a klíčovým slovem else se nepíše středník! Je-li podmínka pravdivá, jsou provedeny příkazy uvedené za ní, které jsou uzavřeny do složených závorek. Tedy ohraničení stejné, jako celého programu. Takový styl platí i pro zápis cyklů. Existuje jedna vyjímka při zápisu jediného příkazu - nemusí být uzavřený v závorkách.

Blok příkazů uvedený za else se provádí při neplatnosti podmínky. Používání else je rozšířením podmínky a není povinné.

Tvar zápisu není nijak omezovaný. Znak pro přechod na nový řádek, mezi ataristy hovorově nazývaný RETURN, je z hlediska textu programu prázdným znakem. Proto vůbec není nutný a jeho vhodným používáním se pouze dosahuje přehlednosti programu. To samé platí i o mezerách, případně znaku tabulátoru. U naší malé verze platí opět jisté omezení - délka programového řádku je omezena na délku 79 znaků. Proto nějaké ty "returny" používat musíme.

Nyní můžeme již s přehledem vyřešit úkol vydělit zadávaná čísla.

  
include

  main()
  }
    int i,j,m,n,k,l,o,p,q;
    i=getchar();
    j=getchar();
    if(j!=0)
      printf("vysledek: ©d/n",i/j);
    printf("konec");
    o=getchar();
  }

Většina příkazů programu je vám doufám jasná, ale raději zopakuji i poznatky z minulé části. První řádek oznamuje překladači, že v programu je použitá knihovna funkcí vstupů/výstupů. V naší malé verzi jazyka C tento příkaz nepoužíváme, je uveden jen pro přehled.

Funkce main bez parametrů - prázdné závorky - označuje vlastní program. Její užití je povinné. Celé tělo programu je uzavřeno ve složených závorkách, nebo pro nás jejich ekvivalenty.

Jako první se píší deklarace proměnných používaných v dané funkci. Zde se jedná o celá čísla. Pozorný programátor si všimne, že je jich deklarováno více, než je skutečně použito. Rozsáhlejší překladače na tuto skutečnost upozorňují formou varovného hlášení. Pro nás je důležitější si uvědomit, že deklarací se připraví paměťové místo pro proměnnou, ale její vlastní hodnota se nijak implicitně nenastavuje. Je v tuto chvíli zcela náhodná. Sám jsem udělal chybu u programu PYRAMIDA, když jsem zapoměl proměnnou vynulovat. Jenom náhodou program po překladu spočítal správně počet řešení. Na druhý den však tisknul úplný nesmysl, až jsem žasnul. Modernější kompilárory umožňují sloučit deklaraci a přiřazení do jediného příkazu, ale ten náš mi to nebral. Vypadalo by to asi takhle: int f=23;

Již známými funkcemi je provedeno čtení dělence i dělitele z klávesnice. Pravděpodobně bude v uvedeném příkladu dělitel vždy 155, protože nám čtení z klávesnice funguje nějak pochybně.

Protože nulou počítač dělit neumí, je nutné ošetřit tuto možnost. Stačí na to jednoduchá podmínka. Výrazem r!=0 testuje, zda se proměnná r nerovná nule. Naopak při porovnávání rovnosti se logický operátor zapisuje ve tvaru dvou rovnítek. Tím se liší od operátoru matematického pro přiřazování zapisovaného rovnítkem jedním. Příručka na rozdíl výslovně upozorňuje, ale stějně jsem strávil část doby odlaďování pyramidy protože jsem napsal rovnítko do podmínky jedno.

Při platnosti podmínky se provede funkce printf(), s jejíž pomocí vydělíme zadana čísla a výsledek ihned vytiskneme. Funkci jsem neuzavřel do závorek, protože je jediným příkazem prováděným při platnosti podmínky. Nic ale nebrání jejich použití pro větší přehlednost.

Následující funkce printf() vytiskne v každém případě zprávu o ukončení programu, poslední getchar() slouží již jen k pozdržení výsledků na monitoru před návratem do systému.

  /*  podmínka vnořená   */

  main()
  }
    int i,j,m,n,k,l,o,p,q;
    i=getchar();
    j=getchar();
    if(j!=0)
      if(i==0)
       } printf("vysledek: naprostá nula/n");
         printf("určitě jsi na to potřeboval počítač ?/n");
       }
      else
         printf("vysledek: ©d/n",i/j);
    else
     } printf("běžně neřešitelné dělení nulou./n");
       printf("spočítáme alespoň jedodušší příklad:/n");
       printf("1+1=©d/n",1+1/n); }
    printf("konec");
    o=getchar();
  }
  

Na druhém příkladu je předvedeno vnořování podmínek do sebe a rozvíjeno pravidlo o používání uzavíracích závorek bloků příkazů uvedených za podmínkou.

Sledujte, že příkazy za první podmínkou se uzavřít nemusí, protože je uveden pouze jediný, kterým je druhá funkce if(). Na tom nic nemění ani skutečnost, že ve vnořené funkci se uzavírky použít musí, protože v ní je předepsán k vykonání celý blok příkazů. Zde je také vidět, jak v orientaci v programu pomáhají prázdné mezery na začátcích řádků.

Pro tvorbu složitějších programů by podmínka bez skokové instrukce nestačila. Proto existují konstrukce zvané cykly. Jako první popíši cyklus for, který je svojí činností velmi podobný jeho BASICovskému protějšku.

Jeho základní tvar:

    for(i=1;i<=9;i++)
      }
      příkaz 1;
      příkaz 2;
      příkaz x;
      }

cyklus je řízen příkazy uvnitř závorek. Jsou rozděleny na tři části oddělené středníky. První z nich udává počáteční nastavení. Může sestávat z více příkazů oddělenými čárkami. Uvedený základní tvar je shodný se zápisem FOR v BASICu. Druhá část je podmínkou opakování cyklu. V BASICu se píše za slovo TO, které je zde nahrazeno kombinací znaků je menší a rovná se. Samozřejmě je možné úmyslně napsat konstantu větší a pak použít jen znak menší (nebo větší), ale takové řešení snižuje přehlednost v číslech.

Ve třetí části jsou uvedeny příkazy prováděné při každém průchodu cyklu. Opět jich může být více oddělených čárkami. V nejednodušším případě se jedná o pravidelnou změnu hodnoty řídící proměnné cyklu, tedy přírůstek zapisovaný v BASICu za slovo STEP. V uvedeném příkladu je použitý zkrácený zápis pro jedničkovou inkrementaci proměnné. Analogicky stejný způsob se používá pro dekrementaci, tedy název proměnné následovaný dvěma znaménky mínus.

Následující příklad vytiskne tabulku malé násobilky a uloží ji do proměnné.

main()
}
int a(10)(10),i,j;
printf("         malá  násobilka/n/n");
for(i=0;i<=9;i++)
 }for (j=0;j<=9;j++)
    printf("©-3d ",a(i)(j)=i*j);
  printf("/n");}
o=getchar();
}

V řádku deklarací vidíme jako novou věc použití dvojrozměrného číselného pole. Jeho prvky jsou číslované od nuly, tedy při nadimezování rozsahu 10 jsou použitelné indexy od nuly do devítky.

Zajímavý je také zápis funkce tisku, která poslouží nejen pro vytištění výsledku, ale i pro jeho uložení do proměnné. Vlastně je nejprve provedeno přiřazení a potom tisk.

Naše malé Céčko nemá vícerozměrné číselné pole. Musíme se proto spokojit s jedním. Obejití tohoto nedostatku je v principu velmi jednoduché, ale může se při tom programátor pěkně zamotat. Stačí připravit pole jednorozměrné o délce součinu jednotlivých indexů. Určení daného prvku se provede tak, že se libovolně zvolený index násobí rozsahem druhého, jehož okamžitá hodnota se k výsledku přičte. Pamatujte, že index o maximální hodnotě 9 má rozsah 10 pozic, protože se počítá i nulová pozice. Podle příručky číslice při deklaraci proměnné vyjadřuje tuto skutečnou délku, možná velikost je tedy o jedničku menší. Zatím jsem naši verzi v tohto podrobně nezkoumal.

Samozřejmě toto libovolně zvolené rozlišení obou indexů se musí jednotně dodržet v celém programu. Příklad užití vysvětleného postupu najdete v uvedené pyramidě. Z matematického hlediska tímto způsobem musí jít nahradit i vícerozměrné matice, ale bude to znamenat pěknou piplačku.

Jako příloha k textu kursu jsou uvedeny tři zdrojové výpisy v našem DEEP BLUE C. První z nich obsahuje všechny drobné příklady zde uváděné. Samozřejmě s tím rozdílem, že deklarace proměnných je provedena naráz hned na začátku programu. Pro zájemce zůstává možnost upravování zejména formátu výpisu na obrazovku, který není dotažený do konce.

Druhý výpis pochází od Jiřího Svobody a vznikl zcela náhodně když Jirka zkoušel srovnávat naše malé "C" s tím na AMIZE. Program bere jeden zadaný znak z klávesnice, pokud jde o písmeno, vytiskne na obrazovku všechny následující podle abecedy. Rozlišuje při tom malá a velká písmena. Nebude-li zadáno písmeno, program ukončí činnost vytištěním zprávy.

Třetí program je řešení hlavolamu PYRAMIDA převedené do jazyka "C". Převod jsem uskutečnil analogicky k tvaru programu v BASICu, aniž bych znal jeho skutečnou činnost. U větších programů by to tak asi dělat nešlo. Je doplněn zkompilovanou verzí, aby si program mohli vyzkoušet i odběratelé, kteří se jinak Céčkem zabývat nechtějí. Překvapilo mě samého, že oproti TURBOBASICu není nijak výrazně rychlejší. Další možností porovnávání rychlostí je zkusit kompilátor TURBOBASICu, nebo naopak spustit program v obyčejném ATARI BASICu při vynechání funkce měřící čas.

Jinak většinu přikládaných výpisů programů budu uvádět bez přeložené verze, protože ty zabírají dosti místa. Doufám, že ze stovek špatných verzí se mně podaří dávat do FLOPu ty fungující konečné.

Tematicky je kurs "C" doplněn článkem amigisty Jirky, bohužel ale jeho druhou verzí. První verzi napsal s nadšením, když se dozvěděl, že na malém ATARI také tento jazyk existuje a sám si jej zkusil. Jenomže jeho druhý projekt - textová hra - použít nešel, protože naše "C" je velmi omezené. Celý článek proto přepsal do pochmurného tónu.

Nebuďte zklamaní, protože na malém počítači se stejně dobré věci dají dělat jen ve strojovém jazyce. Na seznámení s jazykem naše možnosti stačí a kdo snad bude programovat v "C" vážněji na velkých počítačích, využije znalosti z kursu. Až na ty složené závorky je všechno stejné.