{{indexmenu_n>5}}
====== 5 - Pole variabilní délky a textové řetězce ======
* [[courses:b0b36prp:internal:tutorialinstruction:05|pro vyučující]]
===== Cíle cvičení =====
- 1D pole variabilní délky.
- Ukazatel, reference ''&'' a dereference ''*''.
- Pointerová aritmetika.
- Textové řetězce.
==== Materiály ====
* [[https://en.wikipedia.org/wiki/ASCII|ASCII tabulka]]
* Délka textového řetězce: [[https://en.cppreference.com/w/cpp/string/byte/strlen|strlen]]
* Porovnání řetězců: [[https://en.cppreference.com/w/c/string/byte/strcmp|strcmp]], [[https://en.cppreference.com/w/c/string/byte/strncmp|strncmp]]
===== Pole Variabilní Délky =====
- Napište program, který provede inicializaci 1D pole. Velikost pole zadá uživatel ze standardního vstupu. Protože se jedná o inicializaci za běhu programu, je třeba zkompilovat program s podporou standardu C99.
- Pole naplňte celými čísly ze standardního vstupu.
- Doplňte program tak, aby prošel pole pomocí cyklu a vypsal jednotlivé prvky pole. Zkuste napsat cyklus tak, aby program vypsal pole ve více sloupcích.
- Napište funkci, která vypíše prvky pole, které je jejím argumentem. Funkci implementujte v přechozím programu.
/* PV: Zkraceno protoze je malo casu
- Napište funkci, která naplní pole zadané velikosti náhodnými celými čísly v zadaném rozsahu. Vytvořené pole je návratovou hodnotou funkce.
- Naplňte pole pomocí funkce z předchozího bodu. Napište funkci, která určí četnost čísel v tomto poli (histogram).
==== Další úkoly ====
- Napište funkci, která setřídí pole metodou counting-sort. Nesetříděné pole je argumentem funkce, návratovou hodnotou funkce je pole setříděné.
*/
===== Pointery a jejich aritmetika =====
==== Reference, Dereference a Paměť ====
Odhadněte výstupy následujících výpisů a ověřte odhady v spuštěním programu.
int x = 10;
int *px = &x;
printf("px = %ld\n", px);
printf("*px = %d\n", *px);
++++ Otázky k diskuzi |
* Proč se hodnota ''px'' mění při každém spuštění?
++++
char c = 10;
int x = 10;
int* px = &x;
char* pc = &c;
printf("sizeof(c) = %ld\n", sizeof(c));
printf("sizeof(x) = %ld\n", sizeof(x));
printf("sizeof(px) = %ld\n", sizeof(px));
printf("sizeof(pc) = %ld\n", sizeof(pc));
printf("(pc - px) = %ld\n", (pc - (char*)px));
++++ Otázky k diskuzi |
''int'' zabere víc místa v paměti než ''char''.
* Ale adresy na ''int'' a ''char'' zaberou stejné množství místa, jak to?
* Jak kompilátor ví, kolik paměti má očekávat (při čtení či zápisu) při derefernci ''*px''?
* Proč se poslední výpis nemění?
++++
int x;
char *pcx = &x;
pcx[0] = 'a';
pcx[1] = 'b';
pcx[2] = 'c';
pcx[3] = '\0';
printf("x = %d\n", x);
printf("&x = %ld\n", &x);
printf("&x = %s\n", &x);
++++ Otázky k diskuzi |
* Co je hodnotou proměnné ''x''? Číslo nebo pole znaků?
++++
==== Pointerová aritmetika ====
- Určete výsledek a ověřte programem:
int array[] = {5, -6, 0, 8, -9, 3, 1, -4};
int *up = array;
int **uup = &up;
printf("array[1] = %d \n", array[1]);
printf("array[1] + 4 = %d \n", array[1] + 4);
printf("(array + 1)[2] = %d \n", (array + 1)[2]);
printf("*up = %d \n", *up);
printf("*up + 4 = %d \n", *up + 4);
printf("*(up + 1) = %d \n", *(up + 1));
printf("**uup = %2d \n", **uup);
printf("*(*uup + 2) = %2d \n", *(*uup + 2));
printf("**uup + 4 = %2d \n", **uup + 4);
===== Textové řetězce =====
* Definujte textový řetězec "Everybody likes PRP" a vypište ho. Následně vypište z tohoto řetězce pouze "likes PRP" a nakonec řetězec změňte na "Tom likes PRP" a vypište ho. Přemýšlejte, jak to provést nejúsporněji.
* Naprogramujte funkce strlen, strcmp a strncmp.
=== cat ===
* Naprogramujte zjednodušenou verzi programu ''cat''. Načtěte vstup ze stdin a zase ho vypište na výstup (stdout).
echo "Hello world" | cat
Hello world
* Upravte program tak, aby vypsal vstup až za první mezerou:
echo "Hello world" | cat2
world
* Vypište každe slovo ze vstupu na samostatný řádek (za oddělovače slov považujte mezeru, konec řádku ''\n'' a tabulátor ''\t'').
echo "Hello world and hello again " | words
Hello
world
and
hello
again
* Nyní zkuste totéž, ale za každé slovo vypište i jeho délku a slova 'and' a 'or' nejak označte.
echo "Hello world and hello again " | words-len
Hello 5
world 5
and 3 <--
hello 5
again 5
=== tr ===
* Načtěte vstup a vypište ho s malými písmeny přepsanými na velké a naopak
echo "Hello world" | cap
=====
hELLO WORLD
* Nyní zkuste zjednodušenou verzi programu ''tr''. Program bude mít zadány dva argumenty na příkazové řádce, které budou sloužit jako předpis pro překlad znaků viz. následující příklad:
echo "Hello world" | tr 'Hl' 'Xk'
Xekko workd
echo "Hello world" | tr 'dweji' '01234'
H2llo 1orl0
* Zkuste si pospojovat dnešní programy. Např.:
echo "Hello world and hello again " | words | cap
hELLO
WORLD
AND
HELLO
AGAIN
=== Feedback ===
Pro cvičení Jakuba Dupáka: [[https://jakubdupak.com/prp-feedback/]]