Kurz C++ (4.)
V tΘto, ji₧ ΦtvrtΘ lekci, se podφvßme na typovou konverzi typ∙, co₧
je velice d∙le₧itß v∞c, kdy₧ chceme p°evßd∞t prom∞nnou jistΘho typu na typ
jin². Druhß Φßst kurzu se zab²vß preprocesorem jazyka C. Vysv∞tlφm Vßm,
jak se vytvß°ejφ makra, jak se definujφ symbolickΘ konstanty atd.
4.1. Typovß konverze
Nejd°φve se podφvßme na p°evody prom∞nn²ch urΦitΘho typu na jin² typ
(nap°φklad z int na double). Existujφ dva druhy typovΘ konverze:
- implicitnφ Φili automatickß konverze
- explicitnφ Φili vynucenß konverze
4.1.1. Implicitnφ typovß konverze
Pravidla:
- P°ed vykonßnφm operace se typy char a
short konvertujφ na int. Zde
nenφ ₧ßdn² problΘm, proto₧e char i
short jsou celoΦφselnΘ hodnoty a
maximßlnφ hodnoty jsou menÜφ ne₧ u typu int.
Typy
unsigned char
(BYTE) a unsigned short (WORD) se automaticky konvertujφ na
int jen
pokud se hodnota prom∞nnΘ vejde do maximßlnφ hodnoty
int jinak se
konvertuje na unsigned int (UINT).
- U operacφ s r∙zn²mi typy operand∙ se konvertuje podle priority typu.
Implicitnφ konverze v₧dy probφhß jen na typy s vyÜÜφ prioritou.
Hierarchie priorit jednotliv²ch typ∙ (typ int
mß nejni₧Üφ prioritu):
int
| ->
| unsigned int (UINT) |
unsigned int (UINT)
| ->
| long |
long
| ->
| unsigned long (DWORD) |
unsigned long (DWORD)
| ->
| float (FLOAT) |
float (FLOAT)
| ->
| double |
double
| ->
| long double (nejvyÜÜφ priorita)
| V zßvorkßch jsou uvedeny typy, kterΘ se
pou₧φvajφ ve Visual C++.
P°φklad:
int
i = 5; double d;
// // Toto je mozne diky
implicitni konverzi // Typ int (i) se automaticky prevede na typ
float (d)
d = i;
- V uvedenΘm p°φkladu vidφte p°i°azenφ. V p°i°azenφ je prav² operand
konvertovßn na typ levΘho operandu Φili v²sledek mß typ levΘho operandu.
4.1.2. Explicitnφ typovß konverze
Tuto konverzi pln∞ °φdφ programßtor. M∙₧e tak prakticky p°evΘst cokoliv
na cokoliv, ale nezaruΦφ v₧dy p°esnΘ nebo oΦekßvanΘ v²sledky (nap°.
konverze z double na int zaokrouhlφ reßlnΘ Φφslo na celΘ Φφslo -
3.14 ->
3).
Explicitnφ typovß konverze mß tvar:
(typ)
vyraz
a znamenß to, ₧e vyraz je v Φase
p°ekladu konvertovßn na typ .
M∙₧eme takΘ
pou₧φt explicitnφ konverzi tam, kde mi normßln∞ prob∞hla implicitnφ, ale
programßtor tak m∙₧e vyjßd°it, ₧e konverzi cht∞l.
Seznam Φasto
pou₧φvan²ch explicitnφch konverzφ:
(int) char_vyraz
| - p°evod znaku na ordinßlnφ Φφslo (po°adφ v ASCII tabulce) |
(char) int_vyraz
| - p°evod ordinßlnφho Φφsla na znak |
(int) float_vyraz
| - zaokrouhlenφ reßlnΘho Φφsla (zaokrouhluje se v₧dy dolu)
| Pokud se pokusφte o implicitnφ konverzi,
kterß n∞jak²m zp∙sobem zhorÜuje p°esnost Φφsla, kompilßtor vßs na to
upozornφ. Toto varovnΘ hlßÜenφ odstranφte explicitnφ
konverzφ.
P°φklad:
double d =
3.14; int i;
// // Explicitni konverze odrizne
desetinnou cast // takze promenne i se priradi hodnota 3
i =
(int) d;
4.2. Preprocesor jazyka C
Preprocesor zpracovßvß k≤d jeÜt∞ p°ed vlastnφm p°ekladem. Zatφm
jsme pou₧φvali jen p°φkaz include , kter² nßm
umo₧≥oval pou₧φvat n∞jakΘ dalÜφ u₧iteΦnΘ funkce v naÜich programech. V
tΘto lekci si rozÜφ°φme znalosti p°φkaz∙ preprocesoru. Preprocesor
p°ipravφ VßÜ k≤d k p°ekladu.
Preprocesor provßdφ:
- Nahrazuje symbolickΘ konstanty za sprßvnΘ ΦφselnΘ hodnoty
- Nahrazuje vÜechny makra vlastnφm k≤dem makra
- Vypustφ z k≤du vÜechny komentß°e
- Provßdφ podmφn∞n² p°eklad
Jist∞ jste si vÜimli, ₧e p°φkaz
include musφ mφt p°ed sebou znak # . To je spravn² post°eh a neplatφ jen pro p°φkaz include , ale pro vÜechny ostatnφ p°φkazy preprocesoru.
Tak₧e znakem # uvozujeme vÜechny p°φkazy urΦenΘ pro
preprocesor.
4.2.1. SymbolickΘ konstanty
Symbolick²m konstantßm se n∞kdy tΘ₧ °φkß makra bez parametr∙. Pomocφ
t∞chto konstant zbavφte program "magick²ch Φφsel" tzn. konstant, kterΘ
pou₧φvßte v programu. Kdy₧ pak n∞kdo Φte vßÜ program a vidφ konstantu
PI mφsto Φφsla 3.141592654 ,
velmi ho to pot∞Üφ.
Navφc definovßnφm takov²ch konstant m∙₧ete
snadno m∞nit parametry programu. Kdy₧ nap°φklad vypisujete 100 °ßdek na
monitor, ale nßhle rozhodnete, ₧e chcete aby program vypisoval jen 50
°ßdek, staΦφ zm∞nit konstantu na zaΦßtku programu a nemusφte p°episovat
vÜechny konstanty v programu.
Syntaxe:
#define
JMENO_KONSTANTY hodnota
Pro symbolickΘ konstanty platφ tyto
pravidla:
- JmΘno konstant se pφÜφ velk²mi pφsmeny (je to pouze doporuΦenφ)
- JmΘno konstanty je odd∞leno od vlastnφ hodnoty nejmΘn∞ jednou
mezerou
- Za hodnotou by m∞l b²t komentß°
- NovΘ konstanty mohou vyu₧φvat existujφcφ konstanty
- Pokud je hodnota konstanty dlouhß (nap°. °et∞zec) a nevejde se na
jednu °ßdku, musφ b²t na konci znak
"\" .
P°φklady:
#define PI
3.141592654 // Presne Ludolfovo cislo #define
DATA_TXT "DATA.TXT" // Jmeno souboru #define EOL
'\n' // Odrakovani - End of
Line #define DLOUHY_RETEZEC "Tohle je strasne dlouhy retezec,
\
takze bacha."
A
te∩ m∙₧ete psßt definovanΘ konstanty mφsto konkrΘtnφch Φφseln²ch hodnot a
preprocesor je nahradφ sprßvn²mi hodnotami p°i p°ekladu.
Poznßmka: Makro se v programu nerozvine (nebude nahrazeno), pokud
je uzav°eno v uvozovkßch. Nap°φklad:
printf("Ludolfovo cislo je PI\n");
Toto je Üpatn∞,
konstanta PI nebude nahrazena. ╪eÜenφm m∙₧e b²t t°eba toto: printf("Ludolfovo cislo je %f\n", PI);
Platnost definice konstanty
Pokud nadefinujete ji₧ definovanou
konstantu a p°itom zm∞nφte jejφ hodnotu, kompilßtor vypφÜe varovnΘ
hlßÜenφ. Pokud chcete v pr∙b∞hu programu konstanty m∞nit, musφte ji
nejd°φve "oddefinovat" a teprve potΘ ji nadefinovat znovu.
P°φklad:
#define MAX_POLE 50
// prvni definice MAX_POLE .. .. .. #undef MAX_POLE
// Oddefinovani stare definice #define MAX_POLE
75 // Definice nove hodnoty
Toto
platφ obecn∞ pro vÜechny makra tzn. symbolickΘ konstanty i makra s
parametrem.
4.2.2. Makra s parametrem
Tyto makra fungujφ podobn∞ jako funkce. Na zaΦßtku programu si
nadefinujete urΦitΘ makra, kterΘ pak pou₧ijete v programu, preprocesor
op∞t nahradφ makro konkrΘtnφm k≤dem v dob∞ p°ekladu.
Pou₧itφ makra je rychlejÜφ ne₧ funkce, proto₧e se nic nevolß, jen se v
k≤du nahrazujφ kousky k≤du makra, ale v²sledn² program je v∞tÜφ, proto₧e s
ka₧d²m v²skytem makra, se k≤d makra opakuje narozdφl od funkce.
Syntaxe makra:
#define jmeno_makra(arg1,....,argN)
telo_makra
P°φklad:
#define
je_velke(c) ((c) >= 'A' && (c) <= 'Z')
V
programu pak makro volßte takto:
ch = je_velke(ch) ? ch
+ ('a' - 'A') : ch;
T∞sn∞ p°ed p°ekladem se makro rozvine
takto: ch = ((ch) >= 'A' && (ch) <=
'Z')) ? ch + ('a' - 'A') : ch;
DobrΘ rady:
- Argument pou₧it² v makru (v naÜem p°φpad∞ c) by m∞l b²t v definici
makra v zßvorkßch. P°edejdete tak zbyteΦn²m chybßm, kdy₧ jako parametr
makra pou₧ijete v²raz.
- DoporuΦuji celΘ makro tΘ₧ uzav°φt do kulat²ch zßvorek. Op∞t se
vyvarujete chyb, kdy₧ makro pou₧ijete ve v²razu.
4.2.3. P°eddefinovanΘ makra
Soubor stdio.h obsahuje n∞kolik maker, kterΘ
jsme ji₧ vyu₧φvali: putchar(c) a getchar()
My si uvedeme dalÜφ hlaviΦkov² soubor
ctype.h , kter² obsahuje definice dalÜφch u₧iteΦn²ch
maker. Makra jsou zde rozd∞lena do dvou skupin, z nich₧ prvnφ skupina
nem∞nφ hodnotu parametr∙, ale jen zjiÜ¥ujφ vlastnosti parametru:
JmΘno
| Pou₧itφ |
isalnum
| Vracφ argument, pokud je argument Φφslice, malΘ Φi velkΘ
pφsmeno, jinak vrßtφ 0 (FALSE) |
isalpha
| Vracφ argument, pokud je argument malΘ Φi velkΘ pφsmeno, jinak
vrßtφ 0 (FALSE) |
isascii
| Vracφ 1 (TRUE), pokud je argument z ASCII tabulky, jinak vrßtφ 0
(FALSE) |
isdigit
| Vracφ znak (Φφslici), pokud je argument Φφslice, jinak vrßtφ 0
(FALSE) |
islower
| Vracφ znak, pokud je argument malΘ pφsmenko, jinak vrßtφ 0
(FALSE) |
isspace
| Vracφ znak, pokud je argument neviditeln² znak (mezera,
tabulßtor), jinak vrßtφ 0 (FALSE) |
isupper
| Vracφ znak, pokud je argument velkΘ pφsmenko, jinak vrßtφ 0
(FALSE) | Narozdφl makra druhΘ skupiny m∞nφ
hodnotu parametru:
JmΘno
| Pou₧itφ |
tolower
| P°evede argument (velkΘ pφsmenko) na malΘ pφsmenko |
toupper
| P°evede argument (malΘ pφsmenko) na velkΘ pφsmenko
|
4.3. Pole
Velice u₧iteΦnou souΦßstφ programovacφho jazyka jsou pole. P°edstavte
si, ze byste cht∞li napsat jednoduch² telefonnφ seznam. UrΦit∞ Vßs napadß,
₧e uklßdat jmΘna VaÜich kamarßd∙ tak, ₧e pro ka₧dΘ jmΘno budete mφt jednou
prom∞nnou, nenφ moc dobr² nßpad. To byste museli program zkompilovat znovu
poka₧dΘ, kdy₧ chcete n∞koho p°idat. A to je jen ta nejmenÜφ nev²hoda. Pole
Vßm dovolφ pou₧φvat vφce prom∞nn²ch stejnΘho typu, jedna vedle druhΘ, pod
stejn²m jmΘnem: void main(int argc, char *argv[]) {
int pole[10]; // deklarujeme pole 10 prom∞nn²ch int
pole[5] = 1; // m∞nφme jedno z prvk∙ pole
cout << pole[5]; // a vypisujeme ho
}
V p°φkladu jsme deklarovali pole deseti prvk∙ typu int , a ukßzali jsme si, jak se k jednomu
z prvk∙ pole p°istupuje, toti₧ pomocφ stejnΘho operßtoru, kter²m se pole
deklarujφ - hranat²ch zßvorek. Je d∙le₧itΘ si pamatovat, ₧e poΦφtßnφ prvk∙
pole v₧dy zaΦφnß nulou, tak₧e m∙₧eme pou₧φvat Φφsla prvk∙ (sprßvn∞ se jim
°φkß indexy) 0 a₧ 9 (v dalÜφch p°φkladech budu vynechßvat funkci
main() ,
proto ji nezapomφnejte poka₧dΘ p°idat):
int pole[10];
for (int i = 0; i < 10; i++)
pole[i] = i; // prochßzenφ polem cyklem for
for (int i = 0; i < 10; i++)
cout << pole[i] << ' ';
DalÜφm d∙le₧it²m faktem je, ₧e kompilßtor nekontroluje, zda jsme
nep°ekroΦili meze pole, tak₧e kdy₧ napφÜeme n∞co jako: int pole[10];
int dalsi;
pole[10] = 1; // 10 nenφ platn² index
p°epφÜeme si tφmto jinou prom∞nnou, zde zrovna prom∞nnou dalÜφ , a program nßm urΦit∞ nebude
fungovat sprßvn∞. Musφme si tedy pamatovat, ₧e nejvyÜÜφ index, kter²
m∙₧eme pou₧φvat, je o jedniΦku menÜφ, ne₧ deklarovanß velikost pole.
NejmenÜφ index je 0, aΦkoli jestli se pokusφte pou₧φt zßpornΘ Φφslo
kompilßtor Vßm to klidn∞ dovolφ.
Jazyky C a C++ obsahujφ i prost°edek, kter²m se zjiÜ¥uje velikost pole,
je jφm operßtor sizeof :
char pole_char[10];
int pole_int[10];
cout << sizeof pole_char; // vypφÜe se 10
cout << sizeof pole_int; // vypφÜe se 40
V²sledek druhΘho °ßdku cout
mo₧nß p°ekvapφ. Je to tφm, ₧e operßtor sizeof vracφ skuteΦnou velikost pole v
bajtech, ne poΦet jeho prvk∙. U pole prvk∙ typu char je to jedno, ale to jen proto₧e char je velk² jeden byte. U prvk∙ int to u₧ jedno nenφ. Kdybychom cht∞li zjistit poΦet
prvk∙, musφme pou₧φvat jeden z t∞chto zßpis∙: cout << sizeof pole / sizeof int;
cout << sizeof pole / sizeof pole[0];
cout << sizeof pole / sizeof *pole; // tento zßpis pochopφte pozd∞ji
Podle prvnφho zp∙sobu zjiÜ¥ujeme poΦet prvk∙ "napevno" - vφme, ₧e se
jednß o pole "int∙", tak₧e d∞lφme p°φmo velikostφ datovΘho typu int (zjiÜ¥ujeme-li velikost datovΘho
typu, musφ tento b²t uveden v zßvorkßch, u prom∞nn²ch jsou zßvorky
nepovinnΘ).
Podle druhΘho a t°etφho zp∙sobu zjiÜ¥ujeme p°φmo velikost prvnφho prvku
pole, a nezßle₧φ na tom, jakΘho je typu. DruhΘmu zp∙sobu byste m∞li
rozum∞t hned, a t°etφ zp∙sob, kter² se mi zdß ze vÜech nejelegantn∞jÜφ,
pochopφte pozd∞ji, a₧ budeme probφrat ukazatele, zatφm staΦφ kdy₧ budete
v∞d∞t, ₧e zßpis *pole vracφ prvnφ
prvek pole, mß tedy stejn² v²znam jako pole[0] .
V²hoda druhΘho a t°etφho zp∙sobu spoΦφvß v tom, ₧e kdybyste v budoucnu
zm∞nili datov² typ prvk∙ pole na jin², staΦφ, kdy₧ ho upravφte pouze v
deklaraci pole, ale nemusφte ho m∞nit i v k≤du sizeof . Doporucuji v₧dy pou₧φvat
operßtor sizeof tam, kde to je
mo₧nΘ, mφsto pevn∞ zadanΘho rozm∞ru pole.
T°etφ zp∙sob, kter² se mi zdß ze vÜech nejelegantn∞jÜφ, ·pln∞ pochopφte
pozd∞ji, a₧ budeme probφrat ukazatele, zatφm staΦφ kdy₧ budete v∞d∞t, ₧e
zßpis *pole vracφ prvnφ prvek
pole, mß tedy stejn² v²znam jako pole[0] .
P°i deklaraci pole ho m∙₧eme hned inicializovat. Nap°φklad: int pole1[4] = { 0, 1, 2, 3 };
int pole2[] = { 0, 1, 3, 3, 4, 5 };
Jak vidφte, v deklaraci pole2 chybφ poΦet prvk∙. To
proto₧e z poΦtu konstant ve slo₧en²ch zßvorkßch (inicializßtor∙)
kompilßtor poznß, jak velkΘ musφ alokovat pole. Tento zßpis je v²hodn∞jÜφ,
proto₧e umo₧≥uje urΦit velikost pole nep°φmo, podle poΦtu inicializßtor∙.
Uvedenφ jak rozm∞ru pole, tak i inicializßtor∙ je jistß redundance, jeden
z t∞chto ·daj∙ je nadbyteΦn², m∙₧eme ho tedy vynechat. Tady je takΘ vid∞t
d∙le₧itost operßtoru sizeof - bez
n∞j bychom velikost pole pole2
nemohli zjistit. Tato vlastnost se nßm takΘ bude hodit p°i
deklarovßnφ °et∞zc∙, jak uvidφme pozd∞ji.
4.4. Vφcerozm∞rnß pole
Jazyky C a C++ umo₧≥ujφ pou₧φvat i pole vφcerozm∞rnß. Deklarujφ se
obdobn∞ jako jednorozm∞rnß pole:
float matice[3][4];
for (i = 0; i < 3; i++)
for (j = 0; j < 4; j++)
matice[i][j] = i * j; // postupnΘ prochßzenφ a napln∞nφ pole
Tady jsme deklarovali dvourozm∞rnΘ pole, prvnφ rozm∞r je 3, druh² je 4.
Je to vlastn∞ matice o t°ech °ßdcφch a Φty°ech sloupcφch. Na tuto
deklaraci je takΘ mo₧no hled∞t jako na pole t°φ polφ, z nich₧ ka₧dΘ mß
Φty°i prvky typu float. Mo₧nß to znφ slo₧it∞,
ale skuteΦn∞ nic na tom nenφ a urΦit∞ si rychle zvyknete. Z tohoto pohledu
vypl²vß takΘ pou₧itφ operßtoru sizeof : cout << sizeof matice; // vypisuje se velikost v bajtech, tedy 12 * 4 = 48 //(velikost typu float je 4 byty)
cout << sizeof matice[0]; // vypisuje se velikost "prvnφho °ßdku", tedy 4 * 4 = 16
Inicializace vφcerozm∞rn²ch polφ se provßdφ obdobn∞ jako
jednorozm∞rn²ch: int pole[2][3] = {
{0, 1, 2},
{3, 4, 5}
};
VÜimn∞te si, jak tato deklarace opravu p°ipomφnß to, co je v²Üe °ekl o
"poli polφ". Vn∞jÜφ slo₧enΘ zßvorky jako by zaΦφnajφ inicializaci pole
dvou prvk∙, tyto jsou ale zase pole. Toto uspo°ßdßnφ k≤du nemusφte
dodr₧ovat a m∙₧ete vÜe napsat na jednom °ßdku, jß si myslφm, ₧e je
p°ehledn², proto₧e je v n∞m vid∞t ta matice.
Samoz°ejm∞ nenφ problΘm deklarovat pole i vφce ne₧ dvourozm∞rnß, prost∞
p°idßme dalÜφ pßr hranat²ch zßvorek s dalÜφm rozm∞rem.
4.5. ╪et∞zce
Pole a °et∞zce majφ v C a C++ k sob∞ velmi blφzko. Tyto jazyky toti₧
pohlφ₧ejφ na °et∞zce jako na pole prvk∙ char: char retezec[100];
Takto jsme deklarovali °et∞zec, kter² m∙₧e obsahovat maximßln∞ 99
znak∙. ProΦ 99, kdy₧ jsme deklarovali pole o 100 prvcφch? To proto₧e jazyk
C++ vy₧aduje, aby poslednφ znak °et∞zce byl specißlnφ ASCII znak s k≤dem
0. Tφmto poznß, kde °et∞zec konΦφ, nap°φklad p°i jeho vypisovßnφ. To
znamenß, ₧e kdy₧ deklarujeme °et∞zec musφme uvΘst poΦet znak∙ o jednu
v∞tÜφ ne₧ maximßlnφ poΦet znak∙, kter² zam²Ülφme do °et∞zce uklßdat.
V²Üe deklarovan² °et∞zec nßm zatφm nenφ k niΦemu, zkusφme si tedy ho
rovnou inicializovat. Tady se nßm bude hodit mo₧nost inicializace bez
uvedenφ poΦtu znak∙. Kdybychom museli ten poΦet uvΘst museli bychom znaky
°et∞zce poΦφtat... no, nebylo by to nic p∞knΘho: char str[] = "Ahoj";
Kompilßtor poznal, ₧e deklarujeme °et∞zec, a alokoval pro °et∞zec 5
byt∙, co₧ uvidφte, kdy₧ si nechßte vypsat velikost str operßtorem sizeof. Existuje jeÜt∞ jeden zp∙sob, elegantn∞jÜφ,
·pln∞ ho zase pochopφte a₧ budeme brßt ukazatele, zatφm musφte jen v∞d∞t,
₧e to znamenß ·pln∞ to samΘ: char *str = "Ahoj";
Na druhou stranu se nßm ale m∙₧e hodit i inicializace uvedenφm poΦtu
prvk∙, nap°φklad kdybychom cht∞li mφt mo₧nost uklßdat do prom∞nnΘ i delÜφ
°et∞zce ne₧ je ten uveden² p°i deklaraci. Musφme ovÜem dßvat pozor na to,
abychom deklarovali alespo≥ tolik znak∙, kolik mß inicializßtor
(samoz°ejm∞ plus jedna), jinak kompilace skonΦφ chybou. char str[20] = "DalÜφ °et∞zec.";
char str[5] = "Toto skonΦφ chybou";
Jazyk C++ nabφzφ pro prßci s °et∞zci vφce funkcφ. VÜechny jsou ulo₧eny
v takzvanΘ run-time knihovn∞, co₧ je soubor funkcφ, kter² se p°idß
k vaÜemu programu p°i jeho sestavenφ (build). K nejd∙le₧it∞jÜφm funkcφm
pro prßci s °et∞zci pat°φ: strlen ,
strcpy , strcat , strchr ,
strcmp a jinΘ (je jich
skuteΦn∞ spousta, uvedl jsem jen nejpou₧φvan∞jÜφ):
Funkce strlen vracφ dΘlku
°et∞zce, volß se strlen(°et∞zec) : char str1[30] = "Jß jsem krßtk² °et∞zec.";
cout << strlen(str1);
Pozor, neplΘst si funkci strlen
a operßtor sizeof , jsou to dv∞
r∙znΘ v∞ci: sizeof vracφ velikost
°et∞zce, tedy kolik znak∙ se do n∞j maximßln∞ vejde (vΦetn∞ nulovΘho znaku
na konci) - podle naÜeho p°φkladu by to bylo 30, kde₧to strlen vracφ skuteΦn² poΦet znak∙, kter²
°et∞zec obsahuje (to poznßvß podle nulovΘho ukonΦovacφho znaku, kter² se v
naÜem p°φpad∞ nachßzφ hned za teΦkou).
Funkce strcpy kopφruje °et∞zec
do jinΘho vΦetn∞ nulovΘho ukonΦovacφho znaku, volß se strcpy(kam, odkud) . Nap°φklad: char str1[] = "Zkopφruj me!";
char str2[20];
strcpy(str2, str1);
cout << str2; // nynφ str2 obsahuje stejn² text jako str1
P°i pou₧φvanφ tΘto funkce je t°eba dßvat pozor na to, ₧e nekontroluje
velikost cφlovΘho °et∞zce. Jestli₧e se pokusφme zkopφrovat 100znakov²
°et∞zec do °et∞zce, jeho₧ velikost je 10, funkce strcpy si nebude st∞₧ovat, velmi ochotn∞
to provede, ale na funkΦnosti programu se toto asi projevφ katastrofßlnφm
zp∙sobem, proto₧e nßm urΦit∞ p°epφÜe Φßst jin²ch dat.
Te∩, kdy₧ znßme funkci strcpy
m∙₧eme si ukßzat dalÜφ mo₧nost inicializace °et∞zc∙, a to °et∞zcovou
konstantou v programu: char str1[20];
strcpy(str1, "Konstanta"); // toto je °et∞zcovß konstanta
cout << str1;
Jde o to, ₧e v v programu m∙₧eme kdykoli pou₧φvat °et∞zec, kter² nemß
jmΘno a kter² jsme p°edtφm nedeklarovali. Je to totΘ₧ jako kdy₧ napφÜeme
a = 3 . Tu trojku jsme p°ece nikde
nedeklarovali, a s °et∞zci je to to samΘ. Nev²hoda tohoto postupu ale je,
₧e k jednou pou₧itΘmu °et∞zci se nem∙₧ete vrßtit, nem∙₧ete se k n∞mu znovu
odkazovat, prost∞ ho musφte napsat znovu. A a₧ VßÜ program bude slavn² a
budete ho chtφt p°elo₧it do jinΘho jazyka, budete muset projφt cel² k≤d a
hledat kde vÜude mßte °et∞zcovΘ konstanty. Je to d°ina, a tak Vßm tuto
praktiku p°φliÜ nedoporuΦuji.
Chceme-li spojit dv∞ °et∞zce do jednoho, pou₧ijeme funkci strcat(kam, odkud) . Nap°φklad: char str1[20];
strcpy(str1, "Prvnφ ");
strcat(str1, "Druh²");
cout << str2; // vypφÜe se Prvnφ Druh²
DalÜφ u₧iteΦnou funkcφ je strcmp . Jak jste mo₧nß poznali z jejφho
jmΘna (cmp je zkratka anglickΘho compare), slou₧φ k
porovnßvßnφ °et∞zc∙. Funkce se volß strcmp(prvnφ_°et∞zec, druh²_°et∞zec) , a
vracφ hodnotu int, kterß mß tento v²znam: je-li
menÜφ ne₧ nula, prvnφ_°et∞zec by
byl ve slovnφku p°ed druh²_°et∞zec , je-li v∞tÜφ ne₧ nula bylo
by to naopak, a je-li nula °et∞zce jsou stejnΘ. Tato funkce mß variantu
stricmp , kterß porovnßvß bez
ohledu na velikost pφsmen (vnit°n∞ p°evßdφ vÜechna pφsmena na
malß). char str1 = "abcd";
char str2 = "bcde";
int vysledek;
vysledek = strcmp(str1, str2);
cout << vysledek;
T∞Üφme se p°φÜt∞ nashledanou.
|