[Cvičení 1] [Obsah] [Cvičení 3]

Cvičení 2


Témata


Zápis konstant (literál)

Celočíselné desítkové konstanty se zapisují běžným způsobem, např. 10, -5. Je možné zapsat celočíselné konstanty také v osmičkové nebo šestnáctkové soustavě. Zápis v osmičkové soustavě začíná nulou, tj. 012, 03. Zápis v šestnáctkové soustavě začíná 0x nebo 0X, např. 0x20, 0xFE, 0X3f, 0x2a.

Desetinná čísla zapisujeme také obvyklým způsobem, pro oddělení celé a desetinné části používáme desetinnou tečku, např. 3.14, -6.354, 0.5. U čísel menších než 1 lze úvodní nulu vynechat, tedy .4 je totéž jako 0.4. Číslo lze zapsat i v tzv. semilogaritmickém tvaru - 4.25E-3, -1e6.

Znakové konstanty se uzavírají mezi apostrofy, např., 'a', 'A', 'x', '4', '*'. Potřebujeme-li zapsat konstatnu neviditelného (řídicího) znaku, použijeme zápis ve tvaru '\ddd', kde ddd je osmičkový zápis kódu (ASCII kódu) příslušného znaku, resp. '\0xHH', kde HH je šestnáctkový zápis, např. '\0x0A' je znak nová řádka (LF). Pro nejpoužívanější řídicí znaky existují znakové ekvivalenty, uvedené v tab. 1:

EkvivalentVýznam
'\n'nová řádka (LF)
'\r'návrat na začátek řádky (CR)
'\f'nová stránka (FF)
'\t'tabulátor (TAB)
'\b'posun doleva (back space)
'\a'pípnutí (BELL)
'\\'lomítko
'\''apostrof
'\0'nulový znak, NULL, znak s ASCII kódem 0

Tabulka 1: Znakové ekvivalenty

Znakové konstanty nemají velikost 1 Byte, ale int.

Ačkoliv jazyk C nemá typ řetězec, lze zapsat řetězcové konstanty. Řetězcové konstanty se uzavírají do uvozovek, např. "Ahoj, světe!".


Proměnné

Proměnné (variables) v programovacím jazyce uchovávají určitou hodnotu (data), jejich obsah se může během výpočtu měnit. Proměnná vlastně představuje abstrakci adresy paměťové buňky, ve které jsou data uložena.

Jazyk C patří mezi tzv. jazyky s deklarovanými a typovanými proměnnými. Znamená to, že před použitím jakékoliv proměnné v kódu programu je nutné proměnnou deklarovat (neformálně, napsat seznam proměnných). Termín typované proměnné značí, že u každé proměnné je povinnost uvést, jakého je datového typu. Datový typ determinuje hodnoty, které může proměnná obsahovat (neboli typ určuje množinu hodnot) a také množinu operací, které je možné s proměnnými provádět.

Povinnost deklarovat proměnné má výhodu pro programátory v tom, že překladač snadno odhalí překlepy programátora v názvech (identifikátorech) proměnných. Určení typu proměnné umožňuje kontrolovat při překladu, zda programátor nepřiřazuje proměnné nesmyslná data nebo nepíše do kódu nepovolené či „podivné“ operace, např. se nepokouší sčítat znaky (jazyk C na rozdíl od Pascalu ale tuto operaci dovolí, protože se jedná o jazyk se slabou typovou kontrolou, kdy se kontrola provádí pouze na úrovni vnitřní reprezentace). Typování proměnných překladači umožní také generovat efektivní kód.

Jednoduché datové typy

Jednoduché datové typy jazyka C shrnuje tab. 2. Hrubé rozdělení typů je možné provést následovně:

SkupinaTypCharakteristika
Znakový typcharObsahuje znaky, velikost 1 Byte
Celočíselné typyshort 
intZákladní celočíselný typ
long 
Typy v pohyblivé řádové čárcefloatDesetinná čísla s jednoduchou přesností
doubleDesetinná čísla s dvojitou přesností
long doubleNový typ v normě ANSI C

Tabulka 2: Jednoduché datové typy v jazyce C

