Kurz C++ (3.)
Ve t°etφ lekci naÜeho kurzu o C/C++ se dostßvßme k podstatnΘ
Φßsti jazyka. Nejd°φve
si povφme o funkcφch getchar(), putchar(), printf() a scanf().
Povφme si o velice d∙le₧itΘm p°φkazu if-else.
Dßle si °ekneme, co jsou to iteraΦnφ p°φkazy neboli cykly a ukß₧u vßm
vÜechny typy takov²ch cykl∙. S cykly ·zce souvisφ
p°φkazy break a continue a nakonec vysv∞tlφm p°φkaz switch.
5.1. Terminßlov² vstup a v²stup
Na zaΦßtek je nutnΘ poznamenat, ₧e vÜe, co je uvedeno
v tΘto lekci je podstata jazyka C a je nutnΘ, abyste vÜe
sprßvn∞ pochopili, proto₧e p°i dalÜφm programovßnφ
se bez toho urΦit∞ neobejdete.
Abyste mohli vyu₧φvat funkce pro vstup a v²stup musφte
k vaÜemu programu p°ipojit hlaviΦkov² soubor (header file).
O vklßdßnφ hlaviΦkov²ch soubor∙ jsem se ji₧ zmφnil v minulΘ
lekci. Provede to
p°φkazem include .
Vlo₧te nßsledujφcφ °ßdek na zaΦßtek vaÜeho programu:
#include <stdio.h>
Nynφ m∙₧ete pou₧φvat vÜechny funkce
deklarovanΘ prßv∞ v souboru
stdio.h a kterΘ
souvisφ s I/O (input/output - vstup/v²stup)
operacemi jako je i v²stup na
obrazovku a vstup z klßvesnice
(dßle m∙₧e obsahovat nap°φklad
v²stup na tiskßrnu Φi Φtenφ a zßpis do souboru).
5.1.1. Vstup a v²stup jednoho znaku
V²stup jednoho znaku zajiÜ¥uje funkce putchar() , kterß
mß jeden parametr kupodivu typu int (nikoliv char),
kter² p°edstavuje hodnotu znaku v ASCII tabulce.
Druhß funkce getchar() p°eΦte jeden znak. Pokud
na °ßdek napφÜeme vφc znak∙ a stiskneme Enter,
funkce p°eΦte pouze prvnφ znak a ostatnφ ignoruje.
Program p°eΦte znak, vypφÜe ho a od°ßdkuje.
Krßtky p°φklad:
int c;
c = getchar();
putchar(c);
putchar('\n');
VÜimn∞te si, ₧e jako parametr funkce
putchar()
m∙₧ete pou₧φt znakovou konstantu tj. znak
uzav°en² mezi apostrofy nap°.
'a', '5' apod.
Hodnota znakovΘ konstanty odpovφdß celoΦφselnΘ
hodnot∞ z ASCII tabulky nap°.
'a' mß hodnotu
97. (ASCII tabulka nemusφ b²t na vÜech systΘmech
stejnß).
Zßpis
putchar(97);
a
putchar('a');
je ekvivalentnφ.
5.1.2. Formßtovan² vstup a v²stup
Co kdy₧ ale chceme p°eΦφst vφce ne₧ jeden znak nebo
naopak chceme vypsat celou v∞tu? Od toho mß C dv∞ funkce:
scanf() - naΦte znaky, °et∞zce nebo Φφsla z klßvesnice a ulo₧φ je
v po₧adovanΘm formßtu do prom∞nnΘ.
printf() - vypφÜe °et∞zec v po₧adovanΘm
formßtu na obrazovku.
Zp∙sob formßtovßnφ
Ob∞ funkce majφ prom∞nn² poΦet parametr∙ a my
jim tedy musφme °φct, kolik parametr∙ majφ zpracovßvat.
K tomu slou₧φ prvnφ parametr, co₧ je °et∞zcovß konstanta (nebo takΘ °φdφcφ °et∞zec)
obsahujφcφ jistΘ znaky, kterΘ prßv∞ °φkajφ kolik mß mφt funkce
parametr∙ a jakΘho jsou typu.
╪φdφcφ °et∞zec m∙₧e obsahovat:
- FormßtovΘ specifikace, kterΘ v₧dy zaΦφnajφ znakem "%" (procenta)
a urΦujφ typ vstupnφ nebo v²stupnφ hodnoty. Konkretnφ typ je urΦen znaky,
kterΘ nßsleduje t∞sn∞ za tφmto znakem.
- ZnakovΘ posloupnosti, jsou b∞₧nΘ ΦitelnΘ °etezce, kterΘ
se vypφÜφ tak jak jsou, ale dajφ se pou₧φt jen ve funkci
printf() .
Tabulka nejΦast∞ji pou₧φvan²ch formßtov²ch specifikacφ:
Znak za % | Typ parametru |
c | znak - je lepÜφ pou₧φt funkci getchar() nebo putchar() |
d | celΘ Φφslo typu signed int |
ld | celΘ Φφslo typu signed long |
u | celΘ Φφslo typu unsigned int |
lu | celΘ Φφslo typu unsigned long |
f | reßlnΘ Φφslo typu float |
lf | reßlnΘ Φφslo typu double |
Lf | reßlnΘ Φφslo typu long double (L musφ b²t skuteΦnΘ velkΘ) |
x | Φφslo v hexadecimßlnφm tvaru s mal²mi pφsmeny - 5b8f |
X | Φφslo v hexadecimßlnφm tvaru s velk²mi pφsmeny - 5B8F |
o | Φφslo v osmiΦkovΘm tvaru |
s | °et∞zec |
P°φklady pou₧itφ printf() :
printf("Je presne %2d:%2d\n", hodiny, minuty);
VypφÜe nap°φklad "Je presne 21:27".
╚φslem mezi % a formßtov²m znakem je poΦet cifer, kterΘ
se vypφÜφ. U reßlnΘho Φφsla lze urΦit poΦet cifer
p°ed a za desetinou teΦkou nßsledovn∞:
printf("Cena vyrobku je %6.2f Kc\n", cena);
VypφÜe nap°φklad "Cena vyrobku je 10.40 Kc".
Bude vytiÜt∞no 6 cifer z toho 2 budou za desetinou teΦkou.
printf("Cislo %d je hexa %XH\n", cislo, cislo);
VypφÜe nap°φklad "Cislo 85 je v hexa 55H".
VÜimn∞te si konverze dekadickΘho Φφsla na hexadecimßlnφ Φφslo.
P°φklady pou₧itφ scanf() :
scanf("%d", &cele_cislo);
Tento p°φkaz p°eΦte celΘ Φφslo z klßvesnice a ulo₧φ ho do prom∞nnΘ cele_cislo.
Pozor! VÜimn∞te znaku & p°ed prom∞nnou cele_cislo .
Funkci scanf() p°edßvßme
ukazatel na prom∞nnou cele_cislo a tento operßtor vracφ prßv∞ ukazatel.
To je rozdφl od p°edchozφ funkce a zaΦφnajφcφ programßtor na to Φasto zapomene. Kompilßtor
₧ßdnou chybu nevypφÜe, ale program funguje chybn∞.
Zatφm vßm staΦφ v∞d∞t, ₧e na tento operßtor nesmφte zapomenout.
scanf("%f", &realne_cislo);
Tento p°φkaz p°eΦte reßlnΘ Φφslo z klßvesnice a ulo₧φ ho do prom∞nnΘ realne_cislo.
Poznßmka:
Minule jsem se zmi≥oval o objektech cout a cin .
Tyto objekty majφ stejnou funkci
jako funkce printf() a scanf() .
5.2. BooleovskΘ v²razy
Booleovsk² v²raz je v²raz, kter² vracφ bu∩ logickou
1 (TRUE - pravda) nebo logickou 0 (FALSE - nepravda).
Jazyk C nemß p°φmo typ Boolean a tak mφsto toho vyu₧φvß
typ int , kde hodnota 0 p°edstavuje FALSE a nenulovß
hodnota (nejΦast∞ji 1, ale nenφ to podmφnkou)
p°edstavuje TRUE.
Nßsledujφcφ tabulka ukazuje tzv. relaΦnφ operßtory,
kterΘ pou₧φvßme v podmφnkßch. VÜe si ukß₧eme na p°φkladu.
Operace | Syntaxe |
rovnost | = = |
nerovnost | != |
logick² souΦin | && |
logick² souΦet | || |
negace | ! |
v∞tÜφ | > |
menÜφ | < |
v∞tÜφ nebo rovno | >= |
menÜφ nebo rovno | <= |
Ka₧d² booleovsk² v²raz obsahuje jeden nebo vφce t∞chto operßtor∙.
P°φklad:
// Toto je prirazeni, nikoliv porovnani, menime hodnotu promenne i
i = 5
// Zde vidite porovnani hodnoty promenne i a cisla 5
// Vyraz vraci nenulovou hodnotu (TRUE) v pripade ze v promenne i je skutecne cislo 5, jinak vraci 0 (FALSE)
i == 5
5.1.1. Zkrßcene vyhodnocovßnφ logick²ch v²raz∙
ZkrßcenΘ vyhodnocovßnφ platφ pro logickΘ operace tzn. logick² souΦin
a logick² souΦet. Znamenß to, ₧e jakmile je mo₧no urΦit koneΦn² v²sledek
vyhodnocovßnφ skonΦφ.
P°φklad:
// Toto je zcela sprßvnΘ a k d∞lenφ nulou nikdy nedojde,
// proto₧e y != 0 ukonΦφ vyhodnocovßnφ d°φve ne₧ by k n∞Φemu takovΘmu doÜlo
if(y != 0 && x / y < z)
5.2. P°φkaz if a if-else
Jak jsme si °φkali v²Üe, booleovsk² v²raz vracφ n∞kajou logickou hodnotu (0 nebo 1).
K vyhodnocenφ takovΘhoto v²razu pou₧ijeme p°φkaz if :
if(v²raz) { // zavorky jsou nutne
p°φkaz_1;
}
p°φkaz_2;
Pokud je podmφnka v²razu spln∞na (vracφ TRUE), program provede
p°φkaz_1 a potΘ i p°φkaz_2 .
V opaΦnΘm p°φpad∞ (pokud v²raz vrßtφ FALSE) je proveden pouze p°φkaz_2 .
P°φklad:
// Program testuje zdali hodnota promenne i je vetsi nez 5
// V kladnem pripade vypise hlasku
if(i > 5) {
printf("Hodnota promenne i je vetsi nez 5\n");
}
VÜimn∞te si, ₧e v²raz je v₧dy uzav°en do kulat²ch zßvorek () a ₧e p°φkazy "pod"
if jsou
uzav°eny do zßvorek slo₧en²ch {}. Pokud je "pod" if
pouze jeden p°φkaz, slo₧enΘ zßvorky
nejsou nutnΘ, naproti tomu kulatΘ jsou nutnΘ v₧dy!
P°φkaz
if-else se liÜφ jen mßlo. P°φkazy "pod"
else jsou provßd∞ny
jen kdy₧ v²raz vracφ FALSE. ╚esky °eΦeno: "Kdy₧ (if) n∞co (v²raz),
tak ud∞lej tohle (p°φkaz_1), jinak (else) ud∞lej tamhleto (p°φkaz_2)."
P°φklad:
// Program testuje zdali hodnota promenne i je vetsi nez 5
// V obou pripadech vypise logickou hlasku
if(i > 5) {
printf("Hodnota promenne i je vetsi nez 5\n)";
}
else {
printf("Hodnota promenne i je mensi, rovna nez 5\n)";
}
VÜimn∞te si, jak jsou p°φkazy a¥ u₧ "pod" if nebo else ,
mφrn∞ odsazeny
oproti ostatnφm p°φkaz∙m. Je to zd∙vodu Φitelnosti programu a siln∞
doporuΦuji se toho dr₧et.
P°φkazy if-else jsou Φasto vhnφzd∞nΘ do jin²ch p°φkaz∙
if nebo if-else . Ka₧dΘ dalÜφ
if je odsazeno o jeden tabelßtor doprava.
P°φklad:
// Program nejprve testuje hodnotu promenne a a teprve pak pokracuje
if(a != 0) {
if(i > 5) {
printf("Hodnota promenne i je vetsi nez 5\n");
}
else {
printf("Hodnota promenne i je mensi nebo rovno nez 5\n");
}
}
Te∩ znovu p°epφÜu p°edchozφ p°φklad, ale trochu jinak:
// Zde vidite uzity operator logickeho soucinu neboli AND (zaroven)
// Vyraz v zavorkach tedy znamena:
// Pokud a je ruzne od 0 A ZAROVEN i je vetsi nez 5, pak vypis hlasku
if(a != 0 && i > 5) {
printf("Hodnota promenne i je vetsi nez 5\n");
}
V nßsledujφm p°φkladu vidφte logick² souΦet:
// Zde vidite uzity operator logickeho soucinu neboli OR (nebo)
// Vyraz v zavorkach tedy znamena:
// Pokud a je ruzne od 0 NEBO i je vetsi nez 5, pak vypis hlasku
if(a != 0 || i > 5) {
printf("Hodnota promenne i je vetsi nez 5\n");
}
Poznßmka:
╚asto m∙₧eme vid∞t p°φkaz if zkrßcen².
Mφsto p°φkazu:
if(vyraz != 0)
pφÜeme jen
if(vyraz)
a mφsto p°φkazu:
if(vyraz == 0)
pφÜeme jen
if(!vyraz)
5.3. Ternßrnφ operßtor
Ternßrnφ operßtor mß stejn² v²znam jako p°φkaz if-else , jen syntaxe je jinß.
V n∞kter²ch p°φpadech je lepÜφ pou₧φt ternßrnφ operßtor kv∙li
kratÜφmu zßpisu na jeden °ßdek, ale doporuΦuji rad∞ji pou₧φvat if-else .
Ternßrnφ operßtor mß nßsledujφcφ syntaxy:
vyraz_podm ? vyraz_1 : vyraz_2;
P°φklad:
// Pokud je a ruzne od 0, i bude rovno 5
// V opacnem pripade bude i rovno 10
i = (a != 0) ? 5 : 10;
Stejn² p°φklad s pou₧itφm if-else :
// Funkce je uplna stejne jako v predchozim prikladu
// Vidite ze zapis pomoci if-else je delsi, ale je prehlednejsi
if(a != 0) {
i = 5;
}
else {
i = 10;
}
Poznßmka: Zßvorky kolem podmφnky u ternßrnφho
operßtoru nejsou nutnΘ, ale v°ele je doporuΦuji kv∙li Φitelnosti programu.
5.4. IteraΦnφ p°φkazy - cykly
Jazyk C rozliÜuje t°i typy iterace (opakovßnφ): for, while
a do-while .
5.4.1. P°φkaz for
Tento cyklus pou₧ijeme v p°φpad∞, kdy₧ p°edem znßme poΦet pr∙chod∙ cyklem.
Syntaxe je nßsledujφcφ:
for(vyraz_start; vyraz_stop; vyraz_iter) {
prikaz;
}
Cyklus for nejd°φve vyhodnotφ vyraz_start, otestuje pravdivost vyrazu_stop
(kdy₧ v²raz vratφ FALSE, cyklus skonΦφ) a provede p°φkazy
uvnit° cyklu a nakonec provede vyraz_iter. Toto celΘ se opakuje dokud vyraz_stop nevratφ
nepravdu (FALSE).
Ukß₧eme si n∞kolik p°φklad∙:
// Program vypise pod sebe 20 cisel (0-19)
// Promenna i je predem deklarovana jako int
// Toto je doporucene pouziti cyklu for
for(i = 0; i < 20; i++) {
printf("%d\n", i);
}
// Program vypise pod sebe 20 cisel (19-0)
// Promenna i je deklarovana primo v cyklu (toto nemusi vzdy fungovat)
// Toto je caste pouziti cyklu for
for(int i = 19; i >= 0; i--) {
printf("%d\n", i);
}
M∙₧eme vyu₧φt nekoneΦn² cyklus:
// Takovy program radeji nezkousejte, protoze nikdy neskonci
// ale za chvilku si povime jak ukoncit cyklus explicitne
for( ; ; ) {
printf("Ahoj\n");
}
5.4.2. P°φkaz while
DalÜφm velice d∙le₧it²m cyklem je cyklus while .
Testuje podmφnku p°ed pr∙chodem cyklu, tzn., ₧e
cyklus nemusφ prob∞hnout ani jednou. UkonΦovacφ
podmφnka v∞tÜinou zßvisφ na p°φkazu v t∞le cyklu
a my p°edem nevφme kolikrßt cyklus prob∞hne.
Syntaxe:
while(podm) {
prikaz;
}
V²raz podm se testuje a pokud vrßtφ
0 (FALSE), cyklus skonΦφ.
5.4.3. P°φkaz do-while
Poslednφm iteraΦnφm cyklem je do-while (d∞lej-dokud).
LiÜφ se od p°edchozßho tφm, ₧e testuje podmφnku
a₧ po pr∙chodu cyklem tzn., ₧e cyklus prob∞hne alespo≥ jednou.
Cyklus je ukonΦen a₧ kdy₧ v²raz v podmφnce vrßtφ 0 (FALSE).
Syntaxe:
do {
prikaz;
} while(podm);
5.4.4. P°φkazy break a continue
P°φkazy break a continue ovliv≥ujφ normßlnφ
pr∙b∞h cyklu. Lze je pou₧φt na vÜechny v²Üe uvedenΘ
typy cykl∙.
- break
Tento p°φkaz ukonΦuje nejvnit°n∞jÜφ smyΦku neboli opouÜtφ okam₧it∞ cyklus.
- continue
Druh² uveden² p°φkaz skßΦe na konec cyklu a tφm si vynutφ dalÜφ opakovßnφ cyklu,
ale cyklus neopouÜtφ.
5.4.5. P°φkaz switch
C obsahuje jak²si p°epφnaΦ neboli switch, kter²
umo₧≥uje mnohonßsobnΘ v∞tvenφ programu.
Syntaxe:
switch(vyraz) {
case hodnota_1: // Toto je jedna vetev
prikaz_1; // ...
break; // ...
case hodnota_2: // A zde zacina dalsi vetev
prikaz_2;
break;
case hodnota_3:
prikaz_3;
break;
default:
prikaz_def;
break;
}
Program porovnßvß vyraz s jednotliv²mi
hodnotami_X ka₧dΘ v∞tve a provede
tu v∞tev, kde se vyraz rovnß hodnote_X .
Pozor!
Nenφ-li v∞tev ukonΦena p°φkazem break ,
program zaΦne zpracovßvat dalÜφ v∞tve
v po°adφ dokud nenarazφ na break . Proto
je t°eba na konci ka₧dΘ v∞tve psßt
break . Z tohoto ale vypl²vß, ₧e pokud
chceme pro vφce hodnot zpracovat pouze jednu v∞tev,
staΦφ vynechat p°φkaz break v t∞chto v∞tvφch.
Nap°φklad:
switch(vyraz) {
case hodnota_1:
prikaz_1;
break;
case hodnota_2:// Zde neni break
case hodnota_3:
prikaz_23;
break;
}
Prikaz_23 se provede, kdy₧ je vyraz roven bu∩
hodnote_2 nebo hodnote_3 .
5.5. P°φklad
VÜe si samoz°ejm∞ ukß₧eme na p°φkladu. P°φklad si m∙₧ete stßhnout z CD v sekci Downloads.
VÜe, co pot°ebujete v∞d∞t k p°φkladu je v tΘto nebo v minulΘ lekci a popis funkce najdete v komentß°φch.
#include <stdio.h>
int main(int argc, char* argv[])
{
int iVolba, i;
char c;
double f, g;
do {
//
// Informace pro uzivatele
printf("1) Test smycky for\n");
printf("2) Test smycky while\n");
printf("3) Test smycky do-while \n");
printf("4) Konec programu\n");
printf("Zadejte co chcete otestovat:");
//
// Ulozime uzivatelovu volbu do promenne iVolba jako hodnotu typu int
scanf("%d", &iVolba);
//
// Vetveni programu podle toho, co zvoli uzivatel
switch(iVolba) {
case 1:
//
// Test cyklu for
printf("Zvolil jste prikaz for, vypisu 10 cisel a skoncim.\n");
//
// Cyklus for od 0 do 9
for(i = 0; i < 10; i++) {
printf("%d\n", i);
}
//
// Nakonci jeste odradkujeme
printf("\n");
break;
case 2:
printf("\nZvolil jste prikaz while.\n");
printf("Program cte znaky z klavesnice, tisknutelne znaky opisuje,\n");
printf("neviditelne preskakuje a zastavi se pri precteni znaku 'z'.\n\n");
//
// Precteni znaku
while((c = getchar()) != 'z') {
if(c >= ' ') { // Vynechavame neviditelne znaky
putchar(c); // Tisk znaku
printf("\n"); // Odradkuju
}
}
break;
case 3:
printf("Zvolil jste prikaz do-while. \n");
printf("Program nacte dolni a horni mez intervalu\n");
printf("a pote vypise vsechny cela cisla z tohoto intervalu.\n");
//
// Nacteme dve realna cisla
printf("Zadejte dolni mez intervalu:");
scanf("%lf", &f);
printf("Zadejte horni mez intervalu:");
scanf("%lf", &g);
//
// Test zdali je horni mez skutecne vetsi nez dolni mez
if(f < g) {
//
// Zaokrouhleni realneho cislo na cele cislo (explicitni konverze)
i = (int) f;
do {
// Vypsani celeho cisla
printf("%d\n", i);
// Prejdeme na dalsi cele cislo
i++;
// A testujeme zdali jsme jiz dosahli horni hranice intervalu
} while(i <= g);
}
else {
printf("Chyba! Zadali jste chybne meze.\n");
}
break;
case 4:
//
// Konec
printf("Konec...\n");
break;
default:
printf("Zvolil jste kravinu\n");
break;
}
//
// Testujeme promennou iVolba na hodnotu 4,
// coz je volba, pri ktere ma program skoncit
} while(iVolba != 4);
return 0;
}
Poznßmka:
Op∞t si vÜimn∞te odsazenφ jednotliv²ch v∞tvφ p°φkazu switch a odsazenφ t∞l
cykl∙. Toto je velmi dobrΘ d∞lat kv∙li p°ehlednosti v programu.
5.6. Zßv∞r
Na zßv∞r vßm prozradφm, co nßs Φekß p°φÜt∞.
P°φÜt∞ probereme preprocesor jazyka a funkce.
Mezi p°φkazy preprocesoru pat°φ i nßm znßm² p°φkaz
include . Zjistφte, ₧e p°ed ka₧d²m p°φkazem preprocesoru
je znak '#' .
Dßle si vytvo°φme vlastnφ funkce mimo funkci
main() .
Tyto funkce pak budeme volat z funkce main() .
T∞Üφm se p°φÜt∞ nashledanou.
|