You are on page 1of 23

Objektno orijentirano programiranje Elektrotehnički fakultet

Osijek
Auditorne vježbe 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:
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 System.Int32
do 2 147 483 647)
short Cijeli broj (manji: od -32768 System.Int16
do 32767)
long Cijeli broj (veliki, oko 16 System.Int64
znamenaka)
decimal Decimalni broj (fiksna System.Decimal
preciznost)
double Veliki realni broj s pokretnim System.Double
zarezom
string Niz karaktera (tekst) System.String
bool Logički podatak (istina ili System.Boolean
laž)
object Generički objekt koji može System.Object
sadržavati druge tipove
float Mali realni broj s pokretnim System.Float
zarezom
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.

You might also like