Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Základy programování v jazyce C# pro naprosté začátečníky Vladimír Váňa
[email protected] SPŠE Ječná šk.r. 2005/2006 http://www.spsejecna.cz
Úvod Výuka základů programování probíhající na středních školách seznamuje studenty se základními pojmy z teorie programování a vytvářením algoritmů při řešení různých, často jen ukázkových, problémů. Nedílnou součástí této výuky je i výuka syntaxe některého programovacího jazyka i vlastní programování v tomto jazyce. Často je tímto jazykem Turbo Pascal. Dny jeho slávy jsou již dávno sečteny. Současná vývojářská praxe je naprosto odlišná. Na to reagovaly vysoké školy přechodem od výuky programování v jazyce Pascal k výuce programování v jazyce Java či C#. Úspěšnost těchto jazyků zajistila, že i v českém jazyce vyšla celá řada publikací o programování v těchto jazycích. Ty mohou být používány i studenty vysokých škol. Pro začínající studenty středních škol jsou však často příliš složité, obsahují značné množství informací, ve kterém se student „utápí“, a přitom je látka prezentována ve zhuštěné formě, vyhovující zkušeným programátorům. Proto na základě zkušeností z výuky programování v jazyce C# na SPŠE Ječná v Praze v letech 2003 – 2005 vznikl tento učební materiál. Protože učebnic a učebních textů zabývajících se základními pojmy z teorie programování a vytvářením algoritmů je k dispozici řada, je tento učební text věnován jen základům jazyka C#. Skládá se z těchto částí: Kapitola 1 - Jazyk C# Kapitola 2 - Základy programování v jazyce C#: Vytvoření prvního programu. Kapitola 3 - Základní příkazy jazyka C# (Podmínkové příkazy): Vysvětlení podmínkových příkazů. Načtení vstupních znaků, řeťězců a čísel. Převody a podmíněné příkazy. Kapitola 4 - Základní příkazy jazyka C# (Cykly ): Seznámení se s pojmem cyklus a praktické využití cyklu for. Kapitola 5 - Základní příkazy jazyka C# (Cykly - pokračování): Vysvětlení cyklů while, do...while a foreach a dále příkazů skoku goto, break a continue. Kapitola 6 - Třídy a překladač jazyka C#: Základní vlastnosti tříd, vytvoření instance, objektu, pojem static a možnosti překladače jazyka C# Dodatek 1 - Naše konzolové příklady převedené do WinForm Dodatek 2 - Pascal v DELPHI2005
(C) 2005 Vladimír Váňa
1
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Kapitola 1.
Jazyk C# Předtím, než se u počítačů objevily programovací jazyky, programovalo se přímo ve strojovém kódu, tj. většinou v binární, oktalové nebo hexadecimální reprezentaci instrukcí počítače. Všechny objekty, s nimiž počítač pracoval, byly pochopitelně označovány pouze číselně. Např. naplnění registru R16 konstantou ve strojovém jazyce mikroprocesoru ATMEL AVR má tvar: 1100 1111 0000 0110 Je zřejmé, že programování ve strojovém jazyce je obtížné a nepřehledné a mohlo vyhovovat jen v úplných začátcích, kdy programy byly krátké a jednoduché. Se zdokonalováním technického vybavení rostly nároky na programy a programovat ve strojovém jazyce začalo být neúnosné. Brzo se zjistilo, že pracnost programování lze značně snížit, zrušímeli nutnost označovat objekty v instrukcích číselně (vyhovuje stroji) a zavedeme-li symbolické označování objektů (vyhovuje člověku) s tím, že vazbu symbolů na jejich vyjádření nebude provádět programátor, ale zajistí je specielní program – překladač. Tak vznikly jazyky symbolických adres, v nichž mohly operační znaky instrukcí a jejich operandy označovat symboly. Současně vznikly i překladače jazyků symbolických adres (assemblery), které překládaly symbolický jazyk do strojového jazyka. Brzo se ukázalo, že programátorovi lze práci ještě více usnadnit, zbavíme-li ho závislosti na instrukční síti počítače, se kterou byl spjat i při programování v jazyce symbolických adres. Objevily se proto vyšší programovací jazyky nezávislé na počítači, které jsou navrženy tak, aby programátor instrukční soubor počítače vůbec nemusel znát. Syntaxe vyšších programovacích jazyků většinou obsahuje mj. klíčová slova převzatá z anglického jazyka. Vyšší programovací jazyky jsou implementovány řadou výrobců a pro mnoho různých procesorů a operačních systémů. Různé implementace překladačů téhož jazyka se liší rychlostí překladu, velikostí a rychlostí výsledného kódu. Definice vyššího programovacího jazyka, jeho lexikální symboly, syntaxe, sémantika, je často dána nějakou normou, ať mezinárodní (např. ANSI C, ANSI C++) nebo podnikovou (Java u SUNu). Příklady vyšších programovacích jazyků: ADA, Basic, C, C++, C#, Fortran, Java, Perl, PHP, SQL …
Překladače Překladač nějakého programovacího jazyka je počítačový program. Znamená to, že i překladač musel někdo naprogramovat. Tvorba překladače je velice složitá úloha a proto se při jeho tvorbě postupuje stejně, jako při řešení jiných složitých úloh = celý problém se rozloží na jednodušší problémy a ty se vyřeší. Překladač je program, jehož vstupními daty je zdrojový text, tj. např. textový soubor obsahující text programu napsaného ve vyšším programovacím jazyce, zdrojový kód. Výstupem překladače je např. výstupní binární soubor, spustitelný program počítače.
(C) 2005 Vladimír Váňa
2
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná Činnost překladače může být např. takováto: 1. Lexikální analýza – provede se převedení zdrojového textu na jiný, vnitřní kód. Odstraní se přitom např. nadbytečné mezery, závorky a komentáře. Provede se transformace klíčových slov, identifikátorů proměnných apod. na číselné objekty stejné délky. (např. v Pascalu klíčová slova begin, end, … mají různou délku, obdobně identifikátory. Překladač místo těchto objektů bude používat čísla. Tato čísla budou mít navíc stejný počet číslic. Je to z toho důvodu, že počítači se s čísly bude lépe pracovat). 2. Syntaktická analýza = kontroluje správné použití prvků programovacího jazyka (v Pascalu musí mít každé Begin své End apod.). Syntaktická analýza je vlastně „větný rozbor“ používaný u přirozených jazyků jako čeština, angličtina apod. 3. Sémantická analýza = zjišťuje se význam jednotlivých konstrukcí našeho programu tj. např. co se má provést – např. nějaká matematická operace, přesun hodnoty do paměti či naopak z paměti apod. 4. Generace výsledného strojového kódu z mezikódu vzniklého po skončení 1., 2. a 3. Dále se ještě může provést optimalizace výsledného kódu.
Již před řadou let se v Teorii překladačů objevila zajímavá myšlenka snižující množství práce, které musí vynaložit softwarový výrobce překladačů při tvorbě překladačů z několika programovacích jazyků do několika různých platforem. Chce např. vytvořit překladače jazyků Pascal, Basic, C, Fortran pro počítač PC s MS DOS, vytvoří celkem 4 překladače. Má-li ještě vytvořit překladače z těchto jazyků do WIN XP, jsou to další 4 překladače.
(C) 2005 Vladimír Váňa
3
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná Jestliže se mají udělat ještě překladače pro LINUX, Solaris, BSD Unix pro všechny uvedené jazyky, znamená to vytvořit 4 x 5 = 20 překladačů. Obecně pro N jazyků na M platforem je třeba vytvořit N x M překladačů. Myšlenka na zjednodušení tvorby těchto překladačů spočívá v tom, že se definuje jakýsi společný mezijazyk a vytvoří se pro N jazyků N překladačů do tohoto mezijazyka. Dále se pro M platforem vytvoří M překladačů z mezijazyka. Vytvoří se tedy pouze M + N překladačů, což je méně než M x N překladačů při tradiční tvorbě překladačů. V našem případě by to bylo 4 + 5 = 9, což je méně než. 4 x 5 = 20 Teoretická struktura – pravděpodobně žádný výrobce SW takový projekt tvorby překladačů nerealizoval:
Tomuto nápadu se nejvíce přiblížily dvě platformy: J2EE firmy SUN Microsystems a .NET Framework firmy Microsoft. V současné době jsou to zároveň nejrozšířenější a nejbouřlivěji se vyvíjející platformy. Ve firemní praxi jsou nejžádanější právě programátoři pro J2EE a .NET
Prakticky realizované firmou SUN Microsystems:
(C) 2005 Vladimír Váňa
4
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Architektura Microsoft .NET Framework – uvedeny jen jazyky z Microsoft VS.NET, existují i překladače z jiných Jazyků „třetích stran“, zatím asi 50 jazyků, např. i DELPHI
Poznámka: předchozí popis platforem J2EE a zejména .NET je silně zjednodušený. Důležitou součástí obou platforem jsou rozsáhlé knihovny tříd a dalších komponent OOP. U MS. NET
(C) 2005 Vladimír Váňa
5
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná navíc společný typový systém pro všechny jazyky této platformy, což má řadu výhod. Podrobněji se budeme platformou .NET Framework zabývat v dalších učebních materiálech.
Typy překladačů Kompilační – překladač jako vstup vezme zdrojový kód, přeloží ho do binárního, spustitelného kódu. Při překladu je přeložen celý zdrojový kód.Výsledkem je např. soubor s extenzí .EXE (MS DOS, WIN). Překlad je proveden jen jednou. Při spouštění přeloženého programu již není potřeba překladač.Případné syntaktické chyby ohlásí překladač již při překladu, takže vytvoření spustitelného programu je možné až po jejich odstranění. Interpretační – ke spuštění programu je nutné mít interpretační překladač. Ten po startu programu přeloží část kódu, někdy i jen jeden příkaz, do strojového kódu a ten nechá počítač vykonat. Poté přeloží další část kódu a získaný binární kód opět nechá počítač provést = provádí se interpretace našeho kódu. Příkladem kompilačního překladače je např. Turbo Pascal, příkladem interpretačního řada implementací jazyka Basic. Program přeložený kompilačním překladem je rychlejší, než program interpretovaný, protože jeho běh již není zdržován překladem. Výhodou interpretovaného programu je obvykle menší spotřeba paměti neboť je přeložena vždy jen část programu. Interpretovaný program se obvykle lépe odlaďuje. V praxi se v současné době čistě interpretační překladače příliš nepoužívají. Používají se však překladače, které využívají obou principů. Příkladem je jazyk JAVA. Překladač javac překládající zdrojový kód do byte kódu je kompilační. JVM (Java Virtual Machine) pak byte kód interpretuje. Aby Java trochu omezila pomalost interpretace byte kódu, používá někdy tzv. JIT kompilátory (Just in Time),který v době zavádění programu do paměti jej přeloží do strojového kódu a ten poté vykonává. Pokud jde o platformu .NET, tam je překlad vždy prováděn kompilátory JIT. Po počátečních zkušenostech s používáním vyšších programovacích jazyků se ukázalo, že programátorský styl založený na tom, že programátor si programuje naprosto svobodně, používá vymoženosti programovacího jazyka bez jakýchkoli omezení atd. není příliš efektivní. Pokud byl takový program složitější, obsahoval chyby, které se obtížně hledaly. Po čase se v programu nevyznal ani jeho tvůrce, natož někdo jiný. Změny úpravy programu byly pak velice obtížné až nemožné. Programování v té době mělo blíž k umělecké činnosti než k práci inženýrské. Proto se objevily snahy zavést na programátorskou práci určitá omezení a doporučení – objevila se koncepce strukturovaného programování .Nově vznikající jazyky jako např. Pascal tuto koncepci podporovaly. Program se měl členit do menších částí např. bloků, procedur či funkcí, které se daly samostatně odlaďovat. Z funkčních, odladěných, částí se pak skládal výsledný program. Tyto části se daly znovu používat i v jiných programech – tzv. znovupoužitelnost kódu. Tím se šetřila programátorská práce. Požadavek na tvorbu stále složitějších programů a programových balíků vedly nakonec k tomu, že ani strukturované programování již nestačilo. Prosadila se proto koncepce Objektově orientovaného programování se svými třídami a objekty, tj. datovými strukturami obsahujícími i metody pro práci s daty těchto struktur. S OOP souvisí i zapouzdření dat, polymorfismus, dědění apod. Mezi jazyky objektově orientované patří i JAVA a C#.
Kapitola 2.
(C) 2005 Vladimír Váňa
6
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Základy programování v jazyce C# Protože při vytváření programů v C# můžeme používat různé vývojové nástroje, ukážeme si teď jak pracovat s těmi nejrozšířenějšími. Syntaxe jazyka C# je ve všech případech stejná. Používáme totiž stále stejný překladač jazyka C# tj. program csc.exe, který je součástí Microsoft .NET Framework verze 1.1 . K jistým změnám v syntaxi jazyka C# dojde v právě nastupující verzi 2.0, kterou bude používat např. nové Visual studio 2005. Nicméně zcela jistě zůstanou zachovány základní vlastnosti C#, tj. ty, kterými se zabýváme v této základní příručce.
Základy programování v jazyce C# s použitím DELPHI2005 Předpokládám, že již máte nainstalovaný program DELPHI2005. (Popis instalace najdeme v souboru install.htm na instalačním CD.) Spustíme program DELPHI2005. Budeme vytvářet nový Project – konzolovou aplikaci. V záložce File vybereme New a potom v rozvinutém menu zvolíme charakter projektu. Vybereme Console Application.
Ve většině případů to po prvním spuštění DELPHI2005 po jeho nainstalování nebude tak jednoduché. Konzolová aplikace totiž není v praxi příliš častým případem vytvářeného programu a proto také nemá po nainstalování DELPHI2005 svou položku a ikonu v menu, viz. obr.1.
Proto vybereme položku Other... .Otevře se tím okno, viz.obr.2
(C) 2005 Vladimír Váňa
7
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Vybereme ikonku Console Application a stiskneme OK. Tím zavoláme dialogové okno New Application, ve kterém v textboxu Name vyplníme název našeho projektu a v listboxu Location vyhledáme složku (adresář ), do kterého budeme ukládat soubory našeho projektu, obr.3.
Nyní stiskneme tlačítko OK. Tím jsme vytvořili (resp. DELPHI2005 vytvořilo za nás ) první jednoduchý program. Jeho zdrojový kód je using System; namespace Program1 { /// <summary> /// Summary description for Class. /// (C) 2005 Vladimír Váňa
8
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná class Class { /// <summary> /// The main entry point for the application. /// [STAThread] static void Main(string[] args) { // // TODO: Add code to start application here // } } } Řádku obsahující class Class přepíšeme na class Prvni. Dále v Project Manageru obr.4.
označíme soubor Class.cs, klikneme pravým tlačítkem myši. Tím se rozvine menu, ve kterém vybereme položku Rename a Class.cs přepíšeme na Prvni.cs. Nyní můžeme sestavit projekt a současně přeložit náš program vybráním položky Project v menu a v něm výběrem Build Program 1, popř. klávesami Shift + F9.
(C) 2005 Vladimír Váňa
9
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Touto akcí spustíme překladač, který již vytvoří soubor Program1.exe, spustitelný v prostředí .NET Frameworku (Později se dozvíme, že jsme vytvořili assembly, přeložili kód v jazyce C# do kódu v MSIL. Ten je před vlastním spuštěním interně přeložen do nativního kódu Justin-time kompilátorem). Takto vytvořený krátký soubor Program1.exe lze spustit z příkazové řádky, nicméně při vývoji je výhodnější ho spouštět přímo z vývojového prostředí ( tj. nyní z DELPHI2005). Lze to provést výběrem Run v menu, obr.6.
V tomto menu zvolíme Run, popř. Run Without Debugging. Jak je zřejmé z obr.6., lze spuštění programu provádět i přímo klávesou F9. Tento náš program, jak jste si jistě všimli, nedělá nic. Jen se spustí v režimu Příkazové řádky a ihned se ukončí (vždyť nic nedělá). Po ukončení programu je také ukončen režim příkazové řádky. Navenek se tedy běh našeho prvního, nejjednoduššího, programu projeví jen probliknutím „černého“ okna příkazové řádky.
(C) 2005 Vladimír Váňa
10
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná Aby náš program něco dělal, doplníme ho o dvě řádky kódu, kterými nahradíme následující úsek původního kódu
// // TODO: Add code to start application here // Výsledkem tedy bude zdrojový kód using System; namespace Program1 { /// <summary> /// Summary description for Class. /// class Prvni { /// <summary> /// The main entry point for the application. /// [STAThread] static void Main(string[] args) { Console.WriteLine("Ahoj C#"); Console.ReadLine(); } } } Takto upravený zdrojový kód pro jistotu uložíme (v menu vybereme File a potom Save ) a potom přeložíme již popsaným způsobem. Např. klávesami Shift + F9 či pomocí menu Project a Build Program1. Takto vytvořený Program1.exe spustíme, např. pomocí F9. Jeho činnost se projeví následujícím oknem, obr.7.
(C) 2005 Vladimír Váňa
11
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Stiskneme klávesu Enter a toto okno zmizí. Třebaže náš první program funguje, nerozumíme spoustě věcí v zdrojovém kódu. Jazyk C# je jazykem objektově orientovaným a k jeho dokonalému využívání, k využívání tříd .NET Frameworku a k vytváření svých vlastních tříd, k tomu, abychom se stali MISTRY v programování v C# bychom si potřebovali osvojit koncepci objektově orientovaného programování - OOP. K tomu budou sloužit další výukové materiály. V tomto materiálu, určeném pro začátečníky se zatím bez těchto znalostí obejdeme. Zaplatíme za to tím, že nebudeme vytvářet hezké „okenní“ aplikace či webovské ASP.NET stránky, ale jen „ošklivé“ konzolové aplikace. Až se naučíme základy programování v C#, budeme moci pokračovat tím, že si osvojíme základní znalosti o objektovém programování, a pak nám již nebude nic bránit v tom, abychom vytvářeli hezké a užitečné aplikace s využitím veškerého dobrodiní, které nám poskytuje .NET Framework i vývojová prostřed RAD. Na tomto místě učiním ještě dvě poznámky: 1. naše konzolové aplikace vytváříme ve vývojovém prostředí DELPHI2005 či MS Visual Studio, můžeme však využít i jiná prostředí např. CSharpDeveloper a dokonce i jen jednoduchý textový editor např. Poznámkový blok (Notepad). Zdrojový kód těchto programů je totiž velice jednoduchý a přehledný. 2. v příloze 1 jsem se pokusil naše cvičné konzolové programy předělat na běžné windowsovské programy (v terminologii .NET nazývané WinForms). Přitom jsem je pojmenoval tak, aby bylo ihned zřejmé, jak se jmenuje WinForm program vzniklý úpravou našeho konzolového programu. Např. WinForm program odpovídající konzolové aplikaci Prog3 se jmenuje Prog3w .Můžete zkusit místo konzolových aplikacích psát rovnou odpovídající Winform aplikace. Zdrojový kód je sice o mnoho složitější, než kód konzolové aplikace, ale jeho podstatnou část vytvoří wizard vývojového prostředí. Kód, který potom dopisujeme my, je však stejně dlouhý, jako ten, který píšeme u konzolové aplikace. Nesmíme ovšem přepisovat kód vytvořený wizardem, především proto, že k tomu zatím nemáme dostatečné znalosti. Navíc to není nutné a raději si zatím této části kódu nebudeme vůbec všímat. Protože začátečníci jsou často netrpěliví a místo
(C) 2005 Vladimír Váňa
12
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
konzolových aplikací by rádi psali rovnou „okenní“ programy, může být varianta WinForm programů z dodatku 1 pro ně přijatelnější, než obyčejné, byť přehledné, konzolové programy.
Poté, co jsme na začátku zvolili, že chceme vytvářet konzolovou aplikaci, nám wizard z DELPHI2005 vytvořil kostru kódu (Vývojové nástroje, na rozdíl např. MS Office, nejsou lokalizovány do češtiny, tj. komunikují s námi většinou v angličtině. Proto je používám i v tomto textu. V Delphi2005 i v VS.NET najdete velký počet wizardů – průvodce tvorbou aplikace tam totiž nenajdete). Ta obsahuje právě ty prvky OOP, které neznáme, a tak tuto práci budeme i nadále nechávat na DELPHI2005. Pouze pro informaci si teď řekneme, co vlastně vytvořil. Na první řádce zdrojového kódu je uvedeno using Systém; Jaký je jeho účel? Velice zjednodušeně si můžeme představit, že se tím kódu sděluje, jakou knihovnu tříd chceme použít. V našem případě to bude knihovna System, která obsahuje nejpoužívanější třídy platformy .NET. Budeme-li chtít použít několik knihoven tříd, napíšeme několik řádků kódu. Každý z nich bude začínat slovem using a za ním bude uvedeno jméno požadované knihovny.
Přesnějším vysvětlením první řádky using Systém; je to, že se tím provádí importování jmenného prostoru
Druhý řádek namespace Program1 říká, že třída, jejíž kód je umístěn mezi složenými závorkami {}, bude umístěna v jmenném prostoru Program1 (který jsme si tímto příkazem právě vytvořili). Vysvětlení pojmu jmenný prostor ponecháme do dalších učebních materiálů. Na tomto místě si jen řekneme, že jeho účel je obdobný, jako je účel složek ( adresářů) v hierarchickém souborovém systému DOSu či Windows který nám umožňuje sdružovat spolu související soubory a tím udržovat pořádek v souborovém systému. Jistě si dovedete představit nepořádek v případě, kdy by všechny soubory Vašeho PC byly umístěny v jedné složce. Řádkem s kódem class Prvni začíná kód třídy jejíž jméno je První. Kód této třídy je opět umístěn mezi závorkami {}. V našem případě kód této třídy obsahuje jen kód jediné metody a to statické metody Main. Kód metody Main začíná řádkem static void Main(string [] args ) a je umístěn mezi závorkami {}. Metoda Main je vstupním bodem programu a musí být obsažena v každém programu v C#, který je konzolovou či WinForm aplikací. Klíčová slova void a static říkají, že tato metoda je statická, tj. není to metoda nějaké konkrétní instance nějaké třídy a že nevrací žádnou hodnotu. Co znamená předchozí věta si vysvětlíme, až se budeme učit OOP. Pokud jste se někdy setkali s jazykem C, C++ či Java, znáte metodu main(). V C# jste se na rozdíl od těchto jazyků setkali s metodu, která se jmenuje stejně, ale její první písmeno je velké. Navíc teď musíme učinit jednu velice důležitou poznámku. V některých jazycích, např. v jazyce Pascal nezáleží na velikosti písmen. Tj. v Pascalu je Begin, begin, BEGIN, beGin totéž.
(C) 2005 Vladimír Váňa
13
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná V jazyce C#, stejně jako v dalších jazycích odvozených od jazyka C záleží na velikosti písmen, takže např. main je něco jiného než Main .
Poslední věcí ze zdrojového kódu vytvořeného wizardem, kterou si vysvětlíme jsou komentáře. Komentáře v zdrojových kódech mnoha programovacích jazyků slouží zejména k tomu, aby si programátor mohl v kódu udělat nějaké své poznámky. Např. poznámky o tom, co má program nebo nějaká jeho část dělat apod. Překladač pak tyto komentáře ignoruje a nepřekládá je. Jazyk C# zná tři typy komentářů. Wizard použil dva typy komentářů. Začátek těchto dvou typů komentářů začíná // resp. /// a končí koncem řádku. V dalším textu budu v některých případech uvádět kód, ze kterého vymažu komentáře vytvořené wizardem. Bude to v případech, že se tím uvedený kód zpřehlední. Kód, kterým budeme doplňovat kód vytvořený wizardem budeme ve všech programech vytvářených a popisovaných v tomto materiálu umisťovat místo poznámek:
// // TODO: Add code to start application here //
Proto zatím nepotřebujeme mít znalosti OOP. Další naší specialitou bude to, že budeme mít kód programu v jediném souboru, v tomto prvním programu v souboru Program1.cs .
Až budeme v budoucnosti vytvářet větší programy, bude náš projekt často zdrojový kód v několika souborech. Dokonce bude možné kombinovat soubory se zdrojovými kódy v rozdílných programovacích jazycích platformy .NET
Nakonec si vysvětlíme jediné dvě řádky kódu, které jsme napsali sami. Je to Console.WriteLine("Ahoj C#"); Tímto příkazem voláme metodu WriteLine. Parametrem této metody, umístěným mezi kulatými závorkami je řetězec, ohraničený uvozovkami. Tento řetězec vypíše program na konzolu, tj. do toho černého okna. Pokud bychom v těle metody Main měli jen tento řádek, program by vypsal
(C) 2005 Vladimír Váňa
14
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná nápis na konzolu a ukončil by se. Takže černé okénko s našim nápisem by jen krátce probliklo a ani bychom si nestačili nápis přečíst. Proto jsme do kódu dopsali ještě řádku: Console.ReadLine(); Zde se volá metoda ReadLine, která čte znak z klávesnice. Takže náš program prvním příkazem pomocí metody WriteLine vypíše nápis a pak čeká, až stiskneme klávesu. Po stisknutí klávesy metoda ReadLine přečte znak odpovídající námi stisknuté klávesy. V našem případě je nám jedno, co tato metoda přečetla. Použili jsme ji jen kvůli tomu čekání. Po stisknutí klávesy a přečtení odpovídajícího znaku se náš program ukončí. Než budeme pokračovat v studiu jazyka C# a psát další programy, ukážeme si, jak můžeme pracovat v jiných prostředích, než bylo námi zatím používané DELPHI2005.
Základy programování v jazyce C# s použitím Visual Studia .NET 2003 popř. s VC#.NET 2003 Opět předpokládáme, že již máme nainstalovaný vývojový software. Spouštíme Visual Studio 2003. Poté v menu File vybereme New a poté Project..., popř. použijeme klávesovou zkratku Ctrl+Shift+N viz. obr.8
Po výběru Project... se objeví okno New project... V něm vybereme Project type: Visual C# Project, dále Templates: Console Application a dále vyplníme jméno projektu a jeho umístění, obr.9 a stiskneme OK.
(C) 2005 Vladimír Váňa
15
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Nyní nám wizard Visual Studia připravil kód
using System; namespace Program1 { /// <summary> /// Summary description for Class1. /// class Class1 { /// <summary> /// The main entry point for the application. /// [STAThread] static void Main(string[] args) { // // TODO: Add code to start application here //
(C) 2005 Vladimír Váňa
16
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná } } }
Nyní již můžeme dopsat vlastní kód a umístit ho místo poznámky // TODO: Add code to start application here
Dopíšeme jedinou řádku Console.WriteLine("Ahoj C#");
Po případném uložení si našeho programu pomocí File a Save all můžeme přeložit náš program. Provedeme to výběrem Build a poté Rebuild Program 1, obr.10.
(C) 2005 Vladimír Váňa
17
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná Po tomto výběru se provede kompilace programu, že tato akce byla úspěšná, potvrzuje obsah okna Output, obr.11
Nyní již můžeme z prostředí Visual Studia spustit výsledný Program1.exe výběrem Debug a Start Without Debuging, popř. klávesovou zkratkou Ctrl+F5, obr.12
Výsledek vidíme v konzolovém okně, obr.13
(C) 2005 Vladimír Váňa
18
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Po stisknutí libovolné klávesy okno zmizí a program je ukončen. Pokud porovnáme vytváření programu v DELPHI2005 a v Visual Studio.NET 2003, tak vidíme, že postup je prakticky stejný. I vývojová prostředí se liší jen velice málo. Největším rozdílem, kterého jste si mohli všimnout, je to, že nemusíme psát kód, ve kterém čekáme na stisknutí klávesy, abychom mohli v klidu vidět výsledek práce svého programu v konzolovém okně. Vývojové prostředí VS.NET2003 v Debug režimu totiž předpokládá, že si budete chtít obrazovku prohlídnout. Tak Vám jen dopíše Press any key to continue a čeká na zmáčknutí klávesy. Pokud bychom chtěli, mohli bychom, stejně jako v DELPHI2005 přejmenovat jméno třídy Class1 vytvořené wizardem na nějaké jiné jméno, popř. přejmenovat jméno souboru se zdrojovým kódem.
Základy programování v jazyce C# s použitím Visual Studia .NET 2005 popř. s VC#.NET 2005 Express Opět předpokládáme, že již máme nainstalovaný vývojový software. Spouštíme Visual Studio 2005. Poté v menu File vybereme New a poté Project..., popř. použijeme klávesovou zkratku Ctrl+Shift+N viz. obr.14 (takže postup stejný, jako u VS.NET 2003 )
(C) 2005 Vladimír Váňa
19
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Po výběru Project... se objeví okno New project... V něm vybereme Project type: Visual C# Project, dále Templates: Console Application a dále vyplníme jméno projektu a jeho umístění a jméno řešení, obr.15 a stiskneme OK.
(C) 2005 Vladimír Váňa
20
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Opět nám wizard připraví kostru zdrojového kódu:
Nám zbývá jen dopsat řádku vlastního kódu do těla metody Main. Výsledný kód bude
(C) 2005 Vladimír Váňa
21
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
using System; using System.Collections.Generic; using System.Text; namespace Program1 { class Program { static void Main(string[] args) { Console.WriteLine("Ahoj C#"); } } }
Spustíme překlad
Bezchybný překlad je potvrzen v okně Output:
(C) 2005 Vladimír Váňa
22
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Takže můžeme výsledný program spustit z prostředí VS.NET 2005
Jeho činnost se projeví výpisem do okna konzole:
(C) 2005 Vladimír Váňa
23
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Porovnání vývojových prostředí Zatím jsme se seznámili s třemi vývojovými prostředími. Mohli jsme si všimnout, že práce s nimi je téměř totožná. DELPHI 2005 i Visual Studio.NET 2003 dokonce vytváří i stejnou kostru aplikace, obě pracují nad .NET Frameworkem v.1.1. Mají i prakticky stejný vzhled prostředí. Nové Visual Studio. NET 2005 má jiný, modernější vzhled a navíc pracuje nad novější verzí .NET Frameworku – verze 2.0. Proto wizard importuje trochu jiné jmenné prostory:
using System; using System.Collections.Generic; using System.Text;
Další viditelnou změnou je to, že wizard do kostry konsolové aplikace nevložil žádné poznámky. Toto prostředí budeme používat v dalších výukových materiálech.. Zatím je zdarma k dispozice ve verzi beta 2. ( červen 2005 ). Ostrá verze ve vydání Visual C# .NET Expres má být od podzimu k dispozici opět zdarma a již teď je zřejmé, že půjde o nejdokonalejší vývojový nástroj, takže využití tohoto profesionálního nástroje bude jistě dobrou volbou i pro výuku.
V tomto elementárním výukovém materiálu však budeme v dalších kapitolách používat DELPHI 2005. Chci tím ve výuce základů programování zjednodušit přechod od jazyka PASCAL
(C) 2005 Vladimír Váňa
24
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná k jazyku C#. Na tomto místě se pokusím zodpovědět na vnucující se otázku, proč se místo PASCALu učit C#: •
Začneme historií: V prosinci 1969 profesor Nicklaus Wirth vytvořil programovací jazyk Pascal. Jeho účelem bylo usnadnit studentům si osvojit koncepci strukturovaného programování. Komerčně využitelným se však jazyk PASCAL stal až poté, co v roce 1983 Andres Hejisberg z firmy Borland uvedl TURBO Pascal. Nejprve pro OS CP/M a poté i pro počítače PC s MS DOSem. Tento produkt pro DOS, jehož vývoj byl již dávno ukončen se dodnes často používá při výuce programování. Poté, co se v praxi začala prosazovat koncepce objektově orientovaného programování doplnil A. Hejisberg svůj Turbo Pascal o prvky OOP. Další významný počin učinil A. Hejisberg, když po příchodu operačního systému Windows doplnil Turbo Pascal, který mezitím přejmenoval na Object Pascal, o visuální prvky a vytvořil slavné DELPHI. DELPHI se pak stalo na dlouhou dobu vlajkovou lodí firmy Borland. Třetím významným počinem Andrese Hejisberga bylo to, že svou erudici a zkušenosti začal zúročovat poté, co opustil firmu Borland a začal pracovat jako senior architekt firmy Microsoft na návrhu platformy .NET. Počátkem roku 1998 pak začal pracovat na vývoji jazyka C#.
•
I po odchodu A. Hejisberga pokračovala firma BORLAND ve vývoji svého produktu DELPHI a stejně jako konkurence přicházela v 1 až 2 letých cyklech s novou verzí svého produktu. Dokonce přišla s výborným nápadem implementovat úspěšné DELPHI i na platformu Linux a tento svůj nápad uskutečnila. DELPHI pro Linux uvedla pod názvem Kylix. Jako velká výhoda měla být možnost v jazyce Pascal napsaný zdrojový kód využít při tvorbě programů pro Windows i Linux. Poměrně brzy po uvedení Kylixu uvedla Kylix 2. Poslední verzí je však Kylix 3 z října 2002. Poté tento nápad opustila a raději se věnovala vývoji prostředí pro jazyk Java JBuilderu. V maximálně ročních intervalech přichází s novými verzemi JBuilderu. Když se začala prosazovat platforma Microsoft .NET, začala firma Borland nejprve v verzi DELPHI 7 a hlavně DELPHI 8 portovat tento svůj významný produkt na .NET. Vítězně se prosazující platforma .NET s jazykem C# v praxi nakonec zcela porazila jazyk PASCAL. Zcela zvítězily dvě platformy. Starší J2EE s jazykem Java firmy SUN Microsystems a novější Microsoft .NET s jazykem C#. Programátoři v těchto jazycích patří k nejvyhledávanějším a velká poptávka je po těch, kteří programují v obou jazycích: Javě i C#.
•
Firma Borland nakonec reagovala na výše zmíněné skutečnosti tím, že zcela přepracovala prostředí DELPHI a v DELPHI 2005 je toto prostředí téměř dvojníkem prostředí Visual Studio. NET 2003. Hlavně ale doplnila DELPHI o jazyk C#, přičemž jeho možnosti v DELPHI 2005 jsou větší, než jazyka Pascal, který v DELPHI 2005 ještě pod názvem Delphi language ponechala
•
Kromě toho, že firma Borland, praktický tvůrce jazyka Pascal, přechází na C# je dalším důvodem, proč ve výuce nahradit jazyk Pascal a to, že tento jazyk byl navržen s ohledem na koncepci strukturovaného procedurálního programování. Jazyk C# vznikl o mnoho let později, v době kdy zcela převládlo objektově orientované programování a událostní programování. Vznikl v době, kdy již byly zkušenosti s velice úspěšným jazykem Java a tak mohl použít klady jazyka Java a naopak se vyvarovat jejich nedostatků.
•
Hlavním důvodem, proč učit právě C# jsou ale požadavky firemní praxe a to, že již je zřejmé, že nejde o nějakou módní novinku. Firmě Microsoft se podařilo svého korunního prince prosadit.
(C) 2005 Vladimír Váňa
25
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná Kromě profesionálních vývojových nástrojů můžeme při výuce programování v C# používat i nástroje jako např. SharpDeveloper. I tato cesta může vést k úspěchu, viz např. http://vyuka.drahos.cz , kde si můžeme přečíst i další důvody, proč se učit C# . Než přistoupíme k další výuce programování v C#, musíme učinit ještě dvě poznámky týkající se DELPHI 2005 a VS.NET. Po překladu našich programů jsme prováděli spuštění našeho programu přímo z vývojového prostředí. VS.NET nám umožnilo, že i bez vložení řádky Console.ReadLine(); můžeme v režimu příkazové řádky sledovat činnost našeho programu. V případě, kdy budeme náš program spouštět přímo, tj. rovnou ze systému spustíme Program1.exe, dojde k tomu, že po ukončení běhu tohoto programu bude ukončen režim příkazové řádky a my uvidíme jen krátké probliknutí černé obrazovky. Proto bude rozumné na konci našich programů umisťovat řádku s Console.ReadLine(); i ve VS.NET. Další poznámka se týká upozornění, že jsme vytvořili program za použití kompilátoru v režimu Debug. Pro školní účely by to mohlo stačit. Z hlediska praxe je ale dobré si zvykat na to, že po odladění programu je vhodné vytvořit pro zákazníka konečnou verzi za použití kompilátoru v režimu Release. V DELPHI 2005 tento režim nastavíme volbou Project a poté Optioms…
(C) 2005 Vladimír Váňa
26
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná A vybereme možnost Release. ( v ostatních vývojových prostředích postupujeme obdobně) Nyní již máme dostatečné počáteční vědomosti týkající se práce s některým z vývojových prostředí a tak se pustíme do programování. Program2 bude jen rozšířením Programu1. Jeho zdrojový kód
using System; namespace Program2 { class Class { static void Main(string[] args) { Console.Write("ahoj"); Console.WriteLine("toto je muj"); Console.Write("novy program."); Console.Read() ; } } }
Při jeho vytváření jsme opět využili wizard a vybrali jsme konzolovou aplikaci. Z kódu vytvořeného wizardem jsme odstranili všechny poznámky a naopak jsme doplnili 4 řádky vlastního kódu. Třebaže zatím neznáme nic z OOP, můžeme k našim 4 vlastním řádkám kódu poznamenat, že v nich se provádí volání metod třídy Console. Jména těchto metod jsou umístěna za tečkou ( tzv. tečková notace) .Jistě jste si všimli, že pokud při psaní zdrojového kódu používáte VS.NET či DELPHI2005, zobrazí se Vám po napsání tečky za jménem třídy seznam jejich datových a funkčních členů ( metod). V DELPHI2005 to vypadá takto:
(C) 2005 Vladimír Váňa
27
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Po překladu a spuštění Programu2, se na konzoli vypíše
ahojtoto je muj novy program.
Určitě jste si všimli, že za slovem ahoj není mezera. Metoda Write při výpisu totiž pokračuje za předchozím textem. Metoda WriteLine vypisuje text stejně jako metoda Write, ale po výpisu textu ještě přejde na nový řádek. Od dalších programů kromě výpisu na konzoli budeme vyžadovat i další činnost. K tomu budeme v programech potřebovat proměnné ( později se dozvíme, že v jazyce C# mohou být proměnné třídy a proměnné instance).
Proměnné Zatím jsme v prvních dvou programech pracovali jen s znakovými řetězci. Předpokládejme, že chceme dělat něco složitější, např. sečíst dvě čísla a výsledek vytisknout. K tomu ale budeme potřebovat místo v paměti, kam uložíme hodnoty obou sčítanců, a také místo pro uložení výsledku. Jinak řečeno, budeme potřebovat proměnné. Abychom mohli proměnné používat, musíme systému přikázat, aby je vytvořil. Musíme deklarovat proměnné. Deklarujeme ji takto: datový_typ identifikátor. Abychom mohli proměnnou používat, musíme ji inicializovat. Později si ukážeme, jak se inicializace provádí. Nejdříve si ale vyjmenujeme a popíšeme datové typy, které budeme při programování používat. Proměnné rozdělujeme do dvou skupin, podle toho, v jaké paměti se uchovávají. V zásobníkové paměti se uchovávají tzv. Hodnotové typy. Naopak v tzv. haldě se uchovávají Odkazové typy. Za definice typů používaných v prostředí .NET zodpovídá jednotný typový systém ( CTS Common Type System). Většina programovacích jazyků pro prostředí .NET však často používá
(C) 2005 Vladimír Váňa
28
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná alternativní názvy neboli aliasy těchto typů. Např. celé číslo v systému CTS skládající se ze čtyř bytů je označeno typem Systém.Int32. Jazyk C# používá jako přezdívku int. V použití obou názvů nejsou žádné rozdíly. V následující tabulce jsou uvedeny běžné typy CTS a jejich aliasy v C# .
Typ systému CTC alias v C#
popis
Systém.Object
object
základ všech typů systému CTS
Systém.String
string
řetězec
Systém.SByte
sbyte
8 – bitová hodnota se znaménkem
Systém.Byte
byte
8 – bitová hodnota bez znaménka
Systém.Int16
short
16 – bitová hodnota se znaménkem
Systém.UInt16
ushort
16 – bitová hodnota bez znaménka
Systém.Int32
int
32 – bitová hodnota se znaménkem
Systém.UInt32
uint
32 – bitová hodnota bez znaménka
Systém.Int64
long
64 – bitová hodnota se znaménkem
Systém.UInt64
ulong
64 – bitová hodnota bez znaménka
Systém.Char
char
16 – bitový znak v kódování Unicode
Systém.Single
float
32 – bitové reálné číslo podle standardu IEEE
Systém.Double
double
64 – bitové reálné číslo podle standardu IEEE
Systém.Boolean
bool
logická hodnota
Systém.Decimal
decimal
Datový typ o 128 bitech pro výpočty s 28 nebo 29 platnými číslicemi
Vyjmenovali jsme si všech 15 předdefinovaných typů, které se v jazyku C# vyskytují. Mezi nimi jsou typy object a string odkazové typy. Zbývající jsou hodnotové. U nich si nyní ukážeme, jak je definovat a následně inicializovat v programu. Pojďme si nyní postupně vysvětlit jak je definovat a následně inicializovat v programu.
Definice
a
inicializace
Ukázky definice a inicializace proměnných si ukážeme na dalším příkladu programu:
using System;
(C) 2005 Vladimír Váňa
29
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná namespace Program3 { class Prog3 { static void Main(string[] args) { int i ; long l = 1234567890; float f; bool b; char ch; string s; i = 10; f = 1.2345f; b = true; ch = 'A'; s = "řetězec znaků"; Console.WriteLine(i); Console.WriteLine("toto je reálné číslo f = " + f); Console.WriteLine("toto je řetězec " + s + " a jeden znak " + ch); Console.WriteLine("toto je velké číslo l={0}",l); Console.WriteLine("tuto hodnotu vypíšeme na dalším řádku \n\t\"" + b + "\""); Console.ReadLine() ; } } }
V těle metody Main je nejprve definována proměnná i datového typu int. Na dalším řádku máme nejenom definici proměnné typu long, ale je jí i přiřazena hodnota, konkrétně 1234567890. Na dalších čtyřech řádcích jsou definice dalších proměnných. Máme tedy definováno šest
(C) 2005 Vladimír Váňa
30
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná proměnných, jedna z nich je i inicializovaná. Zbývajících pět proměnných je inicializováno na dalších řádcích. Všimněme si, že v jazyce C# za číslicemi, kterými označujeme hodnoty proměnných můžeme a někdy dokonce musíme napsat určité písmeno. K reálné proměnné f, kterou jsme definovali jako float musíme za číslo napsat malé nebo velké písmeno f (F) aby tato proměnná byla definovaná jako typ float. Jinak by překladač jazyka C# vypsal chybu. Považuje každé číslo jiné než celé, za číslo typu double. Rovněž za číslem typu decimal musí následovat písmeno m nebo M. např. decimal = 34.456M. Zdá se to sice zbytečně komplikované, ale donutí nás to přemýšlet o typech použitých proměnných, a tím zmenšit možnost toho, že způsobíme chybu. Typ bool může nabývat hodnot true (pravda) nebo false (nepravda). Jako další typ jsme inicializovali char. Hodnoty typu char jsou znaky. Přestože je tento typ zvnějšku podobný typu char používanému v jazycích C a C++, je mezi nimi jeden podstatný rozdíl. Typ char v jazyce C++ zastupuje 8bitový znak, zatímco stejnojmenný typ v jazyce C# zastupuje znak o délce 16 bitů. I to je jeden z důvodů, proč v jazyce C# nelze implicitně převádět hodnoty typu char na 8bitové hodnoty typu byte. Přestože ke kódování všech znaků anglické abecedy a číslic stačí pouhých 8 bitů, stejný počet bitů je již zcela nepostačující pro kódování abeced s větším rozsahem znakových sad (např. čínštiny). Proto se v IT oboru přechází od 8bitových znakových sad k 16bitovému kódu Unicode, jehož podmnožinou je i kódování ASCII. Konkrétní hodnoty (literály) typu char jsou ohraničeny apostrofy např. 'A'. Pokusíme-li se ohraničit znak uvozovkami, bude překladač hlásit chybu.. Posledním typem v našem programu je string. String chápeme jako určitý řetězec znaků typu char, který zadáváme do uvozovek. Další příkaz, WriteLine jsme si již popsali. Metoda WriteLine umožňuje zobrazit výstup z programu. Ukázali jsme si různé možnosti použití této metody. Na první řádce se vypíše jen hodnota proměnné. Na dalším řádku se provádí spojení retězců pomocí znaménka +. Řetězec je v uvozovkách a hodnota se zobrazí po přidání + a názvu hodnoty. Všechny řetězce se spojují pomocí +. Znaménko + v tomto případě neslouží k označení operátoru sčítání čísel, ale spojení, zřetězení, řetězců. Další výpis řetězce je ukázkou použití indexů v složených závorkách. Slouží k označení míst v řetězci, do kterých metoda WriteLine umístí hodnoty proměnných, jejichž názvy jsou umístěny za čárkou uvedenou za řetězcem. U posledního použití metody WriteLine jsme použili spojení řeťězců, ale i použití některých řídících znaků. Tak \n vyjadřuje, že se má skočit na nový řádek, potom následuje \t což znamená (tabulátor) posun a nakonec jsme použili \”, které zobrazí uvozovky. Výstup z našeho třetího programu bude tedy následující: 10 toto je reálné číslo f = 1,2345 toto je řetězec řetězec znaků a jeden znak A toto je velké číslo l = 1234567890 tuto hodnotu vypíšeme na dalším řádku “True”
(C) 2005 Vladimír Váňa
31
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Kromě proměnných občas potřebujeme konstanty. V podstatě jsou to proměnné, jejichž hodnoty nemůžeme při běhu programu měnit. Zapisujeme je tak, že před definici a inicializaci umístíme klíčové slovo const. Např. const int i = 10;. Abychom mohli pracovat s proměnnými, potřebujeme ještě operátory, jimi se budeme zabývat v poslední části této kapitoly.
Operátory Množina operátorů v jazyce C# je až na několik výjimek identická s operátory dostupnými v jiných programovacích jazycích. Nejvíce se podobá množině operátorů v C++ a Javě. Uvedeme si tabulku základních operátorů: Operátory
kategorie
operátory
Aritmetické
+-*/%
Logické
& | ^ ~ && || !
Spojování řetězců
+
Inkrementace a dekrementace
++ --
Posun bitů
<< >>
Porovnání
== != <> <= >=
Přiřazení
= += -= *= /= %= |= ^= <<= >>=
Přístup k členům (pro objekty a struktury)
.
Indexování(pole a indexy)
[]
Přetypování
()
Podmíněný příkaz
?
:
Tvorba objektů
new
Typové informace
sizeof is typeof as
Řídící přepínač
checked unchecked
Zatím není nutné si ukazovat, jak všechny tyto operátory fungují, protože ještě neznáme další prvky jazyka, např. cykly, podmíněné příkazy apod..Všechny operátory se ale budeme snažit používat v našich programech. Alespoň několik jich použijeme v následujícím, posledním, programu této kapitoly.
(C) 2005 Vladimír Váňa
32
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná Ještě se ale zmíníme o komentářích. Komentáře vkládáme do zdrojového kódu abychom ho tím učinili srozumitelnějším. Můžeme do nich napsat cokoli, protože překladač ignoruje vše umístěné v komentářích. Známe dva tvary komentářů: /* vše co je za lomítkem a hvězdičkou se chápe jako komentář až k jeho ukončení pomocí */ Dalším druhem komentáře je // vše co se nachází za dvěma lomítky na daném řádku Modifikací tohoto komentáře je komentář začínající /// sloužící k tvorbě dokumentace v souborech XML. Zdrojový kód slíbeného čtvrtého programu:
using System; /* program Prog4 je napsán, aby předvedl použití operátorů - tento text je poznámkou, která se nepřekládá */ namespace Program4 { /// <summary> /// slouží k popisu v dokumentaci k Prog4. /// class Prog4 { [STAThread]
//atributy jsou novinkou v C#
static void Main(string[] args) { int i, j, z;//toto je komentář na jednom řádku int x = 1, y = 2; string s, k, l;
/* rovněž komentář
ale tento může být na několika řádkách */ i = 34; j = 56; i = i + j; //toto je součet x += y; //toto je totéž, co x = x + y z = i % x; // % znamená že dostaneme zbytek po dělení j++; // operátor inkrementace, připočítává 1 k j y--; // dekrementace -- odčítá 1 od y /* ++ a -- mohou být postfixové, tj. uvedené za proměnnou, ale mohou být i prefixové ++j či --y */ Console.WriteLine(i + " " + x + " " + z + " " + j + " " + y);
(C) 2005 Vladimír Váňa
33
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná Console.WriteLine("dá se to napsat i takto "); Console.WriteLine("i={0} x={1} z={2} j={3} y={4}",i,x,z,j,y); s = "ahoj"; k = "C#"; l = s + k; // spojení dvou řetězců pomocí + s = @" ahoj takto se používá @ "; Console.WriteLine("\n" + l); Console.Write(s); Console.ReadLine(); } } }
V tomto programu jsme použili jen několik základních operací. S dalšími se seznámíme v dalších programech. V zdrojovém kódu jsme umístili komentáře popisující jednotlivé operace. Výstup programu bude:
90 3 0 57 1 dá se to napsat i takto i=90
x=3 z=0 j=57 y=1
ahojC# ahoj takto se používá @
Jediné co ještě potřebuje vysvětlení je použití řetězce string s, kterému jsme nejprve přiřadili řetězec “ahoj“ a potom o dva řádky později jsme tento řetězec změnili. Takto měnit hodnoty řetězce je možné. Naopak není možné tentýž řetězec definovat několikrát. Například není možné: string s = "ahoj"; string s = "C#";
Na druhé string s = "ahoj"; s = "C#";
(C) 2005 Vladimír Váňa
straně
dovolené:
je
34
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná Ještě si všimněme použití zavináče @ před uvozovkami. Vše co je za nimi až k uzavíracím uvozovkám se pošle na výstup. Včetně řídícího znaku nový řádek.
Závěr V této kapitole jsme se seznámili s proměnnými, s operátory, příkazem WriteLine, s prací s vývojovým prostředím, s tím, jak kompilovat a spouštět programy. Rovněž jsme poznali, jak vypadá struktura konzolové aplikace, jak inicializovat proměnné a jak vypadají základní operace s proměnnými. Pokud jste již programovali v nějakém programovacím jazyce, nebylo to pro Vás nic objevného. Ale pokud jste ještě žádný programovací jazyk nepoužívali, měli byste po této kapitole pochopit alespoň trochu základy jazyka C#.
Kapitola 3.
Kontrola běhu programu v jazyce C# (Podmínkové příkazy) K tomu, abychom uměli alespoň základy programování v jazyce C# potřebujeme mít možnost provádět větvení algoritmu. Jinak řečeno, mít příkazy větvení, které umožňují předepsat, která část programu se má provést a to v závislosti na hodnotě určitého výrazu. Jazyk C# nám poskytuje dva takové příkazy if a switch.
Podmínkové
příkazy
V podmínkových příkazech se při splnění podmínky vykoná námi definovaný příkaz, není-li splnění, vykoná se jiný námi definovaný příkaz. Mezi podmínkové příkazy patří if, který zjišťuje zda je splněná podmínka a příkaz switch který porovnává výrazy. Příkaz if se vyskytuje asi v každém programovacím jazyce. Jeho tvar je následujcí: if (podmínka){ příkazy ,které se mají provést v případě splnění podmínky } else { příkazy ,které se mají provést v případě nesplnění podmínky }
Pokud by ze podmínkou následoval jen jeden příkaz, tak bychom nemuseli psát složené závorky. Je však lepší tyto složené závorky používat i v případě jediného příkazu. Výsledný kód je přehledný a snadno doplnitelný o další příkazy prováděné při splnění podmínky. Pokud chceme použít více než dvě podmínky, místo else použijeme else if. Pokusme se vytvořit jednoduchý program s použitím if, else, else if.
using System;
(C) 2005 Vladimír Váňa
35
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná namespace Program5 { class Prog5 { [STAThread] static void Main(string[] args) { int i, j; i = 2; j = 20; string s = "ahoj"; if (i != 1) // i !=(se nerovná) 1 { j = 10; //změna hodnoty proměnné j Console.WriteLine("Toto je if a hodnota j = " + j); } else //jinak, v opačném případě { Console.WriteLine("Toto je else a hodnota j = " + j); } if (s == "ahoj") //if vždy vrací booleovsku hodnotu { Console.WriteLine(s); } else if (s == "a") //pokud chceme mít několik podmínek použijeme else if { Console.WriteLine(s); } else if (s == "b") { Console.WriteLine(s); } Console.Read (); }
(C) 2005 Vladimír Váňa
36
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná } }
V prvém if zjišťujeme zda hodnota i se nerovná jedničce. V případě nerovnosti se provede příkaz následující za složenými závorkami.Tedy tuto podmínku splňuje každá hodnota různá od 1. Pokud by se, ale i rovnalo jedničce, tak se vykoná příkaz, který následuje za else. Při druhém if zjišťujeme zda se rovnají obsahy řetězců. Není-li splněná první podmínka (if), skočí se na druhé (else if), kde se zkontroluje zda je splněná podmínka. Pokud ne, tak se přesuneme na další (else if). Pokud není splněná žádná z podmínek, neprovede se žádný příkaz. Výstup je: Toto je if a hodnota j = 10 ahoj Je vidět, že se v obou případech splnila první podmínka. Pokud bychom hodnotu i nebo s změnili, tak se změní i výstup. Podmínkové příkazy lze do sebe vnořovat. Uveďme si další program ve kterém je použito vnořené if:
using System; namespace Program6 { class Prog6 { [STAThread] static void Main(string[] args) { int i; i = 7; if ((i > 1) && (i < 10)) //když hodnota bude z intervalu (1,10) { if (i <= 5)// interval (1,5> { Console.WriteLine("Číslo je menší nebo rovno 5"); } else // interval (5,10) { Console.WriteLine("Číslo je větší než 5 ale menší než 10");
(C) 2005 Vladimír Váňa
37
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná } } else // hodnota bude z intervalu <10, ∞ ) { Console.WriteLine("Číslo je větší nebo rovné 10"); } Console.ReadLine(); } } }
K příkazu if v jazyce C# musíme poznamenat, že výsledkem vyhodnocení podmínky je vždy jen true nebo false. To znamená, že v podmínce nemůžeme použít např. přiřazení nějaké hodnoty (i = 1 nebo i++). Tím se liší C# např. od jazyka C. Pro spojení dvou podmínek je použit logický operátor &&, znamenající “a zároveň”. V našem případě je podmínka splněná, takže pokračujeme v zjišťování dalších vnořených podmínek. Hodnota i = 7, proto výstup bude: „Číslo je větší než 5 ale menší než 10“.
Vstup
z
konzole
Než uvedeme další program využívající příkazy if, popíšeme si užití metody Console.Read() umožňující provádět vkládání znaků z konzole, a tím vkládat data při běhu programu. Metoda Console.Read() vrací hodnotový typ int. Zadáme-li například číslo 4 do konzoly, vrací nám tato metoda hodnotu znaku 4 v ASCII kódu.(Což je 52). Pokud bychom chtěli tuto hodnotu převést na načtený znak, použili bychom kód: int i = Console.Read(); char ch = (char) i; Console.WriteLine(ch);
Na prvém řádku se do proměnné i načte hodnota vloženého znaku v ASCII kódu. Na dalším řádku se provede převod, přetypování, na znak typu char. Metoda Console.Read() vždy vrací jen první znak. Pokud chceme přečíst celý řádek (řetězec znaků) musíme použít metodu Console.ReadLine(). string s = Console.ReadLine(); Console.WriteLine(s);
Metody Console.Read() a Console.ReadLine() ukončujeme po stisknutí klávesy Enter. Existuje ještě další metoda Console.ReadKey (), která provádí načtení stisknuté klávesy.
Převody
typů
Převod typů neboli přetypování se v jazyce C# provádí implicitně nebo explicitně.
(C) 2005 Vladimír Váňa
38
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
int i = 1234; long l = i; float f = i;
Implicitní převod dovoluje převést menší typ na typ větší. Menším či větším typem rozumíme, zda zaujímá v paměti více či méně bytů. Lze též provést převod mezi číslem celým a reálným. Implicitní převod vlastně znamená automatický převod bez použití nějakého specielního příkazu. Např. typ int můžeme převést na typ long, float, double a decimal. Typ char na ushort, int, uint, long, ulong, float, double, decimal. V případě kdy chceme převést větší typ na menší, musíme použít explicitní převod (přetypování), např.. long l = 45678; int i = (int)l;
V závorkách je uveden typ, na který chceme přetypovat hodnotu proměnné uvedené za závorkou. Pokud se ale hodnota této proměnné nevejde do přetypovaného typu, uloží se do ní nesprávná hodnota. Přesto program neohlásí žádnou chybu. V dalším programu s využitím příkazů if a Console.ReadLine() naprogramujeme jednoduchou kalkulačku.
using System; namespace Program7 //program kalkulačka - pozor, neprovádí se // kontrola vkládaných dat = pokud vložíme nesmysly, dojde k výjimce { class Prog7 { [STAThread] static void Main(string[] args) { decimal i,x,y; // budeme počítat s desetinnými čísly string s; Console.WriteLine("Zadej číslo"); x = Convert.ToDecimal(Console.ReadLine());/* Console.ReadLine() vrací * string, proto ho musíme * převést na číslo pomocí * Convert.ToDecimal */
(C) 2005 Vladimír Váňa
39
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná Console.WriteLine("Zadej operátor + - * /"); s = Console.ReadLine();//vrací string Console.WriteLine("Zadej druhé číslo"); y = Convert.ToDecimal(Console.ReadLine());// vrací číslo y // podle obsahu proměnné s se vybere operace if (s == "+") { i = x + y;//spočte výsledek Console.WriteLine("Součet " + x + " + " + y + " = " + i); } else if (s == "-") { i = x - y; //spočte výsledek Console.WriteLine("Rozdíl " + x + " - " + y + " = " + i); } else if (s == "*") { i = x * y; //spočte výsledek Console.WriteLine("Součin " + x + " * " + y + " ={0}",i); } else if (s == "/") { //výpočet lze provádět až při výpisu Console.WriteLine("Podíl " + x + " / " + y + " ={0} ",i = x / y); /* pokud chceme výstup formátovat, např. mít výstup na tři desetinná * místa, použijeme za nulou v závorce :F3 */ Console.WriteLine("Podíl " + x + " / " + y + " ={0:F3} ",i = x / y); } Console.ReadLine(); } } }
(C) 2005 Vladimír Váňa
40
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Pomocí metody Console.ReadLine() se načte řetězec znaků. Protože chceme provádět aritmetické operace, musíme ho převést na číslo. K tomu lze použít metodu Convert. Za slovem Convert následuje ten typ proměnné, na který chceme řetězec převést. V našem programu to je Convert.ToDecimal. Jinou možností by bylo použití metody Parse. Příkaz by pak vypadal takto: x = Decimal.Parse(Console.ReadLine()); Podle zvoleného operátoru + - * / se pak vybere příslušný úsek kódu a provede se v něm odpovídající operace. U výpisu výsledku dělení jsme provedli tento výpis 2 x. Ten druhý výpis je uveden jen proto, abychom si na něm předvedli možnost formátování výstupu na konzoli. V našem případě jsme ho naformátovali na výpis výsledku jen na tři desetinná místa. V našem programu nemáme ošetřen případ, kdy místo čísel x či y zadáme jiný znak. Program pak vypíše chybu a ukončí se. Ošetření těchto nežádoucích případů lze provést tzv. ošetřením výjimek pomocí konstrukcí try … catch … finally. Jak provádět ošetření výjimek si ukážeme v dalších učebních materiálech.
Podmíněný
příkaz
Obdobným příkazem jako je if...else je ternární operátor (podmíněný příkaz) (? :). Používáme jej obvykle v případě kdy výsledek má dvě možnosti, např. ano či ne. Syntaxe tohoto příkazu je : podmínka? splněná:nesplněná Použitími předvedeme na příkladě:
using System; namespace Program8 { class Class { [STAThread] static void Main(string[] args) { int i = 1; int j = 2; string s; s = (i == j ? "ano" : "ne"); /* Otázka: Rovná se obsah proměnné i obsahu proměnné j? Když ano, uloží se do s ano. Když
(C) 2005 Vladimír Váňa
41
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná ne uloží se do s ne.*/ Console.Write(s + " "); int x =10; x *= (i < j ? i : j); /* Je i menší než j? Když ano vynásobí se x hodnotou i Když ne, tak se x hodnotou j */ Console.Write(x); Console.ReadLine() ; } } }
Výstup tohoto programu je: ne
10
Switch Druhým podmínkovým příkazem je příkaz switch...case. V tomto případě porovnáváme přesné hodnoty. To znamená, že daný blok příkazů se provede jen v případě shody řetězce, znaku nebo čísla za case s naší hodnotou. Příkaz začínáme klíčovým slovem switch, za kterým v závorkách následuje proměnná, kterou chceme porovnávat. Do složených závorek vkládáme klíčová slova case, za kterými se nacházejí hodnoty proměnné. V případě shody hodnoty za case s hodnotou, kterou má daná proměnná, přesune se běh programu do bloku tohoto case. Za case a hodnotou následuje dvojtečka a teprve za ní je definovaný příslušný blok operací. Ukončení příslušného case (bloku) se označí klíčovým slovem break. V případě že chceme cosi provést když není splněna ani jedna z podmínek v case, použijeme klíčové slovo default. Ukážeme si jednoduchý program:
using System; namespace Program9 { class Prog9 { [STAThread] static void Main(string[] args) { int i = 6;
(C) 2005 Vladimír Váňa
42
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná switch (i) { case 1: // když se hodnota i rovná 1 Console.Write("Číslo je 1"); break; // konec prvního case case 2: // když se hodnota i rovná 2 Console.Write("Číslo je 2"); break; // konec druhého case default: // když hodnota i je různá od 1 a 2 Console.Write("Číslo se nerovná 1 ani 2"); break; // konec posledního case } Console.ReadLine(); } } }
Všimněme si, že každý case musí být ukončený příkazem break! V našem programu se provedl skok až na default, neboť ani jeden case nebyl splněný. Výstup tedy byl „Číslo se nerovná 1 ani 2”. V případě, kdy několika různým hodnotám chceme přiřadit stejný příkaz nebo příkazy, uděláme to takto:
using System; namespace Program10 { class Prog10 { [STAThread] static void Main(string[] args) { Console.WriteLine("Zadej název měsíce"); string s = Console.ReadLine(); s = s.ToUpper() ; switch (s)
(C) 2005 Vladimír Váňa
43
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná { case "LEDEN": case "BŘEZEN": case "KVĚTEN": case "ČERVENEC": case "SRPEN": case "ŘÍJEN": case "PROSINEC": Console.WriteLine(s + " má 31 dní"); break; case "DUBEN": case "ČERVEN": case "ZÁŘÍ": case "LISTOPAD": Console.WriteLine(s + " má 30 dní"); break; default: Console.WriteLine(s + " má 28 dní, v přestupném roce 29"); break; } Console.ReadLine() ; } } }
Vidíme, že break následuje vždy až za příkazem, který se má vykonat. Je v podstatě na Vás, který příkaz použijete, zda to bude switch či if, oba jsou podmínkové a dá se jimi provést totéž. Volbu toho, který z nich použijeme je dobré provádět tak, aby výsledný kód byl srozumitelnější.
Závěr V třetí kapitole jsme si ukázali podmínkové příkazy, načítání znaků z klávesnice a přetypování. Další konstrukce si ukážeme v následující kapitole.
Kapitola 4.
(C) 2005 Vladimír Váňa
44
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Kontrola běhu programu v jazyce C# (Cykly ) V třetí kapitole se budeme věnovat cyklům. Cykly rovněž patří k základním příkazům většiny programovacích jazyků.
Cykly Cyklus umožňuje vykonávat příkazy tak dlouho, dokud je splněná podmínka. Když dojde k tomu, že podmínka již nebude splněna, bude se pokračovat prováděním dalších příkazů umístěných za kódem cyklu. Mezi cykly patří příkazy for, while, do...while a foreach. O posledním příkaze si povíme jen okrajově, protože ho využijeme až u polí.
Cyklus
for
Pomocí cyklu for bude program opakovaně vykonávat příkazy, u kterých víme, kolikrát se mají opakovat. Cyklus for vždy nejprve kontroluje, zda je splněná podmínka, a teprve potom se provede blok příkazů. Tvar cyklu for vypadá takto:
for ( inicializace řídící proměnné; podmínka;aktualizace) Inicializace řídící proměnné je buď výrazový příkaz nebo deklarace proměnné. Zpravidla sem vkládáme klasickou inicializaci proměnné s přiřazením konkrétní hodnoty. Např. int i = 0; (popř. deklarace několika lokálních proměnných). V podmínce se zjišťuje, zda je splněna podmínka opakování. Pokud ne, provádění podmínky for skončí. Poslední částí příkazu for je aktualizace (Iterators). Je to výrazový prostředek, který typicky upravuje hodnotu řídící proměnné. Použití příkazu for si ukážeme na příkladech. Vytvořme program, který vypíše čísla od jedničky do deseti pomocí příkazu for.
using System; namespace Program11 { class Class { [STAThread] static void Main(string[] args) { for (int i = 1; i <= 10; i++) {// (inicializace; podmínka; iterátor;) Console.WriteLine(i); } Console.ReadLine() ;
(C) 2005 Vladimír Váňa
45
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná } } }
Nejprve jsme inicializovali řídící proměnou i, které jsme přiřadili hodnotu 1. V příkaze for proběhne tato inicializace jen jednou, a to při spuštění cyklu. Po přiřazení hodnoty se ověří podmínka, v našem případě je 1 <= 10 to znamená, že se provedou příkazy uvnitř cyklu. V našem případě je uvnitř cyklu jediný příkaz a to volání metody WriteLine(i); - vypíše hodnotu proměnné i tedy 1. Program pokračuje skokem na aktualizaci (iterátor), kde se k hodnotě i přičte jednička, neboť i++ provede i = i + 1. Odtud se chod programu vrátí zpět na podmínku a opět se ověřuje její platnost 2 <= 10, takže se znova bude provádět příkaz uvnitř cyklu. Takto se cyklus opakuje, dokud je podmínka splněná. Až ale nastane situace, kdy hodnota i bude větší než 10, cyklus bude ukončen a program pokračuje následujícím příkazem. Takže výstupem programu bude výpis čísel od 1 do 10. Je vidět, že v příkaze for předem víme kolikrát proběhne cyklus. Ne vždy předem víme, kolikrát má proběhnout cyklus. V tom případě místo cyklu for použijeme jiné příkazy cyklu. Cyklus for, stejně jako podmínkové příkazy lze vnořovat. Vnořený cyklus se bude provádět při každém průchodu vnějšího cyklu. Příkladem použití vnořených cyklů může být následující program, vypisující násobky čísel od jedničky do desítky.
using System; namespace Program12 { class Prog12 { [STAThread] static void Main(string[] args) { for (int i = 1; i <= 10; i++) { for (int j = 1; j <= 10; j++) /* vnořený cyklus, proběhne 10 x * pro i = 1 potom 2..3..4....10 */ { int r = i * j; Console.Write(r + " "); }// proběhne 10 x pro 10 různých i, tj.100 x
(C) 2005 Vladimír Váňa
46
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná Console.WriteLine();/* po každém ukončení vnitřního cyklu * se pošle znak nová řádka*/ } Console.ReadLine() ; } } }
1 2 3 4 5 6 7 8 9 10 2 4 6 8 10 12 14 16 18 20 3 6 9 12 15 18 21 24 27 30 4 8 12 16 20 24 28 32 36 40 5 10 15 20 25 30 35 40 45 50 6 12 18 24 30 36 42 48 54 60 7 14 21 28 35 42 49 56 63 70 8 16 24 32 40 48 56 64 72 80 9 18 27 36 45 54 63 72 81 90 10 20 30 40 50 60 70 80 90 100
Program vytvořil tabulku malé násobilky. V prvém cyklu se nejprve proměnné i přiřadí hodnota jedna. Podmínka je proto splněná a program pokračuje spuštěním vnitřního cyklu.V něm do proměnné j přiřadíme rovněž jedničku, podmínka je opět splněná, takže se provede násobení čísel i a j. Výsledkem je 1 a tento výsledek se vypíše. Ve vnitřním cyklu s proměnnou j se pokračuje, dokud je hodnota j menší nebo rovná 10. Po nesplnění vnitřního cyklu se program vrátí zpět k vnějšímu cyklu, kde se do proměnné i přiřadí číslo 2, a program znovu pokračuje ve vnitřním cyklu, kde se všechny hodnoty proměnné j násobí číslem 2 uloženým v i. Tyto dva cykly se opakují tak dlouho dokud v proměnné i je číslo menší nebo rovné 10. V dalším programu si opět ukážeme použití cyklu for. Vytvoříme program, který počítá faktoriál zadaného čísla. Tvar faktoriálu je: n! = n* (n-1)! n ≥ 1
using System; namespace Program13 { class Prog13 { [STAThread] static void Main(string[] args)
(C) 2005 Vladimír Váňa
47
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná { Console.WriteLine("Zadej číslo pro výpočet faktoriálu: "); long n = Convert.ToInt64(Console.ReadLine()); for (long i = n-1; i > 0; i--) // podle vzorce (n-1) { Console.WriteLine(n + " * " + i+ " = " + (n * i)); // mezivýsledky n *= i; //výpočet faktoriálu n*(n-1)=n*i } Console.WriteLine(n); // výsledek Console.ReadLine() ; } } }
Nejprve zadáme číslo, jehož faktoriál chceme vypočítat. Například: 5! = 5*4*3*2*1!. Jedna faktoriál se rovná jedničce, takže můžeme zapsat 5! = 5*4*3*2 = 120. Výstup našeho programu bude.
Zadej číslo pro výpočet faktoriálu: 5 5 * 4 = 20 20 * 3 = 60 60 * 2 = 120 120 * 1 = 120 120
Číslo se vždy po vynásobení v cyklu zmenší o jedničku, a tedy se postupně provádí násobení číslem zmenšeným o 1. Do n načteme 5, v cykle for přiřadíme proměnné i číslo 4, pokračujeme vynásobením a vypsáním prvého násobení, po tomto bloku příkazů snížíme hodnotu i o 1 na číslo 3. Podmínka je stále splněná, takže pokračujeme v provádění bloku příkazů. Dokud i nedosáhne 0, bude se cyklus for stále opakovat. Na konci programu už jen vypíšeme poslední (výslednou) hodnotu faktoriálu. Výpočet faktoriálu se dá jednoduše naprogramovat i pomocí rekurze. Používání příkazu for si procvičíme v dalším programu, který pomocí vytisklých znaků kreslí pyramidu - rovnoramenný trojúhelník.
(C) 2005 Vladimír Váňa
48
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
using System; //program na tisk pyramidy - rovnoramenného trojúhelníka namespace Program14 { class Prog14 { [STAThread] static void Main(string[] args) { Console.WriteLine("Zadej počet řádků pyramidy:"); int r = Convert.ToInt32(Console.ReadLine()); for (int i = 1; i <= (r * 2)+1 ; i++) // 1ní for { Console.Write("-"); } //vytiskne čáru z pomlček Console.WriteLine(); for (int i = 0; i < r; i++) // 2hé for { for (int j = i; j < r; j++) // 3tí for { Console.Write(" "); // vypíše mezery } for (int g = i + 2; g > 1; g--) // 4té for { Console.Write("*"); } for (int g = i + 1; g > 1; g--) // 5té for vypíše vždy o jeden {
// znak méně než 4té for Console.Write("*");
} for (int k = i; k < r; k++) // 6té for { Console.Write(" "); // vypíše mezery }
(C) 2005 Vladimír Váňa
49
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná Console.WriteLine(); } for (int i = 1; i <= (r * 2) + 1; i++) // 7mé for { Console.Write("-"); } //vytiskne čáru z pomlček Console.WriteLine(); Console.ReadLine(); } } }
Výstup bude např.:
Zadej počet řádků pyramidy: 6 ------------* *** ***** ******* ********* *********** -------------
U cyklu for si můžeme ještě říci, že není povinné mít uvedeny všechny tři položky – inicializaci, podmínku, aktualizaci. Ukážeme si to na příkladech:
(C) 2005 Vladimír Váňa
50
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
using System; // výpis řady čísel - klesající řada namespace Program15 { class Prog15 { [STAThread] static void Main(string[] args) { Console.WriteLine("Zadej počet čísel: "); int i = Convert.ToInt32(Console.ReadLine()); for ( ;i > 0 ;i-- ) { Console.Write(i + " "); } Console.ReadLine(); } } }
V tomto případě je vynechána inicializace, to ale znamená, že inicializace řídící proměnné se nalézá někde nad cyklem v programu. Rovněž lze vynechat podmínku, ale pak dojde k zacyklení programu a z cyklu se program dostane jen velmi obtížně, hodnoty našeho programu budou neustále klesat. for (
;
; i-- )
Aktualizace - iterátor nemusí být rovněž zadaná pokud se nachází uvnitř cyklu. for (
; i > 0 ;
)
V případě vynechání všech položek vytvoříme nekonečnou smyčku. for (
;
;
)
(C) 2005 Vladimír Váňa
51
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Závěr V této kapitole jsme se dokonale seznámili s cyklem následující kapitoly.
for. Další cykly budou předmětem
Kapitola 5.
Kontrola běhu programu v jazyce C# (Cykly - pokračování ) V páté kapitole budeme pokračovat v popisovaní cyklů a řekneme si něco i o příkazech skoku. Víme, že v cyklu dochází k opakování určitého příkazu nebo skupiny příkazů. Cyklus for používáme hlavně v tom případě, kdy předem víme, kolikrát se má opakovat. Pokud ale nevíme jaký bude počet opakovaní a zda se vůbec daný cyklus má provést použijeme buď cyklus while nebo do...while. V jazyce C# máme ještě další typ cyklu, a to cyklus foreach.
Cyklus
while
V cykle while je podmínka testovaná, ještě před tím než se spustí vnitřní blok příkazů a jeho tvar je podobný podmínkovému příkazu if.
while (podmínka) { blok příkazů } Cyklus while použijeme tehdy, když neznáme předem počet opakovaní. Opakování cyklu se provádí pokud je podmínka splněná. Ve vnitřním bloku příkazů se nachází výraz, který při určitém průchodu cyklem nastaví hodnotu podmínky na false, a tím se cyklus ukončí a pokračuje se v běhu programu. Opět si to předvedeme na příkladu programu:
using System; using System.Runtime.InteropServices; namespace Program16 { class Class { [DllImport("kernel32.dll")] public static extern bool Beep(int frequency, int duration); static void Main(string[] args) { int i = Convert.ToInt32(Console.ReadLine()); while (i == 1)
(C) 2005 Vladimír Váňa
52
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná { Beep(1000,500); // pc reproduktor vydá zvuk 1kHz, i = Convert.ToInt32(Console.ReadLine()); } } } }
Poznámka: kód
[DllImport("kernel32.dll")] public static extern bool Beep(int frequency, int duration);
nesouvisí s cyklem. Chtěli jsme si jen zpestřit naše programy a kromě výpisu znaků a řetězců na konzolu, mít i možnost generování zvuků reproduktorkem počítače PC. Tento kód nám umožní používat funkci Beep z knihovny kernell32.dll v programu v jazyce C#. Tato funkce má dva parametry. Prvním je frekvence generovaného zvuku, druhým délka jeho trvání. Obdobně lze v C# využívat další DLL knihovny. Nyní již můžeme popsat činnost Programu16. Nejprve dojde k načtení znaku z konzole. Podmínka v cyklu while je i == 1 znamená, že cyklus se provede pouze v případě, kdy v proměnné i je uložená hodnota 1. V kladném případě se provede blok příkazů v cyklu. Místo výpisu na konzolu, což jsme činili v předchozích programech, jsme naprogramovali vydávání zvuku reproduktorem PC. Po vygenerování zvuku se opět přečte znak z klávesnice. Pokud zadáme nějaké číslo, skočí se na začátek cyklu a kontroluje se platnost podmínky. V případě jejího splnění, se celý blok příkazů a metod opakuje dokud nedojde k nesplnění podmínky.
Všimněme si jedné skutečnosti týkající se použití příkazu while v předchozím programu. Hned na začátku jsme museli vytvořit novou proměnnou a přiřadit ji nějakou hodnotu. Pokud tato hodnota nebude vyhovovat podmínce, neprovede se kód v cyklu ani jednou. Pokud chceme, aby se tento kód provedl alespoň jednou, můžeme použít cyklus do...while.
Cyklus do...while Od příkazu while se liší jen tím, že podmínka opakování se vyhodnocuje až po průchodu tělem cyklu, takže se tělo provede alespoň jednou. Jeho syntaxe je
(C) 2005 Vladimír Váňa
53
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná do { blok příkazů } while(podmínka) Jak pracovat s tímto cyklem si opět ukážeme v jednoduchém programu.
using System; using System.Runtime.InteropServices; namespace Program17 { class Prog17 { [DllImport("kernel32.dll")] public static extern bool Beep(int frequency, int duration); static void Main(string[] args) { int i; do { Beep(1500,1000); Console.WriteLine("Pokud chceš pokračovat zadej 1, když ne zadej jiné číslo"); i = Convert.ToInt32(Console.ReadLine()); } while (i == 1); } } }
Nejprve inicializujeme proměnnou i. Nemusíme ji přiřadit žádnou hodnotu, protože podmínka se kontroluje až po prvním průchodu cyklem. Takže této proměnné můžeme přiřadit hodnotu až uvnitř cyklu. Cyklus začíná klíčovým slovem do, po kterém následují složené závorky, ve kterých jsou příkazy (metody) těla cyklu. Za ukončovací závorkou je umístěna podmínka, která se kontroluje vždy po průchodu tělem cyklu. Pokud jsme zadali jedničku, je podmínka splněná a znova se provede cyklus do...while. Pokud bychom zadali jiné číslo, program se ukončí.
(C) 2005 Vladimír Váňa
54
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Cyklus
foreach
Tento cyklus se v řadě programovacích jazyků vůbec nevyskytuje. Do C# byl převzat z jazyka Visual Basic. To odpovídá tomu, že tvůrci jazyka C# převzali z jiných programovacích jazyků to nejlepší, co v nich bylo. Cyklus foreach využíváme hlavně při práci s poli. Pomocí tohoto cyklu totiž můžeme přecházet přes všechny prvky pole. Zatím jsme se o polích nebavili, ale předpokládejme že máme množinu prvků M = { 0, 1, 2, 3, 4 }. Tato množina má pět prvků. Cyklus foreach umožňuje práci s touto množinou prvků. Ukážeme si program, který připočítá ke každému prvku z množiny číslo jedna a vypíše ho.
using System; namespace Program18 { class Prog18 { [STAThread] static void Main(string[] args) { int[] i = { 0, 1, 2, 3, 4 }; foreach (int j in i) { Console.Write(j + 1 +" "); } Console.ReadLine() ; } } }
Cyklus začne vždy u prvého prvku množiny (pole) a pokračuje až k poslednímu prvku v poli. V našem příkladě máme pět prvků a proto náš cyklus proběhne 5x. Funkce cyklu foreach je zřejmá již z jeho názvu. Přeložíme si for each = pro každý. Neboli pro každý prvek dělej …
Příkazy
skoku
V předchozí a této kapitole jsme pracovali s cykly. S cykly souvisí tzv. příkazy skoku, které umožňují skočit na určité označené místo v programu, ukončit cyklus nebo pokračovat v cyklu. Mezi příkazy skoku patří goto, break a continue. Pokusíme si je vysvětlit na jednoduchých příkladech. Zde si dovolíme jednu historickou poznámku. Příkazy skoku byly součástí programovacích jazyku již v dávné minulosti. Jsou např. součástí každého asembleru a staly se součástí i vyšších programovacích jazyků. Programátoři je s oblibou a často užívali, což
(C) 2005 Vladimír Váňa
55
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná mnohdy vedlo k nepřehledným programům s mnoha chybami. To byl jeden z důvodů vzniku tzv. strukturovaného programování. To doporučovalo pokud možno se příkazům skoku vyhýbat. Tato zásada platí i v době OOP. Takže příkazy skoku budeme používat jen pokud to bude opravdu účelné a jiné konstrukce jazyka by byly složité.
Příkaz
goto
Tento příkaz umožňuje programu skočit na určený řádek programu a přeskočit tak některé řádky kódu. To znamená, že např. použije-li se uvnitř cyklu, lze po kontrole hodnoty některé proměnné při splnění jisté podmínky cyklus ukončit a skočit na označený řádek a tam pokračovat v běhu programu. V následujícím programu chceme, aby cyklus po dosažení čísla 5 skočil na jiný řádek programu.
using System; namespace Program19 { class Prog19 { [STAThread] static void Main(string[] args) { for (int i = 1; i < 10; i++) { if (i == 5) goto skok;/*za goto následuje název řádku * = label * na který chceme skočit*/ Console.Write(i + " "); } Console.WriteLine("Toto se nevypíše"); //přeskočí se!!! skok: Console.WriteLine("konec"); Console.ReadLine() ; } } }
Vidíme, že součástí těla cyklu je podmínka, že v případě dosažení čísla 5, se má skočit na řádek označený návěštím skok. První čtyři čísla se tedy vypíší a při pátém čísle se skočí na label výpis a
(C) 2005 Vladimír Váňa
56
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná vypíše se konec. Vidíme, že byl přeskočen jeden řádek kódu. V programu jsme ho umístili jen jako kontrolní, abychom předvedli, že je opravdu proveden skok. Příkaz goto má i jistá omezení jeho používání. Například nelze skočit dovnitř cyklu.
Příkaz
break
S příkazem break jsme se již setkali u příkazu switch ...case. Tam jsme si vysvětlili, že ho používáme vždy na ukončení case. V našem příkladě ho použijeme na ukončení cyklu a tedy k vyskočení z daného cyklu. Opět to předvedeme na konkrétním příkladě.
using System; namespace Program20 { class Prog20 { [STAThread] static void Main(string[] args) { for (int i = 1; i < 10; i++) { if (i = = 5) break; /*za breakem je jenom středník ;*/ Console.Write(i + " "); } Console.WriteLine("Po breaku se skočí sem"); Console.ReadLine() ; } } }
Program je v podstatě stejný jako předchozí příklad. Po dosažení hodnoty 5 v cyklu for se náš cyklus ukončí klíčovým slovem break, vyskočí se z cyklu a pokračuje se v provádění programu. V případě kdy máme několik vnořených cyklů, vždy se vyskočí jen z toho cyklu, ve kterém je klíčové slovo break umístěno.
Příkaz
continue
Příkaz continue je obdobou příkazu break , ale při jeho použití dojde jen k ukončení aktuálního průběhu cyklu, a řízení programu se vrátí zpět na začátek cyklu. Jednoduchý příklad je:
(C) 2005 Vladimír Váňa
57
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
using System; namespace Prgram21 { class Prog21 { [STAThread] static void Main(string[] args) { for (int i = 1; i < 10; i++) { Console.Write(i + " "); if (i == 5) continue; Console.Write(i + " "); } Console.ReadLine() ; } } }
Vidíme, že pro každé číslo se provádějí dva výpisy. Pouze v případě, kdy se hodnota řídící proměnné i bude rovnat 5, vyhodnotí se podmínka i == 5 jako splněná a provede se continue. Znamená to, že se ukončí tento průběh cyklu a skočí se zpět na začátek cyklu. To znamená, že se neprovede druhý výpis čísla 5 a cyklus pokračuje číslem 6. Výstup z programu je 11223344566778899
Závěr V této kapitole jsme se naučili pracovat s cykly a vysvětlili jsme si, jak v cyklech používat příkazy skoku. Cykly patří mezi základní prvky většiny programovacích jazyků. Bez nich by tvorba programů byla velice obtížná. Nejčastějším cyklem který budeme používat je cyklus for. U tohoto cyklu skoro vždy víme, kolikrát se má daný cyklus provádět. Rovněž užitečné jsou cykly while a do...while, u kterých dopředu nevíme, zda se vůbec provedou a kolikrát se provedou. Poslední z cyklů foreach je používaný hlavně při práci s poli. Dále známe tři příkazy skoku. Příkaz goto dovoluje skočit na dané místo , break ukončí celý cyklus a continue ukončí jen daný průběh cyklu.
(C) 2005 Vladimír Váňa
58
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná Kapitola 6.
Třídy jazyka C# V této kapitole se pokusíme si vysvětlit některé pojmy, které jsme v našich programech používali, aniž bychom znali jejich význam. Byly to konstrukce, které nám vytvořil wizard a tak jsme se o ně nemuseli starat. Řekneme si něco o třídách (class), jak je vytvářet, a k čemu jsou dobré. Vysvětlíme si pojem static a ukážeme si jak vytvářet instance. Tato kapitola bude náročnější na pochopení, ale poskytne nám dobrý základ pro pozdější pochopení objektově orientovaného programování.
Třídy
(class)
V každém programu, který jsme zatím napsali, jsme se s tímto pojmem setkali. Pokusíme se naznačit, co to vlastně je. Zatím jsme se setkali s datovými typy, např. int a definicí a inicializací proměnných. Např.
int a ; int b ; int c ; a=2; b=3; c=4;
Od jednoho datového typu int jsme vytvořili tři proměnné a, b, c a inicializovali je hodnotami 2, 3, 4. Co vlastně znamená předchozí věta? V kapitole 2 jsme si v podkapitole Proměnné říkali, že typ int je hodnotový, a že proměnné hodnotových typů jsou ukládány v zásobníkové paměti. Dále v tabulce uvedené v kapitole 2 najdeme, že proměnné typu int mají délku 32 bitů tj. 4 byte. Příkaz int a; tedy v zásobníkové paměti přidělí 4 byte proměnné a. Obdobně int b; a int c; přidělí další 4 byte pro b a 4 byte pro c. Příkazy a = 2; b = 3; c = 4; pak do těchto paměťových míst zapíší hodnoty 2, 3 a 4.
Třída (class) je jakýmsi zobecněním datových typů. To zobecnění spočívá mj. i v tom, že se třída může skládat nejen z vnitřních dat, ale i metod, které mohou s těmito daty pracovat. Navíc tento typ není hodnotový, ale odkazový. Někdy se také říká referenční.
Mějme například třídu Tr. Pomocí příkazů Tr a;
(C) 2005 Vladimír Váňa
59
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná Tr b; Tr c; nevytvoříme nějaké proměnné, jak byste možná očekávali. Pouze v zásobníkové paměti vyhradíme paměťová místa pro a, b, c. (zatím to není důležité, ale pro Vaši informaci – v těchto paměťových místech je zatím uložena jakási hodnota nazvaná NULL). Teprve pomocí operátoru new můžeme vytvořit instanci třídy, místo instance třídy také říkáme objekt. Např. pomocí: a = new Tr(); vytvoříme objekt a neboli instanci třídy Tr. Teprve tento objekt, až po svém vytvoření pomocí new, je umístěn někde v dynamické paměti (nazývané též halda). Informace o tom, kde na haldě je umístěn je uložena v zásobníkové paměti v místě označeném a. Nebude tam tedy již NULL, ale odkaz (neboli reference) na objekt a. Můžeme si představit, že odkaz na objekt je vlastně adresa místa v dynamické paměti, kde je objekt umístěn. U hodnotových typů víme kolik byte určitý typ zaujímá v zásobníkové paměti. U objektů obvykle nevíme, kolik místa zabírá na haldě, a kde se na haldě nachází. Ostatně by nám tato informace stejně k ničemu nebyla. Vrátíme se k našemu příkladu – vytváření instancí a, b, c třídy Tr. Budou k tomu sloužit příkazy Tr a; a = new Tr(); Tr b; b = new Tr(); Tr c; c = new Tr(); Místo toho lze psát:
Tr a = new Tr(); Tr b = new Tr(); Tr c = new Tr();
(C) 2005 Vladimír Váňa
60
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná Zbývá ještě říci, kde jsme ten zobecnělý datový typ tj. třídu Tr vzali: napsali jsme kód této třídy. Tento kód začíná klíčovým slovem class a názvem třídy. Za ním je pak mezi složenými závorkami umístěn vlastní kód třídy, tj. místo, kde jsou definována vnitřní data a kód metod. Ukážeme si to na příkladě:
using System; namespace Program22 { class Tr { public static int i; //veřejná statická proměnná public int j; //veřejná nestatická proměnna private string s = "soukromá data"; //soukromá proměnná public void VypisData() { Console.WriteLine(s); } } class Prog22 { [STAThread] static void Main(string[] args) { Tr.i = 5; Tr a = new Tr(); Tr b = new Tr(); Tr c = new Tr(); a.j = 6;
(C) 2005 Vladimír Váňa
61
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná b.j = 7; c.j = 8; Console.WriteLine(Tr.i) ; Console.WriteLine(a.j) ; Console.WriteLine(b.j) ; Console.WriteLine(c.j) ; a.VypisData() ; b.VypisData() ; c.VypisData() ; Console.ReadLine() ; } } }
Jeho výstup bude:
5 6 7 8 soukromá data soukromá data soukromá data
Pokusíme se aspoň trochu vysvětlit jednotlivá místa kódu. Vidíme, že jsou v něm definovány dvě třídy Tr a Prog22. Třída Tr má tři datové složky i, j, s a jednu metodu VypisData() . Třída Prog22 má jedinou metodu Main(). V jejím těle jsou kódem
Tr a = new Tr(); Tr b = new Tr(); Tr c = new Tr();
(C) 2005 Vladimír Váňa
62
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
vytvořeny instance třídy Tr tj. objekty a, b, c. Přístup k jednotlivým složkám těchto objektů je umožněn pomocí tečkové syntaxe. Například k vnitřní celočíselné proměnné j typu int se přistupuje např. takto: a.j = 6; Obdobně se pomocí tečkové syntaxe přistupuje i k metodám: a.VypisData() ; Tímto kódem zavoláme metodu a tím se provede její kód. Před tečkou píšeme jméno objektu. Je zřejmé, že k složkám objektu můžeme přistupovat až poté, co je objekt vytvořen. Není-li vytvořen, nemůže mít ani žádné složky. Spouštíme-li program, nemáme ještě vytvořen žádný objekt. Nemůžeme tedy ani zavolat nějakou metodu objektu, např. takovou, která by pomocí operátoru new vytvořila nějakou instanci třídy tj. objekt. Jsme tedy u klasické otázky: co bylo dřív, slepice nebo vejce ? Řešením jsou tzv. statické metody, které existují již po spuštění programu. Existují tedy i v době, kdy ještě nejsou vytvořeny žádné objekty. Vždy musí existovat alespoň jedna statická metoda. Její jméno je Main a je vstupním bodem programu, tj. místem, odkud začíná běh programu. V našem případě je metoda Main metodou třídy Prog22. Protože je to jediná metoda této třídy a protože tato třída nemá jiné další složky, je také zřejmé, že je zbytečné vytvářet nějaké instance této třídy. Tak tomu bylo ostatně ve všech předchozích programech konzolových aplikací.
Obdobně, nejen metoda, ale i datová složka nějaké třídy může být definována jako static. Pak existuje i v době, kdy třeba neexistuje objekt, instance příslušné třídy. V našem programu je to statická proměnná i. Ukázali jsme si, že přístup k ní Tr.i = 5; je možný již před vytvořením jakéhokoli objektu. Dále vidíme, že tentokrát je před tečkou jméno třídy. Častým případem v učebnicích OOP, kdy se ukazuje k čemu lze použít statickou proměnnou, je počítání vytvořených objektů. Na začátku je hodnotou takové proměnné nula. Při každém vytvoření nějakého objektu se hodnota této proměnné zvýší o jedničku. Při zániku objektu se naopak sníží o jedničku.
(C) 2005 Vladimír Váňa
63
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
V kódu programu můžeme vidět další klíčová slova – modifikátory public a private. Jejich význam je alespoň zčásti zřejmý z jejich překladu do češtiny. Vysvětlení významu modifikátorů, stejně jako takových pojmů jako je dědičnost, kompozice, polymorfismus, konstruktory, destruktory, vlastnosti, rozhraní a dalších bude obsahem dalších učebních materiálů.
Závěr V této kapitole jsme učinili jen krátkou exkurzi do oblasti OOP. Účelem bylo alespoň naznačit, co nás v budoucnu ještě čeká při dalším studiu jazyka C#.
dodatek 1- Naše konzolové příklady převedené do WinForm V tomto dodatku si ukážeme, jak naše jednoduché konzolové programy předělat na aplikace WinForm. V žádném případě to nebude výuka toho, jak programovat WinForm aplikace. Bude to spíš „kuchařka“ na jeden z mnoha způsobů, jak z konzolové aplikace udělat aplikaci „okenní“. Dod.1.1 – začínáme Po spuštění DELPHI2005 postupně provedeme výběr v menu File Æ New Æ Windows Forms Application – C# Builder:
(C) 2005 Vladimír Váňa
64
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Wizard se nás zeptá na jméno našeho projektu a složku ( adresář) do které ho chceme umístit. Vyplníme tedy textBoxy tohoto okna nazvaného New Application
A stiskneme OK. Nyní nám vývojové prostředí nabídne jak zdrojový kód kostry aplikace, tak její grafickou reprezentaci:
(C) 2005 Vladimír Váňa
65
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Tato grafická reprezentace umožňuje grafický návrh . Při něm pomocí myši, popř. pomocí klávesových zkratek měníme vzhled naší aplikace, tedy to, jak bude vypadat při běhu programu. Pomocí myši můžeme vkládat různé buttony (tlačítka), textBoxy ,listBoxy (prvky umožňující vstup a výstup textu), labely (popisky) a další prvky, komponenty, z nichž jsou složena okna windowsovských programů. Jako zkušení uživatelé windows je jistě dobře znáte. První prvek Vám do grafického návrhu vložil již návrhový wizard. Tento prvek se nazývá formulář. Je tzv. kontejnerem, do kterého vkládáme další komponenty, např. tím, že je myší umisťujeme na grafickou reprezentaci formuláře.Pokud vložíte při grafickém návrhu nějaký prvek na formulář, automaticky wizard dopíše odpovídající kód do zdrojového kódu programu. Obdobně pokud změníme nějaké vlastnosti tohoto prvku, např. barvu, rozměry, velikost písma a jeho fonty apod., automaticky změní i odpovídající část kódu. Naopak pokud ručně něco změníme v kódu, automaticky se změní jeho grafická reprezentace. Vývojové nástroje s touto vlastností se nazývají dvoucestné. Je zřejmé, že grafický návrh je daleko jednodušší, než ruční psaní kódu (ostatně to je důvod existence vývojových nástrojů RAD). Nám to umožní napsat jednoduché „okenní“ programy bez sebemenší znalosti OOP a znalosti toho, jak windows „uvnitř“ fungují. Firmě Microsoft se při vytvoření platformy .NET podařila ještě jedna velice důležitá věc a totiž to, že výše popsaným způsobem lze vytvářet nejen programy pro desktopy (neboli programy které běží přímo na našem počítači), ale i aktivní internetové stránky, tj. psát programy, které mohou běžet na serveru a k nimž přistupujeme pomocí lokální sítě (intranet) nebo přes Internet. Přesněji řečeno komunikujeme s nimi prostřednictvím webovských stránek pomocí nějakého prohlížeče. (klidně i z počítače pracujícího pod jiným OS než jsou Windows).Pomocí grafického návrhu tak vlastně vytváříme vzhled a funkčnost webovských stránek. Protože se v .NET formuláře používají
(C) 2005 Vladimír Váňa
66
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná i pro tvorbu webu, rozlišuje dva typy formulářů – WinForms a WebForms. Protože i firma Borland v DELPHI2005 používá pojmenování WinForm. Ve starších Delphi při vytváření desktopové aplikace používala jen název Form. Při vytváření aplikace můžeme používat nejen několik prvků stejného typu, tj. např. Několik tlačítek, ale i několik formulářů. Abychom mohli odlišit, který prvek či formulář je ten, jehož se týká nějaká část kódu, musíme je nějak pojmenovat. I tuto práci nám wizard ulehčuje a pojmenování provádí sám. Pokud se nám ovšem nějaké jím navržené pojmenování nelíbí, můžeme ho přepsat. Nám návrh, aby se formulář jmenoval WinForm1 a odpovídající kód byl umístěn v souboru WinForm1.cs Budeme pokračovat v programování naší první windowsovské aplikace. Protože se mi zdálo, že rozměry formuláře jsou příliš malé, rozhodl jsem se je zvětšit. Postup je jednoduchý: myší přemístíme kurzor ke čtverečku, který je umístěn uprostřed hrany, kterou chceme posunout tak, aby se zvětšily rozměry formuláře. Po umístění kurzoru na značku čtvereček se změní tvar kurzoru:
Myší jsem nyní táhl tento kurzor doprava a tím zvětšil šířku formuláře. Při tažení myší musíme mít stisknuté levé tlačítko.Po dosažení potřebné šířky formuláře tlačítko pustíme. Obdobně postupujeme při zvětšování výšky formuláře. Výsledkem je:
(C) 2005 Vladimír Váňa
67
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Další akcí bude umístění textboxu, tj. editačního políčka, na formulář. Nejprve na panelu nástrojů Tool Palette vybereme položku TextBox:
(C) 2005 Vladimír Váňa
68
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Potom přesuneme kurzor myši na to místo formuláře, kde chceme mít textbox umístěný:
Pote klikneme levým tlačítkem myši. Tím způsobíme zobrazení textboxu na formuláři:
Obdobně jako při změně rozměrů formuláře, můžeme měnit i rozměry textboxu.Zatím jen ve vodorovném směru.
(C) 2005 Vladimír Váňa
69
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
To je ostatně vidět na první pohled podle toho, že pouze dva z osmi čtverečků na obvodu mají vnitřek bílý. Zbývajících 6 čtverečků je uvnitř zabarvených barvou formuláře. Tím se signalizuje, že je nelze použít při změně rozměrů textboxu. Jak název textbox napovídá, jde o prvek umožňující práci s textem, specielně jeho vstup či výstup. Wizard ho pojmenoval TextBox1 a navíc tento název umístil coby text do editačního políčka.V kapitole 6 jsem se zmínil o základních pojmech OOP, takže víme že instance nějaké třídy mají svá vnitřní data a metody, tj. funkce a procedury pro práci s těmito daty. V jazyce C# mohou mít i další složky, např. properties (vlastnosti). Jejich prostřednictvím lze přistupovat k vnitřním datům. Bez znalosti OOP nám poslední věta sice nic neříká, její důsledek však budeme často používat. Hodnoty properties (vlastností) si můžeme přečíst či změnit nejen napsáním nějakého kódu, ale můžeme při grafickém návrhu použít I tabulku v tzv. Object Inspektoru:
Každý prvek, který jsme vložili do formuláře i sám formulář mají své vlastnosti. V object inspektoru se zobrazuje tabulka odpovídající označenému prvku. Na výše uvedeném obrázku je tabulka patřící TextBoxu jehož jméno je textBox1. Jména vlastností jsou volena tak, aby bylo ihned zřejmé, co reprezentuje. Např. BackColor obsahuje informaci o barvě vnitřku editačního políčka – bude bílá a je vybrána z kolekce barev Windows. Barva písmen bude černá, což říká vlastnost ForeColor.Položka TEXT zase informuje o obsahu editačního políčka. Posuvníkem na pravé straně tabulky s properties si zpřístupníme popis obsahu dalších properties.
(C) 2005 Vladimír Váňa
70
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
M.j. vidíme, že vlastnost Multiline je přednastavena na False. Znamená, že editační políčko může mít jen jednu řádku textu. V předchozích kapitolách jsme psali konzolové aplikace, neboli programy, které posílali výstup na konzolu (ošklivého černého okna).V našem windowsowském programu je možnost využít pro zobrazování výstupu programu do textboxu. Protože naše programy poslaly na výstup často více než jeden řádek textu, potřebujeme, aby i textbox mohl zobrazovat více řádků. Myší proto umístíme kurzor k trojúhelníčku napravo od políčka s obsahem Multiline:
Klikneme levým tlačítkem a zvolíme true místo false .Nyní již můžeme měnit výšku i šířku textboxu. Takže postupně oba dva rozměry zvětšíme:
(C) 2005 Vladimír Váňa
71
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
(C) 2005 Vladimír Váňa
72
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Dále vložíme do formuláře několik tlačítek – buttons. Postupujeme obdobně, jako při vkládání textboxu. Nejprve v Tool Patlete vybereme Button:
Umístíme button do formuláře:
(C) 2005 Vladimír Váňa
73
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
a text na ploše tlačítka button1 pomocí změny properte TEXT, která obsahuje text button1
(C) 2005 Vladimír Váňa
74
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Změníme na text start
Vzhledem k dvoucestnosti našeho vývojového prostředí se tato změna ihned projeví:
(C) 2005 Vladimír Váňa
75
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Stejně budeme postupovat i při vkládání dalších tlačítek. Výsledek bude:
(C) 2005 Vladimír Váňa
76
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Při nastavování properties jste si možná všimli, že v object inspectoru je kromě záložky properties ještě další záložka – events .OS windows totiž využívá tzv. events tj. události.Takovou událostí je např. kliknutí myší, stisk klávesy apod. Napsat program ve windows vlastně znamená naprogramovat odezvy, jimiž náš program bude reagovat na různé události. Událostí ve windows je ovšem velké množství a většiny z nich si vůbec nebudeme všímat. Seznam události, které jsou vyvolávány např. tlačítkem button1 najdeme v object inspektoru pod záložkou events. Přitom musíme mít na formuláři tlačítko button1 vybrané. V hlavičce object inspektoru přitom vidíme text, obsahující jméno vybraného prvku, tj. button 1.
(C) 2005 Vladimír Váňa
77
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Rozhodl jsem se, u našich programů vzniklých úpravou konzolových programů z kapitol 2 až 6 by po kliknutí myší na tlačítko s nápisem start, tj. button1 se měl spustit kód, který bude provádět totéž, co původní konzolový program. Protože kliknutí myší na button vyvolá událost Click, umístím kód původního konzolového programu do těla metody, kterou bude volat právě událost kliknutí myší na button1. Předchozí věta poněkud kostrbatě popisuje co budeme dělat. Proto si raději popíšeme, jak to budeme dělat: Jednoduše myší umístíme kurzor do prázdného políčka napravo od textu Click v object inspektoru a levým tlačítkem myši provedeme dvojklik. Nyní vývojové prostředí automaticky místo grafického návrhu bude zobrazovat kód programu a v něm kus kódu, který právě vytvořil wizard.
(C) 2005 Vladimír Váňa
78
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Tento nový kód vypadá takto:
private void button1_Click(object sender, System.EventArgs e) { }
Wizard totiž předpokládá, že chceme naprogramovat odezvu na událost kliknutí na button1 a proto nám připravil alespoň tuto část kódu. Více již nemohl vytvořit, protože vlastně neví, co chceme a jak chceme naprogramovat. Náš kód reagující na kliknutí na button1 můžeme psát mezi dvojici složených závorek. My tam umístíme část kódu konzolové aplikace. Bude to ta část kódu, kterou jsme v konzolové aplikaci psali do metody Main(). Takže např. u Prog2w to bude kód z metody Main() programu Prog2. V tomto kódu ovšem musíme provést úpravu spočívající v tom, že volání metody výstupu do konzole nahradíme voláním metody výstupu to textBoxu.
(C) 2005 Vladimír Váňa
79
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná Pokud bychom při běhu programu klikali na tlačítko button1 několikrát, spustili bychom pokaždé kód této metody a tedy do textboxu1 přidávali stále další a další text. Proto jsem se rozhodl, že by bylo dobré mít možnost obsah textboxu1 vymazat. Proto mám na formuláři další tlačítko button2 s nápisem vymaž. Třetí tlačítko bude sloužit k ukončení celé naší aplikace. Proto nechám wizard vytvořit ještě kostru metod reagujících na kliknutí druhého či třetího tlačítka. Budeme postupovat stejně, jako při vytváření kostry metody reagující na klik prvního tlačítka. Neboli – v režimu grafického návrhu musíme vybrat druhé tlačítko a v object inspektoru v odpovídajícím políčku provést dvojklik. Protože po vytvoření metody button1_Click nám wizard přepnul vývojový nástroj do režimu zobrazování a editace zdrojového kódu, potřebujeme přepnout do režimu grafického návrhu. Přechod mezi oběma režimy se provádí výběrem záložek
Zatím jsme nenapsali ani řádek kódu a již máme vytvořen poměrně rozsáhlý zdrojový kód:
using System; using System.Drawing; using System.Collections; using System.ComponentModel; using System.Windows.Forms; using System.Data; namespace Progr1w { /// <summary> /// Summary description for WinForm. /// public class WinForm : System.Windows.Forms.Form { /// <summary> /// Required designer variable. /// private System.ComponentModel.Container components = null; private System.Windows.Forms.TextBox textBox1; private System.Windows.Forms.Button button1; private System.Windows.Forms.Button button2;
(C) 2005 Vladimír Váňa
80
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná private System.Windows.Forms.Button button3; public WinForm() { // // Required for Windows Form Designer support // InitializeComponent(); // // TODO: Add any constructor code after InitializeComponent call // } /// <summary> /// Clean up any resources being used. /// protected override void Dispose(bool disposing) { if (disposing) { if (components != null) { components.Dispose(); } } base.Dispose(disposing); } #region Windows Form Designer generated code /// <summary> /// Required method for Designer support - do not modify /// the contents of this method with the code editor. /// private void InitializeComponent() {
(C) 2005 Vladimír Váňa
81
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná this.textBox1 = new System.Windows.Forms.TextBox(); this.button1 = new System.Windows.Forms.Button(); this.button2 = new System.Windows.Forms.Button(); this.button3 = new System.Windows.Forms.Button(); this.SuspendLayout(); // // textBox1 // this.textBox1.Location = new System.Drawing.Point(32, 24); this.textBox1.Multiline = true; this.textBox1.Name = "textBox1"; this.textBox1.Size = new System.Drawing.Size(376, 408); this.textBox1.TabIndex = 0; this.textBox1.Text = "textBox1"; // // button1 // this.button1.Location = new System.Drawing.Point(440, 32); this.button1.Name = "button1"; this.button1.Size = new System.Drawing.Size(64, 40); this.button1.TabIndex = 1; this.button1.Text = "start"; this.button1.Click += new System.EventHandler(this.button1_Click); // // button2 // this.button2.Location = new System.Drawing.Point(440, 96); this.button2.Name = "button2"; this.button2.Size = new System.Drawing.Size(64, 32); this.button2.TabIndex = 2; this.button2.Text = "vymaž"; this.button2.Click += new System.EventHandler(this.button2_Click); // // button3 // this.button3.Location = new System.Drawing.Point(440, 152);
(C) 2005 Vladimír Váňa
82
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná this.button3.Name = "button3"; this.button3.Size = new System.Drawing.Size(64, 32); this.button3.TabIndex = 3; this.button3.Text = "konec programu"; this.button3.Click += new System.EventHandler(this.button3_Click); // // WinForm // this.AutoScaleBaseSize = new System.Drawing.Size(5, 13); this.ClientSize = new System.Drawing.Size(512, 453); this.Controls.Add(this.button3); this.Controls.Add(this.button2); this.Controls.Add(this.button1); this.Controls.Add(this.textBox1); this.Name = "WinForm"; this.Text = "WinForm"; this.ResumeLayout(false); } #endregion /// <summary> /// The main entry point for the application. /// [STAThread] static void Main() { Application.Run(new WinForm()); } private void button1_Click(object sender, System.EventArgs e) { } private void button2_Click(object sender, System.EventArgs e) {
(C) 2005 Vladimír Váňa
83
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
} private void button3_Click(object sender, System.EventArgs e) { } } }
Do tohoto kódu doplníme řádku kódu realizujícího vymazání textboxu1 po kliknutí na button2:
private void button2_Click(object sender, System.EventArgs e) { textBox1.Clear() ; } private void WinForm_Load(object sender, System.EventArgs e) { textBox1.Multiline = true; textBox1.Clear() ; } private void button3_Click(object sender, System.EventArgs e) { this.Close() ; }
Doplněný kód jsem v tomto textu zvýraznil silnějším písmem. Obdobně kód this.Close() ; v těle metody bttton3_Click má zabezpečit ukončení aplikace WinForm1. To by zatím mohlo stačit. Nicméně jako ukázku jsem do kódu nechal wizard umístit metodu WinForm_Load. Nejen komponenty jako textBox, button apod. mají své události, ale má je i
(C) 2005 Vladimír Váňa
84
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná formulář WinForm1. Jednou z nich je i událost Load, která nastane po spuštění našeho windowsovského programu, kdy se nejprve vytvoří formulář WinForm1. V počátcích jeho vzniku dojde k několika událostem, m.j. i Load. V praxi se dá metoda WinForm_Load využít jako místo k inicializaci nějakých proměnných, nastavení počátečního stavu nějakých komponent apod. Já jsem tam dal, vcelku zbytečně, kód textBox1.Multiline = true; Umístil jsem ho tam jako ukázku toho, že properties lze nastavovat nejen v object inspektoru, ale i v kódu programu. Protože jsem nastavení textboxu do víceřádkového režimu provedl již v object inspektoru, je tento kód zbytečný. Chtěl jsem jenom ukázat, že např. nastavení víceřádkového režimu textboxu lze provést dvěmi způsoby: buď v object inspektoru, nebo v kódu nějaké metody. Nastavení pomocí Object inspektoru je jednodušší, nemusíme napsat žádný kód. Příslušná properties je ale stále stejná po celou dobu běhu programu. Někdy bychom ale chtěli, aby se nějaká property mohla měnit i při běhu programu. Například si představme, že při běhu programu vkládáme nějaká data tím, že je zapisujeme do textboxu a náš program provádí kontrolu jejich správnosti a my chceme, aby po vložení špatné hodnoty se změnila barva písma nebo popř. barva pozadí tohoto textboxu. Proto umístíme do programu nastavení property Color v závislosti na správnosti či nesprávnosti vkládaného textu. O dalším kódu textBox1.Clear() ; již víme, že provádí vymazání textboxu. Chci, aby po spuštění programu byl textbox1 prázdný. Zatím vytvořený kód bude stejný ve všech programech Prog1w, Prog2w, Prog3w … Jediné, čím se bude kód těchto našich programů lišit, bude tělo metody button1_Click .Proto se v další části tohoto textu již nebude k této časti všech našich win programů vracet. Dokonce je možné si v tomto stavu naší činnosti si všechny soubory zkopírovat do nějakého pomocného adresáře a při psaní dalších programů využívat tyto soubory jako jakousi šablonu a při tvorbě nějaké další aplikace si vytvořit nový adresář, do něho zkopírovat naše soubory z „šablony“ a poté spustit projekt z tohoto nového adresáře a v něm doplňovat kód do metody button1_Click. Pozn. Tento způsob vytvoření jakésy šablony a kopírování souborů jistě není příliš elegantní, ale pro začátečníky snadno pochopitelný a proveditelný. V VisualStudio.NET, DELPHI2005 a jistě i dalších prostředích existují další, lepší možnosti. Např. můžeme používat nejen komponenty z Tool Palette, ale můžeme používat i své vlastní komponenty nebo komponenty získané třeba na Internetu. V našem případě bychom např. mohli vytvořit komponentu, která by vznikla složením tří tlačítek a jednoho textboxu a měla by již na začátku nastaveny nápisy na tlačítkách, jejich velikost a umístění v celkové, naší nové komponentě. Rovněž by v ní byly nastaveny počáteční vlastnosti textboxu. Při tvorbě našich programů bychom na začátku do prázdného formuláře WinForm1 umístili tuto naši komponentu a tak jediným pohybem myši měli na formuláři jak tři tlačítka a jeden textbox, tak i nastaveny jejich vlastnosti. Další možností je vytvoření vlastního wizardu. Představme si, že pracujeme ve firmě, kde je několik programátorů. Ti pracují na několika projektech a požadavek vedení firmy je, aby všechny vytvořené programy vypadaly stejně, nebo velice podobně., aby dodržovaly jakýsi firemní styl. Tomuto požadavku lze vyhovět např. tím, že pro tento firemní styl si napíší a potom používají svůj wizard. Možnosti VisualStudio.NET a dalších jsou opravdu mohutné… Kromě zatím vytvořeného kódu bude dalším programům společný i způsob vytvoření spustitelného kódu. Nebudeme si ho proto ukazovat u každého programu Prog1w, Prog2w …
(C) 2005 Vladimír Váňa
85
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná .Ostatně tento postup je naprosto stejný, jako při tvorbě konzolových aplikací. Takže si jenom zopakujeme: V menu Project vybereme Build ..
Vytvořený exe soubor můžeme spustit běžným způsobem z prostředí windows, nebo z vývojového prostředí:
Spuštěný program pak vypadá takto:
(C) 2005 Vladimír Váňa
86
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Dod.1.1 – program Prog1W Začneme prvním programem, který má vypsat nápis Ahoj C#. Do metody button1_Click Napíšeme
private void button1_Click(object sender, System.EventArgs e) { textBox1.Clear() ; //Console.WriteLine("Ahoj C#"); textBox1.AppendText("Ahoj C#") ; }
V našich programech budeme na všech místech, kde je použita metoda Console.WriteLine. Použijeme metodu textBox1.AppendText. Aby bylo zřejmé, která místa to jsou, ponechal jsem v kódu kód volání metody Console.WriteLine, ale napsal jsem před ní // a tím z ní udělal poznámku, která bude čitelná pouze pro nás a kterou bude překladač ignorovat. Po překladu programu, jeho spuštění a kliknutí na první tlačítko s nápisem start uvidíme:
(C) 2005 Vladimír Váňa
87
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
-Přesněji řečeno, uviděli bychom obdobné okno s bílým pozadím textboxu. Já jsem ale změnil pomocí object inspektoru vlastnost BackColor komponenty textbox:
Dod.1.2 – program Prog2W Protože naše činnost při tvorbě tohoto programu bude stejná, jako při tvorbě programu Prog1w, uvedu jen to, čím se liší tj. obsahem metody button1_Click
private void button1_Click(object sender, System.EventArgs e)
(C) 2005 Vladimír Váňa
88
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná { textBox1.Clear() ; //Console.Write("ahoj"); textBox1.AppendText("ahoj") ; //Console.WriteLine("toto je muj"); textBox1.AppendText("toto je muj\r\n") ; // \r\n dělá CRLF //Console.Write("novy program."); textBox1.AppendText("novy program.") ; }
A tím jak vypadá výsledek po překladu, spuštění programu a kliknutí na první tlačítko start. Vysvětlení toho, co a jak dělá tento program, stejně jako další programy najdeme v kapitolách 2 až 6 popisujících konzolové programy.
program Prog3W U tohoto programu uvedu jen obsah metody button1_Click. Výsledek je zřejmý – měl by vypadat stejně, jako u předchozího programu s výjimkou obsahu textboxu. Ten by měl být stejný jako u konzolové aplikace Prog3
private void button1_Click(object sender, System.EventArgs e) { textBox1.Clear() ; int i; long l = 1234567890; float f;
(C) 2005 Vladimír Váňa
89
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná bool b; char ch; string s; i = 10; f = 1.2345f; b = true; ch = 'A'; s = "řetězec znaků"; //Console.WriteLine(i); textBox1.AppendText(i.ToString()+ "\r\n") ; //Console.WriteLine("toto je reálné číslo f = " + f ); textBox1.AppendText("toto je reálné číslo f = " + f + "\r\n") ; //Console.WriteLine("toto je řetězec " + s + " a jeden znak " + ch); textBox1.AppendText("toto je řetězec " + s + " a jeden znak " + ch + "\r\n") ; //Console.WriteLine("toto je velké číslo l= {0}",l); textBox1.AppendText("toto je velké číslo l= " + l + "\r\n") ; //Console.WriteLine("tuto hodnotu vypíšeme na dalším řádku \n\t\"" + b + "\""); textBox1.AppendText("tuto hodnotu vypíšeme na dalším řádku \r\n\"" + b + "\"") ; }
program Prog4W Rovněž u toho programu uvedu pouze obsah metody button1_Click a výsledek.
private void button1_Click(object sender, System.EventArgs e) { textBox1.Clear() ; int i, j, z;//toto je komentář na jednom řádku int x = 1, y = 2;
(C) 2005 Vladimír Váňa
90
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná string s, k, l;
/* rovněž komentář
ale tento může být na několika řádkách */ i = 34; j = 56; i = i + j; //toto je součet x += y; //toto je totéž, co x = x + y z = i % x; // % znamená že dostaneme zbytek po dělení j++; // operátor inkrementace, připočítává 1 k j y--; // dekrementace -- odčítá 1 od y /* ++ a -- mohou být postfixové, tj. uvedené za proměnnou ale mohou být i prefixové ++j či --y */ //Console.WriteLine(i + " " + x + " " + z + " " + j + " " + y); textBox1.AppendText(i + " " + x + " " + z + " " + j + " " + y); textBox1.AppendText("\r\n"); //CR LF //Console.WriteLine("dá se to napsat i takto "); textBox1.AppendText("dá se to napsat i takto "); //Console.WriteLine("i={0} x={1} z={2} j={3} y={4}",i,x,z,j,y); textBox1.AppendText("i={0} x={1} z={2} j={3} y={4} "); textBox1.AppendText("\r\n"); //CR LF s = "ahoj"; k = "C#"; l = s + k;// spojení dvou řetězců pomocí + s = @" ahoj takto se používá @ "; //Console.WriteLine("\n" + l); textBox1.AppendText("\n " + l); textBox1.AppendText("\r\n"); //CR LF //Console.Write(s); textBox1.AppendText(s); //Console.ReadLine(); }
(C) 2005 Vladimír Váňa
91
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná program Prog5W
private void button1_Click(object sender, System.EventArgs e) { textBox1.Clear() ; int i, j; i = 2; j = 20; string s = "ahoj"; if (i != 1) // i !=(se nerovná) 1 { j = 10; //změna hodnoty proměnné j //Console.WriteLine("Toto je if a hodnota j = " + j); textBox1.AppendText("Toto je if a hodnota j = " + j + "\r\n"); } else //jinak, v opačném případě { //Console.WriteLine("Toto je else a hodnota j = " + j); textBox1.AppendText("Toto je else a hodnota j = " + "\r\n") ; } if (s == "ahoj") //if vždy vrací booleovsku hodnotu { //Console.WriteLine(s); textBox1.AppendText(s + "\r\n"); } else if (s == "a") //pokud chceme mít několik podmínek použijeme else if { //Console.WriteLine(s); textBox1.AppendText(s + "\r\n"); } else if (s == "b") { //Console.WriteLine(s); textBox1.AppendText(s + "\r\n");
(C) 2005 Vladimír Váňa
92
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná } //Console.Read (); }
program Prog6W
private void button1_Click(object sender, System.EventArgs e) { textBox1.Clear() ; int i; i = 7; if ((i > 1) && (i < 10)) //když hodnota bude z intervalu (1,10) { if (i <= 5)// interval (1,5> { //Console.WriteLine("Číslo je menší nebo rovno 5"); textBox1.AppendText("Číslo je menší nebo rovno 5") ; } else // interval (5,10) { //Console.WriteLine("Číslo je větší než 5 ale menší než 10"); textBox1.AppendText("Číslo je větší než 5 ale menší než 10") ; } } else // hodnota bude z intervalu <10, ∞ ) { //Console.WriteLine("Číslo je větší nebo rovné 10"); textBox1.AppendText("Číslo je větší nebo rovné 10") ; } //Console.ReadLine();
(C) 2005 Vladimír Váňa
93
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná }
program Prog7W Konzolový program Prog7 byl našim prvním programem, ve kterém jsme nejenom posílali text na konzolu, ale také jsme z konzole znaky přijímali. Naprogramovali jsme si jednoduchou kalkulačku provádějící součet, rozdíl, součin či podíl dvou čísel. Tato čísla jsme zadávali do konzole pomocí metody ReadLine() třídy Console, tj. používali jsme výrazy typu Console.ReadLine().Pokud budeme předělávat program Prog7 na okenní aplikaci Prog7w, budeme jako výstup opět používat textBox1, tj. v původním konzolovém programu nahradíme všechny výskyty Console.WriteLine voláním metody AppendText textboxu1. Použijeme tam tedy textBox1.AppendText, stejně jako v předchozích programech Prog1w až Prog6w. Pro vstup dat jsme v původním konzolovém programu 3 x použili Console.ReadLine(); .Poprvé pro vstup, zadání x. Potom pro zadání y a nakonec pro výběr aritmetické operace. Proto jsem pro vstup dat v Prog7w použil tři další textboxy – textBox2, textBox3 a textBox4. Postupem uvedeným na začátku tohoto dodatku jsem je umístil na formulář WinForm1 a dále jsem na něj dal jen jedno tlačítko s nápisem spočti. Výsledek může vypadat např. takto:
(C) 2005 Vladimír Váňa
94
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Upravená část konzolového programu bude opět v těle metody tlačítka button1 reagující na jeho stisknutí, tedy na událost Click. private void button1_Click(object sender, System.EventArgs e) { decimal x, y, z; String s; textBox1.Clear(); x = Convert.ToDecimal(this.textBox2.Text); y = Convert.ToDecimal(this.textBox3.Text); s = this.textBox4.Text; // podle obsahu proměnné s se vybere operace if (s == "+") { z = x + y;//spočte výsledek //Console.WriteLine("Součet " + x + " + " + y + " = " + z); textBox1.AppendText("Součet " + x + " + " + y + " = " + z); } else if (s == "-") { z = x - y; //spočte výsledek //Console.WriteLine("Rozdíl " + x + " - " + y + " = " + z); textBox1.AppendText("Rozdíl " + x + " - " + y + " = " + z); } else if (s == "*") { z = x * y; //spočte výsledek //Console.WriteLine("Součin " + x + " * " + y + " ={0}",z); textBox1.AppendText("Součin " + x + " * " + y + " = " + z); } else if (s == "/") { //výpočet lze provádět až při výpisu //Console.WriteLine("Podíl " + x + " / " + y + " ={0} ",z = x / y); textBox1.AppendText("Podíl " + x + " / " + y + " = " + (x / y)); /* pokud chceme výstup formátovat, např. mít výstup na tři desetinná
(C) 2005 Vladimír Váňa
95
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná * místa, použijeme za nulou v závorce :F3 */ //Console.WriteLine("Podíl " + x + " / " + y + " ={0:F3} ",z = x / y); } }
program Prog8W V tomto programu se vrátíme k naší původní verzi WinForm1 s jedním textboxem a třemi tlačítky. Nepotřebujeme totiž zadávat žádná data pomocí klávesnice:
private void button1_Click(object sender, System.EventArgs e) { textBox1.Clear() ; int i = 1; int j = 2; string s; s = (i == j ? "ano" : "ne"); /* Otázka: Rovná se obsah proměnné i obsahu proměnné j? Když ano, uloží se do s ano. Když ne uloží se do s ne.*/ //Console.Write(s + " "); textBox1.AppendText(s + " ") ; int x =10; x *= (i < j ? i : j); /* Je i menší než j? Když ano vynásobí se x hodnotou i Když ne, tak se x hodnotou j */ //Console.Write(x); textBox1.AppendText(x.ToString()) ; //Console.ReadLine() ;
}
(C) 2005 Vladimír Váňa
96
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
program Prog9W
private void button1_Click(object sender, System.EventArgs e) { textBox1.Clear() ; int i = 6; switch (i) { case 1:// když se hodnota i rovná 1 //Console.Write("Číslo je 1"); textBox1.AppendText("Číslo je 1") ; break;// konec prvního case case 2:// když se hodnota i rovná 2 //Console.Write("Číslo je 2"); textBox1.AppendText("Číslo je 2") ; break;// konec druhého case default: // když hodnota i je různá od 1 a 2 //Console.Write("Číslo se nerovná 1 ani 2"); textBox1.AppendText("Číslo se nerovná 1 ani 2") ; break;// konec posledního case }
}
(C) 2005 Vladimír Váňa
97
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
program Prog10W V konzolovém programu Prog10 jsme jednou použili Console.ReadLine() pro vstup dat pomocí klávesnice. Proto v Prog10w jsem textBox2 pro zadávání názvu měsíce. Formulář bude pak vypadat např. takto:
Kód metody button_Clic1 bude:
private void button1_Click(object sender, System.EventArgs e)
(C) 2005 Vladimír Váňa
98
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná { string s; textBox1.Clear() ; s = textBox2.Text; s = s.ToUpper() ; switch (s) { case "LEDEN": case "BŘEZEN": case "KVĚTEN": case "ČERVENEC": case "SRPEN": case "ŘÍJEN": case "PROSINEC": //Console.WriteLine(s + " má 31 dní"); textBox1.AppendText(s + " má 31 dní"); break; case "DUBEN": case "ČERVEN": case "ZÁŘÍ": case "LISTOPAD": //Console.WriteLine(s + " má 30 dní"); textBox1.AppendText(s + " má 30 dní"); break; default: //Console.WriteLine(s + " má 28 dní, v přestupném roce 29"); textBox1.AppendText(s + " má 28 dní, v přestupném roce 29"); break; } }
(C) 2005 Vladimír Váňa
99
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Protože postup předělání konzolových programů na okenní je již zřejmý, uvedu jen jak budou vypadat těla metody buttonClick1 v programechProg11w až Prog15w. Teprve v Prog16w budeme postupovat trochu jinak.
program Prog11W
private void button1_Click(object sender, System.EventArgs e) { textBox1.Clear() ; for (int i = 1; i <= 10; i++) {// (inicializace; podmínka; iterátor;) //Console.WriteLine(i); textBox1.AppendText(i + "\r\n") ; } }
program Prog12W
private void button1_Click(object sender, System.EventArgs e) { textBox1.Clear() ; for (int i = 1; i <= 10; i++) { for (int j = 1; j <= 10; j++) /* vnořený cyklus, proběhne 10 x * pro i = 1 potom 2..3..4....10 */
(C) 2005 Vladimír Váňa
100
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná { int r = i * j; //Console.Write(r + " "); textBox1.AppendText(r + " ") ; }// proběhne 10 x pro 10 různých i, tj.100 x //Console.WriteLine(); textBox1.AppendText("\r\n") ; /* po každém ukončení vnitřního cyklu * se pošle znak nová řádka*/ }
}
program Prog13W
(C) 2005 Vladimír Váňa
101
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
private void button1_Click(object sender, System.EventArgs e) { textBox1.Clear() ; long n = Convert.ToInt64(textBox2.Text); for (long i = n-1; i > 0; i--)// podle vzorce (n-1) { //Console.WriteLine(n + " * " + i+" = " + (n * i));// mezivýsledky textBox1.AppendText(n + " * " + i+" = " + (n * i) + "\r\n") ; n *= i; //výpočet faktoriálu n*(n-1)=n*i } //Console.WriteLine(n);// výsledek textBox1.AppendText(n + "\r\n") ; }
program Prog14W
(C) 2005 Vladimír Váňa
102
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
private void button1_Click(object sender, System.EventArgs e) { textBox1.Clear() ; int r = Convert.ToInt32(textBox2.Text); for (int i = 1; i <= (r * 2)+1 ; i++) // 1. for { //Console.Write("-"); textBox1.AppendText("-") ; } //vytiskne čáru z pomlček //Console.WriteLine(); textBox1.AppendText("\r\n") ; for (int i = 0; i < r; i++) // 2. for { for (int j = i; j < r; j++) // 3. for { //Console.Write(" "); // vypíše mezery textBox1.AppendText(" ") ; } for (int g = i + 2; g > 1; g--) // 4. for { //Console.Write("*"); textBox1.AppendText("*") ; } for (int g = i + 1; g > 1; g--) // 5. for vypíše vždy o jeden {
// znak méně než 4. for //Console.Write("*"); textBox1.AppendText("*") ;
} for (int k = i; k < r; k++) // 6. for { //Console.Write(" "); // vypíše mezery textBox1.AppendText(" ") ; } //Console.WriteLine(); textBox1.AppendText("\r\n") ;
(C) 2005 Vladimír Váňa
103
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná } for (int i = 1; i <= (r * 2) + 1; i++) // 7. for { //Console.Write("-"); textBox1.AppendText("-") ; } //vytiskne čáru z pomlček //Console.WriteLine(); textBox1.AppendText("\r\n") ; } private void button2_Click(object sender, System.EventArgs e) { textBox1.Clear() ; textBox2.Clear() ; }
program Prog15W
(C) 2005 Vladimír Váňa
104
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
private void button1_Click(object sender, System.EventArgs e) { textBox1.Clear() ; int i = Convert.ToInt32(textBox2.Text); for ( ;i > 0 ;i-- ) { //Console.Write(i + " "); textBox1.AppendText(i + " ") ; }
} private void button2_Click(object sender, System.EventArgs e) { textBox1.Clear() ; textBox2.Clear() ;
(C) 2005 Vladimír Váňa
105
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná }
program Prog16W V konzolovém programu Prog16 jsme si ukázali, jak funguje příkaz cyklu while. Naprogramovali jsme v těle tohoto cyklu pípnutí pomocí Beep a volání konzolové metody ReadLine. Ta nám umožnila sejmout znak z klávesnice a po jeho kontrole buď pokračovat v cyklu, nebo cyklus opustit a ukončit program. Předělání tohoto programu na okenní verzi tím, že bychom k zadání v kódu použili nějaký textbox např. textBox1 a přepsali výskyty Console.ReadLine() v našem kódu vlastností textBox1.Text by v tomto případě nevedlo k cíli. Je to důsledek toho, že ve Windows dochází k různým událostem (events), což vyvolává nebo může vyvolat zavolání jejich obsluhy buď přímo v OS, nebo třeba v našem programu. Jistě víte, že ve windows může běžet několik programů současně, kromě toho běží na pozadí několik procesů. To vše může vyvolat různé události a dokonce je možné, že dojde k několika událostem současně. Protože v jednom okamžiku je možné ošetřit jen jednu událost, musí zbývající počkat, až na ně přijde řada. Musí být tedy jasné které události mají přednost atd. Jsou stanoveny priority atd. Je zřejmé, že tato problematika je dosti složitá a při školní výuce patří do předmětů zabývajících se teorií operačních systémů. V našem konkrétním případě by došlo k tomu že po stisku tlačítka by probíhala obsluha události Click tohoto tlačítka.Tuto obsluhu jsme naprogramovali my tím, že jsme napsali kód těla metody button1_Click. Ale v tomto kódu máme smyčku cyklu while, který probíhá tak dlouho, dokud je splněna nějaká podmínka. Tou je hodnota nějaké proměnné. V tomto cyklu běží tak dlouho, dokud se tato hodnota nezmění. K její změně ale může dojít po zadání jiné hodnoty do textboxu popř. přímo jen stiskem nějaké klávesy. Tuto novou hodnotu ale můžeme získat jen jako výsledek zpracování události, ke které dojde tím, že jsme zadali tuto novou hodnotu. Jenomže tato událost je zpracována až poté, co bude zpracována událost button1_Click. Takže máme dvě události přičemž obsluha první události čeká až bude ukončena obsluha druhé události a ta zase naopak čeká, až bude ukončena ta první. Takto budou čekat do nekonečna .Pokud ovšem nedáme oblíbené Ctrl – Alt – Del. Můžete si vyzkoušet, napsat „špatný“ program Prog16w a ověřit si tak pravdivost předchozího odstavce. Není nutné ani, abychom dokonale rozuměli obsahu předchozího odstavce. Stačí, když si z něho vezmeme ponaučení, že logika programování okenních aplikací založená na programování obsluhy událostí je trochu jiná, než při programování konzolových aplikací podobných stařičkým programům pro MS DOS. Předvedeme si tuto jinou logiku na programu Prog16w. Jeho grafický návrh je jednoduchý. Obsahuje samotný formulář Form1. Jediné, co jsem udělal při grafickém návrhu je umístění popisky, labelu s informací pro uživatele.
(C) 2005 Vladimír Váňa
106
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Celý náš kód umístíme do těla metody Form1_KeyDown formuláře. Tato metoda totiž slouží jako obsluha události – stisku libovolného tlačítka. Proto stačí, když v těle této metody umístíme kód, který zjistí, která klávesa byla stisknuta. A bude-li to ta správná klávesa, v našem případě klávesa s 1 na numerické klávesnici, zavolá Beep. Výsledný kód může vypadat např. takto.
namespace Program16w { /// <summary> /// Summary description for Form1. /// public class Form1 : System.Windows.Forms.Form { [DllImport("kernel32.dll")] public static extern bool Beep(int frequency, int duration); private System.Windows.Forms.Label label1;
public Form1() { // // Required for Windows Form Designer support //
(C) 2005 Vladimír Váňa
107
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná InitializeComponent(); // // TODO: Add any constructor code after InitializeComponent call // } /// <summary> /// Clean up any resources being used. /// [STAThread] static void Main() { Application.Run(new Form1()); }
private void Form1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e) { if ( e.KeyCode == Keys.NumPad1) { Beep(1000,500); } } }
Prog16 měl být ukázkou použití cyklu while, který ale v Pro16w vůbec nemáme. Proto jsem vymyslel program, který bude v sobě přece jenom cyklus while mít. Místo metody Form1_KeyDown jsem ale použil metodu Form1_KeyPress a dopsal jsem do ní kód:
(C) 2005 Vladimír Váňa
108
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná private void Form1_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e) { char c; c = e.KeyChar; int i = (int) c; int doba = 1; while (i > 0) { doba++; i--; } Beep(1000,doba * 10); }
Pomocí e.KeyChar do znakové proměnné c dostaneme znak, odpovídající stisknuté klávese. Jeho přetypováním pomoci (int) dostaneme do i celé číslo, jehož hodnota je závislá na tom, kterou klávesu jsme stisknuli. Zároveň tato hodnota určuje, kolikrát proběhne cyklus while. Pomocná proměnná doba slouží ke spočítání toho, kolikrát tento cyklus proběhl. Potom jednou pípne reproduktor, přičemž délka tohoto pípnutí je závislá na tom, kterou klávesu jsme stiskli.
program Prog17W Tento program je obdobou předchozího programu. Jenom místo cyklu while je použit cyklus do … while. Aby dělal něco trochu jiného, umístil jsem Beep do těla cyklu, takže místo jednoho pípnutí bude reproduktor vydávat pípnutí při každém průchodu cyklu. Navíc přitom mění frekvenci vydávaného zvuku. private void WinForm_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e) { char c; c = e.KeyChar; int i = (int) c; int doba = 1; do {
(C) 2005 Vladimír Váňa
109
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná doba++; i--; Beep(doba*4,doba ); }while (i > 0); //Beep(1000,doba * 10); }
Oba programy, Prog16w a Prog17w jsou velice neumělé. K vygenerování tónu, jehož délka trvání bude záviset na tom, která klávesa byla stisknuta se dá napsat jednodušší kód bez použití cyklu while. Při generování více pípnutí je již použití cyklu oprávněné, ale i tak by se dal napsat elegantněji. Chtěl jsem ale předvést jednoduché prográmky využívající cykly while a do..while. U těchto cyklů nevíme předem, kolikrát budou probíhat. Tak jsem ukázal, jak pomocí proměnné (doba) můžeme zjistit počet průchodů alespoň dodatečně, po jeho ukončení. Zbývající programy jsou již bez problému, takže u nich uvádím jen stěžejní část kódu – button1_Click. program Prog18W
private void button1_Click(object sender, System.EventArgs e) { textBox1.Clear() ; int[] i = { 0, 1, 2, 3, 4 }; foreach (int j in i) { //Console.Write(j + 1 +" "); textBox1.AppendText(j + 1 +" ") ; } }
(C) 2005 Vladimír Váňa
110
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
program Prog19W
private void button1_Click(object sender, System.EventArgs e) { textBox1.Clear() ; for (int i = 1; i < 10; i++) { if (i == 5) goto skok;/*za goto následuje název řádku * = label * na který chceme skočit*/ //Console.Write(i + " "); textBox1.AppendText(i + " ") ; } //.WriteLine("Toto se nevypíše");//přeskočí se!!! textBox1.AppendText("Toto se nevypíše") ; skok:
textBox1.AppendText("konec") ; //Console.WriteLine("konec");
}
program Prog20W
(C) 2005 Vladimír Váňa
111
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná private void button1_Click(object sender, System.EventArgs e) { textBox1.Clear() ; for (int i = 1; i < 10; i++) { if (i == 5) break;/*za breakem je jenom středník ;*/ //Console.Write(i + " "); textBox1.AppendText(i + " ") ; } //Console.WriteLine("Po breaku se skočí sem"); textBox1.AppendText("Po breaku se skočí sem") ; }
program Prog21W
private void button1_Click(object sender, System.EventArgs e) { textBox1.Clear() ; for (int i = 1; i < 10; i++) { //Console.Write(i + " "); textBox1.AppendText(i + " "); if (i == 5) continue; //Console.Write(i + " "); textBox1.AppendText(i + " "); } } program Prog22W Konzolovou aplikaci Prog22 můžete bez problémů předělat na okenní Prog22w tím, že místo Console.WriteLine použijeme textBox1.AppendText kdy výstupní text budeme posílat do textBoxu1 tak, jak jsme to dělali ve všech předchozích programech. Já jsem ale tento kód trochu upravil a do metody VypisData() jsem umístil MessageBox.Show(s) ; Výsledek si můžete zkusit:
(C) 2005 Vladimír Váňa
112
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná class Tr { public static int i;//veřejná statická proměnná public int j; //veřejná nestatická proměnna private string s = "soukromá data";//soukromá proměnná public void VypisData() { MessageBox.Show(s) ; } }
private void button1_Click(object sender, System.EventArgs e) { textBox1.Clear() ; Tr.i = 5; Tr a = new Tr(); Tr b = new Tr(); Tr c = new Tr(); a.j = 6; b.j = 7; c.j = 8; //Console.WriteLine(Tr.i) ; textBox1.AppendText(Tr.i + "\r\n") ; //Console.WriteLine(a.j) ; textBox1.AppendText(a.j + "\r\n") ; //Console.WriteLine(b.j) ; textBox1.AppendText(b.j + "\r\n") ; //Console.WriteLine(c.j) ;
(C) 2005 Vladimír Váňa
113
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná textBox1.AppendText(c.j + "\r\n") ; a.VypisData() ; b.VypisData() ; c.VypisData() ; }
Vidíme, že pomocí MessageBox.Show(s) ; jsme si jednoduše naprogramovali okénko pro zprávy, tzv. MessageBox .
(C) 2005 Vladimír Váňa
114
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
dodatek 2- Pascal v DELPHI2005 Předvedeme si,jak by některé programy, které jsme napsali v C# vypadaly v jazyce Pascal. Po spuštění DELPHI2005 zvolíme File Æ New Æ Other ...
Objeví se …
(C) 2005 Vladimír Váňa
115
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Vybereme Console Application a stiskneme OK. Objeví se základ kódu vytvořeného wizardem
program Project1; {$APPTYPE CONSOLE} uses SysUtils; begin { TODO -oUser -cConsole Main : Insert code here } end.
Tento kód upravíme následujícím způsobem
program Project1;
(C) 2005 Vladimír Váňa
116
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
{$APPTYPE CONSOLE} uses SysUtils; begin Console.WriteLine('ahoj Pascal v Delphi2005'); Console.ReadLine(); end.
A obvyklým způsobem ( File Æ Save as ... ) uložíme zdrojový kód s názvem Program1 Automaticky se upraví zdrojový kód
Spustíme překlad
(C) 2005 Vladimír Váňa
117
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Z prostředí DELPHI2005 můžeme spustit výsledný program Program1.exe
V okně konzole se objeví
(C) 2005 Vladimír Váňa
118
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
V další části uvádím už jen kód jednotlivých programů. Tato část je určena jen těm, kteří již Pascal a “staré” Delphi znají a chtěli by programovat pro .NET.Proto není potřeba žádného komentáře. Jenom upozorňuji na to, že při zahajování projektu je třeba dát pozor na to, zda opravdu vybíráme DELPHI for .NET a ne DELPHI for WIN32.
Program 2
program Program2; {$APPTYPE CONSOLE} uses SysUtils; begin Console.Write('ahoj'); Console.WriteLine('toto je muj'); Console.Write('novy program.'); Console.Read() ; end.
Program 3 (C) 2005 Vladimír Váňa
119
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
program Program3; {$APPTYPE CONSOLE} uses SysUtils; var i: Integer ; l: Longint ; f: Single; b: Boolean; ch: Char; s: string; begin l := 1234567890 ; i := 10; f := 1.2345; b := true; ch := 'A'; s := 'řetězec znaků'; Console.WriteLine(i); Console.WriteLine('toto je reálné číslo f = ' + f.ToString()); Console.WriteLine('toto je řetězec ' + s + ' a jeden znak ' + ch); Console.WriteLine('toto je velké číslo l=' + l.ToString()); Console.WriteLine('tuto hodnotu vypíšeme na dalším řádku \n\t\"' +
b.ToString() + '\"');
Console.ReadLine() ; end.
Program 4
(C) 2005 Vladimír Váňa
120
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná program Prog4; {program Prog4 je napsán, aby předvedl použití operátorů, - tento text je poznámkou, která se nepřekládá } {$APPTYPE CONSOLE} uses SysUtils; var i,j,z : Integer; x ,y : Integer; s, l, k : String; begin x := 1; y := 2;
//toto je komentář, stejný jako v C++
i := 34; j := 56; i := i + j; x := x + y; z := i mod x; Inc(j); // procedura inkrementace, totéž co j := j + 1; Dec(y); // procedura dekrementace, totéž co y := y - 1; s := ' '; Console.WriteLine(i.ToString() + ' ' + x.ToString() + ' ' + z.ToString() + ' ' + j.ToString() + ' ' + y.ToString()); Console.WriteLine('dá se to napsat také takto'); // WriteLn je standardní procedura Pascalu // naopak WriteLine je metoda třídy Console .NET frameworku WriteLn('i= ',i,' x= ',x,' z= ',z,' j= ',j,' y= ',y ); s := 'ahoj'; k := 'Pascal'; l := s + k; s := ' nazdar ' + #13 + #10 + ' takto to jde také'; Console.WriteLine(#10 + l ); (C) 2005 Vladimír Váňa
121
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná Console.WriteLine(s); Console.ReadLine(); end.
Program 5
program Prog5; {$APPTYPE CONSOLE} uses SysUtils; var i,j : Integer; s:
String;
begin i := 2; j := 20; s := 'ahoj'; if (i <> 1) then // i <> (se nerovná) 1 begin j := 10; // změna hodnoty proměnné Console.WriteLine('Toto je if a hodnota j = ' + j.ToString()); end else begin Console.WriteLine('Toto je else a hodnota j = ' + j.ToString()); end; if (s='ahoj') then begin Console.WriteLine(s); end (C) 2005 Vladimír Váňa
122
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná else if (s = 'a') then begin Console.WriteLine(s); end else if (s = 'b') then begin Console.WriteLine(s); end; Console.ReadLine(); end.
Program 6
program Prog6; {$APPTYPE CONSOLE} uses SysUtils; var i: Integer; begin i := 7; if ((i>1 ) and (i<10 ) ) then
// když hodnota bude z intervalu (1,10)
begin if (i<=5) then // interval (1,5> begin Console.WriteLine('Číslo je menší nebo rovno 5 '); end else
// interval (5,10)
begin Console.WriteLine('Číslo je větší než 5 ale menší než 10 '); end; end (C) 2005 Vladimír Váňa
123
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná else
//hodnota bude z intervalu <10, nekonečno
begin Console.WriteLine('Číslo je větší nebo rovné 10 '); end; Console.ReadLine(); end.
Program 7
program Prog7; // program kalkulačka - pozor, neprovádí se // kontrola vkládaných dat = pokud vložíme nesmysly, // dojde k výjimce {$APPTYPE CONSOLE} uses SysUtils; var i,x,y: Decimal; s:
String;
j:
Single;
begin Console.WriteLine('Zadej číslo '); x := Convert.ToDecimal( Console.ReadLine() ); { Console.ReadLine() vrací string, proto ho musíme pomocí Convert.ToDecimal převést na číslo} Console.WriteLine('Zadej operátor + - * / '); s := Console.ReadLine(); //vrací string Console.WriteLine('Zadej druhé číslo '); y := Convert.ToDecimal( Console.ReadLine()) ; //vrací číslo y //podle obsahu s se vybere operace if (s = '+') then (C) 2005 Vladimír Váňa
124
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná begin i := x + y ; // spočte se výsledek Console.WriteLine('součet ' + x.ToString() + ' + ' + y.ToString() + ' = ' + i.ToString() ); end else if (s = '-') then begin i := x - y ; // spočte se výsledek Console.WriteLine('rozdíl ' + x.ToString() + ' - ' + y.ToString() + ' = ' + i.ToString() ); end else if (s = '*') then begin i := x * y ; // spočte se výsledek Console.WriteLine('součin ' + x.ToString() + '* ' + y.ToString() + ' = ' + i.ToString() ); end else if (s = '/') then begin i := x / y ; // spočte se výsledek Console.WriteLine('podíl ' + x.ToString() + ' / ' + y.ToString() + ' = ' + i.ToString() ); end; //výpočet lze provádět až při výpisu Console.WriteLine('podíl ' + x.ToString() + ' / ' + y.ToString() + ' = ' + (x/y).ToString() ); //jiná možnost výpisu s použitím Pascalovské procedury WriteLn //a formátováním výsledku i := x/y; //podíl je typu decimal, který ale neumí formátovat //procedura WriteLn, umí však formátovat typ single j := single(i); //proto přetypujeme výsledek z decimal na single WriteLn('podíl ', x.ToString(), ' / ',y.ToString(),' = ',j:8:2); Console.ReadLine(); end. (C) 2005 Vladimír Váňa
125
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Program 8 program Prog8; {$APPTYPE CONSOLE} uses SysUtils; var i,j,k,x: Integer; s: String; begin i := 1; j := 2; //místo ternárního operátoru ? v C# if (i = j) then s:='ano' else s:='ne' ; { Otázka: Rovná se obsah proměnné i obsahu proměnné j? Když ano, uloží se do s ano. Když ne uloží se do s ne} Console.Write(s + ' '); x := 10; //místo ternárního operátoru ? v C# if (i < j) then k:= i else k :=j ; x := x * k; { Je i menší než j? Když ano, vynásobí se x hodnotou i Když ne, tak se vynásobí x hodnotou j} Console.Write(x); Console.ReadLine(); end.
Program 9 (C) 2005 Vladimír Váňa
126
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
program Prog9; {$APPTYPE CONSOLE} uses SysUtils; var i: Integer; begin i := 6; case i of
//obdoba příkazu switch v C#
1: // když se hodnota i rovná 1 Console.WriteLine('Číslo je 1'); 2: // když se hodnota i rovná 2 Console.WriteLine('Číslo je 2'); else // když se hodnota i nerovná 1 ani 2 Console.WriteLine('Číslo se nerovná 1 ani 2'); end; Console.ReadLine(); end.
Program 10
program Prog10; {$APPTYPE CONSOLE} uses SysUtils; var (C) 2005 Vladimír Váňa
127
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná s: String; mesic : array[1..12] of string ('LEDEN','ÚNOR','BŘEZEN','DUBEN','KVĚTEN','ČERVEN','ČERVENEC','SRPEN', 'ZÁŘÍ','ŘÍJEN','LISTOPAD','PROSINEC'); k,i: Integer; begin Console.WriteLine('Zadej název měsíce'); s := Console.ReadLine(); s := s.ToUpper(); k:= 0; for i:= 1 to 12 do if (s = mesic[i]) then k := i; case k of 1, 3, 5, 7, 8,10, 12: Console.WriteLine(s + ' má 31 dní'); 4, 6, 9,11: 2: else
Console.WriteLine(s + ' má 30 dní '); Console.WriteLine(s + ' má 28 dní, v přestupném roce 29');
Console.WriteLine(s + ' je špatné zadání');
end; Console.ReadLine(); end.
program Prog10a; {$APPTYPE CONSOLE} // jiná varianta programu uses SysUtils; type mesic = (LEDEN,ÚNOR,BŘEZEN,DUBEN,KVĚTEN,ČERVEN,ČERVENEC,SRPEN, ZÁŘÍ,ŘÍJEN,LISTOPAD,PROSINEC); var
(C) 2005 Vladimír Váňa
128
=
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná s: String; m: mesic; function StrToMesic(s: String): mesic; begin if
(s = 'LEDEN')
then StrToMesic := mesic.LEDEN
else if (s = 'BŘEZEN')
then StrToMesic := mesic.BŘEZEN
else if (s = 'DUBEN')
then StrToMesic := mesic.DUBEN
else if (s = 'KVĚTEN')
then StrToMesic := mesic.KVĚTEN
else if (s = 'ČERVEN')
then StrToMesic := mesic.ČERVEN
else if (s = 'ČERVENEC') then StrToMesic := mesic.ČERVENEC else if (s = 'SRPEN')
then StrToMesic := mesic.SRPEN
else if (s = 'ZÁŘÍ')
then StrToMesic := mesic.ZÁŘÍ
else if (s = 'ŘÍJEN')
then StrToMesic := mesic.ŘÍJEN
else if (s = 'LISTOPAD')
then StrToMesic := mesic.LISTOPAD
else if (s = 'PROSINEC')
then StrToMesic := mesic.PROSINEC
else
StrToMesic := mesic.ÚNOR;
end;
begin Console.WriteLine('Zadej název měsíce'); s := Console.ReadLine(); s := s.ToUpper(); m := StrToMesic(s); case m of mesic.LEDEN, mesic.BŘEZEN ,mesic.KVĚTEN, mesic.ČERVENEC, mesic.SRPEN, mesic.ŘÍJEN, mesic.PROSINEC : Console.WriteLine(s + ' má 31 dní'); mesic.DUBEN, mesic.ČERVEN, mesic.ZÁŘÍ, mesic.LISTOPAD : Console.WriteLine(s + ' má 30 dní '); else Console.WriteLine(s + ' má 28 dní, v přestupném roce 29'); end; Console.ReadLine(); end.
(C) 2005 Vladimír Váňa
129
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Program 11
program Prog11; {$APPTYPE CONSOLE} uses SysUtils; var i: Integer; begin for i:= 1 to 10 do begin Console.WriteLine(i); end; Console.ReadLine(); end.
Program 12
program Prog12; {$APPTYPE CONSOLE} uses SysUtils; var i ,j, r: Integer; begin
(C) 2005 Vladimír Váňa
130
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná for i:= 1 to 10 do begin for j:= 1 to 10 do begin r := i * j; Console.Write(r.ToString() + ' '); end; Console.WriteLine(); end; Console.ReadLine(); end.
Program 13
program Prog13; {$APPTYPE CONSOLE} uses SysUtils; var n, i : Longint; begin Console.WriteLine('Zadej číslo pro výpočet faktoriálu : '); n := Convert.ToInt64(Console.ReadLine()); for i := (n-1) downto 1 do // podle vzorce (n-1) begin Console.Write(n.ToString() + ' * ' + i.ToString() + ' = ' ); n := n * i; Console.WriteLine(n.ToString() ); //mezivýsledky end; Console.WriteLine(n); // výsledek Console.ReadLine(); (C) 2005 Vladimír Váňa
131
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná end.
Program 14
program Prog14; //program na tisk pyramidy - rovnoramenného trojúhelníka {$APPTYPE CONSOLE} uses SysUtils; var r, i, j, g, k : Integer; begin Console.WriteLine('Zadej počet řádků pyramidy: '); r := Convert.ToInt32(Console.ReadLine()) ; for i := 1 to (r*2) + 1 do Console.Write('-'); Console.WriteLine(); for i:= 0 to r-1 do begin for j :=i to r-1 do Console.Write(' '); for g :=i+2 downto 2 do Console.Write('*'); for g :=i+1 downto 2 do Console.Write('*'); for k :=i to r-1 do Console.Write(' '); Console.WriteLine(); end; for i := 1 to (r*2) + 1 do Console.Write('-'); Console.WriteLine(); Console.ReadLine(); end.
(C) 2005 Vladimír Váňa
132
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Program 15
program Prog15; {$APPTYPE CONSOLE} //výpis řady čísel – klesající řada uses SysUtils; var i,j: Integer; begin Console.WriteLine('Zadej pocet cisel: '); i := Convert.ToInt32(Console.ReadLine()) ; for j := i downto 1 do begin Console.Write(j.ToString() + ' ' ); end; Console.ReadLine(); end.
Program 16
program Prog16; {$APPTYPE CONSOLE} uses SysUtils; var i: Integer;
(C) 2005 Vladimír Váňa
133
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná function Pip(frequency: Integer;duration: Integer): Boolean; external 'kernel32.dll' name 'Beep'; begin i := Convert.ToInt32(Console.ReadLine()); while (i > 1) do begin Pip(1000,500); //PC reproduktor vydá zvuk 1kHz i := Convert.ToInt32(Console.ReadLine()); end; end.
program Prog16a; {$APPTYPE CONSOLE} uses SysUtils, Windows; var i: Integer; begin i := Convert.ToInt32(Console.ReadLine()); while (i > 1) do begin Beep(1000,500); //PC reproduktor vydá zvuk 1kHz i := Convert.ToInt32(Console.ReadLine()); end; end.
[Warning] Prog17.dpr(7): W1005 Unit 'Borland.Vcl.Windows' is specific to a platform
(C) 2005 Vladimír Váňa
134
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Program 17
program Prog17; {$APPTYPE CONSOLE} uses SysUtils, Windows; var i: Integer; begin i := Convert.ToInt32(Console.ReadLine()); repeat //opakuj do té doby, než bude platit i = 1 Beep(1000,500); Console.WriteLine('Pokud nechceš pokračovat, zadej 1,' + ' když ano, tak zadej jiné číslo'); i := Convert.ToInt32(Console.ReadLine()); until i = 1; end.
Program 18
program Prog18; {$APPTYPE CONSOLE} uses SysUtils; type interval = 0..50; var imnozina: set of interval; (C) 2005 Vladimír Váňa
135
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná j: Integer; begin imnozina := [0,1,2,3,4]; for j in imnozina do
//obdoba foreach
begin Console.WriteLine(j.ToString + ' '); end; Console.ReadLine(); end.
Program 19
program Prog19; {$APPTYPE CONSOLE} uses SysUtils; label skok; var i: Integer; begin for i:=1 to 10 do begin if (i = 5) then goto skok ; Console.WriteLine(i.ToString + ' '); end; Console.WriteLine('toto se nevypíše'); // přeskočí se skok: Console.WriteLine('konec'); Console.ReadLine(); (C) 2005 Vladimír Váňa
136
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná end.
Program 20
program Prog20; {$APPTYPE CONSOLE} uses SysUtils; var i: Integer; begin for i:=1 to 10 do begin if (i = 5) then break ; Console.WriteLine(i.ToString + ' '); end; Console.WriteLine('po breaku se skočí sem'); Console.ReadLine(); end.
Program 21
program Prog21; {$APPTYPE CONSOLE} uses SysUtils; var (C) 2005 Vladimír Váňa
137
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná i: Integer; begin for i:=1 to 10 do begin if (i = 5) then continue ; Console.WriteLine(i.ToString + ' '); end; Console.WriteLine('konec'); Console.ReadLine(); end.
Program 22
program Prog22; {$APPTYPE CONSOLE} uses SysUtils; type Tr = class const s : String = 'vnitrni data'; public i, j: Integer; procedure VypisData; end; var a, b, c : Tr; procedure Tr.VypisData; begin Console.WriteLine(s); (C) 2005 Vladimír Váňa
138
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná end; begin a := Tr.Create; b := Tr.Create; c := Tr.Create; a.j := 6; b.j := 7; c.j := 8; Console.WriteLine(a.j); Console.WriteLine(b.j); Console.WriteLine(c.j); b.VypisData; a.VypisData; c.VypisData; Console.ReadLine(); end.
program Prog22a; {$APPTYPE CONSOLE} uses SysUtils; type Tr = class private s : String; public i, j: Integer; constructor Init; (C) 2005 Vladimír Váňa
139
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná procedure VypisData; end; var a, b, c : Tr; constructor Tr.Init; begin Self.Create; s := 'ahoj'; end; procedure Tr.VypisData; begin Console.WriteLine(s); end; begin a := Tr.Init; b := Tr.Init; c := Tr.Init; a.j := 6; b.j := 7; c.j := 8; Console.WriteLine(a.j); Console.WriteLine(b.j); Console.WriteLine(c.j); b.VypisData; a.VypisData; c.VypisData; Console.ReadLine(); end. (C) 2005 Vladimír Váňa
140
Základy programování v C# pro naprosté začátečníky – učební materiál SPŠE Ječná
Literatura [ 1] Archer:”Myslíme v jazyce C# “, Grada 2001 [ 2] Drayton, Albahari, Neward:” C# v kostce. Pohotová příručka“, Grada, 2003 [ 3] Eller:”C# začínáme programovat“,Grada, 2002 [ 4] Gunnerson:”Začínáme programovat v C#”, ComputerPress, 2001 [ 5] Kačmář:“Programujeme .NET aplikace ve Visual Studiu .NET“, ComputerPress, 2001 [ 6] Petzold: “ Programování microsoft Windows v jazyce C#”, SoftPress, 2003 [ 7] Robinson, Allen, Dodnes, Glynn, Greenvoss, Harvey, Nagel, Skinner, Watson“ „C# Programujeme profesionálně“, Computer Press 2003 [ 8] Sharp, Jagger:”Microsoft Visual C# .NET krok za krokem”,iDnes,2002 [ 9] Virius:” C# pro zelenáče”, Neocortex,2002 [10] Virius”:Od C k C#”,Kopp,2002
(C) 2005 Vladimír Váňa
141