CVIČENIE 6/13 (S7) Programovanie v jazyku C - struktury a polia About struktury, rozdiel medzi polom a strukturou, polia struktur, polia smernikov, bublinkove triedenie Basic knowledge pole je homogenny udajovy typ (prvky pola su rovnakeho typu). struktura je heterogenny udajovy typ (prvky/polozky struktury mozu mat rozny typ). struct{ polozky; a; v praxi sa najcestejsie pouzivaju nasledujuce dva zapisy: v tomto priklade vytvorime novy typ, ktory pomenujeme MIERY: typedef struct { int vyska; float vaha; MIERY; MIERY jozko, janko, petko; v tomto priklade vytvorime strukturu miery, ktora bude aj novym typom MIERY: typedef struct miery { int vyska; float vaha; MIERY; MIERY jozko, janko, petko; k jednotlivym polozkam struktury pristupujeme cez operator '.': jozko.vyska = 192; jozko.vaha = 86.5; janko.vyska = jozko.vyska; existuje aj vztah poli a struktur - v samotnej strukture moze existovat polozka, ktora predstavuje pole, ale moze existovat aj pole struktur:
MIERY a[10]; // pole typu MIERY, kde kazda polozka pola je reprezentovana jednou strukturovanou polozkou typu MIERY a[5].vyska = 187; // priradenie vysky 6-temu prvku pola v ANSII C neboo mozne nasledovne priradenie: jozko = janko; // skopirovanie celeho obsahu strukturovanej premennej do druhej dnesne prekladace taketo priradenie vsak uz umoznuju. polia smernikov - jedna sa o pole, kde jenodtlive prvky tohto pola predstavuju smerniky char *c[20]; // pole dvadsiatich smernikov na typ char pouzitie takychto poli je vyhodne napriklad pri triedeni, kedy nedochadza k vymene celych poloziek obsiahnutych v takomto poli (cele riadky), ale len adresa s odkazom na takyto riadok: char zoznam[50][10]; // pole obsahujuce zoznam poloziek char *p_zoznam[50]; // pole smernikov odkazujuce na jednotlive polozky predchadzajuceho pola p_zoznam = zoznam; bublinkove triedenie TODO: Nalezení znaku v řetězci... strchr - syntaxe: char* strchr (const char* s, int c) - funkce vrací pointer na první výskyt c v řetězci s ( \0 se považuje za část řetězce) - pokud znak c není nalezen, funkce vrací 0 (nulový pointer... #define NULL 0) Priklad: naprogramovat funkci strchr char* strchr (char* s, int c){ while (*s && c!= *s) s++; return (*s)? s : NULL; Porovnání dvou řetězců... strcmp - syntaxe: int strcmp (const char* s1, const char* s2) - funkce vrací 1 když s1 > s2 0 když s1 == s2-1 když s1 < s2
- funkce kexikograficky porovnává dva řetězce znak po znaku - většinou (známé znakové sady) jsou malá písmena za velkými ale není to přenositelné Priklad: naprogramovat funkci strcmp int strcmp (const char* s1, const char* s2) { while (*s1 && (*s1 == *s2)){ s1++; s2++; if (!(*s1) &&!(*s2)) return 0 else return (*s1 < *s2)? -1 : 1; Vyhledávání podřetězce v řetězci... strstr - syntaxe: int strstr (const char* s1, const char* s2) - funkce vrací první výskyt řetězce s2 v řetězci s1 (podobně jako strchr, ale hledá podřetězec) Priklad: naprogramovat funkci strstr - program musí zpracovat i případ s1 = abababc s2 = ababc fce má vrátit pointer na: abababc 1. řešení přes 2 cykly: - vnější cyklus projíždí znak po znaku s1 - vnitřní cyklus ojede s2 char* my_strstr(char *s1, char *s2) { char* ps1; char* ps2; while(*s1) { ps1 = s1; ps2 = s2; while (*ps1 && *ps2 && *ps1 == *ps2){ ps1++; ps2++; if (*ps2 == '\0') // jsme na konci ps2 -> nasli jsme vzor return s1;
if (*ps1 == '\0') // jsme na konci ps1 -> nic jsme nenasli return NULL; s1++; return NULL; 2. toto řešení je pomocí stavového automatu: char* strstr(char *s1, char *s2) { char* p = NULL; char *ps2 = s2; int shoda = 0; while (*s1) { if (*s2 && *s1==*s2) { if (!shoda) { p=s1; shoda=1; s2++; else { if (shoda) { shoda = 0; s2 = ps2; s1 = p; s1++; if (!*s2) return p; if (!*s2) return p; else return NULL;
Priklad: napište funkci, která dostane na vstup řetězec (slova oddělená jednou nebo více mezerami) a obrátí řetězec => funkce původní řetězec změní "ahoj babi" "joha ibab" void obratslova( char* s){ char* zac; // zacatek obraceneho slova char* kon; // konec obraceneho slova int c; while( *s) { while( *s == ' ') s++; // preskoc mezery if(! *s) // muze byt konec break; for( zac = s; *s && *s!= ' '; s++) ; // dojet ZA konec slova for( kon = s - 1; zac < kon; zac++, kon--) { c = *zac; // obrat slovo *zac = *kon; *kon = c; Priklad: naprogramovat funkci str_replace char* str_replace(char* s1, char*s2, char* s3) - funkce nahradí výskyt řetězce s2 v řetězci s1 řetězcem s3 - nepoužít žádný pomocný buffer - nepoužít žádnou knihovní funkci - můžeme předpokádat, že s1 je dostatečný velký buffer, aby se tam vešel výsledný řetězec -> dokoncit priklad z hodiny
Examples Ex. 1: vytvorte strukturovany typ, ktory bude pozostavat z: meno - 10 znakov priezvisko - 20 znakov vek - cele cislo vyska - desatinne cislo vaha - desatinne cislo pohlavie - M/Z - jeden znak Ex. 2: upravte dany typ tak, aby obsahoval dve polozky - meno a vek. vytvorte pole, ktore bude tohto typu a bude obsahovat 10 prvkov. nacitajte toto pole zo vstupu. nacitavanie ukoncte, ked: bude presiahnuty pocet 10-tich poloziek pri zadavani novej polozky sa miesto mena (1. udaj) zada znak '0' obsah nacitanych udajov (pola) vypiste na obrazovku Ex. 3: pomocou pola smernikov zotriedte nacitane polozky: podla mena (strcmp) podla veku