Norma jazyka nedefinuje velikost celočíselných typů, pouze musí platit sizeof(short)<=sizeof(int)<=sizeof(long). Výsledkem operátoru sizeof() je počet bytů, na kolik je typ v daném překladači implementován. Větší počet bytů znamená přirozeně větší rozsah zobrazitelných čísel. Základní celočíselný typ je typ int, měl by být implementován „nejvýhodněji“ pro danou platformu (např. pro 32 bitový překladač by měl mít velikost 32 bitů).

Celočíselné typy jsou standardně v reprezentaci se znaménkem (bit nejvyššího řádu je znaménkový, čísla jsou uložena v tzv. doplňkovém kódu), např. 16 bitový celočíselný typ má rozsah zobrazitelných čísel -32768 až +32767. Pro reprezentaci čísel bez znaménka existuje v jazyce klíčové slovo unsigned, kterým typ modifikujeme - unsigned short, unsigned int, unsigned long, typ unsigned int je možné zkrátit na unsigned. Klíčové slovo signed ve verzi K&R neexistovalo, bylo doplněno až ve verzi ANSI. Typ char má velikost 1 slabiku (1 Byte) a na proměnné tohoto typu je možné v jazyce C nahlížet také jako na čísla (jazyk C je jazyk se slabou typovou kontrolou!). Reprezentace typu char je zpravidla se znaménkem, závisí na překladači.

Do proměnných typu float a double je možné uložit desetinná čísla, typ double má dvojitou přesnost, tj. větší počet desetinných míst. Čísla v této reprezentaci jsou interně uložena jako trojice znaménko, mantisa, exponent. Tato reprezentace je čtenáři dobře známa ze zápisů čísel zejména ve fyzice, např. -3,4x102, kde znaménko je zřejmé, 3,4 je mantisa, 2 je exponent.

Poznámka: Celočíselné konstanty jsou standardně typu int, chceme-li explicitně vyjádřit konstantu typu long, připojíme za zápis čísla příponu L, např. 126L, obdobně U pro typ unsigned. Desetinné konstanty jsou typu double, konstantu typu float zapíšeme pomocí přípony F, 1.6F.
Na rozdíl od jiných jazyků neexistuje typ boolean, který by nesl logické hodnoty pravda/nepravda. Místo toho se používá celočíselný typ int, kdy jakákoliv nenulová hodnota je chápána jako pravda (true) a nulová hodnota jako nepravda (false). Neexistuje typ řetězec (string), představující text, je nahrazen polem znaků (ale řetězcovou konstantu zapsat lze).
Poznámka: V jazyce C++ již existuje datový typ bool, jehož oborem hodnot jsou dvě hodnoty true/false (pravda/nepravda).

Pro představu uvádíme rozsahy hodnot pro jednotlivé datové typy u typického 32-bitového překladače v tabulce 3. Znovu připomínáme, že standard jazyka C nedefinuje velikost typů, jejich reprezentace záleží na konkrétním překladači (platformě), musí platit nerovnost uvedená výše.

Typ Velikost [bit] Rozsah
char 8 -128 až +127
short 16 -32 768 až +32 768
int 32 -2 147 483 648 až +2 147 483 647
long 32 (64) -2 147 483 648 až +2 147 48 3647
long long 64 -9 223 372 036 854 775 808 až +9 223 372 036 854 775 807
float 32 -3,402823 ⋅ 10+38 až +3,402823 ⋅ 10+38
nejnižší kladná hodnota 1,175494 ⋅ 10+38
počet platných cifer 7 až 8
double 64 -1,7976931348623157 ⋅ 10+308 až +1,7976931348623157 ⋅ 10+308
nejnižší kladná hodnota 2,225073858507202 ⋅ 10-308
počet platných cifer 15 až 16
long double 80 (96) -3,4 ⋅10+4932 až 3,4 ⋅ 10+4932
nejnižší kladná hodnota 1,1 ⋅ 10-4932
počet platných cifer 19

Tabulka 3: Příklad rozsahů hodnot pro jednotlivé datové typy

Deklarace proměnných

Deklarace proměnné v jazyce C se zapíše tak, že nejprve uvedeme typ proměněné a pak indentifikátor proměnné (identifikátor je název proměnné). Identifikátor nesmí začínat číslicí a nesmí dále obsahovat znaky sloužící jako operátory (+.-,! atd.), závorky aj. Deklarace se ukončí středníkem. V rámci jednoho zápisu lze deklarovat více proměnných stejného typu, oddělených čárkou.

