BI-PA1 Programování a Algoritmizace 1. Miroslav Baĺık, Ladislav Vagner a Josef Vogel. 7., 9. a 10. listopadu 2017

Podobné dokumenty
Pole a Funkce. Úvod do programování 1 Tomáš Kühr

8. lekce Úvod do jazyka C 3. část Základní příkazy jazyka C Miroslav Jílek

Ukazatele #2, dynamická alokace paměti

Funkce, intuitivní chápání složitosti

BI-PA1 Programování a algoritmizace 1 Katedra teoretické informatiky

Příkazy if, while, do-while, for, switch

Základy programování (IZP)

Funkce, procedury, složitost

int t1, t2, t3, t4, t5, t6, t7, prumer; t1=sys.readint();... t7=sys.readint(); prume pru r = r = ( 1+t 1+t t3+ t3+ t4 t5+ t5+ +t7 +t7 )/ ;

Operační systémy. Cvičení 4: Programování v C pod Unixem

Ukazatele #1, struktury

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

for (int i = 0; i < sizeof(hodnoty) / sizeof(int); i++) { cout<<hodonoty[i]<< endl; } cin.get(); return 0; }

Jazyk C Program v jazyku C má následující strukturu: konstanty nebo proměnné musí Jednoduché datové typy: Strukturované datové typy Výrazy operátory

Úvod do programování - Java. Cvičení č.4

Základy programování (IZP)

2 Datové typy v jazyce C

Jazyk C++, některá rozšíření oproti C

1. lekce. do souboru main.c uložíme následující kód a pomocí F9 ho zkompilujeme a spustíme:

Mělká a hluboká kopie

Abstraktní třídy, polymorfní struktury

IUJCE 07/08 Přednáška č. 4. v paměti neexistuje. v paměti existuje

BI-PA1 Programování a algoritmizace 1, ZS Katedra teoretické informatiky

Operační systémy. Cvičení 3: Programování v C pod Unixem

Obsah. Předmluva 13 Zpětná vazba od čtenářů 14 Zdrojové kódy ke knize 15 Errata 15

PROGRAMOVÁNÍ V JAZYCE C V PŘÍKLADECH 11 Dynamické datové struktury 11.1 Spojové struktury Příklad PROG_

