23
Objektno orijentirano programiranje Auditorne vježbe Elektrotehnički fakultet Osijek Kneza Trpimira 2b 31000 Osijek www.etfos.hr 1. Uvod u C# C# (CSharp) je nastao u tvrtki Microsoft i razvijen je od strane tima stručnjaka predvođenih sa Anders Hejlsberg-om i Scott Wiltamuth-om. Na tržištu se pojavio 2000. godine zajedno sa .NET platformom. C# je nastao s ciljem da bude jednostavan, siguran, moderan, objektno orijentiran jezik visokih performansi za .NET platformu. C# je nastao na temelju objektnih jezika Java, C++ i Visual Basic. Vrlo je sličan Javi i C++ jeziku (sintaksa i semantika je dobrim dijelom preuzeta iz Jave, koja je kao i C# potpuno objektno orijentirani jezik). Ali C# za razliku od Jave nije neovisan o platformi, tj. operativnom sustavu, već je kreiran za izradu stolnih (desktop) i Internet aplikacija u .Microsoft .NET okruženju. C# sadrži sve dobre odlike potpuno objektnog programskog jezika (koje većinom preuzima iz C++ i Jave), a u sklopu .NET platforme omogućava kreiranje vizualnih aplikacija čak i onim korisnicima koji nemaju programerskog iskustva. Također daje dobar uvid u način na koji nastaju objektne i vizualne aplikacije, i vrlo je lako naučiti korisnike kako projektirati takve aplikacije i upravljati njihovim korištenjem. C# sadrži samo oko 80 ključnih riječi i na desetke ugrađenih tipova podataka kao što su:

1. Uvod u C# - etfos.unios.hrlukic/oop/Auditorne_vježbe_5.pdfLjudi ...daljnja podjela prema rasi, spolu, itd. Postoji hijerarhija prostora za nazive, tako jedan prostor može sadržavati

Embed Size (px)

Citation preview

Objektno orijentirano programiranje

Auditorne vježbe

Elektrotehnički fakultet

OsijekKneza Trpimira 2b

31000 Osijek

www.etfos.hr

1. Uvod u C# C# (CSharp) je nastao u tvrtki Microsoft i razvijen je od strane tima stručnjaka predvođenih sa Anders Hejlsberg-om i Scott Wiltamuth-om. Na tržištu se pojavio 2000. godine zajedno sa .NET platformom. C# je nastao s ciljem da bude jednostavan, siguran, moderan, objektno orijentiran jezik visokih performansi za .NET platformu. C# je nastao na temelju objektnih jezika Java, C++ i Visual Basic. Vrlo je sličan Javi i C++ jeziku (sintaksa i semantika je dobrim dijelom preuzeta iz Jave, koja je kao i C# potpuno objektno orijentirani jezik). Ali C# za razliku od Jave nije neovisan o platformi, tj. operativnom sustavu, već je kreiran za izradu stolnih (desktop) i Internet aplikacija u .Microsoft .NET okruženju.

C# sadrži sve dobre odlike potpuno objektnog programskog jezika (koje većinom preuzima iz C++ i Jave), a u sklopu .NET platforme omogućava kreiranje vizualnih aplikacija čak i onim korisnicima koji nemaju programerskog iskustva. Također daje dobar uvid u način na koji nastaju objektne i vizualne aplikacije, i vrlo je lako naučiti korisnike kako projektirati takve aplikacije i upravljati njihovim korištenjem. C# sadrži samo oko 80 ključnih riječi i na desetke ugrađenih tipova podataka kao što su:

C# ima velike mogućnosti u definiranju klasa (tipova objekata), novih metoda i svojstava, te korištenju enkapsulacije, nasljeđivanja i polimorfizma kao što je to omogućeno u C++ i Javi. Također podržava XML stil unutar dokumenata, sučelja, svojstva, događaje te podržava rad s pokazivačima i ''garbage collection''. C# koristi postupak zvan garbage collection za oslobađanje memorije koju zauzimaju objekti koji više nisu dostupni programu. Programer je oslobođen brige o tome koji su mu objekti više ne trebaju (garbage), jer to umjesto njega radi sustav. Ako je objekt postojao i bio korišten neko vrijeme, može postojati nekoliko poziva na njega. Objekt postaje garbage tek nakon što su nestanu svi pozivi na njega.

Ranije smo rekli da je C# radi u razvojnom okruženjo nazvanom .NET platforma, a sada ćemo objasniti što je to. .NET platforma je zapravo razvojni okvir koji omogućava novo sučelje za programiranje aplikacija (eng. application programming interface, tj. API) i ujedinjuje klasično sučelje Windows operativnog sustava, zajedno s brojnim tehnologijama koje su proizašle iz Microsoft-a, kao što su ASP razvojni okvir za web, XML, objektno-orijentirani dizajn, podršku za nove web uslužne protokole kao što je SOAP, WSDL, i UDDI, sa naglaskom na Internet, a sve integrirano unutar DNA arhitekture (eng. Windows Distributed interNet Applications Arcitecture).

.NET platfoma sastoji se od 4 grupe proizvoda:

1. skup programskih jezika u okviru Visual Studio razvojne okoline (jezici: C#, Visual Basic .NET, Managed C++, Jscript .NET)

2. skup .NET Enterprise servera (u čijem sklopu se nalaze SQL Server, Exchange Server, BizTalk)

3. ponuda komercijalnih web usluga (Project Hailstorm)

4. mobilni .NET uređaji (koji nisu PC), kao npr. mobilni telefoni, uređaji za igre, i dr.

.NET okvir (Framework) je okvir koji povezuje programske jezike uključene u .NET

platformu, omogućavajući korištenje istih objekata (klasa), njihovo nasljeđivanje i polimorfizam u različitim jezicima koje ta platforma podržava. Dakle, jezici u .NET platformi su u isto vrijeme i nezavisni i integrirani. Kako .NET okvir omogućava integriranje programskih jezika? .NET okvir definira specifikaciju zvanu CTS (Common Type System) koje se moraju držati svi .NET jezici (npr. sve u .NET jeziku je objekt neke specifične klase koja je dio korijenske klase System.Object). .NET okvir definira opći koncept klasa, sučelja, delegata, tipova referenci i tipova vrijednosti, također uključuje i Common Language Specification (CLS), specifikaciju s pravilima kojih se treba držati kako bi integracija jezika bila moguća i kako bi neki jezik mogao biti dio .NET platforme. Prevoditelji (compiler-i) tih jezika rade na principu CLS pravila i mogu kreirati objekte koji mogu međusobno komunicirati neovisno o jeziku u kojem su napisani. Tako se stvara biblioteka klasa unutar .NET okvira - Framework Class Library (FCL) koju može koristiti bilo koji jezik koji se drži CLS-a.

Glavne komponente .NET okvira su: Četiri službena programska jezika: C#, Visual Basic .NET, Managed C++, Jscript .NET + ova dva glavna dijela koja može koristiti svaki .NET jezik:

1. Common Language Runtime (CLR) – zajednička platforma izvršavanja programa, koju dijele Windows i web aplikacije kreirane u .NET okviru

2. Skup kreiranih klasa (FCL) - biblioteka klasa koju dijele programski jezici unutar ovog okvira

Slika 1. Arhitektura .NET okvira.

CLR (Common Language Runtime) je mehanizam izvršavanja u zajedničkom jeziku koji različite .NET jezike prevodi u isti zajednički jezik, koji se koristi kada se aplikacije izvršavaju (Barker, 2007). Uključuje virtualni stroj (virtual machine), slično kao Java virtual machine (JVM), a radi tako da aktivira pojedine objekte uključene u aplikaciju, radi debugging (provjeru grešaka), provjeru tipova, te JIT (just in time) prevođenje. Prilikom prevođenja programa u .NET-u se ne kreira odmah izvršna datoteka u strojnom jeziku, nego

najprije MSIL ili IL datoteka (Microsoft Intermediate Language), koja se tek kod pokretanja projekta prevodi u strojni jezik po principu JIT, odnosno prevođenja na zahtjev (on demand). Svi jezici unutar .NET platforme proizvode sličan IL kod i objekti i klase iz jednog jezika mogu se koristiti u drugom. Biblioteke (ili skupovi) klasa u .NET okviru su različiti prostori za nazive (namespaces). Namespaces su skupovi tipova koji su logički organizirani, što omogućuje korištenje više verzija tipova s istim nazivom, ali unutar različitih prostora za nazive (npr. kao što postoje u prirodi skupine ili vrste živih bića), npr.

Živa bića Vodozemci

Gmazovi Sisavci

Životinje Ljudi

...daljnja podjela prema rasi, spolu, itd.

Postoji hijerarhija prostora za nazive, tako jedan prostor može sadržavati druge prostore u hijerarhijskom poretku. Prostori za nazive su sadržani unutar .NET okvira, ali i korisnici razvojnih alata mogu koristiti te prostore. Primjer korisničkog Namespace-a: // Namespace deklaracija using System; // Namespace deklariran od strane korisnika namespace korisnicki_namespace { namespace tutorial { // Neka klasa class NamespaceCSS { // Main pokreće program public static void Main() { // Ispis na konzoli Console.WriteLine("Primjer Namespace-a u C#."); } } } }

Osnovni prostori za nazive u .NET-u su: Naziv klase Opis System Glavni prostor za nazive sustava System.Data Klase koje se upotrebljavaju za ADO.NET i

globalnu manipulaciju podacima System.Drawing Klasa za crtanje oblika i objekata u

aplikacijama System.Windows.Forms Prostori za nazive i klase za korištenje formi

u windows aplikacijama

Alat koji daje prikaz svih raspoloživih prostora za nazive, klasa i metoda, te pruža i sintaksu i pomoć za upotrebu nekog prostora za naziv ili klase je Object Browser. Pokreće se s omoću izbornika View -> Object Browser. Najprije se u prozoru prikazuju prostori za nazive koji se koriste u aktivnom projektu, ali se pretraživanjem može dobiti pomoć za bilo koji prostor za nazive. Pretpostavimo da želimo pronaći upute kako se koristi klasa za ispis poruke korisniku na ekranu aplikacije. Ako u polje za pretraživanje u Object Browser-u upišemo npr. ''MessageBox'' i pritisnemo Enter, dobije se popis svih skupina klasa za ispis poruka. Ako želimo pronaći samo klase za ispis poruka u Windows formi, tada ćemo na popisu klasa označiti ''System.Windows.Form.MessageBox''. Na ekranu će se pojaviti sve metode (postupci koji se mogu napraviti) za tu klasu. Tipkom F1 na ekranu se dobiva pomoć za korištenje te klase. Za povratak natrag potrebno je zatvoriti i prozor za pomoć i prozor Object Browser-a. Sve naredbe možemo pisati upotrebom dužeg načina, tj. navođenjem pune sintakse svih prostora naziva koji se koriste za ispis poruke na ekranu: System.Windows.Forms.MessageBox.Show ("Ispisi neke poruke.","Projekt1", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk); Upotreba kraćeg načina pozivanja klase iz prostora za nazive (ako je System.Windows.Forms klasa već navedena na početku programa u naredbi Using): MessageBox.Show ("Ispisi neke poruke.", "Projekt1", MessageBoxButtons.OKCancel, MessageBoxIcon.Asterisk);

Ako upisujemo duži način pozivanja nekog objekta, to se zove potpuno kvalificirana naredba. Kod kraćeg načina može se koristiti mogućnost IntelliSense ugrađena u alat, koja pruža pomoć pri pisanju naredbi na način da nam prikazuje listu s mogućim klasama, objektima, metodama koje možemo izabrati s popisa. Aktivira se automatski pri početku pisanja naredbe ili tipkom Ctrl-Space. Duži (potpuno kvalificirani) način pisanja naredbi ima smisla koristiti ako u različitim prostorima za nazive koristimo klase ili objekte s istim nazivom, jer se može pratiti iz kojeg prostora je uzet određeni objekt. U svakom drugom slučaju praktičnije je koristiti kraći način pisanja naredbi.

1. 1. C# tipovi podataka

Kao i većina programskih jezika, i C# upotrebljava varijable i konstante za rad s informacijama u memoriji. Vrijednost varijabli se može mijenjati kroz program, dok se konstante koriste za memoriranje vrijednosti koje se neće mijenjati kroz neku proceduru ili cijelu aplikaciju (ključna riječ Const ispred deklaracije varijable). Prema tome tko ih definira, tipovi se mogu podijeliti na dva skupa:

1. intrinsic ili built-in (ugrađeni tipovi) 2. userdefined (oni koje definira sam korisnik).

Nadalje se tipovi dijele prema svrsi:

1. Value types (tipovi vrijednosti) - oni koji se koriste za čuvanje dijelova informacija u memoriji – standardni tipovi (npr. brojevi i tekst)

2. Reference types (tipovi referenci) - oni koji su reference i pokazuju na objekte napravljene iz klasa

Tip Opis .NET tip Tip Opis .NET tip Tip Opis .NET tip int Cijeli broj (od -2 147 483 647

do 2 147 483 647) System.Int32

short Cijeli broj (manji: od -32768 do 32767)

System.Int16

long Cijeli broj (veliki, oko 16 znamenaka)

System.Int64

decimal Decimalni broj (fiksna preciznost)

System.Decimal

double Veliki realni broj s pokretnim zarezom

System.Double

string Niz karaktera (tekst) System.String bool Logički podatak (istina ili

laž) System.Boolean

object Generički objekt koji može sadržavati druge tipove

System.Object

float Mali realni broj s pokretnim zarezom

System.Float

byte 1 znak (vrijednosti 0-255) System.Byte char 1 tekstualni znak System.Char

Slika 2. Standardni tipovi u C#.

Imena varijabli su ključna za programiranje. U programima, imena se koriste za pozivanje različitih stvari. Da bi mogao koristiti te stvari, programer mora razumjeti pravila davanja imena i pravila korištenja imena. Zapravo, programer mora znati sintaksu i semantiku imena. Prema sintaksnim pravilima, ime je niz od jednog ili više karaktera. Mora počinjati slovom i mora biti u potpunosti sastavljeno od slova, brojeva i donje crte "_".

Nekoliko primjera ispravnih imena:

N n rate x15 quite_a_long_name HelloWorld Velika i mala slova smatraju se različitima pa su: HelloWorld helloworld HELLOWORLD i HElloWorLD sasvim različita imena. Neka imena rezervirana su za posebne namjene u Javi i programer ih ne može koristiti za druge namjene. Rezervirane riječi uključuju: class public static if else while i nekoliko desetaka drugih riječi koje smo ranije nabrojali.

1.2. Operatori

Izraz je dio koda programa koji predstavlja ili računa neku vrijednost. Izraz može biti konstanta, varijabla, poziv funkcije ili više ovakvih elemenata kombiniranih operatorima (npr. + ili >). Vrijednost izraza može se dodati varijabli, koristiti kao ulazna vrijednost izlaznog potprograma ili pomoću operatora povezati s drugim vrijednostima u složeniji izraz.

Četiri osnovne skupine operatora su:

- aritmetički - operatori na bitovima - relacijski - logički

Aritmetički operatori

Operator Namjena + Zbrajanje - Oduzimanje * Množenje / Dijeljenje (za brojeve s pomičnim zarezom), cjelobrojno dijeljenje

% Ostatak cjelobrojnog dijeljenja (modulo) ++ Inkrementiranje (povećavanje vrijednosti za 1) += Zbrajanje i dodjela vrijednosti -= Oduzimanje i dodjela vrijednosti *= Množenje i dodjela vrijednosti /= Dijeljenje i dodjela vrijednosti, cjelobrojno dijeljenje i dodjela vrijednosti

%= Ostatak cjelobrojnog dijeljenja (modulo) i dodjela vrijednosti -- Dekrementiranje (smanjivanje vrijednosti za 1)

Operatori na bitovima

Operator Namjena

~ Unarno NE (NOT) na bitovima & I (AND) na bitovima | ILI (OR) na bitovima ^ Ekskluzivno ILI (XOR) na bitovima

>> Pomicanje bitova udesno >>> Pomicanje bitova udesno uz popunjavanje nulom (logičko pomicanje) << Pomicanje bitova ulijevo &= I (AND) na bitovima |= ILI (OR) na bitovima uz dodjeljivanje vrijednosti ^= Ekskluzivno ILI (XOR) na bitovima uz dodjeljivanje vrijednosti

>>= Pomicanje bitova udesno uz dodjeljivanje vrijednosti >>>= Pomicanje bitova udesno uz popunjavanje nulom uz dodjeljivanje

vrijednosti <<= Pomicanje bitova ulijevo uz dodjeljivanje vrijednosti

Relacijski operatori Operator

Namjena == Je jednako != Nije jednako > Je veće < Je manje

>= Veće jednako <= Manje jednako

Logički operatori Operator

Namjena ! Logička negacija & Logički AND | Logički OR ^ Logički XOR

&& Uvjetni AND || Uvjetni OR

== Jednakost != Nejednakost (različito od) &= AND uz dodjeljivanje vrijednosti |= Logički OR uz dodjeljivanje vrijednosti ^= Logički XOR uz dodjeljivanje vrijednosti ?: Ternarni operator

Prioriteti operatora

Ukoliko se koristi više operatora u jednom izrazu, a bez zagrada koje bi odredile redoslijed procjenjivanja, potrebno je voditi računa o prioritetima operatora koji određuju redoslijed procjenjivanja. Lista operatora prema prioritetima:

Unarni operatori: ++, --, !, unarni - i +, pretvorba vrste Množenje i dijeljenje: *, /, % Zbrajanje i oduzimanje: +, - Relacijski operatori: <, >, <=, >= Jednakost i nejednakost: ==, != Logički i: && Logički ili: || Uvjetni operator: ?: Operatori pridjeljivanja: =, +=, -=, *=, /=, %=

Operatori u istom redu imaju jednake prioritete, kad se pojave zajedno, unarni operatori i operatori pridjeljivanja se procjenjuju s desna na lijevo, a ostali s lijeva na desno. Da biste sami odredili prioritet najbolje je koristiti zagrade.

Primjer:

using System; class Binary { public static void Main() { int x, y, rezultat; float floatrezultat; x = 7; y = 5;

rezultat = x + y; Console.WriteLine("x+y: {0}", rezultat); rezultat = x - y; Console.WriteLine("x-y: {0}", rezultat); rezultat = x * y; Console.WriteLine("x*y: {0}", rezultat); rezultat = x / y; Console.WriteLine("x/y: {0}", rezultat); floatrezultat = (float)x / (float)y; Console.WriteLine("x/y: {0}", floatrezultat); rezultat = x % y; Console.WriteLine("x%y: {0}", rezultat); rezultat += x; Console.WriteLine("rezultat+=x: {0}", rezultat); } }

Rezultat:

x+y: 12 x-y: 2 x*y: 35 x/y: 1 x/y: 1.4 x%y: 2 rezultat+=x: 9

1.3. Blokovi, petlje, grananja

Sposobnost računala da obavlja složene zadatke zasniva se na svega nekoliko načina kombiniranja jednostavnih naredbi u upravljačke strukture. U C# postoji šest takvih struktura: blok, while petlja, do ..while petlja, for petlja, foreach petlja, if izraz i switch izraz. Svaka od ovih struktura smatra se jednim "izrazom", iako se zapravo radi o strukturiranom izrazu koji u sebi može sadržavati jednu ili više drugih naredbi.

Blok je najjednostavnija vrsta strukturiranog izraza. Namjena mu je da jednostavno okupi niz naredbi zatvorenih vitičastim zagradama u jednu naredbu. Način zapisivanja bloka je:

{ izrazi }

Blokovi naredbi se najčešće javljaju unutar drugih izjava gdje služe okupljanju više naredbi u jednu cjelinu. Zapravo, blok se može koristiti bilo gdje gdje se može javiti izraz. A već smo vidjeli da je njegovo korištenje nužno kod podprograma main. Po definiciji, podprogram je jedan blok.

Dva primjera blokova:

{ // Ovaj blok ispisuje vrijednost varijable odg System.Console.WriteLine("Odgovor je "); System.Console.WriteLine (("{0}", odg); } { // Ovaj blok zamjenjuje vrijednosti varijabli x i y int temp; // deklariranje privremene varijable koja se koristi //samo u ovom bloku temp = x; // Sačuvaj kopiju vrijednosti varijable x u temp x = y; // Kopiraj vrijednost varijable y u x y = temp; // Kopiraj vrijednost varijable temp u y } Uočite u drugom primjeru: varijabla temp je deklarirana unutar bloka, te je nevidljiva i nedostupna izvan bloka. Takva varijabla naziva se lokalna varijabla. Doseg (scope) nekog identifikatora je dio programa u kojem se taj identifikator može koristiti. Doseg varijable definirane unutar bloka je ograničen na taj blok, točnije na dio bloka nakon deklaracije varijable. Nije dozvoljeno više deklaracija s istim imenom u istom dosegu.

Sam blok ne utječe na tok izvršavanja programa. Preostalih šest navedenih struktura koje za razliku od bloka utječu na tok izvršavanja programa mogu se podijeliti u dvije skupine: petlje i grananja.

While petlja se koristi za uzastopno ponavljanje jednog izraza. Točnije, while petlja ponavlja izjavu dok je zadani uvjet istinit. While petlja ima oblik:

while (logički izraz) izraz

Budući da izraz može biti, a najčešće i je, blok, uobičajene su while petlje oblika:

while (logički izraz) { izrazi }

Kad računalo dođe do while izjave, procjenjuje logički izraz koji vraća vrijednost true ili false. Ako je vrijednost izraza false, računalo preskače ostatak while petlje i nastavlja s izvršenjem programa. Ako je vrijednost true, računalo izvršava izraze unutar petlje, zatim se vraća na početak petlje i ponavlja postupak, tj. ponovo procjenjuje logički izraz, te završava petlju ako je vrijednost false, a nastavlja ako je vrijednost true. Ovo se nastavlja dok izraz ne poprimi vrijednost false; slučaj u kojem se to nikad ne dogodi naziva se beskonačna petlja. Evo primjera petlje koja ispisuje brojeve 1,2,3,4 do 9:

using System; class WhilePetlja { public static void Main() { int myInt = 0; while (myInt < 10) { Console.Write("{0} ", myInt); myInt++; } Console.WriteLine(); } }

Do-while petlja je namijenjena slučajevima kada je potrebno da se uvjet ponavljanja testira na kraju petlje umjesto na početku. Do-while petlja je zapravo while petlja s uvjetom ponavljanja postavljenim na kraju petlje. Riječ do se koristi za označavanje početka petlje. Dakle, do-while petlja ima oblik:

do izraz while ( logički izraz );

ili s korištenjem blokova:

do { izrazi } while (logički izraz);

';' na kraju se ne smije izostaviti jer je to dio izraza. Izostavljanje bi prouzročilo sintaksnu grešku. Pri izvršavanju do petlje, računalo prvo izvršava tijelo petlje, tj. izraze unutar petlje, a zatim procjenjuje logički izraz. Ako je vrijednost izraza true, računalo se vraća na početak do petlje i ponavlja postupak; ako je vrijednost logičkog izraza false, izlazi iz petlje i nastavlja izvršavanje ostatka programa. Budući da se uvjet nastavljanja procjenjuje tek na kraju petlje, tijelo petlje se izvršava bar jedan put.

U slijedećem primjeru pseudokoda "igre", do petlja ima smisla u odnosu na while petlju jer osigurava barem jednu "igru", a osim toga, test koji se izvodi na kraju "igre" ne bi ni imao smisla na početku.

do { Odigraj igru Pitaj korisnika želi li igrati još jednu igru Pročitaj korisnikov odgovor } while ( Korisnikov odgovor je da );

For petlja je slična while petlji i ne donosi nove sposobnosti programskom jeziku, ali je za neke namjene prikladnija od odgovarajuće while petlje. Uobičajena while petlje ima oblik:

inicijalizacija while ( uvjet nastavljanja ) { izrazi promjena vrijednosti }

Na primjer, promotrimo sljedeću while petlju:

godine = 0; // inicijalizacija while ( godine < 5 ) { // uvjet nastavljanja kamata = glavnica * postotak; glavnica += kamata; // izvrši tri izraza System.Console.WriteLine("{0}", glavnica); godine++; // promjena vrijednosti }

Ova petlja se može zamijeniti sljedećom for petljom:

for ( godine = 0; godine < 5; godine++ ) { kamata = glavnica * postotak; glavnica += kamata; System.Console.WriteLine("{0}", glavnica); }

Inicijalizacija, uvjet nastavljanja i promjena vrijednosti su objedinjeni u prvoj liniji for petlje. Na ovaj način su svi činitelji for petlje na jednom mjestu što olakšava čitanje i razumijevanje. For i izvorna while petlja izvršavaju se jednako.

For petlja ima oblik:

for (inicijalizacija; uvjet nastavljanja; promjena vrijednosti ) izraz

ili korištenjem blokova:

for (inicijalizacija; uvjet nastavljanja; promjena vrijednosti) { izrazi }

Uvjet nastavljanja mora biti logički izraz, dok inicijalizacija i promjena vrijednosti mogu biti bilo kakvi izrazi.

Primjer:

using System; class ForPetlja { public static void Main() { for (int i = 0; i < 20; i++) { if (i == 10) break; if (i % 2 == 0) continue; Console.Write("{0} ", i); } Console.WriteLine(); } } Foreach petlja se koristi za iteraciju kroz stavke u popisu. Ona djeluje na polja kao što su ArrayList. Sintaksa foreach petlje je:

foreach (<Tip> <Iteracijska varijabla> in <lista>) { //izrazi

}

Tip je tip stavke koja se nalazi u listi, na primjer, ako je tip liste int [] tip će biti int. Iteracijska varijabla je identifikator koji ste odabrali i trebala bi biti smislena. Na primjer, ako lista sadrži niz sa godinama ljudi, smislen naziv iteracijske varijable je dob. Ključna riječ in je potrebna, jer je dio sintakse foreach petlje. Foreach petlja je samo za čitanje što znači da ne možete mijenjati iteracijsku varijablu unutar petlje. Na svakoj iteraciji kroz foreach petlju provjerava se da li postoji još elemenata u listi i ako postoji u idućem koraku se prelazi na

idući element liste. Kad je lista gotova završit će se petlja i kontrola programa će se prenijeti na prvi izjavu nakon završetka foreach bloka.

Primjer: using System; class ForEachPetlja { public static void Main() { string[] names = { "Ante", "Josip", "Martina", "Robert" }; foreach (string person in names) { Console.WriteLine("{0} ", person); } } } Rezultat: Ante Josip Martina Robert If izraz kaže računalu da izabere jedan od dvaju različitih tokova izvršavanja programa, u ovisnosti o vrijednosti zadanog logičkog izraza. If izraz "grananja" ili "odlučivanja" ima oblik: if (logički izraz) izraz else izraz

Računalo pri izvršavanju if izraza procjenjuje logički izraz koji vraća vrijednost true ili false. Ako je vrijednost true, računalo izvršava prvi izraz, a preskače izraz nakon "else". Ako je vrijednost izraza false, računalo preskače prvi izraz i izvršava drugi. U svakom slučaju, samo jedan od tih dvaju izraza unutar if izraza će biti izvršen. Dva izraza predstavljaju alternativne tokove programa; računalo se odlučuje za jedan od ovih tokova programa na osnovi vrijednosti logičkog izraza.

Jedna od mogućnosti primjene ove naredbe je odlučivanje samo da li će neka naredba biti izvršena ili ne. U tom slučaju if izraz nema else dio:

if (logički izraz) izraz

Ako je vijednost izraza true, računalo izvršava izraz unutar if izraza, a u slučaju rezultata false ga preskače. Korištenjem blokova, if izraz poprima oblik:

if (logički izraz) { izrazi } else { izrazi }

ili samo:

if (logički izraz) { izrazi }

Slijedi primjer if izraza koji zamjenjuje vrijednosti dviju varijabli, x i y, ali samo ako je x veći od y. Nakon izvršavanja ovog if izraza, možemo biti sigurni da je x manji ili jednak y:

if ( x > y ) { int temp; // deklariranje privremene varijable koja se koristi // samo u ovom bloku temp = x; // Sačuvaj kopiju vrijednosti varijable x u temp x = y; // Kopiraj vrijednost varijable y u x y = temp; // Kopiraj vrijednost varijable temp u y }

Na kraju evo primjer if izraza koji ima i dio else:

if ( br_godina > 1 ) { System.Console.WriteLine("Vrijednost ulaganja nakon "); System.Console.WriteLine("{0}", br_godina); System.Console.WriteLine(" godina je "); } else { System.Console.WriteLine("Vrijednost nakon 1 godine:"); } System.Console.WriteLine("{0}", ulaganje +" kn");

Switch izraz koristi znatno rijeđe nego if izraz, vrlo je koristan za grananja u više grana. Switch izraz omogućuje procjenu uvjeta i na osnovu te vrijednosti skok na neko mjesto unutar switch izraza. Vrijednost izraza koji se procjenjuje mora biti cjelobrojna (byte, short, int ili char), nikako ne može biti string ili realni broj. Za razliku od kombinacije if - else, ovdje se ne može nalaziti logički izraz. Razlog je tome u činjenici da naredba switch utvrđuje vrijednost izraza u određenom trenutku i zatim skače na blok koji je označen vrijednošću dobivene cjelobrojne konstante oblika "case konstanta:". Moguća je također upotreba oznake "default:" na koju se izvodi skok u slučaju da vrijednost izraza ne odgovara ni jednoj od oznaka slučaja.

Switch izraz ima oblik:

switch (izraz) { case konstanta_1: izrazi_1 break; case konstanta_2: izrazi_2 break; . . // (ostali slučajevi) . case konstanta_N: izrazi_N break; default: // proizvoljni postavni slučaj izrazi_(N+1) } // kraj switch izraza

Break naredbe su stvar izbora i nisu obavezne. Učinak break naredbe je da skače na kraj switch izraza. Ako se izostavi break naredba računalo će nastaviti s izvršavanjem programa, izvršavajući redom naredbe iz slijedećih slučajeva. Moguće je izostaviti čitave grupe izraza s break naredbom i tako dobiti dvije (ili više) oznaka slučaja u jednom redu, čime se omogućava skok na isti skup izraza za različite vrijednosti izraza u switch naredbi.

Primjer upotrebe switch naredbe (uočiti da konstante u oznakama slučaja ne moraju biti poredane po nekom redu, važno je da su različite):

switch (N) { // N je neka cjelobrojna varijabla case 1: System.Console.WriteLine("Broj je 1.") break; case 2: case 4: case 8: System.Console.WriteLine("Broj je 2, 4, ili 8."); break; case 3: case 6: case 9: System.Console.WriteLine("Broj je 3, 6, ili 9."); break; case 5: System.Console.WriteLine("Broj je 5."); break; default: System.Console.WriteLine("Broj je 7,"); System.Console.WriteLine(" ili nije između 1 i 9."); }

1.4. Rukovanje izuzecima Osim sintaksnih i semantičkih grešaka, u aplikaciji se mogu pojaviti i greške izuzetaka (eng. exceptions). One se ne vide kod prevođenja (prilikom Build-anja i Debug-iranja) nego se pojavljuju prilikom izvršavanja aplikacije i ne mogu se spriječiti. To su greške koje nastaju najčešće zbog unosa neodgovarajućih podataka od strane korisnika, ili zbog neunesenih podataka. Rukovanje izuzecima je važno napraviti u programskom kodu, kako bi se spriječilo ''iskakanje'' programa, i omogućilo daljnje nastavljanje izvršavanja aplikacije. Što bi se dogodilo kada ne bismo rukovali izuzecima u kodu? Ako u programskom kodu nije predviđeno rukovanje izuzecima, tada se prilikom izvršavanja aplikacije može dogoditi da program izbaci ''grubu'' poruku o grešci i zaustavi izvršavanje aplikacije. Korisnik tada ne može dalje raditi s aplikacijom. Ako se prilikom debug-iranja pojavi greška izuzetka, program će nas izbaciti u kod. Da bi se sve to spriječilo, potrebno je u kodu ''hvatati'' moguće izuzetke koje možemo predvidjeti. Primjeri nekih izuzetaka: Ako korisnik u textbox ne unese neki podatak koji je potreban (npr. plaću djelatnika), pa se ne može izračunati prosječna plaća, pojavit će se poruka o grešci i zaustaviti aplikacija. Npr. ako korisnik prilikom unosa nekog podatka s kojim treba dijeliti neki broj unese vrijednost 0. Npr. ako se unese vrijednost koja po tipu ne odgovara tipu vrijednosti koju treba unijeti u odgovarajući textbox (npr. ako se očekuje da se unese broj, a korisnik je unio tekst). Primjer: using System; using System.IO; class tryCatchDemo { static void Main(string[] args) { try { File.OpenRead("Nepostojeca_Datoteka"); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } } Gornji primjer sastoji se od jednog catch bloka koji će uhavitit iznimku ako pokušamo pročitati nepostojeću datoteku. U ovom slučaju samo će ispisati poruku o pogrešci u konzoli.

Iznimka može završiti program, a da pri tome ostavi program u nepostojanom stanju bez oslobađanja svih resursa i čišćenja varijabli. Catch blok je prikladno mjesto da se uhvate iznimke i pokuša popraviti program. Ponekad je potrebno napraviti oslobađanje resursa neovisno o tome jeste li uspjeli popraviti iznimku ili ne. U takvim situacijama se najčešće korisiti finally blok. Kao što znate, datotečni tok mora biti zatvoren kad završite rad s datotekom. U tom slučaju, file stream je resurs koji treba biti očišćen. U idućem primjeru, outStream je uspješno otvoren, što znači da program sada može rukovati datotekom. Kada pokušate otvoriti InStream, pokrenut će se FileNotFoundException i prebaciti izvođenje programa u catch blok. Moguće je zatvoriti outStream catch bloku, ali što ako se algoritam izvrši uspješno? Tada datoteka nikada neće biti zatvorena. Srećom, uključili smo Finally blok koji će se uvijek biti izvršen. Bez obzira da li će algoritam podići iznimku ili ne, kod u bloku Finally će se izvršiti prije nego napusti metodu. Primjer: using System; using System.IO; class FinallyDemo { static void Main(string[] args) { FileStream outStream = null; FileStream inStream = null; try { outStream = File.OpenWrite("Izlazna_datoteka.txt"); inStream = File.OpenRead("Nepostojeca_Datoteka.txt"); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } finally { if (outStream != null) { outStream.Close(); Console.WriteLine("outStream zatvoren."); } if (inStream != null) { inStream.Close(); Console.WriteLine("inStream zatvoren."); } } } }

Primjer Windows form aplikacije koja ne rukuje iznimkama: Kroz jedan primjer pokazat ćemo što se događa ako aplikacija ne rukuje izuzecima. Otvorite novi projekt. U Visual Studio 2008 odaberite File -> New-> Project. Nakon toga Visual C# i Windows Forms Application. Program pohranite pod nazivom Iznimka i kliknite na gumb OK. Otvorit će se prazna forma. Pomoću trake Toolbox kreirajte na formi input polja, texbox-ove i tri gumba kao na slici:

Cilj je pokazati kako se ponaša aplikacija ako se ne rukuje izuzecima. Za tu svrhu koristit ćemo dugme ''Iznimka bez rukovanja''. Kliknite dvaput na to dugme kako bismo upisali kod u metodu button1_click. U metodu button1_click upisat ćemo naredbe koje će vrijednost koju korisnik unese u textBox1.Text pohraniti u cjelobrojnu varijablu broj1, zatim ćemo varijablu broj1 uvećati za 5 i rezultat ispisati u textBox2.Text. Cijela metoda će izgledati ovako: private void button1_Click(object sender, EventArgs e) { int broj1; int rezultat; broj1 = Convert.ToInt32(textBox1.Text); rezultat = broj1 + 5; textBox2.Text = Convert.ToString(rezultat); }

Pohranite i debugirajte aplikaciju, testirajte ispravnost tako da u prvi okvir za tekst unesete broj: 8. Nakon što kliknete na prvo dugme, kao rezultat će se u drugom okviru za tekst upisati broj 13. Sada obrišite unesenu vrijednost 1 u prvom okviru za tekst i nemojte unijeti ništa. Zatim kliknite na dugme ''Iznimka bez rukovanja''. Budući da nije unijeta vrijednost koja je programu potrebna za računanje rezultata, pojavit će se poruka o izuzetku kojim nije rukovano (eng. exception was unhandled), u prozoru kao na slici:

Poruka da ulazni tekst nije u ispravnom obliku se pojavila se jer nismo unijeli niti jednu vrijednost u okvir za tekst. Kliknite na dugme Continue kako biste uklonili taj prozor. Osim što se pojavila poruka o izuzetku kojim nije rukovano (eng. unhandled exception), izvršavanje aplikacije je prekinuto, a program nas vraća u prozor za pisanje koda, u liniju gdje se dogodila greška izuzetka (ta je linija i posebno označena zelenom bojom). Ako pokušamo nastaviti izvršavanje aplikacije naredbom Debug / Continue (F5), vidimo da program ponovo prikazuje istu poruku o izuzetku i aplikacija se ne može nastaviti. Možemo samo prekinuti debug-iranje naredbom Debug / Stop debugging (shift-F5).

Pohranite aplikaciju, zatvorite Visual Studio 2008, te na disku pronađite mapu u kojoj je pohranjena Iznimka.exe izvršna datoteka. Da biste vidjeli što će se dogoditi ako korisnik pokrene aplikaciju koja ne rukuje izuzecima, dvaput kliknite na Iznimka.exe datoteku. U prvi okvir za tekst opet nemojte unijeti ništa, nego samo kliknite na dugme ''Iznimka bez rukovanja''. Pojavit će se poruka kao na slici:

Korisnik sada može nastaviti aplikaciju klikom na dugme Continue ili prekinuti klikom na dugme Quit. Ukoliko korisnik nastavi rad aplikacije (Continue), neće se ispisati rezultat, jer je program prekinuo izvršavanje, a ako klikne na dugme Quit, program će izaći iz plikacije u Windows operativni Sustav. Na taj način onemogućuje se korisniku kvalitetan rad s aplikacijom, te svaki programer treba u aplikaciji predvidjeti barem većinu izuzetaka koji se mogu dogoditi i upisati naredbe koje rukuju s njima i tako omogućiti korisniku nesmetani rad s aplikacijom.

Rukovanje izuzecima pomoću petlja try...catch Da bi se rukovalo iznimkom, potrebno je koristiti naredbe petlje:

try { ovdje naredbe u kojima se može pojaviti izuzetak

} catch (tip izuzetka varijabla) { ovdje naredba kojom se ispisuje poruka korisniku da unese ispravan podatak }

U aplikaciji Iznimka napravit ćemo primjer rukovanja iznimkom. Otvorite projekt Iznimka, te dvaput kliknite na dugme ''Try...catch'', kako biste se pozicionirali u metodu button2_click. U metodu button2_click kopirajte sve naredbe iz prethodne metode button1_click. Neposredno iza vitičaste zagrade, a ispred prve naredbe treba upisati naredbu: try. Dalje dodajte vitičaste zagrade za naredbu try tako da sve upisane naredbe budu u zagradama. U dijelu catch treba upisati naredbu koja će ispisati korisniku poruku da treba unijeti broj1. Trenutni kod za metodu button2_Click izgledat će ovako: private void button2_Click(object sender, EventArgs e) { try { int broj1; int rezultat; broj1 = Convert.ToInt32(textBox1.Text); rezultat = broj1 + 5; textBox2.Text = Convert.ToString(rezultat); } catch { MessageBox.Show("Niste unijeli cijeli broj!"); } } Gore navedene naredbe try...catch sprečavaju pucanje programa ispisivanjem poruke korisniku i omogućavaju nastavak aplikacije. Pohranite i pokrenite aplikaciju debug-iranjem. Nemojte unijeti broj1 u prvi okvir za tekst, nego samo kliknite na dugme Try...catch.

Nakon ispisane poruke u MessageBox-u unesite neku cjelobrojnu vrijednost u prvi okvir za tekst. Koji će se sada rezultat ispisati? Što će se dogoditi ako u prvi okvir za tekst unesemo decimalni broj ili neki tekst? Da li se pojavljuje izuzetak? Pokušajte u prvi okvir za tekst unijeti broj: 2.3. Kliknite na dugme

Try...catch. Ponovo se pojavljuje poruka korisniku da treba unijeti cijeli broj. Isto ponovite tako da u okvir za tekst unesete tekst ''Dobar dan.'' , a zatim kliknete na dugme Try...catch. Što se događa? Petlja try..catch...finally U slučaju kada želimo da program nastavi s radom iako se dogodio izuzetak (ne želimo korisnika vraćati na ponovni unos podataka), u try...catch petlju dodaje se naredba finally. Opći oblik je:

try { ovdje naredbe u kojima se može pojaviti izuzetak

} catch [(tip izuzetka varijabla)] {

ovdje naredba kojom se ispisuje poruka korisniku da unese ispravan podatak } finally {

ovdje naredba kojom se ispisuje poruka korisniku da je program nastavio s radom unatoč izuzetku }

U projektu Iznimka kliknite dvaput na dugme Try...catch...finally kako biste kreirali

metodu button3_click. U tu metodu najprije kopirajte sve naredbe iz prethodne metode button2_Click (sve naredbe petlje try...catch). U ovoj metodi button3_Click na kraju (iza petlje catch, tj. završene vitičaste zagrade za tu petlju), dodajte sljedeće naredbe: textBox2.Text = "Rezultat nije mogao biti izračunat. Program je završen."; Pohranite i pokrenite debug aplikacije. Nakon poruke u MessageBox-u da niste unijeli broj, pojavit će se poruka u okviru textBox2 koju smo upisali u naredbu finally. Zaključak: Rukovanje izuzecima vrlo je važno za kontinuirano izvršavanje aplikacija. Izuzeci se mogu pojaviti zbog neunesenog podatka, ali i zbog pogrešnog ili specifičnog unosa zbog kojeg se ne može dalje nastaviti s radom aplikacije. Ukoliko želimo rukovati izuzetkom na način da korisnik ponovo unese traženu vrijednost, koristi se petlja try..catch. Ukoliko želimo rukovati izuzetkom na način da se nakon pojave izuzetka samo nastavi dalje s izvršavanjem aplikacije, koristi se petlja try...catch...finally.