Příklad: Nadeklarujeme jednu proměnnou c typu char, dvě proměnné a, b typu int a proměnnou polomer typu float.

char c;
int a, b;
float polomer;
Jazyk C dovoluje provést počáteční přiřazení hodnoty proměnné již při deklaraci, např.:
int a=3, b;
Proměnná a má tedy hodnotu 3, proměnná b je neinicializovaná, obsahuje náhodnou hodnotu.

Proměnné mohou být globální a lokální. Globální proměnné jsou deklarovány vně jakékoliv funkce a jsou viditelné (použitelné) v celém zdrojovém kódu, lokální proměnné jsou lokální pouze v daném bloku, tj. části kódu uzavřené mezi { }.

int volba; /* Toto je globální proměnná, viditelná ve funkci obsah i v hlavním programu */

int obsah()
{
  float x, y;  /* Proměnné x a y jsou lokální ve funkci obsah */
}

int main(int argc, char **argv)
{
  int a;  /* Lokální proměnná viditelná pouze v hlavním programu */
  
}
Podle pravidel jazyka C je nutné v bloku uvést nejprve všechny deklarace proměnných a pak programový kód. Podle normy C++ je možné psát deklarace nových proměnných i uprostřed programového kódu.

Přiřazení

Přiřazení hodnoty proměnné se v jazyce C zapisuje pomocí znaku „rovná se“; na levé straně přiřazovacího příkazu je proměnná (tzv. left-value, musí mít přiřazenu adresu paměti), na pravé straně je libovolný výraz. Samotné přiřazení je v jazyce C definováno také jako výraz (přiřazovací výraz), zakončením středníkem se z výrazu stane přiřazovací příkaz (každý výraz ukončený středníkem se stává v jazyce C příkazem). Důsledkem toho, že přiřazení je výraz, je možnost vícenásobného přiřazení.

Příklad:

int a, b; float x, y;

a = 3; 
b = 3*a;  /* násobení */
x = y = 3.5; /* vícenásobné přiřazení */
Zápis přiřazení typu x = x + 3 můžeme nahradit přiřazovacím operátorem x += 3. Obecně, zápis E1 = E1 op E2 lze nahradit zápisem E1 op= E2, E2 může být libovolný výraz. Operátor je libovolný binární (aritmetický, logický, operátor posuvu).


Terminálový vstup a výstup

Nyní uvedeme dvě funkce z knihovny stdio.h, které budeme nejčastěji využívat, a to funkci pro terminálový výstup (pro tisk na obrazovku) printf funkci pro terminálový vstup (pro čtení dat z klávesnice) scanf. Později si uvedeme i další funkce z této knihovny.

Funkce printf je funkce s proměnlivým počtem parametrů. První parametr je povinný formátovací řetězec, který určuje, jak má vypadat tištěný text na obrazovce. Běžné znaky, které se v řetězci objeví, se tisknou na obrazovku. V řetězci je možné použít znakové ekvivalenty z tabulky 2.
V minulém cvičení jsme tiskli pomocí této funkce text Ahoj světe:

printf("Ahoj, svete!");
Chceme-li vytisknout hodnotu proměnné, musíme ve formátovacím řetězci specifikovat pomocí speciální sekvence uvozené znakem %, jaký datový typ dat chceme tisknout. Problematiku nejlépe vysvětlíme na příkladu, kdy vytiskneme součet dvou proměnných a,b:
printf("Součet čísel %d + %d = %d.\n",a,b,a+b);
Na obrazovku vystoupí text Součet čísel a mezera. Sekvence %d říká, že na tomto místě se bude tisknout celé číslo, pak se tiskne mezera, plus, mezera, opět celé číslo, mezera, rovnítko mezera, celé číslo a tečka. Znak '\n' způsobí přechod na nový řádek. Za první sekvenci %d se dosadí hodnota proměnné a atd. Platí, že počet dalších výrazů za formátovacím řetězcem musí odpovídat počtu sekvencí %, jinak funkce tiskne nesmysly.

Přehled několika specifikátorů za znakem % uvádí tabulka 4:

ZnakVýznam
d celé číslo se znaménkem
i celé číslo se znaménkem
u celé číslo typu unsigned
x celé číslo v šestnáctkové soustavě s malými znaky a, b, c, d, e, f
X celé číslo v šestnáctkové soustavě s velkými znaky A, B, C, D, E, F
f číslo typu float
e nebo E číslo typu float v semilogaritmickém tvaru
cznak
sřetězec
pukazatel (adresa)

