Kurz C++ (7.)
Struktury
Zßklady
K vysv∞tlenφ struktur si zase vezmu na pomoc p°φklad adresß°e osob. Ukßzali jsme si, ₧e pomocφ pole m∙₧eme jednoduÜe uklßdat do jednΘ prom∞nnΘ vφc ·daj∙
stejnΘho druhu. Nap°φklad do pole °et∞zc∙ bychom mohli uklßdat jmΘna. Ale my pot°ebujeme uklßdat i adresy, data narozenφ, prost∞ spoustu
·daj∙. M∙₧eme si poradit dalÜφmi poli, ale sami asi uznßte, ₧e to nenφ p°φliÜ elegantnφ. Mnohem lepÜφ °eÜenφ je pou₧itφ tzv. struktur.
Jsou to "slo₧enΘ prom∞nnΘ", tedy takovΘ prom∞nnΘ, kterΘ obsahujφ jinΘ prom∞nnΘ (slo₧ky).
Struktury se deklarujφ klφΦov²m slovem struct :
struct Clovek {
char jmeno[30];
char adresa[50];
unsigned vek;
};
Deklarovali jsme nov² datov² typ: strukturu, kterß se naz²vß Clovek, a mß 3 slo₧ky: dva
°et∞zce (jmeno a adresa ) a jednu
celoΦφselnou prom∞nnou (vek ). Pozor na to, ₧e deklarace struktury musφ konΦit st°ednφkem.
Poznßmka: je zvykem deklarovat struktury mimo t∞la funkcφ. Deklarujte tedy strukturu Clovek mimo funkci main() .
Proto₧e se jednß o datov² typ, deklaraci prom∞nn²ch provedeme tak, jak jsme zvyklφ:
Clovek osoba1; // deklarace prom∞nnΘ novΘho datovΘho typu
Clovek osoba2;
Clovek osoba3;
strcpy(osoba1.jmeno, "Jan Novßk"); // p°istupujeme k slo₧kßm struktury
strcpy(osoba1.adresa, "Kocourkov");
osoba1.vek = 30;
strcpy(osoba2.jmeno, "Petr Nejedl²");
*osoba2.adresa = 0; // adresu neznßme, osoba2.adresa je prßzdn² °et∞zec
osoba2.vek = 35;
osoba3 = osoba2;
Deklarovali jsme t°i prom∞nnΘ datovΘho typu Clovek, kterΘ jsme dßle inicializovali. VÜimn∞te si, ₧e p°istup k
slo₧kßm struktur se provßdφ operßtorem "." (teΦka). Dßle je na poslednφm °ßdku vid∞t, ₧e struktury je mo₧nΘ
vzßjemn∞ p°i°azovat.
Poznßmka: na °ßdku *osoba2.adresa = 0; pou₧φvßme dva operßtory: "*" a ".". ZvφdavΘho Φtenß°e mo₧nß napadne, ₧e
na takovou konstrukci je mo₧nΘ se dφvat dv∞ma zp∙soby:
*(osoba2.adresa) = 0;
tzn. vyhodnotφ se osoba2.adresa a na v²slednΘ adrese se ulo₧φ 0, nebo
(*osoba2).adresa = 0;
tzn. provede se dereference osoba2 (aΦkoli to nenφ ukazatel, ale co kdyby byl?) a pak se na prvnφ mφsto
slo₧ky adresa v²sledku dereference ulo₧φ 0. Jinak polo₧ena otßzka by mohla znφt: mß v∞tÜφ prioritu operßtor "." (co₧ odpovφdß
prvnφ mo₧nosti), nebo operßtor "*"? Sprßvnß je ovÜem prvnφ mo₧nost, co₧ ale znamenß, ₧e kdyby prom∞nnß osoba2
skuteΦn∞ byla ukazatelem, museli bychom k jejφm slo₧kßm p°istupovat pon∞kud
t∞₧kopßdnou konstrukcφ se zßvorkami:
(*osoba2).adresa ). OvÜem, jak uvidφme dßle, existuje zvlßÜtnφ operßtor pro p°φstup k slo₧kßm ukazatele na
strukturu.
Struktury je mo₧nΘ vno°ovat (n∞jakß slo₧ka struktury je jinß struktura), ale nenφ mo₧nΘ, aby slo₧ka struktury byla prßv∞ deklarovanß
struktura. Jin²mi slovy, nenφ mo₧n² takov² zßpis:
struct Clovek {
char jmeno[30];
char adresa[50];
unsigned vek;
Clovek otec;
};
Ukßzali jsme si, ₧e datov² typ struktura deklarujeme klφΦov²m slovem struct . Existuje jeÜt∞ jeden zp∙sob deklarace,
kter² je dokonce o n∞co mocn∞jÜφ (umo₧≥uje deklarovat nap°. datov² typ "ukazatel na strukturu"): je jφm klφΦovΘ slovo typedef .
Jeho prost°ednictvφm je mo₧nΘ nap°φklad p°ejmenovat datov² typ na jin² (pro v∞tÜφ
p°ehlednost):
typedef unsigned int uint;
Tφmto p°φkazem jsme deklarovali nov² datov² typ uint (v tomto okam₧iku uint znamenß to samΘ, co unsigned int ).
TakΘ m∙₧eme deklarovat nap°φklad datov² typ ukazatel na int :
typedef int *pint;
Pou₧itφ takovΘho datovΘho typu by bylo nap°φklad takovΘ:
int i;
pint p; // to samΘ jako int *p
p = &i;
┌pln∞ stejn∞ lze deklarovat nov² datov² typ struktura:
typedef struct Clovek {
char jmeno[30];
char adresa[50];
unsigned vek;
} NovyClovek;
Nynφ lze deklarovat prom∞nnou jak datovΘho typu Clovek , tak i NovyClovek (datov² typ Clovek
jsme deklarovali klφΦov²m slovem struct , datov² typ NovyClovek zase klφΦov²m slovem typedef ) – v²Üe
uveden² zßpis je to samΘ jako:
struct Clovek {
char jmeno[30];
char adresa[50];
unsigned vek;
};
typedef Clovek NovyClovek;
Uvedenφ n∞jakΘho nßzvu jak pro struct , tak i pro typedef je zbyteΦnΘ, tak₧e se v∞tÜinou nßzev za struct neuvßdφ.
JeÜt∞ bych cht∞l podotknout, ₧e deklarace struktur klφΦov²m slovem typedef je spφÜe zßle₧itost jazyka C, v C++ si
a₧ na jednu v²jimku, kterou si ukß₧eme dßle, vystaΦφme s klφΦov²m slovem struct .
Poznßmka: deklarace prom∞nnΘ datovΘho typu struktura se provßdφ v C uvedenφm klφΦovΘho slova struct:
struct Clovek {
...
}
struct Clovek osoba; // uvedenφ struct je povinnΘ
Proto₧e to je nepohodlnΘ, v C se pou₧φvß prßv∞ typedef , kter² tuto nev²hodu odstra≥uje.
P°i deklaraci prom∞nn²ch odvozen²ch od struktur je mo₧nΘ je i inicializovat:
Clovek osoba = {"Jan Novßk", "Kocourkov", 30};
Musφme dodr₧et po°adφ slo₧ek ve struktu°e, a takΘ musφme dbßt, abychom neinicializovali vφc slo₧ek, ne₧ mß struktura (to by skonΦilo
chybou). Ale nemusφme inicializovat vÜechny slo₧ky a pak ty, kterΘ neinicializujeme, budou mφt nulovou hodnotu:
Clovek osoba = {"Jan Novßk", "Kocourkov"}; // vynechßvßme slo₧ku vek
cout << osoba.vek; // vypφÜe se 0
Ukazatele na struktury
Jako i u zßkladnφch datov²ch typu, je mo₧nΘ se strukturami pracovat pomocφ ukazatel∙. Deklarace se provßdφ naprosto stejn∞:
Clovek osoba;
Clovek *p;
p = &osoba;
Jak jsme si °ekli v²Üe, p°φstup k slo₧kßm nebudeme provßd∞t operßtorem ".", ale operßtorem Üipka ("->"):
Clovek osoba1;
strcpy(osoba1->jmeno, "Jan Novßk");
strcpy(osoba1->adresa, "Kocourkov");
osoba1->vek = 30;
Poznßmka: pφÜete-li Φeskou klßvesnicφ, m∙₧e b²t problΘm psanφ znaku "v∞tÜφtko". Nemusφte kv∙li tomu
p°epφnat klßvesnici,
zkuste klßvesovou zkratku Alt + > (jednß se o prav² Alt).
V²Üe jsme si °ekli, ₧e slo₧kou struktury nem∙₧e b²t prßv∞ deklarovanß struktura. Slo₧kou struktury ale m∙₧e b²t ukazatel na
prßv∞ deklarovanou
strukturu.
struct Uzel {
int hodnota;
Uzel *dalsi;
};
Takov² datov² typ se pou₧φvß ve spojov²ch seznamech, o kter²ch si budeme vφce povφdat v jednom z dalÜφch dφl∙, prozatφm prosφm berte uveden² p°φklad
jako teoretick².
V p°φpad∞, ₧e strukturu deklarujeme klφΦov²m slovem typedef, pot°ebujeme ve
struktu°e slo₧ku ukazatel na prßv∞ deklarovanou
strukturu, je t°eba uvΘst n∞jak² nßzev i za struct , je to toti₧ jedin²
zp∙sob jak se na odkazovat na strukturu, kterou prßv∞
deklarujeme:
typedef struct Uzel {
int hodnota;
Uzel *dalsi;
} Uzel;
A koneΦn∞ si m∙₧eme ukßzat i p°φpad, na kter² samotnΘ klφΦovΘ slovo struct nestaΦφ: chceme-li deklarovat datov² typ "ukazatel
na strukturu" musφme pou₧φt typedef :
typedef struct {
char jmeno[30];
char adresa[50];
unsigned vek;
} *PClovek;
Struktury jako parametry funkcφ
V jednom z minul²ch dφl∙ jsme si °ekli, ₧e nejΦast∞ji se parametry funkcφ
p°edßvajφ hodnotou, co₧ p°edstavuje zkopφrovßnφ parametr∙ do funkce.
Struktury se takΘ kopφrujφ, ale zde m∙₧e nastat problΘm: zkopφrovßnφ v∞tÜφch struktur nenφ p°φliÜ
efektivnφ. Mnohem lepÜφm °eÜenφm je p°edßvßnφ
struktur operßtorem reference:
void vypisOsobu(Clovek &osoba) {
cout << "JmΘno: " << osoba.jmeno << "\n";
cout << "P°φjmenφ: " << osoba.adresa << "\n";
cout << "V∞k: " << osoba.vek << "\n";
}
╪ekli jsme si, ₧e reference je ukazatel, kter² se syntakticky chovß jako prom∞nnß danΘho datovΘho typu, tak₧e p°i zavolßnφ funkce
vypisOsobu() dojde ke zkopφrovßnφ pouze 4 byt∙.
Poznßmka: dalÜφ zp∙sob p°edßvßnφ struktur je ukazatelem, ale to je praktika
pou₧φvanß spφÜe v jazyce C. Setkßte se s tφm nap°φklad budete-li psßt
programy pro Windows.
P°φklad
Dnes si ukß₧eme n∞jak² v∞tÜφ p°φklad, bude to adresß° osob, do kterΘho budeme moci uklßdat jmΘno a
p°φjmenφ, ulici, m∞sto a telefonnφ Φφslo.
Adresß° mß umo₧≥ovat p°idßvßnφ osoby, jejφ vymazßnφ, a hledßnφ podle jmΘna. Uklßdat do souboru adresß° nebude um∞t, to ani my jeÜt∞ neumφme, ale
p°idßme to p°φÜt∞.
ZaΦneme nßÜ program rozhodnutφm, jak dlouhΘ budou °et∞zce do kter²ch budeme uklßdat data, a deklarovßnφm p°φsluÜnΘ struktury:
const unsigned DELKA_JMENO = 30;
const unsigned DELKA_ULICE = 40;
const unsigned DELKA_MESTO = 30;
const unsigned DELKA_TELEFON = 20;
struct Osoba {
char jmeno[DELKA_JMENO];
char ulice[DELKA_ULICE];
char mesto[DELKA_MESTO];
char telefon[DELKA_TELEFON];
};
Dßle bychom si m∞li rozmyslet jak budeme uklßdat vφce osob. Pravd∞podobn∞ do pole, ale pole nßm ne°ekne, kolik osob v n∞m mßme ulo₧eno, to si
musφme pamatovat v dalÜφ prom∞nnΘ, nazv∞me ji pocet . Tyto dva ·daje blφzce souvisφ, tak₧e je m∙₧eme takΘ dat do n∞jakΘ struktury,
kterß se bude naz²vat nap°. Osoby . V souvislosti s polem musφme jeÜt∞ rozhodnout, jakß bude jeho velikost (poΦet prvk∙). Abychom
mohli tento poΦet lehce zm∞nit pokud to budeme n∞kdy pot°ebovat, deklarujeme si k tomu konstantu:
const unsigned MAX_POCET_OSOB = 100;
struct Osoby {
Osoba pole[MAX_POCET_OSOB];
int pocet;
};
DatovΘ typy ji₧ mßme, poj∩me si nynφ napsat n∞jakΘ funkce pro prßci s nimi. P°edn∞ budeme pot°ebovat n∞jakou funkci, kterß bude inicializovat
prom∞nnou odvozenou od datovΘho typu Osoby , a to nastavenφm slo₧ky pocet na nulu (na zaΦßtku programu je adresß°
prßzdn², nejsou v n∞m ₧ßdnΘ osoby). Tato funkce dostane jako parametr prom∞nnou, kterou chceme inicializovat (samoz°ejm∞ referencφ):
void osobyInit(Osoby &osoby) {
osoby.pocet = 0;
}
Dßle budeme pot°ebovat n∞jakou funkci pro ulo₧enφ novΘ osoby. Jako parametry dostane prom∞nnou typu Osoby a prom∞nnou typu
Osoba , a bude vracet hodnotu bool podle toho, zda se ulo₧enφ
poda°ilo Φi ne:
bool osobyPridej(Osoby &osoby, Osoba &osoba) {
if (osoby.pocet < MAX_POCET_OSOB) {
osoby.pole[osoby.pocet] = osoba;
osoby.pocet++;
return true;
}
else
return false;
}
Ulo₧enφ prob∞hne zkopφrovßnφm novΘ osoby do pole na mφsto, kterΘ udßvß prßv∞ prom∞nnß osoby.pocet (je-li nap°φklad pocet = 3 ,
jsou v poli obsazenΘ polohy 0, 1 a 2, dalÜφ volnß poloha je tedy prßv∞ 3). Prom∞nnou pocet nßsledn∞ zv∞tÜφme o jedna.
Samoz°ejm∞ jeÜt∞ p°ed zkopφrovßnφm musφme zkontrolovat, zda pole nenφ nßhodnou plnΘ, v tomto p°φpad∞ nenφ kam uklßdat a funkce vracφ hodnotu
false . V p°φpad∞ ·sp∞chu vracφme true .
Dßle budeme pot°ebovat funkci, kterß ve struktu°e Osoby vyhledß osobu se zadan²m jmΘnem. Tato funkce dostane jako parametry
prom∞nnou typu Osoby , ve kterΘ se vyhledß, a takΘ °et∞zec obsahujφcφ jmΘno, kterΘ se mß vyhledat. Prochßzφme pole osob
a porovnßvßme jmΘna se zadan²m jmΘnem. K porovnßvßnφ pou₧ijeme funkci strnicmp() , kterß porovnßvß n∞jak² zadan² poΦet znak∙
v °et∞zcφch bez ohledu na velkß/malß pφsmena. Funkce vracφ polohu v poli v p°φpad∞ nalezenφ, a -1 jinak (proto₧e -1 nenφ platn² index do pole):
int osobyHledej(Osoby &osoby, char *jmeno) {
int i;
for (i = 0; i < osoby.pocet; i++) {
if (!strnicmp(osoby.pole[i].jmeno, jmeno, DELKA_JMENO)) {
return i;
}
}
return -1;
}
Pot°ebujeme jeÜt∞ funkci na vymazßnφ osoby, co₧ je mo₧nß nejslo₧it∞jÜφ akce. Nenφ-li vymazanß osoba poslednφ v poli, bude pot°eba
veÜkerΘ osoby za nφ p°esunout o jednu polohu doleva, jak je vid∞t na obrßzku (ma₧e se osoba na poloze 1):
Parametry funkce budou prom∞nnß typu Osoby a polohu v poli,
udßvajφcφ osobu, kterß se mß vymazat. Samoz°ejm∞ je t°eba zkontrolovat
platnost polohy (musφ to b²t vetÜφ nebo rovna nule, a nesmφ b²t v∞tÜφ nebo rovno existujφcφmu poΦtu osob. Nakonec je t°eba snφ₧it poΦet osob.
bool osobyVymaz(Osoby &osoby, int poloha) {
int i;
if (poloha < 0 || poloha >= osoby.pocet)
return false;
for (i = poloha + 1; i < osoby.pocet; i++)
osoby.pole[i - 1] = osoby.pole[i];
osoby.pocet--;
return true;
}
Poslednφ funkci pro prßci se strukturou Osoby je funkce, kterß vracφ true je-li v poli mφsto pro novou osobu,
a false jinak:
bool osobyJeMisto(Osoby &osoby) {
return osoby.pocet < MAX_POCET_OSOB;
}
Nynφ je pot°eba si napsat funkce pro u₧ivatelskΘ rozhranφ (funkci, kterß p°eΦte ·daje o osob∞ z klßvesnice a z nich vytvo°φ novou prom∞nnou
typu Osoba kterou p°idß do seznamu osob, dßle funkci pro vyhledßnφ a vymazßnφ osoby). K tomu je pot°eba vstup z klßvesnice a tak si
vytvo°φme n∞jakou obecnou funkci prßv∞ pro tento ·Φel.
V jednom z prvnφch dφl∙ jsme si °ekli, ₧e vstup z klßvesnice lze p°eΦφst funkcφ scanf() . Nap°φklad chceme-li p°eΦφst °et∞zec, pou₧ijeme:
scanf("%s", retezec);
Takov² p°φstup mß ale jednu velkou chybu a to je ₧e funkce scanf() by mohla ulo₧it do prom∞nnΘ rezetec vφc znak∙,
ne₧ by se tam mohlo vejφt (velikost prom∞nnΘ neznß a ulo₧φ tolik znak∙, kolik zadß u₧ivatel). Pou₧ijeme tedy trochu jin² formßt, kter²m lze
udßvat
nejvyÜÜφ poΦet, kter² lze do v²sledku (prom∞nnΘ retezec ) ulo₧it:
scanf("%30s", retezec);
V tomto p°φpad∞ je tedy nejvyÜÜφ poΦet znak∙ 30. OvÜem zapφÜe-li se do v²sledku maximßlnφ poΦet znak∙, pak se nezapφÜe nulov² ukonΦovacφ znak, kter² musφme
doplnit sami.
DalÜφm problΘmem funkce scanf() je, ₧e chßpe mezeru jako odd∞lovaΦ polφ. To mß za nßsledek
ulo₧enφ do v²sledu pouze znak∙ do prvnφ mezery. Ale to lze takΘ vy°eÜit: mφsto formßtu %s
lze zadat seznam platn²ch znak∙, nebo naopak seznam neplatn²ch znak∙. To se provßdφ uvedenφm seznam platn²ch znak∙ do hranat²ch zßvorek:
scanf("%[abc]", retezec);
scanf("%[a-z]", retezec);
V prvnφm p°φpad∞ jsou platnΘ znaky a, b a c, v druhΘm znaky a a₧ z. Seznam neplatn²ch znak∙ zase zadßme uvedenφm st°φÜky hned po otevφracφ hranatΘ
zßvorce:
scanf("%[^abc]", retezec);
To znamenß, ₧e platnΘ znaky jsou vÜechny a₧ na a, b a c. My pou₧ijeme formßt "%30[^\n]" , kter² udßvß, ₧e platnΘ znaky
jsou vÜechny a₧ na znak konec °ßdku, a ₧e se mß ulo₧it nejv²Üe 30 znak∙
DalÜφ zßdrhel souvisφ s nejvyÜÜφm poΦtem znak∙ v²sledku. Znaky, kterΘ u₧ivatel zadß navφc, se
neztrßcejφ, n²br₧ z∙stanou ulo₧eny ve
vyrovnßvacφ pam∞ti, a funkce scanf() je bude zpracovßvat p°i dalÜφm zavolßnφ. P°ed ka₧d²m zavolßnφm musφme tedy tuto
vyrovnßvacφ pam∞¥ vyprßzdnit, co₧ provedeme funkcφ fflush() , jejφ₧ p°esn² v²znam si vysv∞tlφme p°φÜt∞:
fflush(stdin);
┌pln∞ poslednφ v∞c na kterou musφme dßt pozor je, ₧e kdy₧ u₧ivatel nezadß nic, funkce scanf() neulo₧φ do v²sledku nic, tedy ani
nulov² ukonΦovacφ znak. Ten si musφme doplnit sami na zßklad∞ nßvratovΘ hodnoty scanf() . Nßvratovß hodnota uvßdφ kolik polφ
bylo zpracovßno (podle naÜeho formßtovacφho °et∞zce "%30[^\n]" jedno pole), nebo 0 pokud nebylo zpracovßno nic.
Nynφ si m∙₧eme napsat funkcφ, kterß p°eΦte z klßvesnice °et∞zec za podmφnek, kterΘ jsme uvedli. Funkce dostane jako parametr °et∞zec, kam se
mß v²sledek ulo₧it, a nejvyÜÜφ poΦet znak∙, kter² se mß do v²sledku ulo₧it. Z tohoto d∙vodu musφme vytvo°it formßtovacφ °et∞zec, pomocφ funkce
sprintf() , kterß funguje jako printf() , ale v²sledek ulo₧φ do °et∞zce:
const char *strFmt = "%%%u[^\n]"; // %% znamenß znak procento, dßle
%u se nahradφ n∞jak²m cel²m Φφslem
// v²sledek je nap°. "%30[^\n]"
const unsigned MAX_FORMAT = 32; // dΘlka pro °et∞zec, do kterΘho vytvß°φme formßtovacφ °et∞zec
void precti(char *vysledek, unsigned maxDelka) {
char fmt[MAX_FORMAT]; // format. °et∞zec
sprintf(fmt, strFmt, maxDelka); // vytvß°φme formßtovacφ °et∞zec
fflush(stdin); // vyprßzdn∞nφ vyrovnßvacφ pam∞ti
if (scanf(fmt, vysledek)) // Φtenφ
vysledek[maxDelka - 1] = 0; // scanf vrßtilo 1, tak₧e pro jistotu dopl≥ujeme nulov² ukonΦovacφ znak
else
*vysledek = 0; // scanf vrßtilo 0, ta₧e dopl≥ujeme na zßΦßtek °et∞zce nulov² ukonΦovacφ znak
// vysledek je tedy p°ßzdn² °et∞zec
}
Nynφ si m∙₧eme napsat funkce pridej() , hledej() a vymaz() , jejich v²pis najdete p°ilo₧en².
Funkce hledej() a vymaz() pou₧φvajφ funkci hledejPolohu() , kterß p°eΦte z klßvesnice
jmΘno, kterΘ se mß vyhledat, pop°. vymazat, a vracφ nalezenΘ osoby v poli nebo -1.
Ve funkci main() je pouze k≤d, kter² vytvß°φ jednoduchΘ menu. U₧ivatel volφ z menu pomocφ jednoznakov²ch zkratek. K p°eΦtenφ
znaku z klßvesnice pou₧ijeme funkci getche() z hlaviΦkovΘho souboru conio.h . TakΘ je na zaΦßtku pot°eba vypnout
vyrovnßvacφ pam∞¥ objektu cout , jinak by se vypsanΘ °et∞zce nezobrazovaly na obrazovce hned, ale jen "jednou za Φas" (po napln∞nφ
vyrovnßvacφ pam∞ti). Vyrovnßvacφ pam∞¥ se vypφnß volßnφm funkce objektu cout , ale tomu zatφm nemusφte rozum∞t, vÜechno si to povφme
a₧ si vysv∞tlφme t°φdy a objekty.
void main() {
Osoby osoby;
char volba = -1;
cout.setf(ios::unitbuf); // nastavujeme v²pis na obrazovce po ka₧dΘ v²pis do objektu cout
osobyInit(osoby);
while (volba != 'k' && volba != 'K') {
cout << strZadejVolbu;
volba = getche();
cout << endl;
switch (volba) {
case 'p':
case 'P':
if (!pridej(osoby))
cout << errAdrPlny;
break;
case 'h':
case 'H':
if (!hledej(osoby))
cout << errNenalezeno;
break;
case 'v':
case 'V':
if (!vymaz(osoby))
cout << errNenalezeno;
}
cout << endl;
}
}
P°φklad rozhodn∞ nenφ p°φliÜ jednoduch². Zp∙sobujφ to r∙znΘ kontroly zda vÜechno prob∞hlo v po°ßdku, a takΘ komplikace kolem funkce scanf() .
Ale programovßnφ u₧ je takovΘ, musφte dßvat pozor na vÜechno. D∞kuji za pozornost a t∞Üφm se p°φÜtφ m∞sφc nashledanou.
|