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:

  1. 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).
  2. 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;

  3. 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.

Ji°φ Formßnek a Andrei Badea