PB161 Programování v jazyku C++ Textové řetězce (1. část) Pole Ukazatele vs. Odkazy Funkce
Řetězce ve stylu C Jedná se o pole znaků zakončených nulovým znakem '\0'. proto při deklaraci pole musíme uvést o 1 znak více, než je délka řetězce. příklady char slovo_a[] = buldozer ; char *slovo_b = buldozer ; char slovo_c[21]; char slovo_d[6] = OK_OK ; char slovo_e[5] = OK_OK ; //chyba slovo_c = ahoj ; strcpy(slovo_c, ahoj ); //chyba //OK
Řetězce ve stylu C co se stane... struct dva_retezy { char s1[4]; char s2[4]; } retezy;
Řetězce ve stylu C co se stane... struct dva_retezy { char s1[4]; char s2[4]; } retezy; strcpy(retezy.s1, "Ahoj"); strcpy(retezy.s2, "Zdar"); cout<<retezy.s1<<endl;
Řetězce ve stylu C co se stane... struct dva_retezy { char s1[4]; char s2[4]; } retezy; strcpy(retezy.s1, "Ahoj"); strcpy(retezy.s2, "Zdar"); cout<<retezy.s1<<endl; AhojZdar
Řetězce ve stylu C++ Používá se třída string. Řetězec ve stylu C++ již není obyčejné pole znaků, je to objekt. Lze je dynamicky zvětšovat a zmenšovat relačními operátory lexikograficky porovnávat řetězit konvertovat na/z styl C zjišťovat velikost (délku) textu bezpečně procházet znak po znaku přímo přiřazovat...
Řetězce ve stylu C++ (2) Nutno vložit hlavičkový soubor <string> operátor = přiřazení řetězu operátory ==,!= srovnání řetězců na rovnost/různost operátory <=, >=, <, >,!= lexikografické porovnání řetězců operátory <<, >> výstup, vstup (načtení) operátor + zřetězení dvou řetězců
Řetězce ve stylu C++ (3) operátor [] indexace znaků v řetězci metoda (funkce) at() bezpečná indexace znaků v řetězci, vyhazuje výjimky string retez = "test_retezce"; for (unsigned i=0; i<retez.length()+10; i++) { cout<<retez[i]; //test_retezce cout<<retez.at(i); } //test_retezceneúspěšně ukončen (SIGABRT)
Řetězce ve stylu C++ (4) příklad repeater #include<iostream> using namespace std; int main (void) { string retez; while (cin>>retez) { cout<<retez; } Program čte vstup. Dle bílých znaků jej rozděluje do jednotlivých řetězců (v každé iteraci cyklu while jeden). A každý z nich jde na výstup. Až se dosáhne konce souboru (v konzoli CTRL+D), operátor >> ve while cyklu vrátí hodnotu, která se vyhodnotí jako false a čtení se zastaví. } retur n 0; Takto lze načítat/vypisovat čísla, znaky, boolean hodnoty,... cokoli, pro co jsou (budou) operátory >> a << přetíženy.
Řetězce ve stylu C++ (5) metoda (funkce) length() zjištění délky řetězce metoda c_str() převod obsahu řetězce na styl C char * string retez = "ahoj"; cout<<"delka: "<<retez.length()<<endl; cout<<"delka: "<<strlen(retez.c_str())<<endl;
Řetězce ve stylu C++ (5) metoda (funkce) length() zjištění délky řetězce metoda c_str() převod obsahu řetězce na styl C char * string retez = "ahoj"; cout<<"delka: "<<retez.length()<<endl; cout<<"delka: "<<strlen(retez.c_str())<<endl; Delka: 4 Delka: 4
Pole v C++ Definujeme li staticky pole, musí být rozměry konstantní, ale nemusí jít o makra. #define X 10 #define Y 5 char pole2[x][y]; VS. const int x = 10; const int y = 5; char pole3[x][y];
Pole v C++ Oproti C99 ISO/IEC C (nikoli ANSI C!) standard C++ (ani C++03 ISO/IEC 14882:2003) neumožňuje proměnnou na místě meze pole lokálního ve funkci: void vypis(int x, int y) { int pole[x][y]; for (int ix = 0; ix < x; ix ++) for (int iy = 0; iy < y; iy ++) pole[ix][iy] = ix * iy; for (int ix = 0; ix < x; ix ++) { for (int iy = 0; iy < y; iy ++) cout<<setw(3)<<pole[ix][iy]; cout<<endl; } } error: ISO C++ forbids variable-size array
Funkce Jazyk C povoloval pouze volání jménem proto se simulovalo předávání odkazem pomocí předávání hodnotou ukazatele prehod(&x, &y); funkce nemůže měnit hodnotu ukazatele, ale může měnit, kam ukazatelé ukazují námi požadovanou hodnotu viz část kolegy Šimona Jazyk C++ umožňuje volání hodnotou i odkazem bez nutnosti simulace.
Funkce (2) Předávání parametrů hodnotou: void ch_point(int *p, int *q){ int pom=*p; *p=*q; *q=pom; } //ch_point(&a, &b); Předávání parametrů odkazem: void ch_ref(int &p, int &q) { int pom=p; p=q; q=pom; } //ch_ref(a, b); Pokud voláte funkci fun(x), nepoznáte, zda předáváte odkazem nebo hodnotou.
Funkce (3) V C++ je nutné uvést prototyp funkce před jejím prvním použitím, je li definována později. hlavička bez parametrů znamená typ void kromě konstruktorů a destruktorů je povinné uvádění návratového typu funkce lze použít... pro funkci s proměnným počtem parametrů ale lepší použít následující lze (postupně zprava) nadefinovat parametrům implicitní hodnoty zprava lze pak vynechávat parametry lze přetěžovat funkce [a metody, a operátorové funkce]
Funkce (4) implicitní parametry #include<iostream> #include<string> using namespace std; string posli(string text, int dulezitost = 1) { return (!dulezitost? "Oznameni: " : dulezitost == 1? "Varovani: " : "VYHRUZKA: ") + text; return "ahoj"; } int main(void) { cout<<posli("bude prset")<<endl; cout<<posli("plaveme v rece", 0)<<endl; cout<<posli("jestli NEDAS POKOJ...", 2)<<endl; } return 0;
Funkce (5) přetěžování (overloading) rozpoznej.cc void rozpoznej(int x) { cout<<x<<" je cele cislo"<<endl; } void rozpoznej(double x) { cout<<x<<" je float cislo"<<endl; } void rozpoznej(int x1, char x2) { cout<<x1<<" je cele cislo a " <<x2<<" je znak"<<endl; }
Funkce (5.5) přetěžování (overloading) rozpoznej(10); rozpoznej(10.2); rozpoznej(10, 'a'); 10 je cele cislo 10.2 je float cislo 10 je cele cislo a a je znak K přetížení nestačí: rozdílný návratový typ parametr předaný hodnotou a odkazem konstantní a nekonstantní typ
1. úkol Napište (zde rovnou na cvičení) program, který: bude číst znaky oddělené bílými znaky tak dlouho, dokud nenarazí na znak ' ' až narazí, bude číst do konce souboru (CTRL+D v shellu) první i druhou skupinu znaků bude považovat za množiny program provede výpočet a vypíše sjednocení a průnik těchto množin můžete předpokládat, že korektní vstup obsahuje každý znak nejvýše 1x můžete použít metodu ř etětec.find(znak/ ř etě z), která vrátí pozici výskytu nebo číslo >= ř etězec.length()
1. úkol (kdyby nešlo) řešení (nic moc moje : )) lze nalézt na: www.fi.muni.cz/~xbayer/pb161/2007/03/prunik.cc používám schválně typ string pro ukládání prvků množin (procvičení), ale není to moc dobré řešení. C++ nabízí v STL již hotové kontejnery, které přesně odpovídají množinám. Mají již definované metody a vypořádají se i duplicitami, dokáží uložit více než jen znaky... ale to je jiný příběh (probereme časem)
2. úkol Dobrovolný (za <0, 2> bodů). Odevzdávat emailem v příloze na pb161extra@fi.muni.cz Na odevzdání je 14 dní (do 15.10. včetně) Platí pro něj obdobné pravidla, jako pro klasicky odevzdávané úkoly, až na způsob odevzdání a nemožnost obdržet další +2 body za včasné odevzdání.
2. úkol (zadání) Napište (doma) program, který načte množinu znaků oddělených bílými znaky a spočte z ní její množinu všech množin (potenční množinu). http://cs.wikipedia.org/wiki/poten%c4%8dn%c3%ad_algebra Hlídat duplicity {a, a} = {a} Stojí li na vstupu ne znak, ale řetězec, použijte pouze jeho první znak, např.: a b zdar c a c množina bude {a, b, z, c}
2. úkol (zadání (2)) Jako oddělovač prvků můžete použít mezeru. Pro ukončení vstupu hlídejte konec souboru CTRL+D v shellu Pro procvičení můžete opět využít string, kdo zná STL, může použít i kontejner. Vzor řeší rekurzivně a pomocí string. Lze zkusit na aise: /home/xbayer/open/potencni_monzina
Fibonacciho posloupnost 1,1,2,3,5,8,13... http://cs.wikipedia.org/wiki/fibonacciho_posloupnost Jen v bodech první povinný vypsat fibonacciho čísla <= zadané číslo (očíslovat) použít unsigned long int pokud nové číslo je menší než minulé ohlásit chybu (přetečení) VRÁTIT NENULU Z MAIN FUNKCE http://www.fi.muni.cz/usr/jkucera/pb161/fibon.htm /home/jkucera/pb161/cvic3/fibon