PB161 Jazyk C++ - 3

Textové řetězce

Řetězce ve stylu C

Při programování v C++ se používají jen výjimečně.

Konstanty:

"text" "Může obsahovat \n řídicí znaky."

Deklarace:

char radek[81]; // Max. 80 znaků, za posledním znakem '\0'
char nadpis[]="Jmeno\tPrijmeni";

Manipulace:

NE:  if(radek=="end")radek="Nějaký text"; - nutno používat funkce:

#include <string.h> nebo #include <cstring>

strcpy(a,b) Zkopíruje řetězec b do řetězce a; vrací ukazatel na začátek a
strcat(a,b) Přidá řetězec b na konec řetězce a; vrací ukazatel na začátek a
strcmp(a,b) Porovná řetězce a a b; vrací číslo <0 / 0 / >0, je-li a lexikograficky menší / rovno / větší než b
strlen(a) Vrací délku řetězce a (počet znaků před ukončujícím nulovým znakem)
strchr(a,c) Hledá, zda je v řetězci a obsažen znak c. Pokud ano, vrátí ukazatel na první výskyt znaku; pokud ne, vrátí NULL
strstr(a,b) Hledá, zda je v řetězci a obsažen podřetězec b. Pokud ano, vrátí ukazatel na začátek prvního výskytu podřetězce; pokud ne, vrátí NULL

#include <ctype.h> nebo #include <cctype>

isalpha() isdigit() isxdigit() ispunct() isalnum()
iscntrl() isprint() isgraph() isspace()
isupper() islower()
toupper() tolower() // pouze 1 znak!

Řetězce ve stylu C++

Třída string

String není pole znaků, ale jednotlivé znaky lze vybírat pomocí [index]. Stringy jsou "nafukovací", lze je bez předeklarování prodlužovat. Je možno (na rozdíl od céčkovského pole znaků) přiřazovat je jako celek operátorem =, řetězit (konkatenovat) operátorem + nebo +=,  porovnávat relačními operátory apod. Navíc je pro ně k dispozici řada funkcí. Konstanty zapsané v uvozovkách lze kombinovat s céčkovskými řetězy i se stringy.

Podrobnosti viz příští přednáška


Pole

float a[5]; vytvoří 5 proměnných typu float: a[0], a[1] ... a[4]
char odpovedi[]={'a','y','n'};

K zamyšlení: je to něco jiného než char odpovedi[]="ayn"; ???

Vícerozměrná pole:

const int RADKY=10,SLOUPCE=8;
/* V K-R C/ANSI C jedině:
#define RADKY 10
#define SLOUPCE 8
*/
...
int table[RADKY][SLOUPCE]; // rozměry musí být konstantní, ale v C++ ne nutně makra
...
for(int i=0; i<RADKY; i++)
  for(int j=0; j<SLOUPCE; j++)
    { ...
      ... table[i][j] ...  // POZOR: nikoli table[i,j] !!!
    } 
... 

V C++ se velmi často místo pole používá kontejner vector (viz další přednášku)


Ukazatele (pointery)

int i, *p; // *p je int, tedy p je ukazatel na int
i=123; p=&i; *p=789; 

Ukazatelová aritmetika

Jsou-li p, q ukazatele na objekty téhož typu a i celočíselná hodnota, jsou povoleny operace:
     p+i p-i p-q
p+1
neukazuje o 1 bajt dále, ale o 1 objekt dále!

Vztah polí a ukazatelů

Ve většině kontextů (i když ne vždy) platí:

A je totéž jako &A[0]
A+i
je totéž jako &A[i]
*(A+i)
je totéž jako A[i] - a totéž jako i[A] !!!

Ukazatel na nespecifikovaný typ

void *ukaz;

Přiřadit mu lze ukazatel jakéhokoli typu, nesmí být dereferencován.

Ukazatel s nedefinovanou hodnotou

