Vraťme se ještě k příkazům z odst. 5.1.4, které jsou až na výjimky prováděny sekvenčně.
Na rozdíl např. od Pascalu, kde přiřazení je příkazem, je přiřazení výrazem. Jazyk C ovšem z libovolného výrazu utvoří příkaz tím, že výraz ukončí středníkem.
Výrazové příkazy typu
sin(alfa)*4; a[i] + b[i];
Výrazy, které mění hodnotu některého z použitých objektů, tedy i všechny přiřazovací výrazy, však význam příkazu mají, např.
x = y*y; i++; --i, ++j;
Speciálním případem je prázdný příkaz (tvořený jen středníkem)
;
Libovolné příkazy mohou být závorkami {, } uzavřeny do příkazu složeného, se kterým se zachází jako s jedním příkazem. Jsou-li na začátku složeného příkazu uvedeny deklarace, mluvíme o bloku. Platí obvyklá pravidla o vnořených blocích a skrývání deklarací identifikátorů deklarovaných v bloku i v blocích nadřazených (uvnitř bloku nejsou vnější významy vidět a po výstupu z bloku se opět objeví).
Objekty deklarované uvnitř bloku mají implicitně přisouzenou třídu auto, tedy zápisy
{ int i; {auto int; ... ... } }
V bloku lze deklarovat i proměnné třídy static jsou pouze definovány (není jim alokována paměť!). To ovlivňuje i možné inicializace. Inicializace objektů třídy auto nebo register jsou provedeny při každém vstupu do bloku přes otevírací závorku '{'. Objekty třídy static jsou inicializovány pouze jednou (při zavední programu do paměti) a externí objekty nemají inicializaci povolenu, protože nemají alokovánu paměť.
V bloku
{ int i=0; static char m[]= "BLOK UKAZKOVY"; register char *p = m; extern float x,y; ... }
Koncová závorka } zřetelně ukončuje složený příkaz, takže není třeba za ním psát středník a syntaxe jazyka C to ani nedovoluje.
Podmíněný příkaz může mít v C podobu neúplného větvení:
if(E) if(E) S1; S1; else S2;
V obou případech se nejdříve vyhodnotí podmínkový výraz E uvedený za if. Má-li nenulovo hodnotu (true), provede se příkaz S1 za podmínkovým výrazem (neužívá se klíčové slovo then). Má-li nulovou hodnotu (false), provede se příkaz uvedený za else, tj. S2. To lze využít např. ve funkci
max(a,b) { if(a > b) return(a); else return(b); }
{ if(a > b) return(a); return(b); }
Nejednoznačnost v přiřazení if a else u vnořených podmíněných příkazů se řeší přiřazením else k nejblíže předcházejícímu volnému if. To vadí v případě, kdy neúplné větvení je vnořeno jako první příkaz do úplného větvení.
if(y!=0) if(x<0) x = -x; else printf("DELENI NULOU?\n"); z = x/y;
Diagnostická zpráva se chybně vypíše pro zápornou hodnotu x. Správný zápis využívá složeného příkazu (byť z jediného jednoduššího):
if(y!=0) {if(x<0) x = -x; } else printf("DELENI NULOU?\n"); z = x/y;
Poměrně často se vyskytuje v programech větvení pro více než dva případy. To lze v C vyjádřit posloupností úplných podmíněných příkazů, např.:
if(odstin == bila) index = -5; else if(odstin == cervena) index = 3; elseindex = 7;
Cyklus while ve tvaru
while(E) S;
k = 1, i = n; while(i--) k*=m;
Cyklus do ve tvaru
do S while(E);
k = 1, i = n; do k*=m; while(i--);
Všimněte si rozdílného použití operátoru dekrementace. V prvním případě se vyhodnotí i jako podmínka a pak se hodnota sníží, v druhém případě se hodnota i sníží a pak se vyhodnotí jeho podmínka. Tím se vyrovná rozdíl mezi oběma cykly (pro n > 0).
Tento neobvyklý cyklus
for(E1; E2; E3) S;
E1; while(E2) { S; E3; }
Za klíčovým slovem for se zapisuje záhlaví cyklu (výrazy E1, E2 a E3 v závorkách jsou odděleny středníky), potom tělo cyklu, příkaz S. Vyhodnotí se E1, otestuje se podmínkový výraz E2. Je-li nenulový, provede se příkaz S a výraz E3 a činnost se opakuje od vyhodnocení podmínkového výrazu E2.
Pro cyklus od 1 do n se užívá např.:
k = 1; for(i=1; i<=n; i++) k*=m;
for(k=1, i=n; i--;) k*=m;
k=1, i=n; while(i--;) k*=m;
Všechny výrazy se závorkami mohou chybět, středníky zůstávají a chybějící druhý podmínkový výraz se považuje za trvale pravdivý. Tedy
for(;;) { ... }
Příkaz cyklu for může být použit i v jiných situacích, např. potřebujeme-li ve znakovém poli c najít první výskyt znaku *. Využijeme k tomu ukazatele p na char:
for(p=c; *p!='*'; p++) ;
Příkaz přepínače je alternativním řešením posloupnosti úplných podmínkových příkazů. Má zpravidla tvar
switch(E) { ... }
switch(odstin) { case bila : index = -5; break; case cervena : index = 3; break; default : index = 7; }
Příkazem break končí provádění nejblíže nadřazeného složeného příkazu příslušného k přepínači switch. Není-li použit, pak provádění větve přepínače nekončí nalezením dalšího místa předání řízení, ale pokračuje dále. To je však málokdy výhodné. Je povoleno označit místo předání řízení několika konstantními výrazy, např.:
switch(dnes){ case PO: case UT: case ST: case CT: case PA: pracovni++; break; case SO: priplatek = 50; break; case NE: priplatek = 100; break; }
Příkazem break lze opustit i nejblíže nadřazený cyklus while, do nebo for. Tak např. při přepisování posloupnosti nejvýše 80 znaků ukončené novým řádkem ze znakového pole x do znakového pole y můžeme použít cyklus:
for(i=0; i<80; i++) { y[i] = x[i]; if(x[i] == '\n') break; }
Tento příkaz se obdobně jako příkaz break pohybuje v kontextu nejblíže nadřazeného cyklu while, do nebo for. Místo, aby způsobil opuštění cyklu, začíná nový průchod cyklem, aniž by se dokončil průchod předchozím. Příklad můžeme přepsat takto:
for(i=0; i<80; i++) { switch(y[i] = x[i]) { case '\n' : break; default : continue; } break; }