Algoritmus
Tvorba algoritmů S algoritmy se setkáváme v běžném životě. Těmito algoritmy jsou například recepty na vaření, postup ovládání video kamery, cesta do školy.
Vlastnosti algoritmů "HERgoD"
Program
Ke kreslení vývojových diagramů používáme standardní grafické symboly:
Jednotlivé značky spojujeme čárami a spojkami:
Integrované vývojové prostřední (IDE - integrated development enviroment) = soubor programů, které si volám podle toho, co potřebuju.
EPiC LeaDeR:
Příkazy pro něj začínají "#" typicky incude: když ho najde, vyhodí ten řádek a vloží tam tu dotyčnou knihovnu.
V hlavičkových souborech nejčastěji: deklarace fcí, maker, konstant. "<>" zobáčky znamenají, že se includy hledají v defaultním místě standartních inkludů.
Jiná možnost: napsat do uvozovek - hledá se v aktuálním adresáři: "C:\prg\headfile.h" nedávají se znaky "\" dvakrát, bo to není string!
Přeloží každý soubor programu - výsledkem je *.OBJ (object module - binární soubor) v TurboC++, DevC++ *.o. V OBJ nejsou odvolávky z knihoven, kontroluje syntaktické chyby. Tyto soubory si předávají členové týmu, protože neodhaluje know-how.
Poskládá OBJ moduly s knihovnami a vytvoří *.exe soubor. Také vkládá absolutní adresy paměti.
Ladící prostředek součástí IDE. Hledá běhové chyby při spuštěném programu.
Umí breakpointy a skoky po instrukcích.
Příkaz if provádí příkazy podle toho, zda byla nebo nebyla splněna zadaná podmínka.
if (x == 0) printf("Proměnná x je nula.\n");
if (x > 0) printf("x je kladné\n"); else printf("x není kladné\n");
Příkaz switch slouží k větvení programu do libovolného počtu větví v závislosti na předaném celočíselném výrazu. Jednotlivé větve tohoto příkazu se provádějí, má-li předaný výraz jim odpovídající hodnotu. Nelze zde tedy vytvářet libovolné podmínky. V konstrukci switch lze od selektoru definovat také default větev, která se bude provádět, pokud výraz nenabude žádné z uvedených hodnot.
switch (cislo){ case 1: printf("cislo je 1\n"); break; case 2: printf("cislo je 2\n"); break; default: printf("neco jineho\n"); }
Vynecháním příkazů break na konci jednotlivých větví je pokračuje v provádění dalších větví.
switch (cislo){ case 1: case 2: printf("cislo je 1 nebo 2\n"); break; default: printf("neco jineho\n"); }
má stejný význam jako příkaz if-else, jen syntaxe je jiná. Ternární, protože má jako jediný operátor 3 operandy.
vyraz_podm ? vyraz_1 : vyraz_2;
i = (a != 0) ? 5 : 10; // Pokud je a ruzne od 0, i bude rovno 5 // V opacnem pripade bude i rovno 10
Grafický zápis vývojového diagramu je dán státní normou. Pokud je větvení neúplné, pak na straně, kde podmínka neplatí je prázdno.
Cykly jsou strukturované příkazy, které při splnění (nebo nesplnění) podmínky provádí příkazy obsažené v tělě cyklu znovu a znovu. Jednotlivé průchody tělem cyklu označujeme
jako iterace.
Někdy potřebujeme provádění cyklu ukončit předčasně. K tomu můžeme použít příkaz break.
Jestliže potřebujeme předčasně ukončit jednotlivou iteraci (vynechat při průchodu zbytek těla cyklu), můžeme použit příkaz continue.
Příkaz while představuje cyklus s podmínkou na počátku.
while ( podmínka ) příkaz
Kde příkaz je tělo cyklu. Podmínka je výraz, který lze implicitně převést na typ bool. Podmínka může obsahovat deklaraci proměnné (jen v C++) a tato proměnná bude lokální v těle cyklu.
Význam příkazu while:
Nejprve se vyhodnotí podmínka. Je-li nepravdivá, tělo cyklu se neprovede a provádění příkazu while skončí.
Je-li podmínka splněna, provede se příkaz tvořící tělo cyklu. Poté se opět vyhodnotí podmínka atd.
Podmínka opakování se tedy vyhodnocuje před každou iterací. Není-li podmínka před prvním průchodem splněna, neprovede se tělo cyklu while ani jednou.
Zkráceně označovaný jako příkaz do. Je to cyklus s podmínkou na konci.
do příkaz while ( podmínka );
Podmínka je výraz, který lze implicitně převést na typ bool. Výraz zde nemůže obsahovat deklaraci!
Význam příkazu do:
Nejprve proběhne tělo cyklu, tedy příkaz. Pak se vyhodnotí výraz. Pokud je roven false, znamená to, že podmínka opakování není splněna
a provádění příkazu do skončí. V opačném případě se opět provede tělo cyklu a znovu se testuje podmínka opakování atd. To znamená, že tělo cyklu se
provede vždy alespoň jednou.
for ( inicializační_příkaz ; podmínka ; krok ) příkaz
Inicializační_příkaz je příkaz, který chceme provést před vstupem do cyklu. Může obsahovat deklaraci (C++) a může být prázdný
(tj. obsahuje pouze středník).
Podmínka může obsahovat deklaraci a také zde můžeme zapsat prázdný výraz.
Krok předepisuje změny proměnných,
které je třeba po průchodu tělem cyklu udělat. I tento výraz může být prázdný.
Proměnné, deklarované v inicializačním_příkazu a v podmínce, jsou lokální v těle cyklu. Přesněji: Proměnné, deklarované v inicializačním_příkazu,
můžeme použít v podmínce, v kroku a v těle cyklu. Proměnné, deklarované v podmínce, můžeme použít v kroku a v těle cyklu.
Příklad: Příkaz for se často používá při zpracování polí. Chceme-li např. vynulovat všechny prvky pole A o 100 prvcích, napíšeme:
const N = 100; int A [N] ; // ... for(int i = 0; i < N; i++) A[i] = 0;
for (;;) { //nekonečný cyklus; }
while(1) { //nekonečný cyklus; }
Tento příkaz smíme použít jen v těle cyklu (for, while, do) nebo v těle příkazu switch; vvskytne-li se jinde, ohlásí překladač chybu.
Význam příkazu break:
Ukončuje nejvnitřnější neuzavřenou smyčku a hned opouští cyklus. A také obsáhleji:
Příkaz break způsobí ukončení příkazu cyklu nebo přepínače (switch), v jehož těle se vyskytl. Při několika do sebe vnořených příkazech
do, while, for nebo switch způsobí ukončení nejvnitmějšího z nich, který tento příkaz break obklopuje.
Příkaz umožňuje předčasně ukončit daný průchod tělem cyklu (iteraci). Smí se vyskytnout pouze v těle cyklu (v příkazech for, do a while).
Jeho použití kdekoliv jinde způsobí chybu.
Význam příkazu continue:
Skáče na konec nejvnitřnější neuzavřené smyčky a tím vynutídalší iteraci smyčky, cyklus neopouští. Také:
Příkaz continue přenese řízení na pokračovací část nej vnitřnějšího příkazu while, do nebo for, v jehož těle se vyskytl. To znamená,
že ukončí právě probíhající iteraci a způsobí vyhodnocení podmínky pro pokračování (a v cyklu for ještě reinicializaci, tedy vyhodnocení výrazu).
Význam příkazu return:
Příkaz return ukončí provádění těla funkce, v níž se nachází, a vrátí řízení funkci volající.
První varianta, ve které není uveden výraz, se používá ve funkcích typu void (které nevracejí žádnou hodnotu, tedy v procedurách).
Uvedeme-li výraz, vrátí funkce hodnotu tohoto výrazu. Typ výrazu musí být možné implicitně převést na typ vracené hodnoty uvedený v deklaraci funkce,
podobně jako např. při přiřazení.
Funkce typu void nemusí příkaz return obsahovat. Dojde-li řízení v těle funkce až ke složené závorce „}“ ukončující její tělo, je to stejné, jako kdyby zde byl zapsán příkaz return; (bez výrazu).
Z funkcí jiného typu (tj. z funkcí, které vracejí nějakou hodnotu) se musíme vždy vrátit pomocí příkazu return s výrazem odpovídajícího typu.
Co určuje datový typ:
Tvoří dvě základní skupiny — typy „se znaménkem“ a „bez znaménka“. Celočíselné typy se znaménkem mohou obsahovat jak kladná tak i záporná čísla,
zatímco typy bez znaménka mohou obsahovat pouze kladná čísla a 0.
Celočíselné typy se znaménkem jsou signed char, short, int a long a ještě typ long long.
Celočíselné typy bez znaménka jsou unsigned char. unsigned short. unsigned. unsigned long a unsigned long long.
int má délku podle kompilátoru a to:
V jazyce C++ máme k disposici 4 znakové typy
Typy char, unsigned char a signed char zabírají 1 B a slouží především pro práci s evropskými znaky. Typ wchar.t zabírá typicky 2B nebo 4B a používá se pro práci s asijskými znaky nebo s kódem UNICODE.
Se znaky zacházíme podobně jako s ostatními celočíselnými typy, to znamená, že je můžeme používat ve výrazech podobně jako celá čísla. Jediný zásadní rozdíl se týká vstupů a výstupů znaků pomocí objektových datových proudů (cin. cout atd.), kdy se hodnoty znakových typů chovají opravdu jako znaky, nikoli jako čísla.
Tyto typy specifikují určité konečné podmnožiny množiny reálných čísel. V paměti jsou tato čísla zpravidla uložena ve tvaru odvozeném od
semilogaritmického zápisu, tedy od zápisu, jako je 6,27 x 10^12. (Počítač ovšem samozřejmě využívá dvojkovou soustavu.) Číslo 6,27 zde nazýváme "mantisa",
číslo 12 "exponent". V C++ můžeme pro práci s reálnými čísly používat typy float, double a long double.
Způsob pro zavedení nového datového typu založeného na struktuře lze provést pomocí klíčového slova typedef.
Nejúplnější definice vypadá takto:
typedef struct clovek { char jmeno[50]; int vek; double hmotnost, vyska; }CLOVEK;
Kde clovek je název struktury a CLOVEK název nového datového typu. Jinými slovy slovní spojení struct clovek vyjadřuje totéž, co jedno slovo CLOVEK a výše definované proměnné nyní mohu zavést i takto:
CLOVEK Jenda, Bara;
Při použití typedef je třeba pojmenovat strukturu pouze v případě, že by některou z jejích složek byl pointer na ni samu. Jinak lze název struktury vynechat.
Položka dané struktury nemůže být právě vytvářeného datového typu přesněji název typu každé položky musí být různý od jména struktury, která ji obsahuje,
či od jména právě vytvářeného typu. Položka však může být typu pointer na strukturu ve které je obsažena (nikoli však pointer na typ,
který vytváříme pomocí typedef ).
K jednotlivým položkám proměnných tohoto typu pak přistupuji takto:
strcpy(p_Bara->jmeno, "Bára Zvučná"); //nebo p_Bara->JMENO = "Bára Zvučná"; p_Bara->vek = 20; printf("%d",p_Bara->vek);
enum den { pondeli, utery = 22, streda, ctvrtek, patek , sobota }; den dnes = streda;
Enum umožňuje pojmenovat číselné výrazy, např. dny v týdnu.
struct Zamestanec { char jmeno[20]; char prijmeni[30]; unsigned plat; };
union DoubleInt { double d; int i; } di;
Jako struktura, ale pamatuje si pouze prvek, který byl nejpozději změněn.
FILE *fw;
Poměnné — tedy pojmenovaná místa v paměti, do kterých ukládáme nějaké hodnoty. Každou proměnnou je třeba deklarovat, tj. oznámit překladači, jak se bude jmenovat a jaké hodnoty do ní budeme ukládat (jakého bude typu).
Bude dostupná ve všech funkcích v programu za místem své deklarace.
Jejich platnost je omezena na tělo funkce.
Inicializace při deklaraci znamená, že jsme proměnné přidělili počáteční hodnotu.
Alokace paměti je vymezení místa v paměti pro proměnnou. Každé proměnné musí být během své existence přidělen paměťový prostor, který je dán datovým typem.
Jméno proměnné je vlastně symbolická adresa tohoto prostoru.
Implicitní paměťová třída pro lokální proměnné. Ukládají se na zásobník. Při každém vstupu má náhodnou hodnotu, proměnná existuje od vstupu do funkce a zaniká výstupem.
Neexistuje implicitní definice. (nutné vždy uvést) Tato PT je uložena v datové oblasti. Využívají lokální proměnné uvnitř funkcí - ponechají si svou
hodnotu mezi jednotlivými voláními funkce.
Existuje od prvního volání funkce až do ukončení programu. Není přístupná z vnějšku funkce.
Globální proměnné a funkce mohou být static, pak jsou viditelné jen v modulu, kde jsou definovány.
static int a; static float f,g; //g není static!
Při prvním volání fce() se x vynuluje při každém volání funkce FCE se hodnota q zvýší o 1.
Implicitní PT pro globální proměnné. Je uložena v datové oblasti. Používá se pro oddělený překlad souborů. (2 a více souborů sdílí tuto proměnnou). V jednom souboru nemusí být "extern", ve všech ostatních musí toto klíčové slovo být.
Proměnná uložena pouze v registru CPU (jen jestli je volný), velmi rychlá, nedá se přesně určit, kde se uloží. Výhradně jako lokální proměnná.
Struktura programu:
Vlastní knihovna musí být ve stejném adresáři jako program.
funkce.h
void funkce(void);
funkce.c
void funkce(void) { /* ... */ }
main.c
#include "funkce.h" int main(void) { funkce(); return 0; }
Souboru main.c v našem příkladu neodpovídá žádný main.h, neboť v main.c neposkytujeme žádné funkce ani proměnné k použití z jiných souborů.
Když tvořím třídu, deklaraci píšu do souboru s příponou h, do cpp píšu definici (metody).
class Trida { private: // zde vidi jen objekty tridy int i; protected: // zde vidi jen objekty teto a zdedenych trid float f: public: Trida(); // implicitni konstruktor
~Trida(); //destruktor void nacti(); // deklarace fce - definice radeji na konci programu };