Pokud chceme deklarovat ukazatel, ale specifikovat, že zpočátku neukazuje nikam, v C++ bývá zvykem přiřadit mu hodnotu celočíselné konstanty 0. V jazyce C se k tomuto účelu používalo makro NULL.

double *ukaz=0;


Odkazy (reference - specialita C++)

long int i; i=123456; long int &j=i;

j je jiný název pro proměnnou i, obě označují totéž místo v paměti.

Hlavní použití: parametry a návratové hodnoty funkcí - viz dále v této přednášce.

Kromě proměnných lze odkazovat i na pole a funkce. Nelze však:

V některých případech odkaz vytvoří pomocnou proměnnou, na kterou se pak odkazuje.


Funkce

2 typy deklarace:

Prototypy

Jsou nutné, pokud je funkce použita dříve (nebo v jiném zdrojovém souboru), než je definována.

typ název(typ parametr, typ parametr ...); (Názvy parametrů v prototypu mohou chybět)

Příklady:

Prototyp: Parametry: Vrací:
void f1(int); 1. int Nic
int f2(char *, double); 1. řetězec
2. double
int
void *f3(int); 1. int Ukazatel na nespecifikovaný typ
int (*f4())[10]; žádné Ukazatel na pole 10 veličin int
long (*f5(char))(); 1. char Ukazatel na funkci bez parametrů vracející long

Poznámka: Je-li parametrem pole, lze vynechat číslo v []; častěji se však parametr deklaruje jako ukazatel.

Prázdný seznam parametrů znamená:

V C++: void (tj. bez parametrů)
Ve všech verzích C: počet a typ parametrů nezadán

Neuvedený návratový typ znamená:

V C++ je uvedení návratového typu povinné (s výjimkou konstruktoru a destruktoru, kde je naopak zakázáno)
ISO/IEC C (C99): funkce nevrací hodnotu (tj. jako by bylo uvedeno void)
Ve starších verzích C: funkce vrací int

Definice

Předávání parametrů

Příklad: Vyměň hodnoty proměnných i a j

Předání hodnotou ukazatele: Předání odkazem (jen v C++):
void vymen1(int *p, int *q)
{ int pom=*p; *p=*q; *q=pom;
}
void vymen2(int &p, int &q)
{ int pom=p; p=q; q=pom;
}

Vyvolání:

vymen1(&i, &j); vymen2(i, j);

Pozor! Ze samotného volání není poznat, zda je parametr volán odkazem nebo hodnotou! (To je zřejmé pouze ze záhlaví funkce.)

Vynechané parametry

typ název(typ parametr, typ parametr ...)

Volá se s >=2 parametry. Přístup k parametrům neuvedeným v hlavičce je pomocí speciálních maker. Skutečný počet parametrů musí být zjistitelný z ostatních parametrů! V C++ málo používané, raději se použijí implicitní parametry nebo přetížené funkce:

Implicitní parametry (C++)

void vodor_cara(int delka,int pocatek=0,int tloustka=1){/* příkazy */}

Volá se s 1 až 3 parametry. nezadané parametry mají implicitní hodnotu zadanou v záhlaví.

Přetěžování (overloading) funkcí (C++)

Několik funkcí s týmž názvem:

void f();
int f(int);
double f(double);
void f(int,double);

Při volání se funkce vybere podle počtu a typu skutečných parametrů. K rozlišení však nestačí:

Funkce main()

Stejně jako v C (včetně toho, že musí vracet hodnotu int):

int main(int argc, char *argv[])

argc ... počet parametrů při volání z příkazového řádku
argv ... pole ukazatelů na jednotlivé parametry z příkazového řádku

Vždy aspoň 1 parametr argv[0] ... název volaného programu

U mnoha překladačů ještě 3. parametr char *env[] ... proměnné prostředí

Návratová hodnota funkce main je sice int, ale s ohledem na to, aby ji správně zpracoval shell operačního systému, je vhodné omezit se na čísla od 0 do 255.


Předchozí Předchozí přednáška Další Další přednáška Hlavní stránka Hlavní stránka