Tabulka 4: Specifikátory

Číslo typu double se vypisuje také pomocí %f, v některých překladačích však %lf. Specifikace způsobu výpisu je mnohem bohatší, např. umožňuje určit počet tištěných desetinných míst či celkový minimální počet tištěných znaků, způsob zarovnání čísla doprava či doleva, vyplnění vlevo mezerami či nulami, povinný tisk znaménka apod. Odkazuji na dokumentaci překladače.

Pro vstup dat z klávesnice slouží funkce scanf. Její syntaxe je obdobná jako u printf: první povinný parametr je formátovací řetězec, pak následují adresy paměťových buněk, kam se mají načtená data uložit. Pro specifikaci typu vstupních dat se používají stejné sekvence se znakem %, např.:

scanf("%d %d",&a,&b); 
Takto načteme z klávesnice do proměnných a, b dvě celá čísla z klávesnice. Před proměnnou musí být znak &, který určuje právě adresu proměnné. Opět platí, že počet dalších parametrů musí být roven počtu specifikátorů, jinak program havaruje za běhu. Je nutné si uvědomit, že pokud zde uvedeme text do formátovacího řetězce, očekává funkce scanf tento text na vstupu, jinak ukončí svoji činnost s chybou a neuloží do proměnných žádné hodnoty. Kdybychom napsali do formátovacího řetězce scanf("Zadej strany a b %d,%d",&a,&b);, funkce by očekávala na vstupu nejprve text Zadej strany a b a potom dvě celé čísla oddělená čárkou. Žádný nápovědný text se na obrazovce neobjeví. Při zadání dvou čísel funkce scanf zjistí, že první zadaný znak není Z, tudíž vstup neodpovídá formátovacímu řetězci a činnost funkce se ukončí (návratová hodnota funkce je počet správně zkonvertovaných vstupů, zde může funkce vrátit maximálně číslo 2).


Operátory

Binární operátory

Seznam základních binárních aritmetických operátorů uvádí tab. 5.

OperátorVýznam
+Sčítání
-Odčítání
*Násobení
/Celočíselné i neceločíselné dělení
%Zbytek po celočíselném dělení

Tabulka 5: Seznam základních aritmetických operátorů

Operátory pro sčítání, odčítání, násobení a dělení lze aplikovat na celočíselné i neceločíselné operandy, operátor zbytek po celočíselném dělení (modulo) pouze na celočíselné operandy. Typ výsledku závisí na typu operandů. Zjednodušeně, jsou-li operandy celočíselné, je výsledek celočíselný. Je-li jeden z operandů neceločíselný, je i výsledek neceločíselný.

Stejné pravidlo se aplikuje při rozlišování mezi celočíselným a neceločíselným dělením. Jazyk C nemá dva různé operátory pro celočíselný a neceločíselný podíl (např. jazyk Pascal má operátor / pro neceločíselné dělení a div pro celočíselné dělení). Překladač rozezná typ operace podle typu operandů. Jsou-li oba operátory celočíselné, jedná se o celočíselné dělení. Je-li jeden z operandů neceločíselný, jde o neceločíselné dělení.

Příklad:

Mějme deklarace: int a, b; float x, y;

V následujících zápisech jde o celočíselné dělení: a/b 5/3 a/2.
A v těchto případech jde o neceločíselné dělení: x/y 3.5/5 x/2.

Výsledek dělení 8/5 je tedy celočíselný a má hodnotu 1. Máme-li deklarovanou proměnnou float z, po provedení přiřazení z = 8/5 je v proměnné z hodnota 1.0000 (dojde k automatické konverzi celého čísla na typ float). Chceme-li provést neceločíselné dělení, musí být jeden operand neceločíselný, tj. např. z = 8/5.0. Po provedení výpočtu bude v proměnné z hodnota 1.6.

