POČÍTAČE A PROGRAMOVÁNÍ 2



Podobné dokumenty
Algoritmizace a programování

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

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

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

5 Přehled operátorů, příkazy, přetypování

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

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

Programovací jazyk Pascal

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

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

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

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

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í. Lekce 1

1.1 Struktura programu v Pascalu Vstup a výstup Operátory a některé matematické funkce 5

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

Operátory, výrazy. Tomáš Pitner, upravil Marek Šabo

ALGORITMIZACE A PROGRAMOVÁNÍ

Formátové specifikace formátovací řetězce

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

Jak v Javě primitivní datové typy a jejich reprezentace. BD6B36PJV 002 Fakulta elektrotechnická České vysoké učení technické

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

Logické operace. Datový typ bool. Relační operátory. Logické operátory. IAJCE Přednáška č. 3. může nabýt hodnot: o true o false

Základní vzorce a funkce v tabulkovém procesoru

DUM 06 téma: Tvorba makra pomocí VBA

Algoritmizace prostorových úloh

Proměnná. Datový typ. IAJCE Cvičení č. 3. Pojmenované místo v paměti sloužící pro uložení hodnoty.

Úvod do programovacích jazyků (Java)

KAPITOLA 9 - POKROČILÁ PRÁCE S TABULKOVÝM PROCESOREM

Data v počítači. Informační data. Logické hodnoty. Znakové hodnoty

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

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

Objektově orientované programování

Základy algoritmizace a programování

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

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

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

VYTVÁŘENÍ DATABÁZÍ, VKLÁDÁNÍ ÚDAJŮ

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ý

7. Datové typy v Javě

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

8 Třídy, objekty, metody, předávání argumentů metod

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

Vzorce. StatSoft. Vzorce. Kde všude se dá zadat vzorec

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

Algoritmizace a programování

Tabulkový procesor. Základní rysy

Vektory a matice. Obsah. Aplikovaná matematika I. Carl Friedrich Gauss. Základní pojmy a operace

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

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

Základy algoritmizace a programování

přetížení operátorů (o)

Michal Krátký. Úvod do programovacích jazyků (Java), 2006/2007

Zápis programu v jazyce C#

Sada 1 - Základy programování

Pascal. Katedra aplikované kybernetiky. Ing. Miroslav Vavroušek. Verze 7

MAXScript výukový kurz

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

Programovací jazyk C++ Hodina 1

Stěžejní funkce MS Excel 2007/2010, jejich ovládání a možnosti využití

Obr. P1.1 Zadání úlohy v MS Excel

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

Přílohy. Příloha 1. Obr. P1.1 Zadání úlohy v MS Excel

Algoritmizace. 1. Úvod. Algoritmus

Datové typy strana 29

EVROPSKÝ SOCIÁLNÍ FOND. Úvod do PHP PRAHA & EU INVESTUJEME DO VAŠÍ BUDOUCNOSTI

- speciální symboly + - * / =., < > <> <= >= a další. Klíčová slova jsou chráněnými útvary, které nelze použít ve významu identifikátorů.

- znakové konstanty v apostrofech, např. a, +, (znak mezera) - proměnná zabírá 1 byte, obsahuje kód příslušného znaku

Fz =a z + a z +...+a z +a z =

Reprezentace dat v informačních systémech. Jaroslav Šmarda

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í

Úvod do programování 7. hodina

Inovace a zkvalitnění výuky prostřednictvím ICT Základy programování a algoritmizace úloh. Ing. Hodál Jaroslav, Ph.D. VY_32_INOVACE_25 09

Programování v jazyce C a C++

1. Základní pojmy a číselné soustavy

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

Stručný návod k programu Octave

Algoritmizace a programování

Algoritmizace prostorových úloh

Čtvrtek 3. listopadu. Makra v Excelu. Obecná definice makra: Spouštění makra: Druhy maker, způsoby tvorby a jejich ukládání

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.

5a. Makra Visual Basic pro Microsoft Escel. Vytvořil Institut biostatistiky a analýz, Masarykova univerzita J. Kalina

Algoritmizace prostorových úloh

STATISTICA Téma 1. Práce s datovým souborem

PHP tutoriál (základy PHP snadno a rychle)

Číselné soustavy v mikroprocesorové technice Mikroprocesorová technika a embedded systémy

Operátory. Základy programování 1 Tomáš Kühr

Programování v jazyce JavaScript

6. blok část C Množinové operátory

PŘETĚŽOVÁNÍ OPERÁTORŮ