for (i = 0, j = 5; i < 10; i++) { // tělo cyklu }

BI-PA1 Programování a algoritmizace 1 Katedra teoretické informatiky

Např.: // v hlavičkovém souboru nebo na začátku // programu (pod include): typedef struct { char jmeno[20]; char prijmeni[20]; int rok_nar; } CLOVEK;

Správné vytvoření a otevření textového souboru pro čtení a zápis představuje

BI-PA1 Programování a algoritmizace 1, ZS Katedra teoretické informatiky

Dekompozice problému, rekurze

Maturitní otázky z předmětu PROGRAMOVÁNÍ

Základy programování (IZP)

Programovanie v jazyku C - pole treba poorat...

Ukazatel (Pointer) jako datový typ - proměnné jsou umístěny v paměti na určitém místě (adrese) a zabírají určitý prostor (počet bytů), který je daný

Úvod do jazyka C. Ing. Jan Fikejz (KST, FEI) Fakulta elektrotechniky a informatiky Katedra softwarových technologií

10 Práce s řetězci - pokračování

IUJCE 07/08 Přednáška č. 6

Pointery II. Jan Hnilica Počítačové modelování 17

Struktura programu v době běhu

IAJCE Přednáška č. 8. double tprumer = (t1 + t2 + t3 + t4 + t5 + t6 + t7) / 7; Console.Write("\nPrumerna teplota je {0}", tprumer);

Paměť počítače. alg2 1

Čtvrtek 8. prosince. Pascal - opakování základů. Struktura programu:

Základy jazyka C. Základy programování 1 Martin Kauer (Tomáš Kühr)

Racionální čísla, operátory, výrazy, knihovní funkce

VÝUKOVÝ MATERIÁL. Bratislavská 2166, Varnsdorf, IČO: tel Číslo projektu

Algoritmy I. Cvičení č. 2, 3 ALGI 2018/19

Racionální čísla, operátory, výrazy, knihovní funkce

Základní datové typy, proměnné - deklarujeme předem - C je case sensitive rozlišuje malá a velká písmena v názvech proměnných a funkcí

Algoritmizace a programování. Ak. rok 2012/2013 vbp 1. ze 44

2 Základní funkce a operátory V této kapitole se seznámíme s použitím funkce printf, probereme základní operátory a uvedeme nejdůležitější funkce.

Algoritmizace a programování

Př. další použití pointerů

Střední škola pedagogická, hotelnictví a služeb, Litoměříce, příspěvková organizace

Programování v jazyce C pro chemiky (C2160) 3. Příkaz switch, příkaz cyklu for, operátory ++ a --, pole

- jak udělat konstantu long int: L long velka = 78L;

6. lekce Úvod do jazyka C knihovny datové typy, definice proměnných základní struktura programu a jeho editace Miroslav Jílek

Začínáme vážně programovat. Řídící struktury Přetypování Vstupně výstupní operace Vlastní tvorba programů

- dělají se také pomocí #define - podobné (použitím) funkcím - předpřipravená jsou např. v ctype.h. - jak na vlastní makro:

BI-PA1 Programování a Algoritmizace 1. Miroslav Baĺık, Ladislav Vagner a Josef Vogel. 10., 12. a 13. října 2017

Programování: základní konstrukce, příklady, aplikace. IB111 Programování a algoritmizace

Programování v C++, 2. cvičení

Výrazy a operátory. Operátory Unární - unární a unární + Např.: a +b

Lekce 6 IMPLEMENTACE OPERAČNÍHO SYSTÉMU LINUX DO VÝUKY INFORMAČNÍCH TECHNOLOGIÍ JAZYK C

7 Formátovaný výstup, třídy, objekty, pole, chyby v programech

Řídící struktury, if, while, switch

BI-PA1 Programování a algoritmizace 1 Katedra teoretické informatiky

PROMĚNNÉ, KONSTANTY A DATOVÉ TYPY TEORIE DATUM VYTVOŘENÍ: KLÍČOVÁ AKTIVITA: 02 PROGRAMOVÁNÍ 2. ROČNÍK (PRG2) HODINOVÁ DOTACE: 1

Algoritmizace a programování

Jazyk C práce se soubory. Jan Hnilica Počítačové modelování 16

Strukturu lze funkci předat: (pole[i])+j. switch(výraz) velikost ukazatele

Střední škola pedagogická, hotelnictví a služeb, Litoměříce, příspěvková organizace

Preprocesor. Karel Richta a kol. katedra počítačů FEL ČVUT v Praze. Karel Richta, Martin Hořeňovský, Aleš Hrabalík, 2016

Úvod do programování 6. hodina

ZPRO v "C" Ing. Vít Hanousek. verze 0.3

Funkce pokročilé možnosti. Úvod do programování 2 Tomáš Kühr

Abstraktní datové typy, moduly

Odvozené a strukturované typy dat

Pole stručný úvod do začátku, podrobně později - zatím statická pole (ne dynamicky) - číslují se od 0

Základy programování. Úloha: Eratosthenovo síto. Autor: Josef Hrabal Číslo: HRA0031 Datum: Předmět: ZAP

Programovanie v jazyku C - funkcie a makra

Základní pojmy. Úvod do programování. Základní pojmy. Zápis algoritmu. Výraz. Základní pojmy

Test prvočíselnosti. Úkol: otestovat dané číslo N, zda je prvočíslem

9. lekce Úvod do jazyka C 4. část Funkce, rekurze Editace, kompilace, spuštění Miroslav Jílek

Program převod z desítkové na dvojkovou soustavu: /* Prevod desitkove na binarni */ #include <stdio.h>

VISUAL BASIC. Práce se soubory

Rozklad problému na podproblémy, rekurze

VÝUKOVÝ MATERIÁL. Bratislavská 2166, Varnsdorf, IČO: tel Číslo projektu

Martin Flusser. Faculty of Nuclear Sciences and Physical Engineering Czech Technical University in Prague. October 17, 2016

Úvod do programovacích jazyků (Java)

Lekce 19 IMPLEMENTACE OPERAČNÍHO SYSTÉMU LINUX DO VÝUKY INFORMAČNÍCH TECHNOLOGIÍ JAZYK C

Základy C++ I. Jan Hnilica Počítačové modelování 18

Programování v jazyce C pro chemiky (C2160) 12. Specifické problémy při vývoji vědeckého softwaru

Základní datové struktury

Řídící struktury, if, while, switch

Jazyk C# a platforma.net

Programovací jazyk Pascal

Vyhledávání. doc. Mgr. Jiří Dvorský, Ph.D. Katedra informatiky Fakulta elektrotechniky a informatiky VŠB TU Ostrava. Prezentace ke dni 21.

ALGORITMIZACE A PROGRAMOVÁNÍ

Transkript:

Pole, Řetězce BI-PA1 Programování a Algoritmizace 1 Miroslav Baĺık, Ladislav Vagner a Josef Vogel Katedra teoretické informatiky a Katedra softwarového inženýrství Fakulta informačních technologíı České vysoké učení technické v Praze xvagner@fit.cvut.cz, vogeljos@fit.cvut.cz 7., 9. a 10. listopadu 2017

Přehled Pole (deklarace, použití). Pole příklady. Řetězce. Multidimenzionální pole (matice). M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 2/43

Pole motivace Problém: uložit změřené teploty pro každý den týdne, spočítat průměrnou teplotu (v týdnu), zobrazit průměr, zobrazit rozdíl mezi naměřenou a průměrnou teplotou pro každý den týdne. M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 3/43

Pole motivace int main ( void ) { int t1,t2,t3,t4,t5,t6,t7,avg; printf ( "Napis zmerene teploty (7 x):\n" ); scanf ( "%d%d%d%d%d%d%d", &t1,&t2,&t3,&t4,&t5,&t6,&t7 ); avg = (t1 + t2 + t3 + t4 + t5 + t6 + t7) / 7; printf ( "Prumerna teplota: %d\n", avg ); printf ( "Nedelni diference: %d\n", t1 - avg ); printf ( "Pondelni diference: %d\n", t2 - avg );... printf ( "Sobotni diference: %d\n", t7 - avg ); return 0; M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 4/43

Pole motivace Naivní řešení je nešikovné: program je rozvláčný, některé příkazy se opakují (pouze s malými modifikacemi), program není škálovatelný (průměr za měsíc, za rok). Problém může být elegantněji vyřešen pomocí pole (array). Pole je strukturovaný datový typ skládající se nějakých prvků (buněk), které jsou všechny stejného typu. Prvek pole je identifikován svým indexem (celočíselnou hodnotou). V jazyce C jsou indexy čísla 0, 1,..., array size - 1. Velikost pole (array size) je dána jeho deklarací. Za běhu nemůže být změněna (pro statická pole). M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 5/43

Pole motivace Pole bude použito pro uložení hodnot teploty: int temp[7] Vstupní hodnoty budou čteny ve for cyklu: for ( i = 0; i < 7; i ++ ) scanf ( "%d", &temp[i] ); Průměr bude opět počítán cyklem: avg = 0; for ( i = 0; i < 7; i ++ ) avg += temp[i]; avg /=7; A závěrečný report: for ( i = 0; i < 7; i ++ ) printf ( "diference: %d\n", temp[i] - avg ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 6/43

Pole Pole p obsahující n prvků typu T se deklaruje: T p[n] T n p je libovolný datový typ, je kladná celočíselná konstanta a je jméno proměnné (identifikátor). Je-li pole globální proměnná (mající rozsah platnosti v celém souboru), pak je počáteční obsah všech prvků pole definován - samé nulové bajty. Je-li pole lokální proměnná (deklarovaná v bloku funkce), pak je počáteční obsah pole nedefinován. Prvky pole jsou přístupné pomocí indexu: p[i] M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 7/43

Pole meze Indexování pole: p[i] je-li i nezáporná hodnota a i je menší než počet prvků pole (dimenze pole) p, pak p[i] je proměnná typu T, když i není v rozsahu indexu pole, tak p[i] znamená nějaké místo v paměti. Čtení nebo zápis na takové místo paměti může mít fatální následky (abnormální konec programu, přepis dat, ztrátu dat,... ), indexy pole nejsou testovány za běhu programu. M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 8/43

Pole meze int a; int b[4]; int c; a b c b[0] b[1] b[2] b[3] b[0] = 10 b[4] = 20 Indexování mimo meze není za běhu programu testováno: chování programu je nedefinované, chování se může lišit podle kompilátoru a operačního systému, indexování mimo meze (out-of-bounds) se obtížně ladí. M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 9/43

Pole sekvence #include <stdio.h> #define DAYS_MAX 100 int main ( void ) { int temp[days_max], n, avg=0, i; printf ( "Napis pocet dni (1.. %d):\n", DAYS_MAX ); scanf ( "%d", &n ); printf ( "Napis teploty (%d x):\n", n ); for ( i = 0; i < n; i ++ ) scanf ( "%d", &temp[i] ); for ( i = 0; i < n; i ++ ) avg += temp[i]; avg /= n; printf ( "Prumerna teplota: %d\n", avg ); printf ( "diference:\n" ); for ( i = 0; i < n; i ++ ) printf ( "%d ", temp[i] - avg ); printf( "\n" ); return 0; M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 10/43

Pole sekvence Co když uživatel napíše počet dní větší než DAYS MAX? int readint ( int min, int max ) { int x; scanf ( "%d", &x ); while ( x < min x > max ) { printf ( "Spatne, prosim napsat znovu:"); scanf ( "%d",&x ); return x;... printf ( "Napis pocet dni (1.. %d):\n", DAYS_MAX ); n = readint ( 1, DAYS_MAX ); printf("napis teploty (%d x):\n", n );... M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 11/43

Pole sekvence Obrácení vstupu (verze s polem). #include <stdio.h> #define ARRAY_MAX 100 int main ( void ) { int arr[array_max], x, i = 0; printf ( "Napis sekvenci, maximum %d cisel, " "zakoncenou nulou\n", ARRAY_MAX ); do { scanf ( "%d", &x ); arr[i++] = x; while ( x!= 0 && i < ARRAY_MAX ); for ( i = i - 1; i >= 0; i -- ) printf ( "%d ", arr[i] ); printf ( "\n" ); return 0; M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 12/43

Pole jako tabulka V předchozích příkladech byly do poĺı uloženy sekvence. Pole mohou být použity i pro tabulky dvojice (index, hodnota). Toto mapování přiřadí hodnotě indexu příslušný prvek pole. Jednoduchý příklad Přečíst sekvenci přirozených čísel z intervalu od 1 do 100, včetně mezí, a sestavit tabulku četnosti hodnot sekvence. Tabulka bude obsahovat 100 prvků typu int. Hodnota frq[x] bude reprezentovat počet výskytů čísla x+1 v sekvenci. Tabulku deklarujeme jako globální pole, tedy její prvky budou na počátku nulové. (Globální pole ale není ideální řešení.) Použijeme dvě funkce na manipulaci s polem: readnumbers() čte prvky ze standardního vstupu a plní frekvenční tabulku, printtable() vypisuje obsah tabulky četnosti. M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 13/43

Pole jako tabulka int frq[100]; void readnumbers ( void ) { int x; printf ( "Napis cisla, zakonceni nulou\n" ); scanf ( "%d", &x ); while ( x!= 0 ) { if ( x >= 1 && x <= 100 ) frq[x-1] ++; scanf ( "%d", &x ); void printtable ( void ) { int i; for ( i = 1; i <= 100; i ++ ) if ( frq[i-1] ) printf ( "%2d vyskyt %d krat\n",i, frq[i-1] ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 14/43

Pole jako tabulka Modifikace tabulka četnosti pro rozsah od MIN do MAX #define MIN 1 #define MAX 100 int frq[max-min+1]; void readnumbers ( void ) { int x; printf ( "Napis cisla zakoncena nulou\n"); scanf ( "%d", &x ); while ( x!=0 ) { if ( x >= MIN && x <= MAX) frq[x-min] ++; scanf ( "%d", &x ); void printtable ( void ) { int i; for ( i = MIN; i <= MAX; i ++ ) if ( frq[i-min] ) printf ( "%2d vyskyt %d krat\n",i, frq[i-min] ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 15/43

Pole jako parametr funkce Problém program čte dva vektory a počítá jejich skalární součin. Dimenze vektorů jsou dány konstantou MAX. Vektory jsou čteny funkcí readvector(). void readvector (int v[], int n ) { int i; printf ( "Napis %d konponent vektoru:\n", n); for ( i = 0; i < n; i ++ ) scanf ( "%d", &v[i] ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 16/43

Pole jako parametr funkce Skalární součin počítá funkce dotproduct(): int dotproduct ( int x[], int y[], int n ) { int i, s = 0; for ( i = 0; i < n; i ++ ) s += x[i] * y[i]; return s; M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 17/43

Pole jako parametr funkce #define MAX 100 int readint( int min, int max ) {... void readvector ( int v[], int n ) {... int dotproduct( int x[], int y[], int n ) {... int main ( void ) { int x[max], y[max], n; printf ( "Pocet komponent vektoru (1.. %d):\n", MAX ); n = readint( 1, MAX ); printf ( "vektor x\n" ); readvector ( x, n ); printf ( "vektor y\n" ); readvector (y, n ); printf ( "Skalarni soucin: %d\n", dotproduct(x, y, n)); return 0; M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 18/43

Pole jako parametr funkce shrnutí Funkce deklaruje pole s prvky typu T jako parametr ve dvou variantách: T arr[] T * arr Obě možnosti jsou jak z pohledu syntaxe, tak implementace, ekvivalentní. Parametr arr slouží pro přístup k prvku pole obvyklým způsobem: arr[i] Skutečným parametrem je pole, jehož prvky musí být typu T, libovolné velikosti. M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 19/43

Pole jako parametr funkce shrnutí Funkce nezná velikost předaného pole. Parametr arr nemá tuto informaci. Hodnota parametru předaná funkci je pouze adresa pole v paměti (ukazatel na počátek pole). Pozor: sizeof ( arr ) vrací délku ukazatele, nikoli velikost pole (tj. skutečný počet prvků pole)! Pokud funkce potřebuje znát skutečný počet prvků pole, je třeba předat další parametr, třeba int nrelem. Jaký je rozdíl mezi polem parametrem funkce a výstupním parametrem? M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 20/43

Řetězce Řetězcový literál je sekvence znaků uzavřená do uvozovek: "Toto je retezec" "jeste jiny retezec\n" "Rekl \"Ahoj!\"\n" "" Reprezentace řetězců v paměti: pole znaků, prvek pole má datový typ char, řetězec je zakončen nulovým znakem (nulový bajt znak \0 ). Řetězcové proměnné: pole znaků, char astring[10] je proměnná, která může obsahovat řetězec dlouhý až 9 znaků (jeden znak je třeba pro zakončení nulovým znakem). M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 21/43

Řetězce Operace s řetězci funkce ve standardní knihovně. Hlavičkový soubor: #include <string.h> Některé důležité funkce: strcpy kopírování řetězce (nebezpečné), strcat připojení řetězce za řetězec (nebezpečné), strcmp porovnání dvou řetězců, strlen délka řetězce, strncpy kopírování řetězce (bezpečná varianta), strncat připojení řetězce za řetězec (bezpečná varianta). Společný problém nebezpečné varianty netestují, zda se výsledný řetězec vejde do cílového pole. Je-li řetězec příliš dlouhý, přepíše se pamět! M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 22/43

int main(void) { char w1[max_len], w2[max_len], gt[max_len]; printf ( "Napis prvni slovo:\n" ); scanf ( "%s", w1 ); printf ( "Napis druhe slovo:\n" ); scanf ( "%s", w2 ); /* scanf %s konverze čte slovo ze vstupu, bílé znaky (mezery, tabulátory, nové řádky) jsou oddělovače */ M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 23/43 Řetězce příklad Přečíst dvě slova. Vypsat jejich délku. Najít a vypsat lexikograficky větší slovo. #include <stdio.h> #include <string.h> #define MAX_LEN 100

Řetězce příklad printf ( "%s, delka je %d znaku\n", w1, strlen(w1)); printf ( "%s, delka je %d znaku\n", w2, strlen(w2)); if ( strcmp ( w1, w2 ) > 0 ) strcpy ( gt, w1 ); else strcpy ( gt, w2 ); printf("vetsi slovo %s\n", gt ); return 0; M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 24/43

Řetězce příklad Program může havarovat, když na vstupu bude slovo delší než 99 znaků. Tato technika se nazývá přeplnění bufferu ( buffer overflow ). Je to obecná metoda, jak se nabourat do vzdáleného systému. K zamezení této zranitelnosti je vhodné vždy omezit max. délku vstupního řetězce:... scanf ( "%99s", w1 ); /* 99 znaků max. */... Dále je dobrou technikou vždy omezit délku i při kopírovacích operacích (zde nelze zneužít k nabourání se do vzdáleného sytému, ale je to dobré obecné opatření pro bezpečnost programu):... strncpy ( gt, w1, sizeof ( gt ) ); /* strncpy místo strcpy */ M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 25/43

Řetězce příklad Slovo pozpátku: #include <stdio.h> #include <string.h> #define MAX_LEN 100 void reverse ( char w[] ); int main ( void ) { char w[max_len]; printf ("Napis slovo:\n"); scanf ( "%99s", w ); reverse ( w ); printf ( "Pozpatku: %s\n", w ); return 0; M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 26/43

Řetězce příklad void reverse ( char w[] ) { int len = strlen ( w ), last = len-1, half = len/2, i; char tmp; for (i=0; i<half; i++) { tmp = w[i]; w[i] = w[last-i]; w[last-i] = tmp; M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 27/43

Multidimenzionální pole Pole je multidimenzionální, když pro přístup k prvku jsou třeba dva nebo více indexů. Multidimenzionální pole je v C implementováno jako pole, jehož elementy jsou pole (která mají o dimenzi méně). Dvoudimenzionální pole může reprezentovat třeba matici: double mat[4][3]; matice má prvky typu double, matice má 4 řádky a 3 sloupce, matice je organizována jako pole 4 prvků, kde každým prvkem je opět pole 3 prvků, každý je hodnotou typu double. Pro přístup k prvku matice musí být použity 2 indexy: sum = 0; for ( i = 0; i < 4; i ++ ) for ( j = 0; j < 3; j ++ ) sum += mat[i][j]; /* součet všech prvků */ M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 28/43

Multidimenzionální pole příklad Vstup programu: dvě matice, obě m x n prvků. Výstup programu: součet matic. Poznámka: velikost matic musí být pevně daná (statická alokace), tudíž velikost matic je omezena na ROWS MAX x COLS MAX prvků, kde ROWS MAX a COLS MAX jsou symbolické konstanty. Program bude umět zpracovávat i menší matice, část vyhrazeného prostoru se nevyužije. Pokud bychom chtěli pracovat s maticemi libovolné velikosti, museli bychom pole alokovat dynamicky. M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 29/43

Multidimenzionální pole příklad #include <stdio.h> #define ROWS_MAX 10 #define COLS_MAX 10 int readint (int min, int max ) {... /* čte číslo ze vstupu, testuje rozsah min..max */ void readmatrix ( int mat[][cols_max], int m, int n ) {... void matrixsum (int x[][cols_max], int y[][cols_max], int z[][cols_max], int m, int n ) {... void printmatrix ( int mat[][cols_max], int m, int n) {... int main (void ) {... M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 30/43

Multidimenzionální pole příklad int main (void ) { int x[rows_max][cols_max], y[rows_max][cols_max], z[rows_max][cols_max], m, n; printf ( "Napis pocet radku (max. %d):\n", ROWS_MAX ); m = readint ( 1, ROWS_MAX ); printf ( "Napis pocet sloupcu (max. %d):\n", COLS_MAX ); n = readint ( 1, COLS_MAX ); printf ( "Prvni matice:\n" ); readmatrix (x, m, n ); printf ( "Druha matice:\n" ); readmatrix ( y, m, n); matrixsum (x, y, z, m, n); printf ( "Vysledek:\n" ); printmatrix (z, m, n ); return 0; M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 31/43

Multidimenzionální pole příklad void readmatrix ( int mat[][cols_max], int m, int n ) { int r, c; printf ( "Napis %d x %d celych cisel\n", m, n ); for ( r = 0; r < m; r ++ ) for ( c = 0; c < n; c ++ ) scanf ( "%d", &mat[r][c] ); void printmatrix ( int mat[][cols_max], int m, int n ) { int r, c; for ( r = 0; r < m; r ++ ) { for ( c = 0; c < n; c ++ ) printf ( "%5d ", mat[r][c] ); printf ( "\n" ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 32/43

Multidimenzionální pole příklad void matrixsum (int x[][cols_max], int y[][cols_max], int z[][cols_max], int m, int n) { int r, c; for ( r = 0; r < m; r ++ ) for (c = 0; c < n; c ++ ) z[r][c] = x[r][c] + y[r][c]; M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 33/43

Minimální a maximální prvek pole Najít nejmenší a největší prvek při použití co nejmenšího možného počtu porovnání. #include <stdio.h> void dump ( int arr[], int lng ) { int i; for ( i = 0; i < lng; i++ ) printf ( "[%2d]=%5d\n", i, arr[i] ); int main ( void ) { int min, max; int a[] = {1, 4, 5, 78, -100, 45, 28, 34, 5; /* počet prvků pole a: sizeof ( a ) / sizeof ( a[0] ) */ dump ( a, sizeof ( a ) / sizeof ( a[0] ) ); minmax ( a, sizeof ( a )/ sizeof ( a[0] ), &min, &max ); printf ( "Max: %d,\nmin %d\n", max, min ); return 0; M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 34/43

Minimální a maximální prvek pole void minmax1 ( int arr[], int len, int *min, int *max ) { int i; *min = *max = arr[0]; for (i = 1; i < len; i ++ ) { if ( arr[i] > *max ) *max = arr[i]; if ( arr[i] < *min ) *min = arr[i]; Kolik porovnání je v nejlepším případě? Kolik porovnání je v nejhorším případě? Co když len == 0? M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 35/43

Minimální a maximální prvek pole void minmax2 ( int arr[], int len, int *min, int *max ) { int i; *min = *max = arr[0]; for ( i = 1; i < len; i ++ ) { if ( arr[i] > *max ) *max = arr[i]; else if ( arr[i] < *min ) *min = arr[i]; Kolik porovnání je v nejlepším případě? Kolik porovnání je v nejhorším případě? {1,2,10,20,50,100 {10,3,0,-7,-200 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 36/43

Minimální a maximální prvek pole void minmax3 ( int arr[], int len, int *min, int *max ) { int i; if ( arr[0] > arr[1] ) { *max = arr[0]; *min = arr[1]; else { *max = arr[1]; *min = arr[0]; for ( i = 2 - len % 2; i < len - 1; i += 2 ) if ( arr[i] > arr[i + 1] ) { if ( arr[i] > *max ) *max = arr[i]; if ( arr[i + 1] < *min ) *min = arr[i + 1]; else { if ( arr[i + 1] > *max ) *max = arr[i + 1]; if ( arr[i] < *min ) *min = arr[i]; Kolik porovnání je v nejlepším případě? Kolik porovnání je v nejhorším případě? Co když je len je liché? A co když len == 1? M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 37/43

Eratosthénovo síto Problém: nalézt prvočísla menší než zadané n. Naivní řešení: zkusit pro každé číslo, zda je či není prvočíslo. Eratosthénes z Kyrény (276-194 př.n.l.): vylepšený algoritmus, který eliminuje složená čísla. M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 38/43

Eratosthénovo síto Problém: nalézt prvočísla menší než zadané n. Naivní řešení: zkusit pro každé číslo, zda je či není prvočíslo. Eratosthénes z Kyrény (276-194 př.n.l.): vylepšený algoritmus, který eliminuje složená čísla. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 prime 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 38/43

Eratosthénovo síto Problém: nalézt prvočísla menší než zadané n. Naivní řešení: zkusit pro každé číslo, zda je či není prvočíslo. Eratosthénes z Kyrény (276-194 př.n.l.): vylepšený algoritmus, který eliminuje složená čísla. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 prime 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 38/43

Eratosthénovo síto Problém: nalézt prvočísla menší než zadané n. Naivní řešení: zkusit pro každé číslo, zda je či není prvočíslo. Eratosthénes z Kyrény (276-194 př.n.l.): vylepšený algoritmus, který eliminuje složená čísla. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 prime 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 38/43

Eratosthénovo síto Problém: nalézt prvočísla menší než zadané n. Naivní řešení: zkusit pro každé číslo, zda je či není prvočíslo. Eratosthénes z Kyrény (276-194 př.n.l.): vylepšený algoritmus, který eliminuje složená čísla. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 prime 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 38/43

Eratosthénovo síto Problém: nalézt prvočísla menší než zadané n. Naivní řešení: zkusit pro každé číslo, zda je či není prvočíslo. Eratosthénes z Kyrény (276-194 př.n.l.): vylepšený algoritmus, který eliminuje složená čísla. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 prime 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 38/43

Eratosthénovo síto Problém: nalézt prvočísla menší než zadané n. Naivní řešení: zkusit pro každé číslo, zda je či není prvočíslo. Eratosthénes z Kyrény (276-194 př.n.l.): vylepšený algoritmus, který eliminuje složená čísla. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 prime 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 38/43

Eratosthénovo síto algoritmus 1 Na voskovou destičku napiš čísla 1 až n. 2 Vypal číslo 1 horkou jehlou. 3 Začni od x = 2, toto je prvočíslo. 4 Vypal horkou jehlou všechny násobky x. 5 Ukonči se, pokud již neexistuje větší číslo. 6 Nalezni další větší nevypálené číslo x, toto číslo je prvočíslo. Pokračuj bodem 4. Který první násobek x budeme v bodě 4 vypalovat? M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 39/43

Eratosthénovo síto algoritmus 1 Na voskovou destičku napiš čísla 1 až n. 2 Vypal číslo 1 horkou jehlou. 3 Začni od x = 2, toto je prvočíslo. 4 Vypal horkou jehlou všechny násobky x. 5 Ukonči se, pokud již neexistuje větší číslo. 6 Nalezni další větší nevypálené číslo x, toto číslo je prvočíslo. Pokračuj bodem 4. Který první násobek x budeme v bodě 4 vypalovat? 2x M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 39/43

Eratosthénovo síto algoritmus 1 Na voskovou destičku napiš čísla 1 až n. 2 Vypal číslo 1 horkou jehlou. 3 Začni od x = 2, toto je prvočíslo. 4 Vypal horkou jehlou všechny násobky x. 5 Ukonči se, pokud již neexistuje větší číslo. 6 Nalezni další větší nevypálené číslo x, toto číslo je prvočíslo. Pokračuj bodem 4. Který první násobek x budeme v bodě 4 vypalovat? 2x 3x M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 39/43

Eratosthénovo síto algoritmus 1 Na voskovou destičku napiš čísla 1 až n. 2 Vypal číslo 1 horkou jehlou. 3 Začni od x = 2, toto je prvočíslo. 4 Vypal horkou jehlou všechny násobky x. 5 Ukonči se, pokud již neexistuje větší číslo. 6 Nalezni další větší nevypálené číslo x, toto číslo je prvočíslo. Pokračuj bodem 4. Který první násobek x budeme v bodě 4 vypalovat? 2x 3x x 2 Pro jaké x budeme naposledy vypalovat nějaké číslo? M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 39/43

Eratosthénovo síto algoritmus 1 Na voskovou destičku napiš čísla 1 až n. 2 Vypal číslo 1 horkou jehlou. 3 Začni od x = 2, toto je prvočíslo. 4 Vypal horkou jehlou všechny násobky x. 5 Ukonči se, pokud již neexistuje větší číslo. 6 Nalezni další větší nevypálené číslo x, toto číslo je prvočíslo. Pokračuj bodem 4. Který první násobek x budeme v bodě 4 vypalovat? 2x 3x x 2 Pro jaké x budeme naposledy vypalovat nějaké číslo? n 2 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 39/43

Eratosthénovo síto algoritmus 1 Na voskovou destičku napiš čísla 1 až n. 2 Vypal číslo 1 horkou jehlou. 3 Začni od x = 2, toto je prvočíslo. 4 Vypal horkou jehlou všechny násobky x. 5 Ukonči se, pokud již neexistuje větší číslo. 6 Nalezni další větší nevypálené číslo x, toto číslo je prvočíslo. Pokračuj bodem 4. Který první násobek x budeme v bodě 4 vypalovat? 2x 3x x 2 Pro jaké x budeme naposledy vypalovat nějaké číslo? n 2 n 3 M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 39/43

Eratosthénovo síto algoritmus 1 Na voskovou destičku napiš čísla 1 až n. 2 Vypal číslo 1 horkou jehlou. 3 Začni od x = 2, toto je prvočíslo. 4 Vypal horkou jehlou všechny násobky x. 5 Ukonči se, pokud již neexistuje větší číslo. 6 Nalezni další větší nevypálené číslo x, toto číslo je prvočíslo. Pokračuj bodem 4. Který první násobek x budeme v bodě 4 vypalovat? 2x 3x x 2 Pro jaké x budeme naposledy vypalovat nějaké číslo? n n 2 n 3 Časová složitost: T (n) O(n log(log(n))), kde n je horní mez. Časová složitost: T (b) O(2 b log(b)), kde b je počet bitů na vstupu (b = log 2 (n) ). M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 39/43

Eratosthénovo síto implementace #include <stdio.h> #include <stdlib.h> #include <math.h> #define MAX 1000000 void sieve ( char set[], int max ); void print ( char set[], int max ); int count ( char set[], int max ); int main ( void ) { char set [MAX]; sieve ( set, MAX ); printf( "Prvocisla od 2 do %d:\n", MAX ); print ( set, MAX ); printf( "Celkem %d prvocisel\n", count ( set, MAX ) ); return 0; M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 40/43

Eratosthénovo síto implementace void sieve ( char set[], int max ) { int i, p = 2, pmax = (int) sqrt ( max ); /* všechna čísla jsou kandidáti */ for (i = 0; i < max; i ++ ) set[i] = 1; set[0] = set[1] = 0; /* 0 a 1 nejsou prvočísla */ do { for ( i = p*p; i < max; i += p ) set[i] = 0; /* škrtání násobků */ /* Hledáme další prvočíslo */ do { p++; while (!set[p] ); while ( p <= pmax ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 41/43

Eratosthénovo síto implementace void sieve ( char set[], int max ) { int i, p = 2, pmax = (int) sqrt ( max ); /* všechna čísla jsou kandidáti */ for (i = 0; i < max; i ++ ) set[i] = 1; set[0] = set[1] = 0; /* 0 a 1 nejsou prvočísla */ do { for ( i = p*p; i < max; i += p ) set[i] = 0; /* škrtání násobků */ /* Hledáme další prvočíslo */ do { p++; while (!set[p] ); while ( p <= pmax ); Je hledání dalšího prvočísla vždy bezpečné? M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 41/43

Eratosthénovo síto implementace int count ( char set[], int max) { int i, res = 0; for (i = 2; i < max; i++ ) res += set[i]!= 0; return res; void print ( char set[], int max) { int i, res = 0; for (i = 2; i < max; i++ ) if ( set[i] ) printf ( " %d", i ); printf ( "\n" ); M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 42/43

Otázky a odpovědi Otázky... M. Baĺık, L. Vagner a J. Vogel, ČVUT FIT Pole, BI-PA1 43/43