Má-li být operace dělení mezi dvěma celočíselnými proměnnými provedena jako neceločíselná, je potřeba převést alespoň jeden operand na neceločíselný. To se provádí pomocí tzv. přetypování (typecasting). Přetypování představuje dočasnou změnu vnitřní reprezentace dat. Přetypování se v jazyce C provádí takovým způsobem, že do kulatých závorek před výraz zapíšeme datový typ, na který chceme výsledek výrazu převést, např.: (float) a. Tím překladači sdělujeme, že v tomto okamžiku má celočíselnou proměnnou a převést do reprezentace typu float (jinak řečeno: „nyní se dívej na proměnnou a jako na číslo typu float“). Samozřejmě, samotná proměnná a zůstává nadále celočíselná. Tedy, neceločíselný podíl dvou celočíselných proměnných zapíšeme z = (float)a/b;

Operace zbytek po celočíselném dělení je zřejmá, např. výsledek 8%3 je 2.

Unární operátory ++, --

Jazyk C má ještě dva unární operátory ++ (plus plus) a -- (minus minus). Unární znamená, že jsou aplikovány na jednu proměnnou. Způsobí zvýšení, resp. snížení hodnoty proměnné o 1. Místo přiřazení a = a+1; můžeme psát zkráceně jen a++;. Mohou být zapsány ve dvou formách, postfixové (za proměnnou,a++) nebo prefixové (před proměnnou,++a), viz dále. Lze je aplikovat na celočíselné i neceločíselné proměnné.

Příklad:

int main(int argc, char **argv)
{
  int a;
  a = 3;
  a = a+1; // po provedení má a hodnotu 4
  a++; // po provedení má a hodnotu 5
  a--;  // po provedení má a opět hodnotu 4
  --a; // po provedení má a hodnotu 3 
  return 0;
}
Operátory ++ a -- mohou být použity i ve složitějších výrazech. Zde se projeví rozdíl mezi prefixovou a postfixovou formou. Je-li operátor použit v prefixové formě (prefix = předpona), je nejprve hodnota proměnné zvýšena (snížena) o 1 a potom teprve použita ve výrazu k výpočtu. Je-li operátor použit v postfixové formě (postfix = přípona), je nejprve hodnota proměnné použita ve výrazu a teprve následně zvýšena (snížena) o 1. Následující příklad demonstruje rozdíl mezi pre- a postfixovou formou.

Příklad:

int main(int argc, char **argv)
{
  int a, b, c, d;
  a = 2; b = 3;
  /* Použití operátoru v postfixové formě */
  c = a*b++;  
  /* Zde je použit operátor v postfixové formě. Nejprve je hodnota proměnné b (3)
     použita k vynásobení hodnoty proměnné a a potom je hodnota b zvýšena o 1.
     Násobí se tedy 2*3, v proměnné c je po vyhodnocení výrazu hodnota  6 a v proměnné b 4.
  */

  /* Použití operátoru v prefixové formě */ 
  d = a*++b;
  /* Zde je použit operátor v prefixové formě. Nejprve je hodnota proměnné b (4)
     zvýšena o 1 a pak teprve použita k vynásobení hodnoty proměnné. 
     Násobí se tedy 2*5, v proměnné d je po vyhodnocení výrazu hodnota  10 a v proměnné b 5.
  */
 
 return 0;
}

Podmínka (příkaz if)

Syntaxi a sémantiku ve formě vývojového diagramu podmíněného příkazu v jazyce C ukazuje tabulka 6 (ve dvou variantách).

SyntaxeOdpovídající vývojový diagram
if (výraz) příkaz;
Vývojový diagram
if (výraz) příkaz1;
else příkaz2;
Vývojový diagram

Tabulka 6: Syntaxe a sémantika podmínky v jazyce C

Jazyk C (a nejen C) je nejednoznačný jazyk, tj. pomocí více gramatických pravidel lze generovat stejné věty. Proto je jazyk doplněn o dodatečná pravidla, která zaručují jednoznačnost. Je-li vnořeno více podmínek „do sebe“ a za nimi následuje else, vztahuje se vždy k nejbližšímu if. Dále platí pravidlo, že k větvi podmínky za if nebo k větvi else náleží vždy jeden příkaz, ostatní jsou již mimo podmíněný příkaz. Chceme-li mít v příslušné větvi více příkazů, musíme je uzavřít do bloku mezi závorky { }, viz tabulka 7.

SyntaxeOdpovídající vývojový diagram
if (výraz) 
{
  příkaz1;
  příkaz2;
}
else
{
  příkaz3;
  příkaz4;
}
Vývojový diagram

Tabulka 7: Uzavření příkazů do bloku