DSL manuál. Ing. Jan Hranáč. 27. října V této kapitole je stručný průvodce k tvorbě v systému DrdSim a (v

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

1. D Y N A M I C K É DAT O V É STRUKTUR Y

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

Vytvoření tiskové sestavy kalibrace

DUM 07 téma: Proměnné, konstanty a pohyb po buňkách ve VBA

Sada 1 - Základy programování

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

WSH Windows Script Hosting. OSY 2 Přednáška číslo 2 opravená verze z

Transkript:

POČÍTAČE A PROGRAMOVÁNÍ 2 Přednášky Zbyněk Raida, Irena Hlavičková, Michal Pokorný a další ÚSTAV RADIOELEKTRONIKY

POČÍTAČE A PROGRAMOVÁNÍ 2 Přednášky Zbyněk Raida, Irena Hlavičková, Michal Pokorný a další ÚSTAV RADIOELEKTRONIKY

Zbyněk Raida, Irena Hlavičková, Michal Pokorný, 2007 ISBN 978-80-214-3536-0

Název POČÍTAČE A PROGRAMOVÁNÍ 2 Přednášky Autoři Vydavatel Vydání Prof. Dr. Ing. Zbyněk Raida Mgr. Irena Hlavičková Ing. Michal Pokorný Vysoké učení technické v Brně Fakulta elektrotechniky a komunikačních technologií Ústav radioelektroniky Purkyňova 118, 612 00 Brno druhé, přepracované Rok vydání 2007 Náklad Tisk 400 ks MJ Servis s.r.o., Kouty 16, 621 00 Brno ISBN 978-80-214-3536-0 Tato publikace neprošla redakční ani jazykovou úpravou

obsah Obsah 1 Úvod... 7 1.1 Programování... 7 1.2 Borland C++ Builder první pohled... 10 2 Jazyk C... 13 3 Identifikátory, typy dat, proměnné... 14 3.1 Lokální a globální proměnné... 14 3.2 Pravidla deklarování proměnných... 15 3.3 Základní typy proměnných... 16 3.4 Ukazatele... 17 3.5 Pole... 18 4 Výrazy, operátory, konverze... 22 4.1 Aritmetické konverze... 22 4.2 Priorita operací... 23 4.3 Aritmetické operátory... 24 4.4 Relační operátory... 25 4.5 Logické operátory... 27 4.6 Bitové operátory... 28 4.7 Operátory inkrementování a dekrementování... 29 4.8 Přiřazovací operátory... 30 5 Řetězce, ukazatele... 31 6 Příkazy... 38 6.1 Příkazy pro větvení programu... 39 6.2 Příkazy pro cykly... 41 6.3 Příkazy pro přenos řízení... 43 6.4 Příklad... 44 6.5 Abecední seznam příkazů... 47 7 Funkce... 48 7.1 Programové jednotky, hlavičkové soubory... 54 7.2 Rekurze funkcí... 57 8 Pokročilé datové typy... 59 8.1 Struktury... 59 8.2 Unie... 60 8.3 Výčtové typy... 61 8.4 Dynamické proměnné... 62-5 -

obsah 8.5 Příklad Auta... 63 8.6 Příklad Žáci... 65 9 Struktury ve Windows... 68 9.1 Borland C++ Builder druhý pohled... 68 9.2 Vývoj aplikace pro Windows... 71 9.3 Seznam počítačů... 76 9.4 Struktury v C++... 82 10 Matice ve Windows... 83 10.1 Sčítání a inverze... 83 10.2 Uživatelské rozhraní... 85 11 Grafika ve Windows... 88 11.1 Kreslení grafů... 93 11.2 Tvary... 95 12 MDI aplikace... 97 13 Práce se soubory... 100 14 Příklady... 103 14.1 Stavový automat... 103 14.2 Interaktivní vykreslování přenosové charakteristiky filtru... 106 15 Literatura... 113-6 -

úvod 1 Úvod Předmět Počítače a programování 2 (ve zkratce BPC2) je vyučován v letním semestru prvního ročníku bakalářského studia. Předmět je společný všem oborům studijního programu Elektrotechnika, elektronika, komunikační a řídicí technika. Základním cílem předmětu je naučit se programovat v jazyku C. Tento jazyk je v současnosti používán pro programování mikroprocesorů řídících vše od vysavače přes měřicí přístroj po jednotlivé subsystémy moderního auta. Jazyk C se používá pro vývoj všemožných aplikací pro Windows i LINUX. Jazyk C je zkrátka všude. S jazykem C se budeme seznamovat prostřednictvím vývojového nástroje Borland C++ Builder. Dvouměsíční licenci programu lze získat zdarma na www.borland.com. Každý se tak může s programováním v jazyce C seznamovat sám doma s využitím legálního software. Programovací jazyk je jazykem stejným jako každý jiný. Naučit se anglicky je dřina a s jazykem C je to stejné. Bez toho, že by člověk hodiny programoval, o programech přemýšlel a zkoušel stejnou věc naprogramovat lépe a lépe, to zkrátka nejde. Přejeme tedy otevřenou mysl a spoustu trpělivosti. Předkládané skriptum vzniklo po několikaleté zkušenosti s výukou jazyka C na FEKT VUT v Brně. S jeho psaním pomohli Ilona Lázničková, Lukáš Oliva, Miloš Richter a mnoho dalších. Všichni se snažíme učit jazyk C co možná nejlépe a nejzajímavěji. Snad se to alespoň trochu daří. 1.1 Programování Pod pojmem programování rozumíme psaní textu, který procesoru počítače jednoznačně říká, co má dělat a jak. Psaní programu můžeme rozdělit do následujících kroků: 1. Sestavení algoritmu. Na základě zadaného úkolu navrhneme postup (sestavíme algoritmus), jakým lze danou úlohu vyřešit. Algoritmus obvykle vyjadřujeme blokovým schématem. Na pevném disku počítače máme v souboru teplo.dat uloženy teploty, které byly během předchozího dne naměřeny v každou celou hodinu. Našim úkolem je určit tu hodinu, kdy byla teplota nejnižší. Soubor tedy otevřeme a data z něj uložíme do sady proměnných souhrnně označených jako temp (temperature, teplota). Dále si vytvoříme pomocnou proměnnou min_temp (minimum temperature) a uložíme start temp teplo.dat min_temp 900 m 1 min_temp >temp(m) ANO NE min_temp teplo(m) min_time m m<25 m m + 1 ANO NE konec Obr. 1.1 Algoritmus hledání nejnižší teploty - 7 -

úvod do ní nerealisticky vysokou teplotu 900 C. Obsah proměnné min_temp budeme postupně porovnávat s jednotlivými zaznamenanými teplotami (na právě porovnávaný obsah proměnné ze sady temp ukazuje index m). Pokud je některá zaznamenaná teplota nižší nežli obsah min_temp (větev ANO) uložíme tuto hodnotu do min_temp, a současně do proměnné min_time uložíme pořadí daného čísla (dané teploty) v souboru teplot; pořadí čísla v souboru totiž odpovídá hodině, kdy byla teplota naměřena. V opačném případě (testovaná teplota ze souboru je vyšší nežli obsah min_temp) se nic neděje. Jakmile projdeme všechna čísla v souboru (index m je větší než počet hodin dne), budeme mít v proměnné min_temp údaj o nejnižší naměřené teplotě a v proměnné min_time údaj o hodině, kdy byla tato teplota naměřena. Popsaný algoritmus lze vyjádřit blokovým schématem z obr. 1.1 1. 2. Zapsání algoritmu v programovacím jazyku. Na základě přesně daných pravidel jazyka (tzv. syntaxe) napíšeme text (tzv. zdrojový kód), který překladač programovacího jazyka umí přeložit do kódu strojového do kódu, kterému rozumí procesor počítače. Pokud se rozhodneme algoritmus pro vyhledávání nejnižší teploty (obr. 1.1) vyjádřit v jazyku C, může zdrojový kód algoritmu vypadat následovně 2 : #include <conio.h> void main( void) // pole teplot; první údaj naměřen v 1:00, poslední údaj // naměřen ve 24:00 float temp[24] = -8.1, -8.3, -8.6, -9.2, -9.4, -9.2, -9.0, -8.5, -7.9, -6.7, -5.0, -2.3, +1.1, +2.3, +1.2, -0.8, -2.6, -4.1, -5.2, -6.3, -7.7, -8.5, -9.1, -9.3; float min_temp; // nejnižší teplota int min_time; // hodina, kdy naměřena min.teplota int m; // index pro vyhledávání min_temp = 900; // počáteční nastavení for( m=1; m<25; m++) // cyklus přes 24 hodiny if( temp[m-1]<min_temp) // pokud v m-té hodině teplota nižší // nežli min_temp min_temp = temp[m-1]; // změň obsah min_temp min_time = m; // ulož údaj o hodině s min.teplotou cprintf("min. teplota %4.1f ", min_temp); cprintf("byla v %d hodin", min_time); // zobraz min.teplotu // zobraz hodinu getch(); 1 2 Obr. 1.1 je tzv. vývojový diagram. Jeho účelem je popsání algoritmu. Oválné rámečky značí začátek nebo konec programu či podprogramu, obdélníkové proceduru, funkci nebo příkaz. Kosodélníky značí místo větvení, ve kterém se rozhoduje o pokračovací větvi. V textu budeme pro psaní programů využívat následující konvence: klíčová slova (float, int, if, for ) budou tučně, poznámky budou psány kurzívou, ostatní zdrojový kód je psán proporcionálním písmem. - 8 -

úvod První řádek nám říká, že do programu zahrnujeme knihovnu naprogramovaných funkcí conio 3 (console input output funkce pro načítání a vypisování do příkazového řádku). Do této knihovny patří např. cprintf (tisk do příkazového řádku) nebo getch (načtení znaku). Druhý řádek programu je tzv. hlavička funkce. Uprostřed hlavičky se nachází jméno funkce (v našem případě main 4 ). Nalevo od jména je uveden typ hodnoty, kterou funkce vrací (v našem případě void 5 ). Napravo od jména se v závorce uveden seznam vstupních parametrů (v našem případě opět void). Slovo void značí prázdný parametr, tedy nic. Každý program v jazyku C je chápán jako funkce. Složené závorky označují kód, který společně tvoří jeden blok tělo funkce. Za dvojité lomítko můžeme psát svůj komentář (znaky komentáře jsou překladačem ignorovány). Slovo float uvozuje reálnou proměnnou, slovo int celočíselnou proměnnou. Proměnná temp sestává z 24 reálných čísel, první číslo má v hranatých závorkách index 0. Znaménkem = vložíme do proměnné konkrétní číselnou hodnotu. Řádkem for říkáme, že následný kód budeme vykonávat od m=1 do m=24 (poté přestane platit m<25), přičemž po každém vykonání následného kódu bude hodnota indexu m zvýšena o jedničku (m++). Pokud je splněna nerovnost v kulaté závorce za if, vykoná se následný blok ve složené závorce; v opačném případě nebude vykonáno nic. Poslední dva řádky vypíší nejnižší teplotu a odpovídající hodinu do příkazového řádku (viz obr. 1.2). Za %4.1f je dosazen obsah proměnné min_temp typu float; vypsané číslo sestává celkem ze čtyř znaků, z nichž jeden je za desetinnou tečkou. Za %d je dosazen obsah proměnné min_time typu int. Obr. 1.2 Textový výstup programu do příkazového řádku. 3. Ladění programu. Člověk je omylný, a proto se při psaní zdrojového kódu dopouští omylů. Naše možné chyby přitom můžeme rozdělit na omyly syntaktické a omyly logické. 3 4 5 Knihovna conio je speciální knihovna prostředí Borland C++ Builder. Jak si asi všimli ti, kteří používají jinou literaturu nebo už s jazykem C měli co do činění, její funkce cprintf, resp. cscanf se podobají funkcím standardní knihovny C pro vstup a výstup (stdio.h) scanf, printf, a stejně se i používají. Funkce knihovny stdio na rozdíl od conio zkompilujeme kdekoli (Linux/Windows, gcc/msvisual Studio/...), a výsledkem jejich používání je přenositelný kód. Funkce main() je nejdůležitější funkcí programu. V každém programu smí být jen jedna. Funkce main() obsahuje, co program dělá. Ostatní funkce jsou pouze pomocné a jsou spouštěny v main() nebo v ostatních funkcích. Pokud by měl být zdrojový kód zcela obecný (tzn. přeložitelný libovolným kompilátorem jazyka C), musela by funkce vracet celočíselnou hodnotu. Jelikož překladač Borlandu nemá s návratovou hodnotou void potíže, nebudeme se jí vyhýbat. - 9 -

úvod Syntaktickým omylem rozumíme omyl v zápisu (záměna malého a velkého písmene, odkaz na neexistující proměnnou, atd.). Na syntaktický omyl nás upozorní překladač, který v důsledku našeho omylu není schopen převést náš zdrojový kód na kód strojový. Pokud bychom cyklus v našem příkladu zahájili slovem For, dopustili bychom se syntaktického omylu. Syntaxe jazyka C totiž vyžaduje začít slovo for malým písmenem. Logickým omylem je omyl, který překladač neodhalí. Po spuštění programu se však naše aplikace chová jinak, než jsme očekávali 6. Napíšeme-li v našem příkladu místo přiřazení min_time=m nesprávně min_time=m+1, bude údaj o času nejnižší teploty posunut o jednu hodinu. Běh programu bude bezproblémový, avšak produkovaný výsledek bude chybný. Proces odstraňování chyb je nazýván laděním (debugging). Ladění je posledním krokem při vývoji programu. 1.2 Borland C++ Builder první pohled Borland C++ Builder je komplexní nástroj pro vytváření rozsáhlých aplikací určených pro operační systémy Microsoft Windows. Zahrnuje podporu programování databázových, internetových, grafických a dalších aplikací. Tyto aplikace jsou programovány v jazyce C++. Jazyk C++ vznikl jako tzv. objektové rozšíření základního jazyka C 7. Stručné vysvětlení pojmu objektově orientované programování si ponecháme na druhou polovinu semestru. Hlouběji se lze s objektovým jazykem C++ seznámit v navazujících předmětech v dalších semestrech studia. Náš předmět se soustřeďuje na základní neobjektovou verzi jazyka C. Abychom se zbytečně nerozptylovali všemi možnostmi, které nám Windows přinášejí, budou naše první programy určeny pouze pro příkazovou řádku. Mluvit budeme o tzv. konzolových aplikacích (console applications). Uživatelský pohled na konzolovou aplikaci vidíme na obr. 1.2. Obr. 1.3 ukazuje základní pohled na Borland C++ Builder. Novou konzolovou aplikaci vytvoříme postupným výběrem položek menu New Other. V okénku, které se následně otevře, vybereme ikonu Console Wizard. Výběrem ikony Console Wizard otevřeme dialog pro základní nastavení konzolové aplikace (viz obr. 1.4). Jelikož budeme psát neobjektový program, v levé části dialogu vybereme možnost C. Jelikož nebudeme psát program, který řeší úlohu rozdělenou do několika paralelních vláken (threads), možnost Multi Threaded zůstane v pravé části okna nevybrána. Potvrdíme-li nastavení aplikace tlačítkem OK, otevře se editor pro psaní zdrojového kódu. Kód můžeme uložit do souboru, spustit, krokovat řádek po řádku. Všechny tyto úkony lze spustit stiskem ikony na tzv. speedbaru Builderu (viz obr. 1.5). 6 7 Toto je lepší varianta. Horší chyby se projeví až v okamžiku, když program považujeme za funkční. Předejít oběma druhům chyb se dá pomocí správných programátorských návyků (inicializace proměnných, kontrola přetečení polí, apod.), jak se dozvíme v dalším textu. Jazyk C++ se na rozdíl od C poměrně rychle vyvíjí. Důvodem jeho vzniku bylo zjednodušení vývoje aplikací a vytvoření jazyka se stručnějším zápisem. V současné době C++ přináší možnosti, které v C přímo nejsou (např. šablony nebo přetížení operátorů). Využití těchto vlastností ale vyžaduje naučit se něco navíc. Tyto možnosti slouží k usnadnění programování. Na druhou stranu není pravda, že by algoritmus, který lze naprogramovat v C++ nešlo naprogramovat v C. - 10 -

úvod Nyní, když jsme se stručně seznámili s programem Borland C++ Builder, můžeme se pustit do studia jazyka C. Získané znalosti si můžeme ověřovat na vlastních programech. Při jejich ladění s výhodou využijeme nástrojů, které nám Builder poskytuje. Obr. 1.3 C++ Builder: konzolová aplikace. Při ladění zastavíme program na začátku bloku, v němž předpokládáme chybu. Toho dosáhneme vložením tzv. breakpointu na odpovídající řádek programu (klikneme myší na šedý levý okraj řádku; řádek zčervená a na okraji se objeví tučná tečka téže barvy). Poté kritický blok krokujeme pomocí Trace Into nebo Step Over. V jednotlivých krocích prohlížíme obsah proměnných a ověřujeme správnost jejich obsahu. Pokud zjistíme nesprávnou hodnotu, můžeme ji pro další ladění nahradit hodnotou korektní. Obr. 1.4 Console Wizard. Ke kontrole obsahu proměnných a jejich změně slouží položka menu Run Evaluate/ Modify. Výběrem této položky otevřeme okno z obr. 1.6. Do řádku Expression vepíšeme název proměnné, stiskneme Evaluate a v editačním poli Result objeví její obsah. Chceme-li obsah proměnné změnit, vepíšeme do řádku New value novou hodnotu proměnné a stiskneme Modify. Do řádku Expression lze psát i celé výrazy (např. i+j). - 11 -

úvod nový projekt otevři ulož funkce v jednom kroku spusť aplikaci zastav běh aplikace krokuj dovnitř funkce Obr. 1.5 Tzv. speedbar Builderu. Ladicí nástroje Builderu jsou efektivní a pohodlné. Přesto je lepší dobře si promyslet a nakreslit algoritmus sestavovaného programu, abychom se nedopouštěli zbytečných logických omylů. Nutné je dobře se naučit syntaxi programovacího jazyka, abychom se nedopouštěli zbytečných omylů syntaktických. Obr. 1.6 Dialog pro sledování obsahu proměnných. - 12 -

jazyk c 2 Jazyk C Programovací jazyk C vyvinul na přelomu šedesátých a sedmdesátých let D.M. Ritchie u firmy AT&T. Jazyk se stal postupem doby natolik oblíbený, že byl kodifikován Americkým národním úřadem pro normalizaci (ANSI 8 ). Na základě této normy vznikla řada implementací jazyka C pro různé typy počítačů a pro různé druhy operačních systémů. Počátkem osmdesátých let byla navržena objektová verze 9 jazyka, pro níž se vžilo označení C++. Jazyk C++ se postupem doby stal základem moderních vývojových nástrojů, jakými jsou Borland C++ Builder nebo Microsoft Visual C++. S nástrojem Borland C++ Builder jsme se již seznámili a zůstaneme mu dále věrni. Nicméně, naši pozornost soustředíme na původní, neobjektovou verzi jazyka, na ANSI C. Důležité pro nás bude, abychom si zvykli na syntaxi jazyka C a abychom se naučili v jazyce C myslet. Přechod k moderní, objektové verzi C++ by pak už měl být pro nás relativně snadný. 8 9 Současná používaná norma jazyka C je ISO99. Program obvykle sestává z nezávislého kódu (posloupnost instrukcí v tělech funkcí) a z nezávislých dat (proměnné, v nichž jsou uloženy programem zpracovávané údaje). Objektové programování skládá funkce (kód) a proměnné (data) do jediné struktury, kterou nazýváme objekt. - 13 -

identifikátory, typy dat, proměnné 3 Identifikátory, typy dat, proměnné Identifikátorem rozumíme libovolnou posloupnost písmen anglické abecedy a číslic 10. Identifikátor hraje roli jména naší vlastní proměnné nebo naší vlastní funkce. Identifikátor musí začínat písmenem (nesmí mít na první pozici číslo). V jazyce C je třeba rozlišovat malá a velká písmena. Termínem proměnná rozumíme místo v paměti, do něhož ukládáme data určitého typu. Jméno proměnné (sestavujeme jej podle výše uvedených pravidel pro identifikátory) zastupuje adresu paměťového místa. Typ proměnné jednoznačně určuje, jak velký paměťový prostor má být na dané platformě vyhrazen pro uložení obsahu proměnné a jak má být interpretován. Proměnné musíme před jejich použitím deklarovat. Deklarace počítači oznamuje, jak velké paměťové místo má být pro naši proměnnou rezervováno a jakým jménem se budeme na toto paměťové místo odkazovat. 3.1 Lokální a globální proměnné Podle umístění deklarace můžeme proměnné rozdělit na lokální a globální. Lokální proměnná je deklarována v těle funkce 11. Tato proměnná je pak dostupná jen v rámci této funkce a existuje jen po dobu jejího provádění. Jakmile tělo funkce opustíme (je vykonána poslední instrukce funkce či bloku), je paměťové místo, v němž byla proměnná uložena, uvolněno (vymaže se jeho adresa, a tím je ztracen i jeho obsah). Globální proměnná je většinou deklarována mimo těla funkce. Tato proměnná existuje po celou dobu provádění programu a mohou k ní přistupovat všechny funkce, které jsou definovány za deklarací této proměnné. Základním programátorským pravidlem je používat globální proměnné pouze v nejnutnějších případech. Deklarace sestává z typu proměnné (kolik bajtů je třeba v paměti rezervovat pro uložení obsahu proměnné) a z identifikátoru proměnné (jméno reprezentující adresu paměťového prostoru pro uložení hodnoty). Práci s lokálními a globálními proměnnými si vysvětlíme na jednoduchém příkladu. Později, až budeme probírat funkce, se k tomuto tématu ještě podrobněji vrátíme. 10 11 Existuje ještě několik dalších znaků, které jsou povoleny, ale s výjimkou podtržítka _ se nedoporučuje je užívat. Přesněji platí, že proměnné lze v C deklarovat na začátku bloku. Blok je ohraničen složenými závorkami vyskytuje se jako těla cyklů for či podmínky if. Je možné ho i vložit kamkoli v programu. Začátek bloku je kromě globální deklarace (před funkcí main) jediným místem programu, kde mohou být deklarovány proměnné. - 14 -

identifikátory, typy dat, proměnné #include <conio.h> int a = 10; void main( void) int b = 20; // global variable // local variable cprintf( "Global: %d\r\n", a); getch(); cprintf( "Local : %d\r\n", b); getch(); Proměnná a je globální a je přístupná ze všech funkcí deklarovaných v programu níže. Proto můžeme její obsah vytisknout i uvnitř funkce main. Proměnná b je lokální. Existuje pouze v rámci funkce main, v níž je deklarovaná. Mimo funkci main není proměnná b přístupná. Ve výše uvedeném výpisu si můžeme všimnout, že se v deklaraci globální proměnné a objevuje za jménem proměnné rovnítko následované celočíselnou hodnotou. Pomocí této konstrukce můžeme přímo v deklarační části programu nově vytvořenou proměnnou inicializovat (na paměťové místo označené identifikátorem a ukládáme hodnotu 10). Dále připomeňme: #include <conio.h> spojí náš program s knihovnou funkcí určených pro vytváření konzolových aplikací. void main( void) je hlavička funkce hlavní program. Náš hlavní program nemá žádný vstupní parametr (void v závorce) a žádný parametr výstupní (void vlevo). K tisku slouží funkce cprintf. Řetězec, který chceme zobrazit v příkazovém řádku, je vepsán do uvozovek. Za %d je do řetězce vložen obsah celočíselné proměnné a (první volání funkce) nebo b (druhé volání funkce). Řídicí znak \r přenese kurzor na začátek příkazového řádku, řídicí znak \n přenese kurzor na nový řádek. Funkce getch() slouží k načtení znaku z konzoly. Zde funkci používáme jako čekání na stisk klávesy. 3.2 Pravidla deklarování proměnných Jak je zřejmé z uvedeného výpisu, deklarování proměnné se řídí následujícími pravidly: 1. Na volném řádku uvedeme typ proměnné (v našem případě int). 2. Typ proměnné oddělíme mezerou od jména proměnné daného typu. 3. Pokud potřebujeme deklarovat více proměnných daného typu, jejich jména oddělujeme čárkami (např. int first, second, third;). 4. Řádek s deklarací je ukončen středníkem. Dosud jsme se v našich příkladech setkali pouze s celočíselným typem proměnné int a racionálním typem proměnné float. O dalších základních typech se dozvíme v následujícím odstavci. - 15 -

identifikátory, typy dat, proměnné 3.3 Základní typy proměnných Vybrané základní typy proměnných jsou uvedeny v tab. 2.1. Proměnné z tabulky můžeme rozdělit do tří skupin: Znakové char (znak ANSI znakové sady 12 ), unsigned char (unsigned omezuje proměnnou pouze na kladné hodnoty). Celočíselné int (32-bitové celé číslo se znaménkem), short int (short sníží možnou velikost celého čísla; ušetříme 16 bitů), unsigned int (unsigned omezuje proměnnou pouze na kladné hodnoty). Racionální float (32-bitové číslo s plovoucí desetinnou čárkou a znaménkem), double (64-bitové číslo s plovoucí desetinnou čárkou a znaménkem), long double (long zvýší přesnost reprezentace racionálního čísla double). Neštěstím jazyka C je skutečnost, že velikosti typů jsou závislé na použitém procesoru či prostředí. Datové typy int a double by měly být nejpřirozenějšími typy z hlediska výpočtů pro danou platformu. Nejsou dány velikosti datových typů, ale pouze jejich relace (obsah menšího datového typu se vždy vejde do typu většího). Typy s pevnou velikostí jsou definovány v rámci normy v stdint.h. U PC Windows to je: typ bitů rozsah unsigned char 8 X <0, +255> char 8 X <-128, +127> short int 16 X <-32.768; +32.767> unsigned int 32 X <0; +4.294.967.295> int 32 X <-2.147.483.648; +2.147.483.647> float 32 1,18 10-38 < X < 3,40 10 +38 double 64 2,23 10-308 < X < 1,79 10 +308 long double 80 3,37 10-4932 < X < 1,18 10 +4932 Tab. 2.1 Vybrané základní typy proměnných Borland C++ Builderu 13 Při výběru vhodného typu proměnné se rozhodujeme nejdříve mezi základními skupinami. Pro uložení znaku volíme skupinu char, pro uložení celočíselného indexu skupinu int, pro uložení racionálního čísla skupinu float-double. Podrobnější specifikaci typu uvnitř zvolené skupiny pak formulujeme pomocí tzv. modifikátorů (modifiers) unsigned, short, long s ohledem na požadovaný číselný rozsah proměnné na jedné straně a na dostupnou velikost paměti na straně druhé. Jakmile procesor vykoná úkony spojené s deklarací, je v paměti vytvořeno místo pro uložení hodnoty daného typu. Adresa tohoto paměťového místa je reprezentovaná proměnnou. Např. pro float z je rezervováno v paměti 32 bitů a adresa tohoto prostoru je repre- 12 13 Každý znak je reprezentován odpovídajícím celočíselným ASCII kódem. Se znakovými proměnnými tedy můžeme pracovat rovněž jako s celými čísly. Aby to nebylo tak jednoduché, velikost typů se může mezi procesory měnit. Pro získání velikosti typu lze použít operátor sizeof(). - 16 -

identifikátory, typy dat, proměnné zentována identifikátorem z. Pokud deklaraci doplníme nepovinným přiřazením float z=3.14, je do vytvořeného paměťového místa přímo uložena hodnota 3.14. Přiřazení počátečních hodnot deklarovaným proměnným nazýváme inicializací. V inicializační části deklarace se mohou vyskytovat i výrazy. Například při deklaraci int a = 3, b = 4; double c = 0.2*a + b; je nejdříve vyčíslen výraz 0.2*a+b, a poté je vypočítaný výsledek uložen do proměnné c. Deklarace a inicializace proměnných a a b musí samozřejmě předcházet výše uvedenou deklaraci a inicializaci proměnné c. Vyčíslování výrazů při inicializaci proměnné c se liší v případě, kdy je c deklarováno jako globální proměnná (na začátku jednotky, mimo funkce) a kdy jako proměnná lokální (uvnitř některé z funkcí). V prvém případě je výraz v inicializační části vyčíslován jen jednou, a to na začátku programu. V druhém případě je výraz počítán při každém volání funkce znovu. Pokud je obsah proměnných a a b neměnný během vykonávání celého programu, je lepší inicializovat c jako globální proměnnou. Pokud se však obsah a a b během programu mění, nezbývá než c inicializovat lokálně. 3.4 Ukazatele Termínem ukazatel (pointer) rozumíme proměnnou, která je určena pro uložení adresy určitého paměťového místa. Každý ukazatel musí být přitom spjatý s datovým typem, který je na dané adrese uložen. Při čtení popisu ukazatelů v dalších odstavcích můžeme mít pocit, že z praktického pohledu nejsou užitečné. O jejich užitečnosti se přesvědčíme později při probírání dynamických proměnných. Deklarujeme-li v programu ukazatel, stačí nám do standardní deklarace přidat před jeho jméno symbol *. Tzn., int *b je ukazatel na celočíselnou proměnnou. Pokud chceme do ukazatele uložit adresu proměnné int a, použijeme zápisu b=&a. Pokud si chceme prohlédnout obsah paměťového místa, jehož adresa je uložena v b, použijeme konstrukce c=*b (c je deklarováno jako celé číslo, obsah adresy uložené v b tzn. hodnotu proměnné a kopírujeme do proměnné c). Práci s ukazateli si opět vysvětlíme na příkladu: #include <conio.h> void main( void) float x = 3.14, y = 2.27; // 1 float* p; // 2 p = &x; // 3 address of x to p *p = y; // 4 cont. of y on address in p cprintf("in x, we have: %4.2f. \r\n",x); // 5 printing result getch(); V našem programu máme deklarovány dvě lokální racionální proměnné x a y. Obě proměnné jsou přímo v deklarační části naplněny konkrétními hodnotami. Po vykonání řádku 1 máme tedy v paměti uloženo na adrese &x číslo 3.14 a na adrese &y číslo 2.27. - 17 -

identifikátory, typy dat, proměnné Na řádku 2 deklarujeme ukazatel na racionální číslo p. Do proměnné p tedy můžeme uložit adresu již existujícího racionálního čísla (v našem případě buď &x nebo &y). Identifikátor p tedy reprezentuje adresu místa v paměti, které je určeno pro uložení adresy. Chceme-li se podívat na obsah proměnné, jejíž adresa je uložena v p, napíšeme *p. Přiřadíme-li p = &x, bude *p vracet hodnotu 3.14. Přiřadíme-li p = &y, bude *p vracet hodnotu 2.27. Situace je graficky znázorněna na obr. 3.1. adresa selektor : offset proměnná místo v paměti &x 3.14 x &y 2.27 y &p p Obr. 3.1 Ukazatele. V našem případě na řádku 3 do proměnné p vkládáme adresu proměnné x, na řádku 4 měníme obsah místa v paměti s adresou uloženou v p přiřazujeme do něj obsah proměnné y. Provedením příkazu na řádku 4 se tedy změní hodnota proměnné x, neboť v p byla uložena právě její adresa. Výsledkem příkazu na 5. řádku tím pádem bude výpis: In x, we have: 2.27 Pokud bychom napsali *x, kompilátor nás upozorní, že se jedná o nesmysl. Proměnná x není ukazatel, proměnná x reprezentuje datovou oblast pro racionální číslo, a proto nemůžeme prostřednictvím hvězdičky říci podívej se do datového prostoru, jehož adresa je uložena v x. Naopak zápis &p je v pořádku. Ptáme se totiž na adresu, na níž je uložena adresa (ukazatel) reprezentovaná proměnnou p, jak je znázorněno na obr. 3.1. Následující program ukazuje poměrně častou chybu: void main( void) int x=1; // 1 int *p; // 2 *p = x; // 3 no address saved in p Na řádku 3 se snažíme změnit obsah místa paměti, jehož adresa je uložena v p. Jenže v p zatím není uložena žádná rozumná adresa, obsah proměnné p nebyl inicializován, takže p může ukazovat na nějaké náhodné místo. Může to být místo zcela neškodné, takže zápisem na ně nic nepokazíme a program bude vypadat, že funguje normálně. Může se však také stát, že se budeme v paměti snažit přepsat nějakou důležitou informaci, což povede k chybě. 3.5 Pole Pole (array) je datová struktura tvořená několika složkami stejného typu. Počet složek pole udáváme v jeho deklaraci v lomené závorce za jménem pole. Počet složek musí být kladné celé číslo. Např. deklarace int d[3] zavádí pole d tvořené třemi složkami typu int. - 18 -

identifikátory, typy dat, proměnné Jelikož složky pole jsou indexovány od nuly, sestává naše pole ze tří celých čísel d[0], d[1] a d[2]. Má-li pole více indexů, objeví se v deklaraci za jménem pole více lomených závorek. Např. pole double d[2][2] sestává ze čtyř racionálních čísel d[0][0], d[0][1], d[1][0] a d[1][1]. Pole můžeme stejně jako prosté proměnné inicializovat přímo v deklarační části programu. U pole je deklarace doplněna složenou závorkou, která obsahuje počáteční hodnoty jeho složek double angle[5] = 0.0, 0.1, 0.2, 0.3, 0.4. 0 A[0] B[x][0] B[x][1] 1 A[1] 0 1 B[0][y] A 2 A[2] B 2 3 B[1][y] 3 A[3] 4 5 B[2][y] 4 A[4] Obr. 3.2 Pole. Práci s poli si vysvětlíme na jednoduchém příkladu. Budeme mít jednorozměrné pole tří celých čísel x, do něhož budeme ukládat velikosti úhlů ve stupních. Ke každé složce pole x chceme vypočítat hodnotu funkce sinus a výsledek uložit do odpovídající složky pole y. Abychom mohli pracovat s funkcí sinus, musíme propojit náš program s matematickou knihovnou math.h. V této knihovně je též definována konstanta π jako M_PI. Ludolfovo číslo π potřebujeme pro přepočítávání velikosti úhlů ze stupňů na radiány. Celý program může vypadat následovně: # include <conio.h> // library of console functions # include <math.h> // library of mathematical functions void main( void) int x[3] = 30, 60, 90, n; // array of angles, variable for cycles float y[3]; // array of functional values cprintf( "Functional values of sine:\r\n" ); cprintf("x sin(x)\r\n"); // printing headline for( n=0; n<3; n++) y[n]=sin( x[n]*m_pi/180.0); cprintf("%d %f\r\n",x[n],y[n]); // computing functional values // printing results getch(); Abychom nemuseli výpočtu každé funkční hodnoty a jejímu tisku do konzolového okna věnovat zvláštní řádek zdrojového kódu, který by se lišil pouze hodnotou indexu pole, použili jsme cyklus for. Fungování cyklu for nyní vysvětlíme jen zhruba, ale později se k němu ještě vrátíme. - 19 -

identifikátory, typy dat, proměnné Cyklus for se používá tehdy, chceme-li nějaké příkazy provádět opakovaně s tím, že hodnota jisté proměnné (říká se jí řídicí proměnná cyklu) se postupně mění od určité počáteční po určitou hodnotu koncovou. Např. v Pascalu cyklus for i:=1 to 10 do xxx provádí příkaz xxx postupně pro hodnoty řídicí proměnné i=1, i=2,..., i=10. V jazyce C má cyklus for syntaxi 14 for( init; cond; incr) tělo cyklu Výrazem init nastavíme počáteční hodnotu řídicí proměnné, výrazem cond zadáme podmínku trvání cyklu a výrazem incr realizujeme zvýšení (nebo nějakou jinou změnu) řídicí proměnné po vykonání všech příkazů z těla cyklu. Dále tělo cyklu je příkaz nebo více příkazů, které se mají cyklicky opakovat. Je-li příkazů více, musí být ohraničeny složenými závorkami. Zvláštní pozornost si zaslouží příkaz i++. Pomocí tohoto příkazu zvyšujeme hodnotu proměnné i o jedničku. Stejného výsledku bychom dosáhli příkazem i=i+1. Je nutné zdůraznit, že kompilátor jazyka C žádným způsobem nekontroluje překročení hranice polí. Při logické chybě se tedy může stát, že náš program pracuje se složkami pole mimo rozsah, daný v deklaraci. Tento případ často nastává při chybné indexaci pole od jedničky namísto od nuly. Potom je poslední složka pole uložena do nedeklarované složky (tj. do paměťového místa mimo prostor vyhrazený deklarací), což může způsobit předčasné ukončení běhu programu. Vše si můžeme ověřit na výše uvedeném příkladě stačí nám změnit parametry cyklu for na ( n=1; n<4; n++). Program se bez problému zkompiluje a spustí, protože neobsahuje žádnou chybu syntaxe, problémy mohou nastat až při jeho vykonávání. Proto musíme práci s indexy polí věnovat zvýšenou pozornost [3]. V dalším příkladu si vyzkoušíme práci s polem dvojrozměrným. Původní (original) dvojrozměrné pole znaků orig odpovídá dvěma slovům psaným nad sebou. Každé slovo sestává z pěti písmen. Našim úkolem je znaky zkopírovat do přepsaného (rewritten) pole rev tak, aby řádky byly přehozeny a slova plynula od konce. Jedno z možných řešení následuje: # include <conio.h> void main( void) char orig[2][5] = 't','a','m','t','o', 's','a','l','e','k'; // first word // second word char rev[2][5]; int i; for(i=0;i<5;i++) rev[0][i] = orig[1][4-i]; rev[1][i] = orig[0][4-i]; // rearranged words // rearranging words // first <- second // second <- first 14 Je dobré si všimnout, za příkazem for není středník. Příkaz for zakončený středníkem by proběhl tolikrát, kolikrát říká jeho hlavička, ale ve výsledku by nic neprovedl (vykonal by několikrát prázdný příkaz reprezentovaný středníkem). - 20 -