Pomocí závorek můžeme upravit i příslušnost else k určitému if. Nechť čtenář sám rozliší sémantiku dvou následujících zápisů a zkusí si nakreslit odpovídající vývojový diagram.

if (výraz1) 
  if (výraz2) příkaz2;
  else příkaz3;
if (výraz1) 
  { if (výraz2) příkaz2; }
  else příkaz3;

V podmínce může být kromě booleovského výrazu jakýkoliv výraz. Platí zásada, že nenulová hodnota je chápana jako pravda (splnění podmínky), nulová hodnota jako nepravda (nesplněná podmínka). V booleovských výrazech používáme relační (srovnávací operátory). Jejich přehled uvádí tabulka 8.

Relační operátorVýznam
<menší než
>větší než
<=menší nebo rovno
>=větší nebo rovno
==rovno
!=nerovno

Tabulka 8: Relační operátory

Příklady:

int a, b; float x; char c;
...
if (a < 3) ...
if (b == 10) ...
if (x <= 3.5) ...
if (c != 'A') ...
Zde je nutné upozornit, že operátor srovnání pro rovnost má podobu dvou rovnítek. Pokud zapíšeme pouze jediné rovnítko, kód se bez problémů přeloží, ale zápis nevyjadřuje porovnání. Napíšeme-li např. if (a=5) ..., výraz a=5 zapsaný v podmínce je přiřazovací výraz a jde tedy o přiřazení v podmínce. Hodnota proměnné a se neporovná s 5, ale do proměnné a se přiřadí 5; výsledek přeřazovací výrazu je 5. Protože jde o nenulovou hodnotu, je chápana jako pravdivá. Podmínka je v tomto případě vždy splněna. Na tuto určitou záludnost jazyka C je potřeba dávat pozor (u některých překladačů se napíše varování)!

Poznámka: Skutečnost, že v podmínce může být zapsán libovolný výraz, má mnoho důsledků. Následující zápisy jsou správné: if (x) ...; if (a+b) ...; V prvém případě, pokud je hodnota proměnné x různá od nuly, je podmínka splněna. Ve druhém případě jsou sečteny hodnoty proměnných a, b. Je-li součet nenulový, podmínka je splněna; výsledek součtu se neuloží. Protože je přiřazení v jazyce C definováno jako výraz, lze v podmínce provést současně přiřazení a porovnání:

if ((x=a+b)<10) ...;
Součet proměnných a, b je uložen do proměnné x a pak je ihned porovnán s hodnotou 10. Výraz x=a+b musí být uzavřen v závorkách, protože relační operátory mají v jazyce C větší prioritu než přiřazovací operátor.

Složené výrazy

Obdobně jako ve výrokové algebře, lze do podmínky zapisovat složené výroky spojené logickými spojkami a, nebo a tvořit negaci výroků. Logické spojky se zapisují pomocí symbolů a jejich přehled uvádí tabulka 9.

SpojkaVýznam
&&a zároveň (konjukce)
||nebo (disjunkce)
!negace

Tabulka 9: Logické spojky

Spojky se musí zapisovat jako pár symbolů, jinak jde o bitové operátory!

Příklady:

if (a < 3 && a > 1) ...
if (!(b == 10)) ...
Jednotlivé výroky není potřeba uzavírat do závorek, relační operátory mají větší prioritu než logické spojky. Pro lepší čitelnost kódu se závorky často píší.

Ještě připomeňme, že konjukce výroků je pravdivá, jsou-li pravdivé oba výroky. Disjunkce je pravdivá, je-li pravdivý alespoň jeden z výroku (matematické nebo není výlučné). Pro práci s výroky je vhodné si zopakovat De Morganovy zákony:

De Morganovy zákony

V jazyce C se provádí zkrácené vyhodnocování složených podmínek. Je-li již z dosavadního výpočtu zřejmé, že podmínka je splněna/nesplněna, další výrazy se ve složených výrocích již nevyhodnocují.


Cyklus s podmínkou na začátku (cyklus while)

Cyklus typu while má v jazyku C následující syntaxi:
while (výraz) příkaz;
Chceme-li mít v těle cyklu více příkazů než jeden, uzavřeme je do bloku mezi složené závorky:
while (výraz)
{
  příkaz1;
  příkaz2;
}
Výraz v závorce ze klíčovým slovem while (česky zatímco, dokud) představuje podmínku a platí pro něj vše, co bylo napsáno o podmínkách (viz
podminka if)

Sémantika cyklu je jednoduchá a zřejmá: dokud je podmínka splněna, provádějí se příkazy v těle cyklu. Nechť si čtenář uvědomí, že tělo cyklu nemusí proběhnout ani jednou. Pokud není již před vstupem do cyklu podmínka splněna, do těla cyklu se nevstupuje.

Příklad jednoduchého programu s cyklem while je výpis malé násobilky čísla 3:

int i = 0;
while (i<=10)
{
  printf("%d ",i*3);
  i++;
}

Úloha 2.1:

Napište program pro výpočet obsahu obdelníka. Velikosti stran zadejte z klávesnice. Vyzkoušejte, co se stane, zapomenete-li deklarovat proměnnou nebo nesouhlasí-li počet parametrů funkcí printf, scanf. Při výpisu výsledku vyzkoušejte různé způsoby formátování (omezený počet des. míst, semilogaritmický tvar). Obě hodnoty velikosti stran načítejte pomocí jedné funkce scanf, otestujte, zda funkce scanf zkonvertovala správně obě vstupní čísla.

Řešení:

Dev C++:obsah.dev, obsah.c
CodeBlocks:obsah.cbp, obsah.c

Úloha 2.2:

Napište program který načte z klávesnice dva časy ve tvaru hh:mm:ss a vytiskne jejich součet. Pro čtení času v tomto formátu využijte vhodně formátovací řetězec ve funkci scanf, ošetřete chybu zadání času. Výsledný čas vypište ve stejném formátu jako vstupní data, každou složku času zobrazte na dvě cifry (hodiny minimálně na dvě místa) s úvodní nulou.

Řešení:

Dev C++:casy.dev, casy.c
CodeBlocks:casy.cbp, casy.c

Úloha 2.3

Upravte program pro výpočet nejmenšího společného násobku z minulého cvičení; napište cyklus while co nejúsporněji.

Řešení:

Dev C++:nsn2.dev, nsn2.c
CodeBlocks:nsn2.cbp, nsn2.c

Úloha 2.4

Napište program, který vypočítá ciferný součet zadaného přirozeného čísla. Číslo je zadáno jako typ int.

Příklad vstupu:
157

Příklad výstupu:
Ciferny soucet cisla 157 je 13.

Návod: použijte cyklus while, využijte operací zbytek po celočíselném dělení a celočíselné dělení.

Řešení:

Dev C++:cif_soucet.dev, cif_soucet.c
CodeBlocks:cif_soucet.cbp, cif_soucet.c

Úloha 2.5

Napište program, který čte posloupnost celých čísel ukončených nulou. Pak vypíše, kolik bylo čísel v intervalu 3 .. 10 (včetně hranic) a dále vypíše nejmenší číslo. Ukončující nula se mezi hodnoty posloupnosti již nepočítá.

Příklad vstupu:
2 -1 3 5 20 0

Příklad výstupu:
Pocet hodnot mezi 3 az 10: 2
Nejmensi cislo: -1
Návod: použijte cyklus while, k načítání hodnot využijte funkci scanf.

Řešení:

Dev C++:posloupnost.dev, posloupnost.c
CodeBlocks:posloupnost.cbp, posloupnost.c

Cyklus s podmínkou na konci (cyklus do while)

Cyklus s podmínkou na konci má v jazyce C syntaxi:
do příkaz; while (výraz);
Chceme-li mít v těle cyklu více příkazů než jeden, musíme je opět uzavřít do bloku mezi složené závorky, i když je tělo ohraničeno klíčovými slovy do, while:
do
{
  příkaz1;
  příkaz2;
}
while (výraz);
Sémantika cyklu je obdobná cyklu s podmínkou na začátku: dokud je podmínka splněna, provádějí se příkazy v těle cyklu. V tomto případě tělo cyklu proběhne alespoň jednou. Jako ukázku použití cyklu uvedeme kód, který vyzývá uživatele k zadání celého čísla tak dlouho, dokud není zadané číslo kladné.
do
{
  printf("Zadej kladne cele cislo: ");
  scanf("%d",&n);
  if (n < 0) printf("Zadane cislo musi byt kladne!");
}
while (n<0);


[Cvičení 1] [Obsah] [Cvičení 3]