190
1. UVOD Ova knjiga je prvenstveno namenjena onim čitaocima koji već znaju da programiraju u nekom programskom jeziku, te da uz pomoć Interneta i teksta kojeg možete saznati u narednim poglavljima naučite da pišete programe u C++-u. Postoji i dodatak za C++ 11 standard, za one kojima trebaju informacije o novitetima. To ne znači da i oni koji ne poseduju prethodno znanje iz programiranja ne mogu da nauče C++ uz pomoć ove knjige, ali uz daleko više napora. Napominjem da algoritimi neće biti detaljno objašnjavani, što je ostavljeno čitaocu za vežbu. Za one koji se prvi put sreću sa programiranjem, navedimo sledeće pojmove, u čija razjašnjavanja nećemo ulaziti, a čitaocu koji je početnik, preporučujemo da ih pronađe: u nekoj knjizi, na Internetu, ili da ih sazna od nekog prijatelja koji ovim pojmovima bolje barata: Algoritam. Blok dijagrami, pseudo kod, i IPO dijagrami. John Von Neumann-ova arhitektura računara. Program, izvorni kod(sours kod), izvršni kod(exe kod), objektni kod. Proces prevođenja, kompajler, prevodilac, linker, JIT(Just in Time Translation). Operativni sistem. Binarni, heksadecimalni i oktalni brojevi. Od Vas se ni ne očekuje da sve razumete, ali ćete sigurno biti bolje obavešteni o ovoj oblasti Informacionih tehnologija. Uradimo sledeći primer. Kreirajmo projekat, kojeg ćemo nazvati RADNI_PROJEKAT. Kako to napraviti: File/New/Project, zatim popunite odgovarajuće podatke u čarobnjaku. Ovo je urađeno u Express Edition Majkrosoftovog programa. Možete naći veliki broj sličnih programa koji su danas i besplatni kao: CodeBloks, Dev i slični.Oni se mogu donekle razlikovati, ali u suštini su isti. Ukoliko Vas interesuje koji od proizvoda da koristite, pogledajte na stranici Bjarne Stoustrupa, koji je ujedno i kreirao ovaj jezik. Danas C++ predstavlja jedan od vodećih jezika, a možemo da kažemo da je nastao 1

UVOD U C++ I DODATAK ZA C++11

Embed Size (px)

DESCRIPTION

Uvod u C++ za programere koji već znaju neki programski jezik, te zele da nuče c++, i za one koji žele da se prilagode novom standardu.Knjigu mogu da koriste i početnici, ali sa daleko više napora

Citation preview

Page 1: UVOD U C++ I DODATAK ZA C++11

1 . U V O D

Ova knjiga je prvenstveno namenjena onim čitaocima koji već znaju da programiraju u nekom programskom jeziku, te da uz pomoć Interneta i teksta kojeg možete saznati u narednim poglavljima naučite da pišete programe u C++-u. Postoji i dodatak za C++ 11 standard, za one kojima trebaju informacije o novitetima.To ne znači da i oni koji ne poseduju prethodno znanje iz programiranja ne mogu da nauče C++ uz pomoć ove knjige, ali uz daleko više napora.

Napominjem da algoritimi neće biti detaljno objašnjavani, što je ostavljeno čitaocu za vežbu. Za one koji se prvi put sreću sa programiranjem, navedimo sledeće pojmove, u čija razjašnjavanja nećemo ulaziti, a čitaocu koji je početnik, preporučujemo da ih pronađe: u nekoj knjizi, na Internetu, ili da ih sazna od nekog prijatelja koji ovim pojmovima bolje barata:

Algoritam. Blok dijagrami, pseudo kod, i IPO dijagrami. John Von Neumann-ova arhitektura računara. Program, izvorni kod(sours kod), izvršni kod(exe kod), objektni kod. Proces prevođenja, kompajler, prevodilac, linker, JIT(Just in Time Translation). Operativni sistem. Binarni, heksadecimalni i oktalni brojevi.

Od Vas se ni ne očekuje da sve razumete, ali ćete sigurno biti bolje obavešteni o ovoj oblasti Informacionih tehnologija.

Uradimo sledeći primer. Kreirajmo projekat, kojeg ćemo nazvati RADNI_PROJEKAT.Kako to napraviti: File/New/Project, zatim popunite odgovarajuće podatke u čarobnjaku. Ovo je urađeno u Express Edition Majkrosoftovog programa. Možete naći veliki broj sličnih programa koji su danas i besplatni kao: CodeBloks, Dev i slični.Oni se mogu donekle razlikovati, ali u suštini su isti. Ukoliko Vas interesuje koji od proizvoda da koristite, pogledajte na stranici Bjarne Stoustrupa, koji je ujedno i kreirao ovaj jezik. Danas C++ predstavlja jedan od vodećih jezika, a možemo da kažemo da je nastao kao evoluirani C, koji je bio široko prihvaćen od strane velikog broja programera. C++ je kreiran kao odgovor na softversku krizu, koja se javila nakon unapređenja računarske tehnologije, a kad su programi postali previše kompleksni da bi se mogli pisati tehnikama tradicionalnog programiranja.

Nakon što smo uradili prve korake. Zgodno je što prazan projekat i nakon toga pridodati odgovarajuću datoteku kao glavni program. Ovaj fajl nazovite main.cpp, jer je tako uobičajeno, a možete da odaberete neko Vama logičnije ime za glavnu teku u programu. Primer koji kreiramo neće koristiti argumente komandne linije. Ako želite da ih koristite u vašim programima, morate da znate da su se ovi argumenti koristili u programima koji su se razvijali pre pojave aplikacija koje koriste grafički interfejs. Ali recimo nešto i o njima▪ int main( void) standardni poziv koji ćemo koristiti u programima.▪ int main( int argc, char * argv[]) ili int main( int argc, char ** argv)▪ int main(int argc, char* argv[], char *envp[]).

Ukoliko koristite argc, na taj način možete odrediti broj argumenata komandne linije, a predstavlja skraćenicu od „argument count“.

1

Page 2: UVOD U C++ I DODATAK ZA C++11

Ako upotrebite argv koristite niz pokazivača na stringove, a predstavlja skraćenicu od „argumenti vektora“.Ukoliko koristite podatke od izvršnog okruženja, tad upotrebite envp, što je skraćenica od „enviroment pointer“.Kako se treći i drugi oblik koriste u konzolnim aplikacijama, a izgubile su značaj ukoliko kreirate grafičke aplikacije, mi ih nećemo ni detaljnije objašnjavati.

Preporuka je da datoteka main.cpp, sadrži glavni program.

Zatim unesite sledeći kod:

#include <iostream>#include <cstdio>

using namespace std;

//Glavni program intmain(void){ //Ponekad ljudi misle da programiraju u C++ //samo zato sto su printf zamenili sa cout, scan sa cin cout<<"Primer prvi!!!"<<endl;

//Stari stil nasledjen iz C-a, ali i dalje mozemo koristiti //ove funkcije iz stdio.h printf("Ovo je ipak samo pocetak.\n");

system("PAUSE"); return EXIT_SUCCESS;}

Objasnimo program koji smo gore napisali.-Prvi red daje direktivu prevodiocu, da uključi biblioteku iostream, koja je standardna C++ biblioteka i omogućava da koristimo tokove. Drugi fajl cstdio, je primer stare C biblioteke koju još uvek možemo koristiti u C++-u, ali tako da dodamo slovo c ispred naziva datoteke.Neke od komandi koje možete koristiti ukoliko dodamo podršku za iostream datoteku su:▪ cerr.▪ cin.▪ clog.▪ cout.▪ kao i verzije za rad sa višebajtnim znakovima, takozvanim wchar_t, ali o njima više kasnije.

Slično kao što postoje metode za rad sa tokovima iz bibloteket iostream, potoje i odgovarajuće funkcije za rad sa datotekama iz stdio.h biblioteke, kao i njihove verzije za rad sa dvobajtnim znakovima:▪ printf.▪ scanf.▪ flush.▪ getc.▪ getchar.

2

Page 3: UVOD U C++ I DODATAK ZA C++11

▪ gets.▪ putc.▪ putchar.▪ puts.

Neću Vas trenutno zamarati sa detaljnim opisim tokova, to ćete detaljnije videti u delu sa datotekama. Za sada je najbitnije da razumete metode, ili funkcije koje se koriste u nekoj od ovih biblioteka. Poželjno je da se odlučite za jedan od ta dva stila, te da se prema Vašem izboru unigormno pridržavate jedne od te dve tehnike.

-Zatim upotrebljavamo imenski prostor namespace std, ono std je skraćeno od standardni.

-Funkcija main predstavlja glavni program, koji od operativnog sistema ne uzima argumente, dok kao rezultat vraća poruku da smo uspešno uradili sve instukcije, ponekad programeri pišu 0 umesto EXIT_SUCCESS.

-Naredba system prosleđuje komandu operativnom sistemu, da želimo da pauziramo izvršavanje programa. Možete sresti komentare na blogovima, o tome kako je ovo loša naredba i slično, a ukoliko Vam se ne sviđa možete koristiti cin.ignore(), ili neki drugi trik.

-Ukoliko želite pisati poruke pomoću cout ili printf, rezultat je isti, ali konceptualno postoje ogromne razlike. Da bi razumeli ovo morate shvatiti objektno programiranje, a i to kako su ove funkcije pisane. Za Vas trenutno nije ni poželjno da ulazite u tako duboke rasprave. Koristite ih da bi prikazali podatke. Od interesa može biti, koja je od ove dve instrukcije brža, tu nedoumicu razrešavate tako što ćete 10 000 puta napisati jedan celi broj na standardnom izlazu, izmerite koliko je vremena trebalo prvoj i drugoj naredbi, te uporedite dobijene rezultate.

-Još samo nekoliko napomena, bitno je da li pišete velikim ili malim slovima, C++ je osjetljiv na upotrebu malih ili velikih slova. Znak tačka zarez „ ; “ se piše na kraju svake naredbe, da označi kraj te komande.Sledeći korak predstavlja pokretanje programa, za to koristimo onaj zeleni trougao što liči na play sa CD plejera.

Ostaje da ispravimo greške, to je mukotrpan posao, koji ponekad može biti zahtevniji od pisanja progama.

3

Page 4: UVOD U C++ I DODATAK ZA C++11

2 . P R O M J E N L J I V E I T I P O V I P O D ATA K A

Podsetimo se malo arhitekture računara. Kombinacija bita, u zavisnosti od računara, se grupiše u 8, 16, 32 ili više bita. Na taj način dobijamo najmanje adresibilne memorijske jedinice. Svaka kolekcija bita ima svoju adresu, na osnovu koje se može pristupiti memorijskim lokacijama. Napomenimo da je danas uobičajeno osam bita nazvati bajtom. Već postoji i odgovarajući standard koji je nametnuo taj način označavanja. U suštini vidimo zašto takvo nazivanje može biti neadekvatno.Program koji je trenutno aktivan, učitava se u RAM, a tu su i potrebni podaci. Očitava se prva instrukcija, te se prebacuje u upravljačku jedinicu gde se interpretira. Podaci se postavljaju u odgovarajuće registre, gde se vrše modifikacije. Nakon izvršenih operacija, podaci se raspoređuju na druge lokacije. Zatim se zahvata sledeća instrukcija, itd... Staje se kad dobijemo odgovarajuću instrukciju za zaustavljanje programa.

Danas je to malo komplikovanije, jer program kojeg pišemo, obično posjeduje svoj virtuelni prostor, itd. Da bi naučili i razumeli programiranje zamislimo da još uvek radimo na starim računarima koji imaju tako simplificirani model. Problem koji početnici u progamiranju imaju je kako stvoriti predstavu o tome kako se program i podaci čuvaju u računaru. Ovo su osnove, i bitno je da programer od samog početka može razmišljati na asemblerskom nivou, jer sve što imamo na računaru čuva se negde na hard disku, a ti podaci su ipak samo biti i bajti i ništa više ili manje, dok programer od njih ne stvori nešto više.Pogledajte sledeći link:http://blogs.msdn.com.b/oldnewthing/archive/2013/03/28/10405881.aspx

Objasnimo pojam varijable.Promjenljiva ima:

Ime. Tip. Adresu. Vrednost. Oblast važenja.

Objasnimo pojam imena.-Kako Vi možete pozvati neku osobu? Na osnovu njenog imena. Drugim rečima, promjenljiva ima svoje ime na osnovu kojeg pristupamo podacima. Grupe bita su organizovane u skupine, koje imaju svoje ime zbog lakšeg manipulisanja njima.Primeri promjenljivih: iBroj, dSuma, bJeste, i slično.

-Tip određuje kako će se konkretna grupa jedinica ili nula interpretirati. Ako imamo širokobajtni znak, ili short int, biti se mogu interpretirati kao slovo, ili kao neki broj. U zavisnosti od tipa koji smo mi odredili, računar će te podatke interpretirati na određeni način.Na određenoj memorijskoj lokaciji se nalazi grupa bita „0110 0001“. Ukoliko je znak u pitanju, prikazujemo neku znakovnu vrednost na monitoru, dok za tip celih brojeva ovi bitovi poprimaju drugu interpretaciju.Primeri int iBroj; double dSuma, dRezultat; bool bPostoji.

-Adresa je pojam koji ćemo objasniti analogijom. Zamislimo poštara, on raznosi pisma od jednog stana do drugog. Kako on zna kome će proslediti određeno pismo? Na osnovu adrese koju pročita na pismu. Tako i podaci bivaju prenešeni sa jedne na drugu memorijsku lokaciju, na osnovu adresa. Adrese su jedinstvene, jer da nisu, podaci bi mogli da zalutaju. Da se to ne bi dešavalo, podaci su lepo organizovani na našem hard disku prema adresama. Ukoliko je potrebno program i podatke prebaciti u memoriju, naravno mislimo o RAM-u, program postaje aktivan. Danas su se stvari zakomplikovale, tako da

4

Page 5: UVOD U C++ I DODATAK ZA C++11

možemo imati više jezgara, keš memoriju i slično. Za razmišljanje o programu, poželjno je da imamo neku vizuelnu predstavu o tome kako to u suštini funkcionše.Primer adrese #12 FF60.

Nadam se da na osnovu ove ilustracije možete da zamislite kako se podaci, programi i delovi operativnog sistema smeštaju negde u memoriji.

Nemojte da pomislite da je poenta ove priče pisanje mašinski zavisnih programa, tj programa koji će ovisite o hardveru. Koliko je to pogubno za računare davno je uočeno, u početku računari do kojih smo mogli doći su bili proizvodin nekih firmi, sve je bilo proizvedeno u okviru te kompanije od hardvera do softera. Drugim rečima nije se verovalo drugim proizvođačima. Takav pristup je bio poguban, jer ukoliko imate računar jedne kompanije tad ste sve morali da kupujete od te kompanije, čak šta više ukoliko vaš drug ima neku interesantnu igricu Vi je niste ni mogli igrati ukoliko Vam se razlikuju tipovi kompjutera, a firma koja proizvodi Vaš računar nije proizvela odgovrajuću verziju te igrice. Zaključak je da treba odvojiti softver od hardvera, tako da možete pisati programe koji neće zavisiti od platforme. Danas se uveliko radi na tome, ali i dan danas postoji prostor za razvoj u ovoj oblasti. Prvo rešenje koje je sveopšte prihvaćeno su predstavljali PC računari. Ova skraćenica znači lični računar. Danas postoji veliki broj uređaja na kojima možemo izvršavati različite programe.Postoje:▪ Serveri, super kompjuteri, klasteri računara, klaud i slična profesionalna rešenja.▪ Lični računar.▪ Laptop.▪ Tablet.▪ Mobilni uređaji itd.

Najverovatnije u doglednoj budućnosti ćemo moći programirati uređaje u našoj kući, odavno se u procesu proizvodnje koriste programibilni uređaji, ne samo mikrokontroleri već i veliki broj drugih tipova uređaja.Robotika je jedana od važnijih oblasti u kojima se naslućuje primena softvera.

-Kada položite vozački ispit dobijate dozvolu. Može se desiti da dozvola važi samo za vašu državu, ili imate internacionalnu vozačku dozvolu. Slično je sa podacima, oni mogu važiti u celome progamu, ili samo u nekim delovima. Oblasti važenja podataka mogu biti:

Datoteka.

5

Page 6: UVOD U C++ I DODATAK ZA C++11

Blok. Prototip funkcije. Funkcija.

Napomenimo da u OOP postoje tri modifikatora: public, private i protected. Ali nećemo sad pričati o objektnom programiranju.Ukoliko je podatak vidljiv u datoteci, to znači da se može koristiti na svim mestima u datoteci.Blokovski podatak se može koristiti u tom bloku. Podaci koji su deklarisani u prototipu funkcije vidljivi su samo u okviru te funkcije, drugim rečima kad Marko ode u Ameriku zovu ga Mark. Promjenljive koje su definisane u funkciji ne mogu da važe van te funkcije, ali mogu da nadjačaju spoljna imena. Učenik iz jednog razreda, ukoliko se prepiše u drugi razred, ne može imati isti broj u dnevniku, jer već postoji neko sa njegovim starim brojem.

Dovoljno je rečeno o promjenljivim, pređimo na tipove podataka. Nećemo detaljno opisivati podatke. Celobrojni tipovi podataka su najčešće korišteni tip. Oni se koriste da bi zabilježili cele brojeve iz nekog opsega. Poznatiji su: int, short, long i long long.Uradite sledeći program. Koristićemo operator sizeof, koji određuje koliko prostora određena promjenljiva zauzima u memoriji, predlažemo da analizirate sadržaj datoteke limits.h. Prilikom razvoja aplikacija za profesijalnu upotrebu, zna se desiti da se programeri dogovore da uvedu svoj tip, koji se može koristiti daleko praktičnije. Ali nećemo sad ulaziti u tako duboke detalje.

PRIMER:#include <iostream>

using namespace std;

intmain(void){

short int siBroj=1;int iBroj=2;long int liBroj=3;long long int lliBroj=4;

cout<<"Velicina tipa iznosti"<<endl <<"----------------------"<<endl;

cout<<"short int "<<sizeof(siBroj)<<endl <<"int "<<sizeof(iBroj)<<endl <<"long int "<<sizeof(liBroj)<<endl <<"long long int "<<sizeof(lliBroj)<<endl;

system("PAUSE"); return EXIT_SUCCESS;

}

6

Page 7: UVOD U C++ I DODATAK ZA C++11

Na osnovu ovog programa možete razumeti koliko prostora zauzima svaki od tipova, a kao posledicu možemo da procenimo koji je maksimalni, a koji minimalni broj koji možemo na osnovu gore pomenutih tipova da prikažemo. Napomenimo samo da se znak čuva u prvom bitu, a ukoliko nam za tip nije bitan znak možemo koristiti i modifikator unsigned. Na osnovu ovog modifikatora možemo proširiti opseg brojeva sa kojima operišemo.Druga važna grupa tipova podataka su karakteri, oni se koriste da bi čuvali znakove. Kad otkucamo neki karakter na tastaturi, on se predstavlja kao binarni broj u memoriji, i u zavsnosti od tipa računar će uvek slovo A interpretirati kao A, a ne kao J ili a.Postoje različita označavanja znakova. Mi ćemo spomenuti char i wchar_t kao tipove podataka.

PRIMER:#include <iostream>#include <cwchar>

using namespace std;

intmain(void){ //char se uobicajeno koristi za ANSII karakterechar cZnak='c';

//junikod se koristi za jezike koji zahtevaju specijalne karaktere koji ne postoje u engleskom jezikuwchar_t wcZnak=L'c';

//staro stil ispisa podataka, da ne zaboravimo i to printf("Tip char %c",cZnak); cout<< " velicina=" <<sizeof(char) <<endl;

// mozemo koristiti funkciju wprintfwprintf(L"Tip wchar_t %c",wcZnak);cout<< " velicina="<<sizeof(wchar_t);

system("PAUSE");return EXIT_SUCCESS;

}

Nadam se da nam je, nakon ovog programa, jasno zašto moramo imati funkciju printf i wprintf. Na žalost možemo samo ustanoviti da bi ovaj problem mogao daleko efikasnije da se reši. Svi ljudi ne govore esperanto. Problem je taj što engleski jezik ima određene karaktere, tačno 26, ali drugi jezici imaju neke specifične karaktere. Naš jezik je prilično zahtevan, ali možete da zamislite šta se dešava kad pišete kineski, japanski, arapski ili neki egzotičniji jezik. Samo nisam sto posto siguran kako na Papua Novoj Gvineji to funkcioniše, pa valjda i ti ljudi tamo hoće Internet i slično.

7

Page 8: UVOD U C++ I DODATAK ZA C++11

Sledeća vrsta promjenljive koja može biti od koristi je logički tip. Izvorno, programski jezik C nije podržavao bool kao tip podatka. Koristila se 0, ili bilo koji drugi broj za true i false.

PRIMER:#include <iostream>

using namespace std;

intmain(void){

bool bLogicki = true, bBoolovTip = false;

cout<<"Velicina logickog tipa je=" <<sizeof(bool)<<endl <<"bLogicki ima vresnost =" <<bLogicki <<endl <<"bBoolovTip ima vrednost =" <<bBoolovTip<<endl;

system("PAUSE"); return EXIT_SUCCESS;

}

Škrtica bi zaista zaplakala nad činjenicom da logički tip zauzima celi bajt, koje rasipništvo. Možete i Vi deklarisati svoj tip koristeći bit polja. Ovo je jedan od načina kako bi kompajler mogo optimizirati program po pitanju veličine programa.Gore pomenuti tipovi podataka nam ne govore ništa o tome kako možemo raditi sa realnim brojevima, može se i pomoću int napraviti složeni broj koji bilježi deo preko, i ispod zareza, ali nećemo sad ulaziti u takve finese.

Hajde da pogledamo sledeći primer i analiziramo program. Samo da kažem da se realni brojevi pamte tako da se čuva znak broja, eksponent i mantisa. Za one koji su upoznati sa principima numeričke matematike ovo će biti trivijalno, dok za one koji su se sretali sa sličnim tipovim u drugim programskim jezicima, možemo najaviti malu zbunjenost. Obično je float dobar za 6 do 7 cifara, double za 15, a long double ukoliko je podržan do 19 znamenki. Ovo je inače okvirna preporuka.

PRIMER:#include <iostream>

using namespace std;

intmain(void){

float fRealniBroj=1.0;double dRealniBroj=2.0;long double ldRealniBroj=3.0;

8

Page 9: UVOD U C++ I DODATAK ZA C++11

cout<< "Realni brojevi " << endl << "float = " << sizeof(float) << " " << fRealniBroj << endl << "double = " << sizeof(double)

<< " " << dRealniBroj << endl << "long double = " << sizeof(long double)

<< " "<< ldRealniBroj << endl;

system("PAUSE"); return EXIT_SUCCESS;

}

Osim ovih vrsta promjenljivih srešćemo i: __int8,__int16, __int32, i__int64, kao i neke druge.Do sada smo videli koji su to tipovi podataka koje su nam omogućili da koristimo, a moguće je definisati i svoj tip podatka pomoću ključne reči typdef.

Recimo da se nalazimo u situaciji kad koristimo sledeći tip unsigned long long int, vidimo da nam treba 22 karaktera. Ukoliko često koristimo ovaj tip u programu može postati naporno pisati upravo jedan takav red da bi deklarisali neki tip. Na svu sreću postoji sledeća mogućnost u C++.

PRIMER:#include <iostream>

using namespace std;

typedef unsigned long long int MojTip;

intmain(void){

MojTip mtBroj1= 3, mtBroj2=1;cout<< mtBroj1<<endl;cout<< mtBroj2<<endl;

system("PAUSE"); return EXIT_SUCCESS;

}

Ako imamo trake na otporniku prve dve mogu primati vrednosti iz sledećeg skupa vrednosti {Crna, Smedja, Crvena, Narandzasta, Zuta, Zelena, Plava, Ljubicasta, Siva, Bela}.

Moguće je nabrojati vrednosti koje traka može da prima, drugim rečima to je skup nekih ograničenih vrednosti. Ali da ne komplikujemo pričom, uradite sledeći primer. Smatram da će svima biti jasno kako možete pobrojati neke vrednosti. Za vežbu možete kreirati tip podatka mesec, dani sedmice, planete u sunčevom sistemu, tip automobila i slično.

9

Page 10: UVOD U C++ I DODATAK ZA C++11

PRIMER:#include <iostream>

using namespace std;

enum TrakaOtpornika { Crna=1, Smedja, Crvena, Narndzasta, Zuta, Zelena, Plava, Ljubicasta, Siva, Bela};

intmain(void){

TrakaOtpornika toPrvaTraka = Crn, toDrugaTraka = Zuta;

cout<<"Prva traka "<<toPrvaTraka<<endl <<"Druga traka "<<toDrugaTraka<<endl;

system("PAUSE"); return EXIT_SUCCESS;}

Ukoliko ne napišete Crna=1, počinjemo sa brojanjem od nula. Ali da vidimo kako raditi sa strukturama. Strukture su važni element C++-a, zbog mogućnosti koje pružaju. Ukoliko se sretnemo sa nekim objektom koji ima više svojih karakteristika kao što su: lokacija po x, y i z osi, tri boje R, G i B. Vidimo da je za jednu promjenljivu koja opisuje obojenu tačku u 3D prostoru potrebno 6 podataka. Daleko je jednostavnije ove podatke objediniti u jednu strukturu, i na taj način zgodnije manipulisati sa njima. Klase sa tehničke tačke gledišta predstavljaju evoluirane struktue. Nemojte da preskočite strukture, lakše će Vam biti da naučite klase, kad se budete zainteresovali za objektno pogramiranje.

PRIMER:

#include <iostream>

using namespace std;

typedef struct Tacka3D_RGB {

double dX, dY, dZ; int iRed, iGreen, iBlue;

};

int

10

Page 11: UVOD U C++ I DODATAK ZA C++11

main(void){ //Deklarisemo tri strukture A, B i C Tacka3D_RGB A,

B, C={0,1,3,3,100,200};

//Struktura C je dobila vrednosti, dok A i B nisu dobile //pocetne vresnosti A.dX=3; A.dY=2; A.dZ=4; A.iBlue=0; A.iGreen=245; A.iRed=255;

//Nakon sto smo inicirali vrednosti za A mozemo prebaciti //sve vrednosti u B B=A;

//Prikazimo sve vrednosti koje cuva A cout<<"("<< A.dX<<","<<A.dY<<","<<A.dZ<<")" <<"RGB="<<A.iBlue<<" "<<A.iGreen<<" "<<A.iRed<<endl; system("PAUSE"); return EXIT_SUCCESS;

}

U prethodnom programu smo upotrebili tri tačke, u trodimenzionom prostoru, svaka tačka ima tri boje koje mešanjem daju stvarnu boju, ovo važi za RGB model.Za vežbu napišite strukturu: osoba, duž, prizma, piramida, i slično. Nemojte da mislite da je dovoljno uraditi samo ove zadatke. Pokušajte samostalno da zamislite nekoliko primera, tako da ih možete primeniti u različitim situacijama.

Unije omogućavaju čuvanje podataka različitog tipa, na nekoliko memorijskih lokacija. Kako to da objasnimo sebi. Zamislite policu, u nju možemo postaviti enciklopediju, strip ili recimo neku novelicu. Ostaje više ili manje prostora, u zavisnoti od veličine knjige koju smo smestili na određenoj polici. Pustimo sad knjige na miru, šta to znači u računaru. Moguće je deklarisati uniju koja može čuvati char, int ili float tip podatka. Prema potrebi mi možemo da promenimo podatke koje želimo da koristimo. Pređimo odmah na primer, ukoliko Vam nije dovoljno jasno, imamo Internet.

PRIMER:#include <iostream>

using namespace std;

union PrimerUnije

11

Page 12: UVOD U C++ I DODATAK ZA C++11

{int i;char c;float f;

};

intmain(void){ union PrimerUnije Broj,Znak,Realni; Broj.i=1; Znak.c='b'; Realni.f=17.71;

cout<<"Velicina |sadrzaj unije"<<endl<<sizeof(Broj)<<" "<< Broj.i<<endl <<sizeof(Znak)<<" "<< Znak.c<<endl <<sizeof(Realni)<<" "<< Realni.f<<endl;

Broj.c='a'; cout<< Broj.i <<" "<< Broj.c<<endl;

system("PAUSE"); return EXIT_SUCCESS;}

Zaključak je više nego očigledan, tako da nećemo trošiti vreme, samo da kažemo da morate da vodite računa šta ste zadnji put upisali u uniji, i naravno budite kreativni. Jedina mana unija je to što u memoriji zauzimaju onoliko prostora koliko i najveći tip koji je deklarisan u uniji. Divno bi bilo da imamo i komprimovane unije, one bi zauzimale manje prostora od običnih unija.Postoji još jedan tip koji ponekad može biti od koristi u situacijama kad želimo da sačuvamo prostor u memoriji. Reč je poljima bita.

Upoznajmo se sa pokazivačima. Varijable koje smo do sada koristili, su imale samo mogućnost direktnog pristupa. Odlika im je da se lako koriste, a problem je to što nemamo dovoljnu fleksibilnost da bi mogli kreirati dinamičke strukture.

Mnogi programeri sebi postavljaju pitanje: „zašto da učim pokazivače?“. Neki će jednostavno naučiti ne razmišljajući zašto im oni trebaju, a tek kasnije će uočiti primene, dio njih će se zapitati čemu to služi „kad vidite koliko smo programa napisali, a nikada nismo ni pomenuli pokazivač“. Odmah da kažem, da deo snage programskog jezika C++ leži upravo u elegantnoj upotrebi pokazivača. U kombinaciji sa pokazivačima koristimo operator & adresa od, da bi uspostavili vezu sa nekom drugom promjenljivom. Pri tom nemojmo zaboraviti prazan pokazivač NULL, danas C++11 već dozvoljava i drugačije označavanje. Pogledajte dodatak za promene novog C++11 standarda.Za razliku od promjenljive koja čuva podatak, pokazivač čuva informaciju gde se podatak nalazi. Zbog toga koristimo i termin indirektni pristup. Otprilike, ako ne znate gde se nalazi neka ulica možete pitati nekog od prolaznika. Ovo je dovoljan osnov da razumete kako pokazivač funkcioniše Pridodajmo da možemo imati pokazivač na pokazivač, kao i

12

Page 13: UVOD U C++ I DODATAK ZA C++11

pokazivač na pokazivač koji pokazuje na pokazivač. Verovatno bi tako mogli ići u nedogled, ali mislim da ćete zbog mogućnosti ljudskog mozga uspeti proširiti ovaj pojam.

Nećemo dugo da teoretišemo o pokazivačima, uradimo sledeći primer.

PRIMER:#include <iostream>

using namespace std;

intmain(void){

//Deklaracije pokazivaca i promjenljivihint iBroj=3;

int * iPtr, ** iPtrPtr;

//Povezivanje pokazivaca iPtr= & iBroj;iPtrPtr = & iPtr;

//prikazi adresa i pokazivacacout<< &iBroj <<" "<<iBroj<<endl;cout<< &iPtr<<" "<<iPtr <<" "<<*iPtr<<endl;cout<< &iPtrPtr <<" "<<iPtrPtr<<" "<<*iPtrPtr<<" "<<**iPtrPtr<<endl;

system("PAUSE");return EXIT_SUCCESS;

}

Na računaru sam dobio sledeći izlaz:0012FF60 30012FF54 0012FF60 30012FF48 0012FF54 0012FF60 3Press any key to continue . . .

Smisao gore prikazanih podataka je sledeći:Promjenljiva iBroj se nalazi na adresi 0012FF60, i sadrži broj 3 kao integer.Varijabla iPtr se nalazi na lokaciji 0012FF54, i sadrži adresu 0012FF60. Vrednost 3 možemo da prikažemo indirektno koristeći *iPtr, ili direktno koristeći iBroj.

13

Page 14: UVOD U C++ I DODATAK ZA C++11

Sledeći red je malo kompleksniji, promjenljiva iPtrPtr se nalazi na lokaciji 0012FF48, u njoj se čuva adresa iPtr, moguće je indirektno dohvatiti iPtr i iPtrPtr.U prethodnom primeru smo videli kako pristupati pokazivačima i pokazivačima koji pokazuju na pokazivač. Za vežbu napravite više pokazivača na ... pokazivač. Ukoliko ilustracija može da Vam pomogne razmotrite sledeću grafiku.

Da sad vidimo kako možemo imati različite tipove pokazivača, kao i kako se koristi NULL pokazivač, napomenimo da imamo mogućnost upotrebe pokazivača bez tipa void *, koja nekome može biti krajnje zbunjujuća, postojat će i oni koji su jedva dočekali upravo takvo šta.

PRIMER:#include <iostream>

using namespace std;

intmain(void){

char cZnak ='c', * ptrChar = &cZnak; int iBroj = 3 , * ptrInt = &iBroj;

cout<< cZnak << *ptrChar <<endl; cout<< iBroj << *ptrInt <<endl;

void * ptrNesto; (int*) ptrNesto; ptrNesto = &iBroj;

(char*) ptrNesto;ptrNesto = &cZnak;

cout<< *(char*) ptrNesto<<endl; system("PAUSE");

return EXIT_SUCCESS;}

Prethodni program je kompleksniji tako da zahteva malo više objašnjenja. Deklarisali smo promjenljive tipa int i char, kao i njihove odgovarajuće pokazivače koji smo istovremeno povezali. Nakon toga smo prikazali sadržaj svake od promjenljivih. Pokušajte da vidite koliko memorijskih lokacija zauzimaju ptrChar i ptrInt. Koristite operator sizeof().Zatim smo deklarisali ptrNesto, kao pokazivač na bilo šta. Potom smo pretvorili ovaj pokazivač u pokazivač na int. Nakon toga smo pokazivač ptrNesto transformisali u pokazivač na char. Ostaje samo da indirektno pristupimo ovim podacima.

Vrednost NULL dodjeljujemo tako što napišemo ptrInt= NULL.Hajde da vidimo šta je to referenca ili alijas, a nakon toga ćemo uraditi primer koji ilustruje konvertovanje promjenljivih iz jednog u drugi tip.

14

Page 15: UVOD U C++ I DODATAK ZA C++11

Recimo da imamo neko komplikovano ime, Maksimilijan ili nešto slično. Naši drugari će nas zvati MaX ili recimo Makso. Reference su kreirane zbog problema koji nastaju prilikom upotrebe pokazivača u funkcijama. Kreiraju se nepregledni izrazi koje je teško čitati. Jednom prilikom sam pisao program koji je računao integral pomoću neke od numeričkih metoda u C-u. Program je radio, ali je kod bio toliko nepregledan. Kasnije su uvedene reference u C++-u. Posledica je to upotrebe operatora dereferenciranja(*-sa desne strane promjenljive). Ah da, kasnije ćemo pomenuti i ->. Ovaj primer ilustruje upotrebu referenci ili alijasa. Nekome možda neće biti jasno zašto postoje, ali upotrebljavaju se i u objektnom programiranju, naučite ih sad, a kasnije će Vam trebati.Dodajmo da reč alijas znači nadimak, kao da neka promjenljiva dobija nadimak, i tad joj možete pristupiti preko tog „nadimka“.

PRIMER:#include <iostream>

using namespace std;

intmain(void){ int iBroj= 12; int& iReferenca = iBroj;

cout<< iBroj<<endl <<iReferenca<<endl;

iReferenca = 19;

cout<< iBroj<<endl <<iReferenca<<endl;

system("PAUSE"); return EXIT_SUCCESS;}

Možda nekome još nije jasno kada će koristiti referencu, ali verujte napravili su ih sa razlogom.

15

Page 16: UVOD U C++ I DODATAK ZA C++11

Pređimo na konvertovanje podataka iz jednog u drugi tip. Navedimo sad primer kad koristimo jednu promjenljivu tipa int, zatim ćemo da je pretvorimo u tip float i double.

PRIMER:#include <iostream>

using namespace std;

intmain(void){

int iBroj= 159;double dBroj= (double) iBroj;float fBroj = float( dBroj);

cout<<" Integer= "<<iBroj<<endl <<" Double = "<<dBroj<<endl <<"Float ="<<fBroj<<endl;

system("PAUSE"); return EXIT_SUCCESS;}

Danas je popularno koristiti sledeće operatore: static_cast<tip>. const_cast<tip>. dynamic_cast<tip>. reintrepret_cast<tip>.

Ove definicije možete pronaći na Internetu,a preporuka je da ih koristite, a ne starije iako u neku ruku simpatičnije načine konvrtovanja podaotaka.

Mi ćemo da vidimo kakve su to konstantne vrednosti. Ako recimo pišemo program koji računa obim i površinu kruga, broj pi ostaje broj pi. Razvijamo li aplikaciju koja računa porez, može se desiti da pdv iznenada promeni svoju stopu, slično je i sa drugim konstantnim vrednostima. Upravo sam dobio vest da je u americi povećan porez bogatima, zamislite sad da ste na 10 000 mesta u programu koristili ovu konstantu, ali na svu sreću možemo definisati konstantu koju menjamo samo na jednom mestu, promene će se automatski raširiti po celome programu.

PRIMER:#include <iostream>

# define PI 3.141592 const float fPi = 3.141592;

using namespace std;

16

Page 17: UVOD U C++ I DODATAK ZA C++11

intmain(void){ cout<<"Unesite poluprecnik kruga->"; float fPoluprecnik; cin>> fPoluprecnik; cout<<"Povrsina ="<< fPoluprecnik*fPoluprecnik*PI<<endl

<<"Obim =" << 2.0*fPoluprecnik*fPi <<endl; system("PAUSE"); return EXIT_SUCCESS;}

Danas, ukoliko Vaš C++ podržava novi C++ 11 standard, možete upotrebiti i auto tip podatka. Ranije je auto bio podrazumevani tip podatka, i nije se pisao ali se podrazumevao, danas ova reč ima drugo značenje, ali o tome možete više saznati u poglavlju posvećenom proširenjima koje je doneo novi standard.Ako se ne možete odlučiti za tip promjenljive, ili Vam promjenljiva može služiti za prihvatanje različitih podataka, a tip podatka može biti int, long int, double ili neki drugi, možda se nalazite u situaciji kad bi bilo poželjno upotre biti auto deklaraciju za promjenljivu.

Uzgred, ukoliko želite da proverite kojeg je tipa promjenljiva, možete upotrebiti decltype. Neko će se zapitati, a zašto bih ja proveravo kojeg je tipa promjenljiva kad sam je ja i deklarisao, pa shodno tome nema smisla proveravati kojeg je tipa nešto što sam deklarisao i slično.

Može se desiti da želite da napravite funkciju koja će u zavisnosti od tipa reagovati na različite načine, danas možete da koriste templejte ili auto tip podatka u toj situaciji. Prilikom rada na jednoj od aplikacija sam imao potrebu da proverim koji je objekat slao poruku, da bih to proverio morao sam i da ustanovim kojeg je tipa taj objekat. Eto, ovo su samo neke od situacija kad bi Vam zaista zatrebale gore pomenute novotarije.

17

Page 18: UVOD U C++ I DODATAK ZA C++11

3 . O P E R AT O R I

U prethodnom poglavlju smo videli kako možemo da čuvamo različite tipove podataka, čije čuvanje i prikazivanje nebi bilo korisno, da sa tim podacima ne možemo nešto da uradimo. Šta mislim kad kažem da nešto uradimo sa podacima. Da bi ih transformisali, vršimo neke operacije nad njima, kao recimo sabiranje, množenje ili oduzimanje. Za to su nam potrebni operatori. Pomoću promjenljivih i operatora formiramo izraze. Sad ćemo da naučimo šta su to operatori.Da bi objasnili operatore moramo da razumemo sledeće pojmove:

Nivo prioriteta. Asocijativnost. Ime operatora. Opis i sintaksa.

O nivou prioriteta i asocijativnosti više u sledećim redovima ovoga poglavlja, ali verovatno ste već čuli za većinu operatora. Ostaje samo da vidimo operatore specifične za C++.Oni su poredani prema nivou prioriteta. Od koristi može biti da pronađete njihovu listu na Internetu te da to isprintate i čuvate na nekom vidnom mestu. Ukoliko duže budete radili sa C++-om, operatore ćete razumeti automatski, tako da nećete mnogo morati ni razmišljati o njihovoj upotrebi.

Grupa operatora prvog nivoa, leve asocijativnosti:▪Operator poziva funkcije ()Koristi se da bi grupisao argumente koje poziva funkcija. Primer PozivFunkcije( ListaArgumenata).

▪Operator pristup elementima niza []Koristi se da bi pristupali elementima niza, kojima pristupamo na osnovu imena niza i indeksa. Primer NekiNiz[indeksNiza].

▪Pristupanje članu strukture ->Upotrebljava se da bi pristupili nekom članu strukture, a često se koristi kod dinamičkih struktura.Primer ptrPok-> a.

▪Pristupanje članu strukture ili klase .Ukoliko imamo strukturu koja ima više polja, ili ako imamo klasu koja ima svoje delove, moguće je pristupati njihovim elementima pomoću ovog operatora. Primer upotrebe bi bio NekaStruktura.ElementStrukture.

▪Razrješavanje dosega ::Ovaj operator se koristi da bi pristupali članovima imenskog prostora, ili da bi razrešili doseg. Primer upotrebe ovog operatora std::cout.

Grupa operatora drugog nivoa, desne asocijativnosti:▪Unarni operator negacije !Koristi se da bi negirali neki iskaz. Drugim rečima ako je iskaz bio tačan, nakon primene ovog operatora iskaz postaje ne tačan, važi i obratno. Primer !(LogickiIskaz).

18

Page 19: UVOD U C++ I DODATAK ZA C++11

▪Negacija bita ~Ukoliko je bit bio 1 nakon bit negacije postaje 0, a ako je bit bio 0 nakon primene ovog operatora bit postaje 1. Primer upotrebe: ~iCeliBrojBitNegiran.

▪Operator inkrementacije ++Ukoliko želimo uvećati vrednost promjenljive za 1, možemo koristiti ovaj operator. Postoje dva oblika prefiksni i sufiksni. Kod prefiksnog oblika ovog operatora, prvo uvećamo vrednost promjenljive, a zatim je upotrebimo u izrazu, dok kod postfiksnog oblika se prvo upotrebi tekuća vrednost varijable, a zatim se vrednost promjenljive uveća za 1. Primer prefiksne upotrebe: ++iBroj; a sufiksne iBroj++;

▪Operator dekrementacije - -Želimo li smanjiti vrednost za jedan nekom broju, koristimo operator minus minus. Sličan je operatoru ++. Primer upotrebe: --Broj; i iBroj--;.

▪Unari minus –Ovaj operator menja predznak izraza. Primer upotrebe –iBroj.

▪Operator dereferenciranja *Operator koristimo pri radu sa pokazivačima. Primer *ptrPokazivac.

▪Operator uzimanja adrese &Koristi se da bi uzeo adresu neke promjenljive. Primer &ptrPokazivac.

▪Operator određivanja veličine promjenljive sizeofPomoću ovog operatora, koliko to čudno zvučalo, možemo odrediti veličinu neke promjenljive u memoriji. Primer upotrebe operatora: sizeof( iBroj).Napomenimo samo da je veličina u bajtima(B), a ne bitima(b).

▪Operator za zauzimanje prostora u memoriji newAko je potrebno u toku rada programa, promeniti veličinu nekog objekta, drugim rečima ako nam treba određeni broj memorijskih lokacija možemo koristiti ovaj operator. Pomenimo da su se ranije koristile: malloc, calloc i realloc, koji se danas većinom smatraju zastarjelim. Primer upotrebe new int, new int[], ili new tip(argument).

▪Operator za oslobađanje prostora u memoriji deleteUkoliko neke članove niza, ili neke dinamičke strukture ne trebamo u programu možemo ih ukloniti pomoću ovog operatora. Stari oblik sličan delete operatoru je free, koji se koristio u kombinaciji sa gore pomenutim funkcijama.Primer upotrebe delte [] iNiz;.

▪Operator za konverziju/kastanje ( )Prilikom pretvaranja promjenljivih iz jednog tipa u drugi, možemo koristiti ovaj operator. Primer (int *) vPok.

19

Page 20: UVOD U C++ I DODATAK ZA C++11

Grupa operatora trećeg nivoa, leve asocijativnosti:▪Operator pokazivač na član .*Ovaj operator koristimo da bi pristupli članu strukture. Primer nekiObjekat.*ptrNaClan.

▪Operator pokazivač na član ->*Ovaj operator je daleko logičniji od prethodnog operatora. Primer ptrNaClan->*ptrClan

Grupa operatora četvrtog nivoa, leve asocijativnosti:▪Operator množenje *Ovaj binarni operator se koristi za množenje dve promjenljive, svima je poznat još iz osnovne škole. Primer upotrebe iBrojPrvi * iBrojDrugi.

▪Operator deljenja /Ako želimo podeliti dva broja koristimo ovaj operator. Primer iBrojPrvi / iBrojDrugi.Operator ostatka celobrojnog deljenja %7= 2*3 +1. Ukoliko nas interesuje koliko iznosi ostatak pri celobrojnom deljenju. Kod djeljenja sa 3 ostatak može biti: 0, 1 ili 2. Primer iBroj% iDelitelj

Grupa operatora petog nivoa, leve asocijativnosti:▪Operator sabiranje +Ovaj opšte poznati binarni operator koristimo pri sabiranju brojeva. Primer dSabirakPrvi + dSabirakDrugi.

▪Operator oduzimanja -Ukoliko želimo oduzeti dva broja koristimo ovaj operator na sledeći način fBrojPrvi – fBrojDrugi.

Grupa operatora šestog nivoa, leve asocijativnosti:▪Operator pomeranja bita u levo <<Ukoliko bitove želite pomeriti u levo, možete koristiti ovaj operator. Ponekad se koristi za brzo množenje brojeva, pri čemu moramo voditi računa da se bitni bitovi ne izgube. Primer iBroj<<2.

▪Operator pomeranja bita u desno >>Ovaj operator koristimo da bi bitove pomerili sa desna. Primer iBroj>>2.

Grupa operatora sedmog nivoa, leve asocijativnosti:▪Operator manje od <Ukoliko poredimo dva broja, ili pokazivača, upotreba ovog iskaza nam vraća tačno ili netačno. Primer upotrebe ovog operator iBrojPrvi < iBrojDrugi.

▪Operator manje ili jednako <=Ukoliko poredimo dva broja, ili pokazivača, upotreba ovog iskaza nam vraća tačno ili netačno. Primer upotrebe ovog operator iBrojPrvi < = iBrojDrugi.

20

Page 21: UVOD U C++ I DODATAK ZA C++11

▪Operator veće od >Ukoliko poredimo dva broja, ili pokazivača, upotreba ovog iskaza nam vraća tačno ili netačno. Primer upotrebe ovog operator iBrojPrvi > iBrojDrugi.

▪Operator veće ili jednako >=Ukoliko poredimo dva broja ili pokazivača, upotreba ovog iskaza nam vraća tačno ili netačno. Primer upotrebe ovog operator iBrojPrvi > = iBrojDrugi.

Grupa operatora osmog nivoa, leve asocijativnosti:▪Operator ispitivanje jednakosti = =Ako je potrebno ispitati da li su dva broja, ili pokazivača jednaka koristimo ovaj operator. Primer iBroj1==iBroj2.

▪Operator ispitivanje različitosti/nejednakosti !=Ukoliko ipitujemo da li su dva broja različita, ili da li pokazivači pokazuju na različite članove niza možemo koristiti ovaj operator. Primer: iA != iB.

Grupa operatora devetog nivoa, leve asocijativnosti:▪Operator i za bitove &Primer upotrebe iBroj1 & iBroj2.

Grupa operatora desetog nivoa, leve asocijativnosti:▪Operator ekskluzivno ili za bitove ^Primer upotrebe iBroj1 ^ iBroj2.

Grupa operatora jedanaestog nivoa, leve asocijativnosti:▪Operator ili za bitove |Primer upotrebe iBroj1 | iBroj2.Nakon operatora orjentisanih na operacije sa bitovimo, prelazimo na logičke operatore.

Grupa operatora dvanaestog nivoa, leve asocijativnosti:▪Operator logičko i &&Ukoliko Vam ne odgovara upotreba ovog operatora, nakon dodavanja biblioteke iso646.h možete koristiti and. Neki proizvođači ne zahtevaju ni da se uključi ova bibliteka. Ovaj operator koristimo prilikom vezanja logičkih iskaza. Primer bPrviIskaz && bDrugiIskaz, ili bPrviIskaz and bDrugiIskaz. Možete i kreirati vlastite makroe.

Grupa operatora trinaestog nivoa, leve asocijativnosti:▪Operator logičko ili ||Prilikom upotrebe dva logička iskaza, ukoliko želimo da bar jedan operator bude tačan da bi nešto uradili možemo koristiti logičko ili. Primer: bPrviIskaz || bDrugiIskaz.

21

Page 22: UVOD U C++ I DODATAK ZA C++11

Grupa operatora četrnaestog nivoa, desne asocijativnosti:▪Ternarni operator ?:Ukoliko imamo posla sa jednostavnim if naredbama, bolji izbor je upotreba ternarnog operatora. Danas je moguće nadovezivanje ovih operatora. Primer ( iBroj<0)? ‘-‘: (iBroj>0)? ‘+’: ‘0’; nadovezanog ili običnog ternarnog operatora (iBroj%2==0)?“paran”: “neparan”;.Prilikom upotrebe ovog operatora povedite računa o tome da će neko posle Vas možda čitati kod.

Grupa operatora petnaestog nivoa, desne asocijativnosti:Nadam se da ste radili sa nekim drugim programskim jezicim, i da ste pisali sledeće izraze:Suma = suma + broj;Uočavamo da dva puta pišemo suma, C++ je pružio pogodniji način zapisa takvih izraza.

▪Operator dodele vrednosti =. Primer iSuma=0.▪Operator sabiranja i dodele vrednosti +=. Primer iSuma+=iBroj;.▪Operator oduzimanja i dodele vrednosti -=.▪Operator množenja i dodele vrednosti *=.▪Operator deljenja i dodele vrednosti /=.▪Operator deljenja po modulu i dodele vrednosti %=.▪Operator pomjeranja udesno i dodele vrednosti >>=.▪Operator pomjeranja ulevo i dodele vrednosti <<=.▪Operator i nad bitima i dodela vrednosti &=.▪Operator ekskluzivno i nad bitima i dodela vrednosti ^=.▪Operator ili nad bitima i dodela vrednosti |=.

Grupa operatora šesnaestog nivoa, desne asocijativnosti:▪Operator zarez ,Ukoliko imamo više naredbi u recimo for naredbi pomoću, ovog operatora možemo ih grupisati u jednu naredbu. Primer for( i= 0, j=1, k=2; ; i++, j--).

Uradimo nekoliko primera da bi razjasnili upotrebu operatora specifičnih za jezik C++.

Sledeći program ilustruje rad sa binarnim operatorima.

PRIMER:#include <iostream>

using namespace std;

intmain(void){ unsigned int uiBroj1=0x0000,

uiBroj2=0x00FF, uiBroj3=0xFF00, uiBroj4=0xFFFF;

22

Page 23: UVOD U C++ I DODATAK ZA C++11

cout<< "decimalno "<<uiBroj1<<" heksa "<<hex<<uiBroj1<<endl;

cout<< "decimalno "<<dec<<uiBroj2<<" heksa " <<hex<<uiBroj2<<endl;

cout<< "decimalno "<<dec<<uiBroj3<<" heksa " <<hex<<uiBroj3<<endl;

cout<< "decimalno "<<dec<<uiBroj4<<" heksa " <<hex<<uiBroj4<<endl<<endl;

cout<<" Bit negacija"<<hex<< ~uiBroj1<<endl;cout<<" Bit negacija"<<hex<< ~uiBroj4<<endl<<endl;

unsigned int uiBrojI = uiBroj2 & uiBroj4;cout<<" 00FF i FFFF="<< uiBrojI<<endl;

unsigned int uiBrojExIli = uiBroj2 ^ uiBroj4;cout<<" 00FF exili FFFF="<< uiBrojExIli<<endl;unsigned int uiBrojIli = uiBroj2 | uiBroj4;cout<<" 00FF ili FFFF="<< uiBrojIli<<endl<<endl;

unsigned int uiResult;uiResult=uiBroj2<<1;cout<<dec<< uiResult<<endl;

system("PAUSE");return EXIT_SUCCESS;

}

Sledeći zadatak ilustruje upotrebu operatora inkrementacije i dekrementacije.

PRIMER:#include <iostream>

using namespace std;

intmain(void){ unsigned short int usiBroj1 = 0,

usiBroj2 = 0;

cout<<usiBroj1<<endl; cout<< ++usiBroj1<<endl; cout<<usiBroj1++<<endl; cout<<usiBroj1<<endl;

23

Page 24: UVOD U C++ I DODATAK ZA C++11

cout<<"--------------"<<endl;

cout<<usiBroj2<<endl; cout<<usiBroj2++<<endl; cout<<++usiBroj2<<endl; cout<<usiBroj2<<endl;

system("PAUSE"); return EXIT_SUCCESS;}

Napišite sličan primer za operator dekrement. Uz još jednu napomenu, moguće je uraditi sledeću stvar ++++i;, dok nije moguće napravit sledeće i++++;. Ovo će nam razjasniti lvrednost.Već smo videli kako raditi sa pokazivačima, ali da vidimo ove operatore na delu.

PRIMER:#include <iostream>

using namespace std;

intmain(void){

// iBroj i pokazivac na tu promjenljivu int iBroj =19,

iPtrBroj ;

iPtrBroj= & iBroj;

// neki operatori koji se koriste sa pokazivacima cout<< & iBroj<<" " << iBroj<<" " << sizeof(iBroj)<<endl;

cout<< & iPtrBroj<<" " << iPtrBroj<<" " << *iPtrBroj

<<sizeof(iPtrBroj)<<endl;

//pokazivac na int i char imaju istu velicinuchar cZnak =' b', * cPtrZnak;

//velicina je ista zato sto sadrze adresucout<<"Velicina pokazivaca na int* "

<<sizeof(iPtrBroj)<<endl;

24

Page 25: UVOD U C++ I DODATAK ZA C++11

cout<<"Velicina pokazivana na char* " <<sizeof(cPtrZnak)<<endl;

system("PAUSE"); return EXIT_SUCCESS;}

Ukoliko Vam nisu jasne logičke operacije evo nekoliko primera da osvežite memoriju.

PRIMER:#include <iostream>

using namespace std;

intmain(void){

bool bTacno = true, bNetacno = false;

bool bLogickoI = bTacno && bNetacno;bool bLogickoILI = bTacno || bNetacno;

bool bNegacijaTacno = !bTacno;

cout<< boolalpha << "bTacno="<< bTacno<<endl << "bNetacno="<< bNetacno<<endl << "Tacno i Netacno= "<< bLogickoI<<endl << "Tacno ili Netacno="<< bLogickoILI<<endl << "!Tacno="<<bNegacijaTacno<<endl;

cout<<noboolalpha;

system("PAUSE"); return EXIT_SUCCESS;}

Iako logičke promjenljive nisu izvorno bile deo C-a, danas se koriste kao njegov ne izbežni deo. Upotreba logičkih prihvatljiva, a postoji mnogo situacija u kojima je upotreba ovog tipa promjenljive najbolji izbor.

25

Page 26: UVOD U C++ I DODATAK ZA C++11

Unesite sledeći zadatak.

PRIMER:#include <iostream>

using namespace std;

intmain(void){

int iA = 0, iB = 1, iC = 2;

cout<<"iA= "<<iA<<" iB= "<< iB<<" iC= "<<iC<<endl;iA++;cout<<"iA= "<<iA<<" iB= "<< iB<<" iC= "<<iC<<endl;iB+=iA;cout<<"iA= "<<iA<<" iB= "<< iB<<" iC= "<<iC<<endl;iC=iA+iB;cout<<"iA= "<<iA<<" iB= "<< iB<<" iC= "<<iC<<endl;iC--;cout<<"iA= "<<iA<<" iB= "<< iB<<" iC= "<<iC<<endl;

system("PAUSE"); return EXIT_SUCCESS;}

iA= 0 iB= 1 iC= 2iA= 1 iB= 1 iC= 2iA= 1 iB= 2 iC= 2iA= 1 iB= 2 iC= 3iA= 1 iB= 2 iC= 2

Postoji mnogo primera na Internetu, ukoliko Vam nisu bili jasni ovi operatori, konstruišite primere samostalno, ili potražite neki od već postojećih sajtova.

26

Page 27: UVOD U C++ I DODATAK ZA C++11

4 . I Z R A Z I

Nakon što smo se upoznali sa promjenljivim i operatorima jezika C++, došao je red na izraze. Ukoliko imamo dva broja, i operator + kreiramo jedan izraz. Drugim rečima, dva sabirka daju zbir. Razmotrimo sledeće linije koda.

int iPrviSabirak = 5, iDrugiSabirak = 7;

int iZbir;

iZbir = iPrviSabirak + iDrugiSabirak;

Analizirajmo zadnji red. Imamo dva operatora: operator = kao dodele vrednosti, i operator + kao binarno sabiranje. Hajde sad da vidimo šta je to izraz.Izraz se sastoji od: ▪ Promjenljivih,▪ Konstanti ▪ i operatora.

Da bi izračunali vrednost izraza, moramo da razumemo pravila koja se koriste za računanje izraza. Da ovi zakoni ne postoje, izrazi ne bi bili određeni.

Navedimo neke pojmove koji će nam omogućiti da produbimo i osvežimo naše razumevnje kako C++ interpretira izraze i kako se kreiraju lekseme.Pre svega recimo nešto o tokenima ili leksemama. Kad napišemo neku liniju teksta imamo posla da potencijlnom naredbom koju treba razdvojiti u tokene, da bi se mogle prevesti u mašinski izvodljiv kod.Primer bi bila naredba:cout<< iBroj<<endl;Imamo raščlanjivanje na sledeće lekseme, odvojićemo ih zarezom: ‘cout’, ’<<’, iBroj, ’<<’, ’endl’, i oznaka za kraj naredbe ’;’.Drugim rečima razbili smo rečenicu na reči koje nešto znače. Ukoliko bi pokušali dalje da cepkamo neki od izraza ne bi dobli nikakvu smislenu naredbu, ili bi došli u situaciju da imamo izraz koji nema smisla. Tokeni mogu biti:▪ Identifikator.▪ Rezervisana reč.▪ Simbol.▪ Konstanta.▪ Ili neki znakovni niz.

Posmatrajmo sledeći izraz:3+2*6Prilikom analize možemo dobiti dva rezultata: 30 ili 15, da nemamo nivoe prioriteta ne bi mogli da se odlučimo ni za jedan od gore ponuđenih rezultata. Na svu sreću, poznato nam je da operator * ima veći prioritet od operatora +, tako da se prvo vrši operacija 2*6 što predstavlja 12, a zatim se dodaje 3. Na ovaj način ne možemo dovesti sebe u neizvesnost koji je rezultat.

27

Page 28: UVOD U C++ I DODATAK ZA C++11

Ukoliko želimo da narušimo ovaj prirodni prioritet možemo koristiti male zagrade. (3+2)*6 Drugim rečima, nakon upotrebe zagrada, promenili smo podrazumevano izvršavanje operatora 3+(2*6). Ponekad možete dodati zagrade da bi izraz učinili očiglednijim.Imamo izraz kod kojeg imamo više operatora istog nivoa primer:a*b/c%d, ili recimo a= b= c=0, da nemamo asocijativnosti ne bi mogli odrediti rezultate izraza.Sledeći bitni pojmovi su: lvalue i rvalue. Sve izraze možemo podeliti u lvrednosti ili rvrednosti. Lvrednosti postoje i one imaju svoje ime i adresu, čuvaju se negdje u memoriji. Što je možda i najbitnije, mogu da prime rezultate operacija. Postoje i lvrednosti, kao što su konstante koje ne mogu da se menjaju, ali su i dalje lvrednosti.Preporuka je da se rvrednosti tako ne nazivaju, ali zbog logičnosti prevoda right value, one mogu da se nalaze sa desne strane izraza, moramo ih pomenuti na ovako ne preporučljiv način.Prilikom analiziranja izraza možete čuti za pojam bočni efekat. Ako računamo izraz koji ima znak dodele, osim vrednosti koje smo dobili kao rezultat mogu se pojaviti neki drugi efekti. Ove izmene ili efekte nazivamo bočnim efektima. Oni mogu, u nekim slučajevima, da stvaraju probleme, a moguće je i da funkcija ima bočne efekte. Primeri b=a=0. Kao loš primer navedimo da se mogu javiti problemi prilikom upotrebe inkrement i dekrement operatora pri pozivima funkcije.

Pojam koji nećemo zaobići je međusekventna tačka. U procesu rada programa, postoje prelomni momenti u kojima su odrađeni bočni efekti izraza, a do bočnih efekata sledećeg izraza još nismo došli, upravo takve tačke nazivamo međusekventnim tačkama. Primer bi bio sledeći izraz: i=i++;. Ovaj izraz nije definisan, jer u različitim programima možemo dobiti različite rezultate.

Hajde da razmislimo šta će biti rezultat sledeće operacije*p++; Pošto smo naučili da se ovo interpretira s desna na levo pokazana vrednost se uvećava za jedan. Uradite sledeći program.

PRIMER:#include <iostream>

using namespace std;

intmain(void){

int iA = 0, * ptriA = & iA;

cout<< iA<<" "<<*ptriA<<endl;

(*ptriA)++;cout<< iA<<" "<<*ptriA<<endl;

*ptriA++;cout<< iA<<" "<<*ptriA<<endl;

system("PAUSE"); return EXIT_SUCCESS;}

28

Page 29: UVOD U C++ I DODATAK ZA C++11

Vidite kako smo koristili male zagrade da uradimo ono što želimo, ne verujem da bi iko želeo da u predhodnoj situaciji uradi *ptriA++;, to je rezervisano za uvećavanje adrese za jedan. Drugi oblik se koristi u radu sa stringovima, na taj način možete kreirati elegantna rešenja.

Za vežbu pokušajte da upotrebite i kombinacije prefiksnog oblika operatora ++, i operatora dereferenciranja: ++*ptriA i *++ptriA.

Ah da, pogledajte i sledeći ne znatno izmenjeni primer.

PRIMER:#include <iostream>

using namespace std;

intmain(void){

int iA = 0, * ptriA = & iA;

cout<< iA<<" "<<*ptriA<<endl;

++*ptriA;cout<< iA<<" "<<*ptriA<<endl;

*++ptriA;cout<< iA<<" "<<*ptriA<<endl;

system("PAUSE");return EXIT_SUCCESS;

}

Ostaje još da razjasnite složene deklaratore i imena tipova. Ponekad se može od Vas očekivati da odredite neke od složenih tipova podataka koje i dalje C++ podržava, inače oni se danas, iako su nasleđeni od C-a, ređe koriste. Ukoliko imate potrebu da ovo razmotrite potražite te pojmove na Internetu, ili u nekoj starijoj knjizi o C-u, siguran sam da ćete pronaći to što Vas interesuje.

29

Page 30: UVOD U C++ I DODATAK ZA C++11

5 . K O N T R O L A T O K A P R O G R A M A

Kad pišemo programe koji se izvršavaju liniju za linijom, možemo rešiti jednostavnije primere, ali to nije dovoljno da rešimo iole ozbiljniji problem. Recimo da se nalazimo u situaciji kada je potrebno proceniti da li klijent može kupiti proizvod, operaciju je moguće načiniti ukoliko klijent ima dovoljnu količinu novca na svom računu. Ovaj scenario se može desiti, ako pišemo dio aplikacije koja će putem Interneta odlučivati, da li se može obaviti određena novčana transakcija ili ne. Ako osoba nema potrebnu količinu novca na svom računu, ne možemo obaviti potrebnu operaciju, dok u slučaju da klijent poseduje dovoljno novca, moguće je izvšiti uplatu sa jednog na drugi račun.Slične situacije možemo razrešiti pomoću if naredbe.

Razlikovaćemo dva oblika if naredbe: potpuni i ne potpuni obilik. Kasnije ćemo nešto više reći o umetnutim if naredbama. Recimo da if naredba reaugeje na logički iskaz, a on može biti tačan ili ne tačan. Moguće je jednostavne logičke iskaze kombinovati u složene, a za to koristimo logičke operatore. Recimo da danas ne morate koristiti && za logičko i, nego možemo upotrebiti AND, slično važi i za ostale logičke operatore. Nećemo razmatrati osnove Bulove algebre, jer je to većini odavna poznato, ali ukoliko ste propustili ili slučajno niste razumeli pregledajte Internet, postoji dosta materijala na tu temu, tako da mi nećemo gubiti vreme na razjašnjavanje logike.Neki autori registruju i neke druge oblike ove naredbe, kao recimo if elese if, if else if else, kao i primer if if elese. Ovaj poslednji ćemo detaljnije razjasniti. U suštini ovo su primeri kombinovanja kompleksnog i prostog oblika if naredbe. Dodajmo da u prevodu if znači ako.

Da ne bi čitaoca držali u neizvesnosti hajde da zajedno uradimo jedan primer.

Potrebno je ispitati da li je uneseni broj paran ili neparan. Nećemo razmatrati negativne brojeve niti nulu. Drugim rečima, verovaćemo da će korisnik uneti odgovarajuće podatke. Za grafičko prikazivanje nepotpunog oblika if naredbe može poslužiti slika 5.1.

U praktičnim problemima nemojte ni slučajno puštati ovakve aplikaciju u slobodnu prodaju, jer će se uvek naći neko ko će želeti da proveri i verifikuje šta sve može, a šta ne.

30

Page 31: UVOD U C++ I DODATAK ZA C++11

PRIMER:#include <iostream>

using namespace std;

intmain(void){ //Unesimo broj iz skupa N cout<<"Unesite neki pozitivni cjeli broj->";

//ovde sam upotrebio long long int, a mogao sam upotrebiti i unsigned long long int //neki ce reci da je ovaj tip vise u duhu jezika C++11, nama je dobrodosao

unsigned long long int iBroj; system("CLS");

cin>>iBroj; //Ukoliko ne unesemo odgovarajuci broj

if(iBroj<=0){

system("COLOR 0C");cout<<"Broj ne razmatramo!!!"<<endl;system("PAUSE");return EXIT_FAILURE;

}

//Ukoliko je korisnik uneo odgovarajuci brojsystem("COLOR 02");cout<<"Uneseni broj "<<iBroj<<' ';if( iBroj%2==0) cout<<" je paran"; else cout<<" je neparan";

cout<<endl;

system("PAUSE");return EXIT_SUCCESS;

}

Analizirajmo gore prikazani primer. Prve četiri linije programa, dio iza main, rezervišu prostor za promjenljivu iBroj tipa long long int, i unose odgovarajuću vrednost, zatim ispitujemo broj pomoću nepotpune if naredbe, koja je nepotpuna zato što nema deo sa else. Ukoliko korisnik ne unese odgovarajuću vrednost tipa long long int možememo uputiti poruku da takav broj uopšte nećemo ni uzeti u razmatranje.

31

Page 32: UVOD U C++ I DODATAK ZA C++11

Ako je broj odgovarajući, prelazimo na razmatranje da li je paran ili neparan. Ovu činjenicu jednostavno možemo ustanoviti tako što ćemo broj podeliti sa 2, ukoliko je ostatak nula broj je paran, dok ukoliko dobijemo ostatak jedan imamo posla sa neparnim brojem. U ovom primeru smo koristili tip podatka unsigned long long int, ovaj tip podatka nam je omogućio da zabilježimo maksimalnu celobrojnu vrednost, ukoliko nam nije dovoljan opseg koji nudi ovaj tip možete upotrebiti unsigned long double ali tad baratamo sa brojevima koji imaju zarez, a ukoliko ni ovaj tip podatka ne zadovoljava Vaš opseg, može se desiti da morate upotrebiti tehnike koje se koriste za rad sa velikim brojevima. Ovo je jedana od interesantnijih oblasti programiranja

Ilustracija 5.2. prikazuje naredbu if else grafički. Ispituje se logički uslov, koji ukoliko je ispunjen nalaže da se uradi naredba1, dok u suprotnom radimo naredbu 2.Drugim rečima možemo da reagujemo na dve situacije, u zavisnoti od logičkog iskaza.Kasnije ćete videti kako možemo da nadovežemo više if naredbi, dok u jesnostavnim situacijama treba koristiti ternatni operator.

Postoji i switch naredba o njoj ćete morati da naučite jer je C++ koristi tako da se njena upotreba ispalti po pitanju brzine.

Pređimo sad na problem koji će imati više mogućnosti u svojoj if elese grani.Potrebno je na osnovu temperature izražene u Celzijusima, prikazati odgovarajuću poruku:

▪ Ako je temperatura u intervalu od 20 do 30 Co, ne hladi niti grij.▪ Ako je temperatura ispod 20 Co potrebno je ugrijati prostoriju. ▪ Pređemo li preko 30 Co, moramo rashlađivati prostoriju.

Ovo je možda ne realno za očekivati u nečijoj sobi, jer ljudi obično žele da uštede i često nisu tako zahtevni, ali će biti interesantan primer za ilustraciju upotrebe više if naredbi. Program može da se iskoristi i kao osnova za neke aplikacije, uz upotrebu tajmera i odgovarajućeg hardvera. Moguće je sresti praktične probleme koji se realizuju na sličan način. Poznata je i kriva upravljanja koja opisuje ovu situaciju, a u suštini liči na krivu prigušene oscilacije.

PRIMER:#include <iostream>

using namespace std;

int

32

Page 33: UVOD U C++ I DODATAK ZA C++11

main(void){

//Unesimo temperaturu u Celzijusima cout<<"Unesite neki pozitivni cjeli broj->";

double dBroj; cin>>dBroj;

//Ocistimo ekran i prikazimo poruku o temperaturi

system("CLS");

if (dBroj< 20){

system("COLOR 09");cout<<"Hladno je ugrijte prostoriju!!!"<<endl;

}else if( dBroj <= 30){ system("COLOR 02"); cout<<"Odgovara, ne grij niti hladi!!!"<<endl;

}else{ system("COLOR 0C"); cout<<"Postalo je previse toplo, ukljuci klimu!!!"<<endl;}

system("PAUSE");return EXIT_SUCCESS;

}

Napomenimo da smo mogli upotrebiti i double, long double, kao i auto tip podatka. Aplikacija bi mogla da, uz odgovarajući hardver, tajmer i neka proširenja bude osnova programa za održavanje temperature u određenim granicama. Ovo je čest problem koji se često javlja kao deo nekog većeg problema, prilikom praktičnih implementacija.

Uradite primer koji će analizirati rešenja a*x+b, u zavisnosti od parametara: a i b.Kao vežbu, a vežbanje je esencijalno, uradite primere koji će ispitati da li kvadratna jednačina ima dva realna , dva istovetna, ili pak ima dva konjugovano kompleksna rešenja. Osim ovog zadatka možete uraditi primer koji menja stanje sijalice. Žarulja može biti upaljena ili ugašena, Vi treba samo da promenite njeno stanje.Napravite program koji proverava da li imamo dovoljan kapacitet na autoputu. Napišite aplikaciju koja procenjuje koliki protok možemo imati u peer to peer mreži, ako znamo maksimlnu potreban protok do klijenta, pogledajte kako to funkcioniše, i da znate da ovaj tip mreža obično dobro funkcioniše sa ne više od 10 umreženih računara. Uradite aplikaciju koja računa porez.

33

Page 34: UVOD U C++ I DODATAK ZA C++11

Vratimo se primeru provere da li je broj paran ili neparan. Ukoliko je broj negativan ili nula, mi nismo ni razmatrali tu situaciju, ali ovaj primer može da se unapredi upotrebom kombinovanom if naredbe.

if(iBroj>0) if(iBroj % 2==0)

cout<<“Broj je paran!!!“<<endl; else cout<<“Broj je neparan!!!“<<endl;

Gore prikazanom naredbom je moguće ispitati da li je broj paran. Ali možemo i postaviti pitanje, da li je onaj else vezan za prvi if, ili za drugi if? Prema definiciji, else se veže za najbliži if. Drugim rečima, ukoliko je broj veći od nula, ispitujemo ostatak pri deljenju sa dva. U drugom slučaju, bilo bi ako je broj veći od nula i ako je broj pri deljenju sa dva dao nula on je paran, a u ostalim slučajevima broj je neparan. Ovo drugo tumačenje iako može imati smisla, da bi se tehnički i realizovalo potrebno je dodati par vitičastih zagrada koji nameću takvo ponašanje.Da li znate šta to znači switch? Tačan odgovor, u ovoj situaciji je, prekidač. Postoji ova instrukcija i u C++-u. Ona je interesantna po više pitanja, može da zameni if naredbu u nekim situacijama i preglednija je. Osim što je preglednija ona ne proverava logički uslov kao if naredbe, te kao posledica je činjenica da se brže izvršava. Ako je moguće birati između if ili switch, obavezno upotrebite switch. Kad dođete do pisanja aplikacija sa prozorima, ova naredba će postati neizbežna.

Uradimo sledeći zadatak, korisnik unosi neki ceo broj, a mi prikazujemo poruku koji ostatak dobijamo pri djeljenju sa 4.

PRIMER:#include <iostream>

using namespace std;

intmain(void){

cout<<"Unesi neki celi broj->";long liBroj;cin>>liBroj;

if(liBroj<=0){

cout<<"Greska pri unosu!!!";system("PAUSE");return EXIT_FAILURE;

}else{

int iOstatak= liBroj% 4;cout<<"Ostatak pri djeljenju "<<liBroj<<" sa 4 iznosi";

34

Page 35: UVOD U C++ I DODATAK ZA C++11

switch( iOstatak){case 0: cout<<" nula";

break;case 1: cout<<" jedan";

break; case 2: cout<<" dva ";

break;case 3: cout<<" tri";

break;default: system("CLS"); system("COLOR 0C");

return EXIT_FAILURE;

}}

system("PAUSE");return EXIT_SUCCESS;

}

Objasnimo kako funkcioniše prethodni program. Nakon unosa liBroja od korisnika ispitujemo da li je uneseni broj adekvatan ili ne, ukoliko broj nije prihvatljiv nećemo ga ni razmatrati, dok ako je broj zadovoljio osnovne uslove prelazimo u else granu if naredbe.U okviru else if naredbe imamo instrukciju kojom dobijamo ostatak pri deljenju sa brojem četiri, a zatim ispisujemo odgovarajući podatak. Ako je ostatak 0 ispisujemo nula, ukoliko je ostatak 1 pišrmo jedan i slično. Ostaje još samo da vidimo kako radi ona komanda break, ova je naredba uvedena da bi omogućila programeru da načini kontrolisani iskok iz tela instrukcije. Kasnije ćemo razmotriti i continue komandu, koja za razliku od break počinje sledeće iteraciju naredbe. Ove dve instrukcije su uvedene da bi iskoristile dobre strane naredbe goto, a prevazišle probleme koje ona može da izazove.

Za vežbu uradite nekoliko primera. Korisnik unosi redni broj dana u sedmici, a Vi treba da ispišete koji je to dan. Unesemo li broj van opsega prikažite poruku greška.Slično kao u prethodnom primeru, unesite redni broj meseca, a Vi ispišite koji je to mesec po redu. Ovo su samo neke primene ove naredbe.

Uradimo zadatak koje testira da li je uneseni znak samoglasnik ili suglasnik. Ovaj problem može biti interesantan kao ilustracija koja će predočiti, kako se može koristiti switch naredba, kao interesantan primer optimizacije koda pogledajte Dafov primer.

PRIMER:#include <iostream>#include <cctype>using namespace std;

intmain(void){

35

Page 36: UVOD U C++ I DODATAK ZA C++11

//Nakon sto naucite funkcije ovaj deo mozete poboljsati upotrebom funkcija cout<<"Unesi ASCII karakter->"; char cZnak; cin>>cZnak;

//Sledeci logicki uslov je prilicno ne pregledan, //prepravite kod koristeci funkciju ili makro if((( cZnak>='A')&&(cZnak<='Z'))||(( cZnak>='a')&&(cZnak<='z'))) {

cout<<cZnak<<" je "; cZnak= tolower(cZnak); switch( cZnak) {

case 'a': case 'e': case 'i': case 'o': case 'u': cout<<" samoglasnik."; break; default : cout<<" suglasnik.";

} } else {

cout<<"Nije slovo!"; }

system("PAUSE");return EXIT_SUCCESS;

}

U programu unosimo karakter, koji čuvamo u promjenljivoj cZnak. Nakon toga ipitujemo da li je znak veliko ili malo slovo, ukoliko jest slovo, pišemo poruku, zatim pretvaramo karakter u malo slovo, ostaje još samo da ispitamo da li je slovo samoglasnik ili suglasnik, u slučaju da unešeni znak nije slovo piše se odgovarajuća poruka.

Switch naredbu grafički možemo prikazati na sledeći način, kao na slici 5.3.

Analizom slike uočavamo da imamo uslov, za više mogućnosti koje uslov može da primi, imamo po jednu naredbu, obično se koriste break naredbe da bi se iskočilo na kraj switch naredbe. Svaka od naredbi može da predstavlja više uklopljenih komandi, ali možemo da izostavimo i break instrukciju.Postoji deo default koji se koristi ukoliko ni jedan od uslova nije predviđen case naredbom.

36

Page 37: UVOD U C++ I DODATAK ZA C++11

Da bi unapredili čitljivost programa, izraz ((( cZnak>='A')&&(cZnak<='Z'))||(( cZnak>='a')&&(cZnak<='z'))), možete da realizujete pomoću parametarskog makroa. Na taj način program postaje pregledniji, a ne gubimo na brzini kao kad upotrebimo funkciju koja vraća logičku vrednost. O funkcijama i makroima ćete više saznati u narednim poglavljima.

Za vežbu ispitajte da li je karakter koji smo uneli slovo, ili cifra, ili da li je znak koji smo uneli neki specijalni karakter. Ovde će Vam od koristi biti tabela sa ASCII znakovima, pronađite potrebne informacije na Internetu ili u nekoj knjizi koju imate od ranije. Pogledajte i funkcije koje možete pronaći u ctype.h bibloteci.

Ternarni operator se koristi da bi zamenio jednostavnije if komande, tj takvim situacijama gde u svakoj od grana imamo po jednu naredbu, jer tad if naredba počinje da izgleda pomalo smešno. Nemojete zaboraviti da je danas moguće napisati sledeći kod:( iBroj<0)? cZnak=’-’: (iBroj==0)?cZnak=’0’:cZnak=’+’;

Pazite samo da ne preterate, jer može Vam se desiti da nakon nekoliko godina proanalizirate taj isti program i da ne razumete kako ste napisali Vaš program. Ovo je jedna od poznatih situcija koja nam govori da treba pisati komentare, a i da ne treba koristiti sve što je dozvoljeno. U ovom momentu je dobro da se prisetite one poslovice „Može se do posla doći na rukama, ali da li je to najefikasniji način da to i uradimo“.Uz ovih nekoliko naredbi grananja zaokružili smo ovaj deo i došli do naredbi ponavljanja. Navedimo ih pre nego što ih obradimo:

for( naredba1; naredba2; naredba3). while( LogickiUslov) naredba;. do naredba; while( LogickiUslov);.

Gore pomenute naredbe nam omogućavaju repeticije. Napomenimo da C++11 dozvoljava korištenje for komande za opsege, ona se može koristi za iteraciju kroz elemente niza, o ovoj instrukciji možete više pročitati u dodatku za C++11.

Analizirajmo sad detaljno instrukciju for.for( naredba1; naredba2; naredba3). Naredba;

Šematski ovu naredbu možemo zabilježiti kao na slici 5.4.. Nemojte da se zabunite i mislite da je ova naredba ista u svim jezicima.

Bitno je shvatiti kako funkcioniše ova komanda, da bi je mogli koristiti prema potrebi. Prvo se izvršava naredba 1, uobičajeno je da se tu obave neke inicijacije ili lokalne deklaracije. Moguće je ovu naredbu preskočiti, a važno je napomenuti da se ista obavlja samo jednom.Pošto se izvrši naredba 1, prelazi se na nareda2, koja je obično neki

37

Page 38: UVOD U C++ I DODATAK ZA C++11

logički uslov. Sve dok je logički uslov ispunjen prelazi se na Naredba, a čim uslov postane ne ispunjen izlazi se iz for naredbe, a moguće je i njih izostaviti.Nakon prolaska kroz telo instrukcije for, koje može biti prošireno sa više naredbi obuhvaćenih otvorenim i zatvorenim vitičastim zagradama, prelazimo na izvršavanje naredba3. Ukoliko je potrebno možemo dodati i operator zarez da bi upotrebili više komandi, a možemo izostaviti i naredba3.Nemojte se iznenaditi kad uočite naredbu:for( ; ; ; ), ovo je primer beskonačne for naredbe.

For naredba se ponavlja nula, ili više puta. Teoretski je moguće imati beskonačnu petlju, ali praktično pre ili kasnije svaki računar se mora ugasiti. Gore prikazana petlja se ponekad koristi u kombinaciji sa break naredbom ili naredbama za kraj programa. Na taj način dobijamo iluziju da se naš program izvršava interaktivno.Potrebno je ispisati sve prirodne brojeve, čiji su kvadrati manji ili jednaki graničnom broju iN.

PRIMER:#include <iostream>

using namespace std;

intmain(void){

cout<<"Unesi prirodni broj n->";int iN; cin>>iN;

for(int i=1; i*i<=iN; i++) cout<<i<<endl;

system("PAUSE"); return EXIT_SUCCESS;}

Pokušajte izračunati faktorijel nekog broja, ili n!!. Ispitajte da li je uneseni broj prost. Ispišite tabelu neke funkcije u granicama od a do b. Osim ovih primera, možete recimo da izračunate sumu svih neparnih brojeva od 1 do 2n-1, ili recimo da proverite koliko je brojeva iz intervala a do b deljivo sa 7, deljivo sa 2 a nije deljivo sa 5 ili koliko je brojeva djeljivo sa 7 i 11.No pređimo na sledeću instrukciju, a to je naredba while sa uslovom na vrhu. Ova se komanda takođe izvršava nula ili više puta. Obično se koristi u situaciji kad čitamo neki tekst u kombinaciji sa scanf naredbom.

38

Page 39: UVOD U C++ I DODATAK ZA C++11

Korisnik će uneti liniju teksta, a mi ćemo prebrojati koliko je cifara, koliko velikih slova, a koliko malih slova u unesenoj liniji teksta.

PRIMER:#include <iostream>#include <cstdio>#include <cctype>

using namespace std;

intmain(void){

int iCifra, iVelikihSlova, iMalihSlova, iUkupno;iCifra=iVelikihSlova=iMalihSlova=iUkupno=0;char cZnak;while((cZnak=getchar())!=EOF){

++iUkupno;if (isdigit(cZnak)){ iCifra++;continue;}if (islower(cZnak)){ iMalihSlova++;continue;}if (isupper(cZnak)){ iVelikihSlova++;}

}

cout<<"Ulazni tekst ima "<<iUkupno<<" karaktera."<<endl<<"Velikih slova ima "<<iVelikihSlova<<endl<<"Malih slova ima "<<iMalihSlova<<endl<<"Cifara ima "<<iCifra<<endl;

system("PAUSE");return EXIT_SUCCESS;}

Prilikom unosa linije teksta odtipkajte određenu rečenicu pritisnite ctrl+Z da bi dobili znak ^Z, koji predstavlja oznaku za EOF ili end of file. Ostaje samo da pritisnete Enter.

Naredbu while sa logičkim uslovom na vrhu možemo grafički da prikažemo kao na lisci 5.5..Nadam se da je prethodni primer bio dovoljno ilustrativan, koristili smo i naredbu continue koja započinje sledeću iteraciju naredbe, jer nema potrebe ispitivati da li je znak veliko ili malo slovo, ako je poznato da je već taj znak cifra.Za vežbu sabirajte parne brojeve dok ne pronađete prvi parni broj koji je veći od nekog graničnog broja, ili prvi pre poslednjeg parnog broja koji je manji od graničnog.Pokušajte analizirati ulaznu rečenicu prebrojavajući: velika ili mala slova, samoglasnike ili suglasnike i slično.

39

Page 40: UVOD U C++ I DODATAK ZA C++11

Pređimo na sledeću naredbu ponavljanja. Poznata je kao while instrukcija sa uslovom na vrhu, ili do while. Ova komanda se razlikuje od prethodne dve po tome što mora bar jednom da se izvrši telo ove naredbe, sem ukoliko ne upotrebimo neku od instrukcija koja može iskočiti iz tela petlje: kao što su to break, goto, exit i slične naredbe.

Recimo da pogađamo broj od 0 do 9, kompjuter „zamisli“ neku cifru, a mi pogađamo. Ukoliko pogodimo ispisujemo koliko smo puta pokušali da pogodimo, dok ukoliko nismo kompjuter ponovo „zamisli“ sledeću cifru. Vidite, kasnije kad naučite o C++11, da li NULL možete da zamenite sa nullptr, tako da bi vam program bio više u duhu jezika novog standarda.

PRIMER:#include <iostream>#include <ctime>

using namespace std;

intmain(void){ //inicijalizacija generatora slucajnih brojeva

srand(time(NULL));

//deklarisanje potrebnih promjenljivihint iUkupnoPogadjaliPuta=0; bool bPogodjeno=false;do{

//generisanje novog slucajnog brojaint iNoviBroj=rand()%10;system("CLS");cout<<"Novi broj u intervalu 0 do 9->";

//koji broj mislite da je kompjuter zamislio ovaj putint iVasBroj; cin>>iVasBroj;

if( iVasBroj==iNoviBroj){

40

Page 41: UVOD U C++ I DODATAK ZA C++11

//ukoliko pogodite neki broj cout<<"Pogodili ste u ukupno" <<iUkupnoPogadjaliPuta; bPogodjeno=true;}else{

//ukoliko niste pogodili brojcout<<"Kompjuter je zamislio" << iNoviBroj <<" pokusaja"<<endl;

iUkupnoPogadjaliPuta++;system("PAUSE");

}} while (!bPogodjeno);

system("PAUSE"); return EXIT_SUCCESS;}

Na početku programa smo inicijalizovali generator slučajnih brojeva, nakon toga smo postavili početne vrednosti promjenljivima iUkupnoPogadjaliPuta i bPogodjeno. Prvu promjenljivu koristimo da izbrojimo koliko smo puta pogađali, a drugu upotrebljavamo da bi ispitali da li smo uneli odgovarajući broj.U okviru naredbe do while kompjuter odabira slučajni broj u granicama od 0 do 9, zatim pitamo čovjeka „koji misli da je broj kompjuter zamislio“. Nakon toga imamo dve situacije koje moramo obraditi: pogođen je broj, ili broj nije pogođen.

Šematski ovu naredbu možemo prikazati sledećim dijagramom.

Proverite, da li možete da napravite Black Jack, ili neki program koji koristi karte, kockice, ili neku sličnu igricu na sreću.

Ostaje još jedna stvar, da se vidi, da li bi ste mogli da napišete program o pogađanju godina, gde se godine kreću u intervalu od 1 do 100. Pri rešavanju ovog problema koristite modifikaciju algoritma koji se upotrebljava za binarne pretrage, ili kod pronalaženja korena neprekidne i monotone

krive, na intervalu. Vidite da se jedan od algoritama može primeniti u različitim situacijama.

41

Page 42: UVOD U C++ I DODATAK ZA C++11

Moguće je kombinovati više for, while ili do while naredbi. Za vežbu pokušajte da napišete program koji prikazuje izlaz sledećih naredbi:for(i = 3; i<= 7; i++){ for(j= 9; j<=11; j++) { cout<< “i=”<<i<<” j=”<<j; }cout<<endl;}Prvo i prima vrednost 3, zatim se j postavlja na 9 i uvećava dok ne dosegne 11, nakon toga prelazimo u novi red, sad se postavlja na i vrednost 4, j ponovo kreće od 9 do 11. Poslednji ciklus promjenljivoj i dodeli 7 dok promjenljivoj j dodjeljujemo 9, 10 i 11.

i=3j=9 i=3j=10 i=3j=11i=4j=9 i=4j=10 i=4j=11i=5j=9 i=5j=10 i=5j=11i=6j=9 i=6j=10 i=6j=11i=7j=9 i=7j=10 i=7j=11

Ispitajmo da li je moguće, i na koje sve načine posudu od N litara napuniti čašama od p i m litara. Brojevi N, p i m su celobrojni. Moramo zahtevati da p, m <= N. Nije dozvoljeno odlivati vodu iz velike posude, kao ni odlivanje vode iz malih posuda. Dozvoljeno je manjim posudama puniti veću.Pre nego što počnete da radite ovaj primer skicirajte sebi ilustraciju na računatu, ili negde u svesci. Možete i da zamislite, ali onda morate da vodite računa da možete lakše nešto i da previdite.

PRIMER:#include <iostream>using namespace std;intmain(void){ cout<<"Koliko je zapremina velike posude->"; int iVelikaPosuda; cin>> iVelikaPosuda;

cout<<endl<<"Kolike su zapremine dve manje posude->"; int iPrvaPosuda, iDrugaPosuda; cin>>iPrvaPosuda>>iDrugaPosuda;

bool bMozeSeNapuniti=false; for(int i= 0; i <= iVelikaPosuda/iPrvaPosuda; i++)

for(int j= 0; j <= iVelikaPosuda/iDrugaPosuda; j++)if( i*iPrvaPosuda+j*iDrugaPosuda == iVelikaPosuda){cout<<i<<"*"<<iPrvaPosuda<<"+"<<j<<"*"<<iDrugaPosuda <<"="<<iVelikaPosuda<<endl;

42

Page 43: UVOD U C++ I DODATAK ZA C++11

bMozeSeNapuniti=true;}

if(!bMozeSeNapuniti){ cout<<"Ne mozemo napuniti!!!"<<endl;} system("PAUSE");return EXIT_SUCCESS;}

Ovaj primer je urađen da bude što razumljiviji, za vežbu pokušajte da ga optimizirate tako da izbegnete neke nepotrebna proveravanja.Navedimo da ukoliko smo napunili posudu sa k*PrvaPosuda, tad ostatak može da se izračunava malo brže, razmisite kako. Možete primer prošitriti tako da zahtevate neke dodtne uslove:▪ Što manji broj posuda.▪ Rešenje koje koristi najviše velikih čaša.▪ Solucija kod koje se koristi najviše malih kontejnera.▪ Odrediti koliko ima rešanje kod kojih je broj čaša paran ili neparan.

Napomenimo da možemo razmatrati situacije kada je dozvoljeno odlivanje nekom od manjih posuda, a i takve probleme kod kojih kombinujemo zapremine dve manje čaše.

Za vežbu, pokušajte da napišete tablicu množenja, šahovsku tablu od zvezdica i blanko simbola, pravougli trougao od zvezdica, prebrojte sve dvocifrene brojeve za koje važi da je suma cifara uvek parna.Za one koji vole da rešavaju kriptograme, jedan od načina kako to možete da uradite je pomoću umetnutih for naredbi. Naravno, možete da kombiniujete i više for naredbi, a dozvoljeno je i koristiti ostale naredbe. Možda je ovo početnički način da se reše ovi tipovi problema, ali oni su dobra početna tačka, na osnovu koje možete da unapredite Vaš program. Nakon što uočite neke od metoda optimizacije možete pokušati da primenite neki brži metod rešavanja problema.

Da bi naučili da programirate morate da znate da procenite koliko brzo se izvšava Vaš program, o tome mo-žete da pročitate na:www.infoarena.ro/blog/numbers-everyone-should-know.

Na ovoj lokaciji ćete upoznati neke važnije algoritme za rešavanje teoretskih i praktičnih problema. Interesantno je pročitati mišljenje programera, koji posjeduje teoretska, kao i bogata praktična znanja. Svaki od algoritama ima svoj značaj i smisao, poželjno je da ih pogledate i detaljnije se upoznate sa svakim od njih. Oni se mogu koristiti u različitim situacijama, a postoje situacije kad se već naučeni algoritam može primerniti u nekoj sličnoj situaciji. Nekada će te morati izvršiti male modifikacije, a kasnije ćete kreirati i vlastite algoriteme.Ono što ste naučili neće biti dovoljno da rešite svaki problem, moraćete da se potrudite, a do izražaja će doći i Vaša kreativnost. Programiranje je oblast koja je prilično kreativna, ali moramo uvek da imamo na umu da naš kod neko mora kasnije modifikovati.

43

Page 44: UVOD U C++ I DODATAK ZA C++11

6 . U P O T R E B A F U N K C I J A

Ukoliko je potrebno ponavljati neku aktivnost, ali sa razlčitim argumentima funkcija može biti dobar izbor. O funkcijama možemo da razmišljamo, kao o kutijama kojima se na ulaz donesu proizvoljni argumenti, a kao izlaz dobijemo rezultate. Postoje dva ključna trenutka u procesu razmišljanja o funkcijama. Momenat kad funkciju upotrebimo u progamu, i trenutak kad pišemo funkciju. Zbog toga je važno zadržati oba stila razmišljanja. Kad koristimo funkciju, nas ne interesuje njena implementacija, dok u momentu kad pišemo funkciju ne razmišljamo o tome kako će se funkcija pozivati. Ovakvo razmišljanje je važno za inženjere svih oblasti. Omogućava nam da razbijemo veliki problem, na grupu manjih problema.Šematski funkcija se može zabilježiti na sledeći način

Dok za razmišljanje možete koristiti i sledeću sliku

Recimo da je potrebno proceniti koliko maksimalno molekula vode možemo dobiti na osnovu broja atoma vodonika i kisika. Sledeći zadatak od nas očekuje da unosimo broj atoma hidrogena i oksigena, te da procenimo kolioko maksimalno molekula vode možemo napraviti na osnovu ovih atoma.

PRIMER:#include <iostream>

using namespace std;

void PisiZaglavlje(void){

system("CLS");cout<<"Procjenjujemo maksimalni broj molekula vode" <<endl <<"na osnovu broja atoma hidrogena i oksigena->";

}

void PriakziMaksimalno(int iH, int iO)

44

Page 45: UVOD U C++ I DODATAK ZA C++11

{cout<<"Maksimalno atoma vode=";if( iH/2< iO) cout<< iH/2;else cout<<iO;system("PAUSE");

}

intmain(void){

do{

PisiZaglavlje();int iAtomaHidrogena; cin>>iAtomaHidrogena;int iAtomaOksigena; cin>>iAtomaOksigena;if((iAtomaOksigena<=0) ||(iAtomaHidrogena<=0)) break;PriakziMaksimalno(iAtomaHidrogena, iAtomaOksigena);

}while(1);

system("PAUSE");return EXIT_SUCCESS;

}

Može se postaviti pitanje, zašto u prethodnom programu ne postoje komentari? Primer je jednostavan tako da nije neophodno komentarisati algoritam, a imena promjenljivih i funkcija dovoljno ilustruju šta smo to želeli da uradimao.Funkcija zahteva komplikovan mehanizam pozivanja, posledica toga je činjenica da poziv funkcije usporava izvršavanje programa. Da bi prevazišli ovu manu klasične funkcije, možemo napisati inline funkciju, koja prevodiocu predlaže zamenu svake upotrebe procedure. Ukoliko želite biti sigurni da će funkcije biti zamenjene možete koristiti makroe sa argumentima. Inline funkcije su kraće, sastoje se od jednog ili dva možda do tri reda, ali program ima kontrolu nad tim da li će ih zameniti, ili će ih ostaviti kao funkcije.Navedimo primer koji, ukoliko se koristi klasična funkcija može usporiti izvrašavanje programa. Pozivi funkcija zahtevaju dosta procesorskog vremena, a i memorija se dodatno upregne. Ako bi koristili funkciju na sledeći način, usporili bi izvršavanje programa. for( int i=1 ; i<= iN ; ++i) Funkcija( i );

Bolje je funkciju implementirati na sledeći način:Funkcija( int iN){...for( int i=1 ; i<= iN ; ++i)

45

Page 46: UVOD U C++ I DODATAK ZA C++11

...}

Ovaj primer omogućava da vidimo kako smo na prvi način funkciju pozivali više puta, dok druga implementacija poziva funkciju samo jednom. Očigledno je, da je drugo rešenje daleko brže, ukoliko razmišljate o brzini vašeg programa, uvjek je bolje upotrebiti onu drugu tehnologiju.

PRIMER:#include <iostream>

using namespace std;

inline double LinearnaFunkcija( double a, double x, double b){ return a*x+b;}

intmain(void){

cout<<"Racunanje vrednosti linearne funkcije u tacki!!!"<<endl;cout<<"Argumenti su a, b, x->";double dA, dB, dX;cin>>dA>>dB>>dX;system("CLS");

cout<<dA<<"*"<<dX<<"+"<<dB<<"="<<LinearnaFunkcija(dA,dX,dB)<<endl;

system("PAUSE");return EXIT_SUCCESS;

}

Kao što rekosmo, u prethodnom primeru smo koristili inline funkciju, te smo prevodiocu pružili mogućnost da on odabere da li će funkciju zameniti ili ne. Ako želimo potpunu kontrolu nad odabirom, da li će se funcija zameniti u kodu ili ne, možemo koristiti makro sa argumentima.

PRIMER:#include <iostream>

#define LINEARNA_FUNKCIJA(a, b, c) ((a)*(b)+(c))

using namespace std; intmain(void){

cout<<"Racunanje vrednosti linearne funkcije u tacki!!!"<<endl;

46

Page 47: UVOD U C++ I DODATAK ZA C++11

cout<<"Argumenti su a, b, x->";double dA, dB, dX;cin>>dA>>dB>>dX;system("CLS");

cout<<dA<<"*"<<dX<<"+"<<dB<<"=" <<LINEARNA_FUNKCIJA(dA,dX,dB)<<endl;

system("PAUSE");return EXIT_SUCCESS;

}

Ako pišemo dio programa, koji ispituje da li je od ponuđene trojke brojeva moguće kreirati trugao. Znamo iz matematike da za trougo moraju da važe uslovi:▪ a + b > c, ▪ b + c > a,▪ a + c > b,▪ a, b, c > 0.

Za vežbu možete kreirati program, koji će unositi trojke brojeva, i ispitivati da li se može konstruisati trougao na osnovu mernih vrednosti (a, b, c). Potrebno je koristeći merne vrednosti stranica trougla izračunati: površinu, obim i visine trougla. Unos stranica zaustaviti ukoliko unesemo trojku koja ne može predstavljati trougao. Ne zaboravite da stranice moraju biti pozitivni brojevi, sem ukoliko se drugačije ne dogovorimo.No šalu na stranu, u sledećem primeru ćemo videti kako funkcija može vratiti više vrednosti. Recimo da je potrebno odrediti koordinate sredine duži u dvodimenzionalnom prostoru, ukoliko su poznate koordinate krajeva duži. U primeru ćemo koristiti referencu i pokazivač. U ovoj situaciji referenca može biti pogodnija zbog ne preglednosti izraza u kojima se koristi pokazivač. Referenca kreira izraze koji su pregledniji, a omogućava da se vrednosti iznesu iz funkcije. Ukoliko funkciji predajemo parametre, bez pokazivača ili reference, oni se kopiraju. Problem kopije je to što se operacije primenjuju na kopijama, koje nestaju nakon kraja funkcije. Pokazivači rade na originalnim vrednostima, koje se u ovom slučjaju ne kopiraju, zbog toga su i malo brže, a promene koje su načinjene na originalnim vrednostima ostaju i nakon izlazka iz funkcije.

PRIMER:#include <iostream>

using namespace std;

//funkcija koja racuna koordinate tezistavoid KoordinateTezista( double dAx , double dAy,

double dBx , double dBy, double * dTx , double& dTy)

{ *dTx = (dAx+dBx)/2.0; dTy = (dAy+dBy)/2.0;

47

Page 48: UVOD U C++ I DODATAK ZA C++11

}

intmain(void){ cout<<"Koordinate sredista duzi!!!"<<endl;

cout<<"Koordinate prve tacke A(Ax, Ay)->";double dAx, dAy; cin>>dAx>>dAy;

cout<<endl<<"Koordinate druge tacke B(Bx, By)->";double dBx, dBy; cin>>dBx>>dBy;

//Koordinate tezista dTx, dTydouble dTx, dTy;

KoordinateTezista( dAx, dAy, dBx, dBy, & dTx, dTy);cout<<"Koordinate tezista su"<<endl <<" Tx="<< dTx <<endl <<" TY="<< dTy <<endl;

system("PAUSE");return EXIT_SUCCESS;}

Ukoliko rešavamo problem koji od nas zahteva da imamo argumente različitih tipova, recimo potrebno je izračunati apsolutnu vrednost broja koji je int ili double tipa, možemo kreirati dve funkcije istog imena, ali različitih ulaznih tipova.

PRIMER:#include <iostream>

using namespace std;

void Apsolutno ( int i){ (i>=0)? cout<<i:cout<<-i;} void Apsolutno ( double d){(d>=0)? cout<<d:cout<<-d;}

intmain(void){ int iBroj1=7, iBroj2=-7;

cout<<"Apsolutna vrednost"<<endl; cout<<iBroj1<<"="; Apsolutno(iBroj1);cout<<endl; cout<<iBroj2<<"="; Apsolutno(iBroj2);

double dBroj1=13.0, dBroj2=-13.0; cout<<"\nApsolutna vrednost"<<endl; cout<<dBroj1<<"="; Apsolutno(dBroj1);cout<<endl;

48

Page 49: UVOD U C++ I DODATAK ZA C++11

cout<<dBroj2<<"="; Apsolutno(dBroj2);

system("PAUSE");return EXIT_SUCCESS;}

Metodologija upotrebe funkcija, koju smo prikazali u prethodnim primerima, odgovara ukoliko su problemi jednostavni. Ako rešavamo komplikovanije probleme, funkcijama navedemo ime i tipove pre glavne funkcije, dok implementaciju prikažemo nakon glavnog programa. Kroz prethodni primer, možemo uočiti da su algoritmi ne zavisni od tipa podatka. Drugim rečima, ako popravljamo automobil sa četvoro vrata, kabriolet, ili sporski model, suština je ista. Mi popravljamo vozilo i nije bitan tip sa kojim radimo. Bitna je činjenica da se radi na grupi problema koji se slično rešavaju. Kasnije ćemo uvesti pojam templejta, a za onoga koji zakorači u svet objektnog programiranja STL će biti nešto što će neizostavno morati da upotrebi.

Analizirajmo sledeći primer, potrebno je tabelirati funkciju X2+X+1 u granicama od dDonjaGranica do dGornjaGranica, korakom dKorak.

PRIMER:#include <iostream>

using namespace std;

void NatpisGranice(void);void TabelirajKorakom(double, double, double);

intmain(void){ double dDonjaGranica, dGornjaGranica;

NatpisGranice();cout<<"Donja granica->"; cin>>dDonjaGranica; system("CLS");NatpisGranice();cout<<"Gornja granica->"; cin>>dGornjaGranica; system("CLS");

if( dDonjaGranica >= dGornjaGranica){

cout<<"Greska!!!"<<endl;system("PAUSE");return EXIT_FAILURE;

}

cout<<"Unesite korak tabeliranja->";double dKorak; cin>>dKorak;

TabelirajKorakom( dDonjaGranica, dGornjaGranica, dKorak);

49

Page 50: UVOD U C++ I DODATAK ZA C++11

system("PAUSE");return EXIT_SUCCESS;}

void NatpisGranice(void){cout<<"Unesi donju i gornju granicu intervala koji tabeliramo"<<endl;}

void TabelirajKorakom( double dD, double dG, double d){

cout<<"TACKA VREDNOST X2+X+1"<<endl;for(double dI= dD; dI <= dG; dI+=d){

cout<<dI<<" "<<dI*dI+dI+1<<endl;}

}

Ukoliko pišemo funkciju, koju potencijalno možemo upotrebiti u nekom narednom projektu, poželjno je kreirati heder datoteku, a kasnije tu datoteku možemo pridodavati svakom od projekata koji koriste naše funkcije. Drugim rečima, jednom napisana datoteka se može koristiti više puta.Unesite dimenziju, neki celi broj od 1 do 20 i vidite šta dobijate na ekranu.

PRIMER:Program se sastoji od dve datoteke: GlavniProgram.cpp i NaseFunkcije.h.Sadržaj fajla GlavniProgram.cpp je:

#include <iostream>#include "NaseFunkcije.h"

using namespace std;

intmain(void){

//Unesi dimenziju srafureint iDimenzija; UnesiDimenziju(iDimenzija);

//Ostaje samo da prikazemo odredjenu srafuruPrikaziCrtez(iDimenzija);

system("PAUSE");return EXIT_SUCCESS;

}

50

Page 51: UVOD U C++ I DODATAK ZA C++11

Dok je sadržaj heder datoteke NaseFunkcije.h sledeći:using namespace std;

//Funkcija koja prikazuje sta ocekujemo// od korisnika.

voidPrikaziUvodniEkran(void){

system("CLS");cout<<"Unesite neki celi broj."<<endl <<"Broj mora biti u granicama od 1 do 20."<<endl;cout<<"Napomena 1 i 20 su odgovarajuci brojevi!!!"<<endl;

}//Unosimo dimenziju dok ne unesemo odgovarajuci celi broj//necemo pretpostaviti da covek moze uneti neki string ili //neki realni broj

voidUnesiDimenziju(int& iDimenzija){

do{

PrikaziUvodniEkran();cin>>iDimenzija;

}while (!((iDimenzija>=1) && (iDimenzija<=20)));system("CLS");

}

//Ostaje samo da prikazemo odredjenu srafuruvoidPrikaziCrtez(int iDimenzija){

int j=1;while( j<= iDimenzija){

for(int i=1; i<= iDimenzija*2+1; cout<<'*', i++); cout<<endl;for(int i=1; i<= iDimenzija; cout<<' ', i++); cout<<'*'<<endl;

j++;}

}

Sad možete napisati nekoliko heder datoteka sa nekim često upotrebljavanim funkcijama: Ispitati da li se tačka nalazi u: trouglu, pravougaoniku, kvadratu, elipsi, ili mnogouglu.Izračunati determinantu u: 2*2, 3*3, ili n*n slučjaju. Moguće je izračunati determinatu za n*n slučaj, jedan od načina je upotreba rekurzije.

51

Page 52: UVOD U C++ I DODATAK ZA C++11

Možete da ispitate da li je matrica dobra da se koristi za Markovljeve lance, a možete da proširite aplikaciju tako da računa stepne matrice.Odrediti da li je godina prestupna, ispitati koji je sledeći dan po redu, odrediti prestupnost godine koristeći Milankovićevu metodologiju.Napisati broj u rimskom obliku.Prikazati broj u obliku a.aaaaa * 10n.Pridodati znak K, M, G itd , tako da se broj lepše prikazuje.Ovo su samo neki predlozi. Pokušajte da razmislite koje bi to funkcije bile često potrebne u većem broju programa. Poželjno je da ih možete koristiti u više različitih situacija, tako da jednom napisani kod može biti recikliran. Setimo se da su jednom napravljeni točak, ljudi koristili u različitim situacijama.

Ali da pređemo na naš sledeći primer, koji koristi rekurzivne funkcije. Sa tehničke tačke gledišta ako funkcija samu sebe poziva, direktno ili indirektno, ona se smatra rekurzivnom. Pogledajte , o rekurziji na Wikipediji, ukoliko niste upoznati sa njom.

PRIMER:#include <iostream>

using namespace std;

int FibonaciRekurzivno(int i){ if ( i<=2) return 1; return FibonaciRekurzivno(i-1)+ FibonaciRekurzivno(i-2);}

intmain(void){ //Fibonacijeve brojeve dobijamo tako sto

//saberemo dva prethodna//1+1= 2, 2+1=3, 3+2=5,...

int iRedniBrojUNizu;cout<<"Koji je po redu u nizu->"; cin>>iRedniBrojUNizu;cout<<"Vrednost "<<FibonaciRekurzivno(iRedniBrojUNizu)

<<" je "<<iRedniBrojUNizu<<" clan fibonacijevog niza";

system("PAUSE");return EXIT_SUCCESS;

}

Napišite nekoliko rekurzivnih funkcija: n!, n!!, m povrh n i slično.

Razmislimo sad malo o pokazivačima i funkcijama. Funkcija predstavlja jedan objekat u memoriji, zar ne? Svaki objekat koji se nalazi u memoriji ima svoju adresu. Pokazivači služe za čuvanje adresa. Možemo da zamislimo nešto kao pokazivač na funkcije. Drugim, rečima postoje situacije kada nam mogu biti od koristi pokazivači na funkcije. U sledećemo primeru, kreiramo pokazivač na funkciju:double (*ptrNaFunkciju) ( double );.

52

Page 53: UVOD U C++ I DODATAK ZA C++11

Nakon analize ove definicije, zaključujemo da imamo posla sa funkcijama koje će uzimati promjenljivu tipa double, a rezultat će biti promjenljiva tipa double. Kako smo u programu definisali tri funkcije ovog zaglavlja: Funkcija1, Funkcija2, i Funkcija3. Možemo u programu pokazivač na funkcije ptrNaFunkciju inicirati adresom neke od ove tri funkcije. Napomenimo samo, da smo mogli uzeti neku od već kreiranih funkcija kao recimo sqrt ili neku sličnu.Program polazi od dLevaGranica korakom dKorak dok ne dosegne dDesnaGranica. Ostaje da se poziva odgovarajuća funkcija, u zavisnosti od korisnikovog odabira.Kao vežbu unapredite program tako da uočite funkcije:

Unos granica i koraka. Odabir funkcije koju tabeliramo. Tabeliraj.

PRIMER:#include <iostream>#include <cmath>

using namespace std;

//Funkcije koje koristimo u tabeliranjudouble Funkcija1 ( double dX){ return dX;}double Funkcija2 ( double dX){ return dX*dX-(double)1;}double Funkcija3 ( double dX){ return (dX-static_cast<double>(1));}

//Pokazivac na neku od gore definisanih funkcija ili sqrtdouble (*ptrNaFunkciju) ( double );

intmain(void){

//Poruka korisnikucout<<"TABELIRANJE FUNKCIJA!!!";

cout<<"Unesi levu granicu->"; double dLevaGranica; cin>>dLevaGranica;

cout<<"Unesi desnu granicu->"; double dDesnaGranica; cin>>dDesnaGranica;

cout<<"Korak delta->"; double dKorak; cin>>dKorak;

//Odabir funkcije koju tabeliramo

53

Page 54: UVOD U C++ I DODATAK ZA C++11

cout<<"Odaberi funkciju x, x*x-1 ili x-1"<<endl;cout<<"Ako zelite funkciju x, unesi 1"<<endl;cout<<"Ako zelite funkciju x*x-1 unesi 2"<<endl;cout<<"Ako zelite funkciju x-1 unesi 3"<<endl;int iOdabir; cin>> iOdabir;

switch( iOdabir){

case 1:ptrNaFunkciju=Funkcija1; break;

case 2:ptrNaFunkciju=Funkcija2; break;

case 3:ptrNaFunkciju=Funkcija3; break;

default: exit(1);

}

//Tabeliranje odgovarajuce funkcije system("CLS");

cout<<"TABELA X F(X)"<<endl;cout<<"__________________________________"<<endl;for(double d=dLevaGranica; d <= dDesnaGranica; d+=dKorak)

{ cout<<"x="<<scientific<<d

<<" F(x)="<<ptrNaFunkciju(d)<<endl;}

system("PAUSE");return EXIT_SUCCESS;}

Recimo da je moguće i kreirati niz pokazivača na funkcije. Sintaksa bi bila sledeća:int ( * ptrNaFunkciju[3]) ( int );

Ukoliko pravimo funkciju koja računa dio iza zareza nekog realnog broja, mogli bi napraviti tri funkcije koje rade sa tipovima: float, double ili long double. Hajde da uradimo sledeći primer, koji koristi templejte, drugim rečima funkcija koju pišemo ne ovisi o tipu podatka. Ovo je i logično, nije bitno sa kojim podacima radimo, nego kako to radimo u funkciji. Prilikom upotrebe templejta kreira se čitava grupa funkcija.

Recimo da prenosimo knjige sa jedne police na drugu, nije bitno da li je knjiga: pripovjetka, zbirka pjesama ili nešto treće, bitno je samo da knjige prenesemo od mesta A do mesta B. Sledeći primer ilustruje kako je ne bitno sa kojim tipom podataka radimo, već koji algoritam primjenjujemo nad određenim skupom podataka.

54

Page 55: UVOD U C++ I DODATAK ZA C++11

Jer zamislite samo kako bi bilo naporno pisati funkcije za sve tipove podataka, a onda se neko pojavi sa nekim svojim tipom podatka, a na to Vaš algoritam ne može da reauguje.

PRIMER:#include <iostream>

using namespace std;template <class T>TDioIzaNule( T t){

if( t<0) t=-t;return (t-static_cast<int>(t));

}

intmain(void){

cout<<"Unesite neki realni broj->";float fBroj; cin>>fBroj;cout<<"Broju "<< fBroj<<" iza zareza="<<DioIzaNule(fBroj)<<endl;

cout<<"Unesite neki realni broj->";double dBroj; cin>>dBroj;cout<<"Broju "<< dBroj<<" iza zareza="<<DioIzaNule(dBroj)<<endl;

cout<<"Unesite neki realni broj->";long double ldBroj; cin>>ldBroj;cout<<"Broju "<< ldBroj<<" iza zareza="<<DioIzaNule(ldBroj)<<endl;

system("PAUSE");return EXIT_SUCCESS;

}

Ostaje da razmotrimo situaciju kad funkcija može imati više različitih argumenata. Za ilustraciju će nam poslužiti funkcija printf. Razmotrimo sad ovu „funkciju“. Moguće je napisati sledeće funkcije:printf(„ %d“, iBroj1);printf(„ %d , %d“, iBroj1, iBroj2);printf(„ %d, %d, %d“, iBroj1, iBroj2, iBroj3);Uočavamo da svaka od ove tri printf funkcije ima različiti broj argumenata, hajde da vidimo kako možemo kreirati funcije, koje imaju više argumenata.No da bi uspeli da razumemo kako ovo funkcioniše moramo nešto pre da naučimo. Potrebno je da razumemo kako funkcionišu neki od makroa u stdarg.h datoteci:

Void va_start ( va_list ptrArgumenata, prosledjeniParametri) Void va_arg ( va_list ptrArgumenata, tipArgumenata) Void va_end ( va_list ptrArgumenata)

55

Page 56: UVOD U C++ I DODATAK ZA C++11

Void va_copy ( va_list ptrOdrediste, va_list ptrTekuci) .

Recimo još, da ove funkcije zahtevaju određeni broj obaveznih argumenata, nakon kojih dolazi ne određen broj argumenata.Opcionim parametrima se pristupa na osnovu va_list objekta. U suštini imamo posla sa pokazivačem argumenata. U narednom primeru ćemo videti kako možemo sabrati unapred nepoznat broj int promjenljivih u jednoj funkciji. Funkciji se prosledi ukupan broj promjenljivih tipa int, a zatim se iBrojeva sabere.

PRIMER:#include <iostream>#include <cstdarg>

using namespace std;

intSaberiCeleBrojeve(int iBrojeva, ...){

//Inicijalizujemo sumu na nulaint iSuma=0;

//Kreiramo pokazivac ptrArgumenatava_list ptrArgumenata;

//Pridruzujemo vrednost ptrArgumenatava_start (ptrArgumenata, iBrojeva);

//Prolazimo kroz listu argumenata//,pridodajuci tekucoj sumi

for(int i= 0; i<iBrojeva; i++)iSuma+=va_arg(ptrArgumenata,int);//zavrsavamo sa upotrebom pokazivaca

va_end(ptrArgumenata); //Vratimo rezultat

return iSuma;}

intmain(void){ cout<<"Zbir cetiri broja 1,2,3,4=" <<SaberiCeleBrojeve( 4, 1,2,3,4)<<endl; cout<<"Zbir pet brojeva 1,2,3,4,5=" <<SaberiCeleBrojeve( 5, 1,2,3,4,5)<<endl;

cout<<"Zbir deset brojeva 0,1,2,3,4,5,6,7,8,9=" <<SaberiCeleBrojeve( 10, 0,1,2,3,4,5,6,7,8,9);

system("PAUSE");

56

Page 57: UVOD U C++ I DODATAK ZA C++11

return EXIT_SUCCESS;}

Pokušajte da napišete funkciju koja će na ulazu imati nepoznat broj int, float i char promjenljivih. Potrebno je izračunati njihove sume.

Za vežbu možete napisati funkciju koja vraća pokazivač. Najlogičnije je ih je koristiti sa nizovima ili nizovima karaktera u stilu jezika C. Ne, nije nimalo zbunjujuće. Adresa na koju pokazuje pokazivač, može da se vrati kao rezultat funkcije. U narednom poglavlju radimo sa nizovima.

57

Page 58: UVOD U C++ I DODATAK ZA C++11

7 . N I Z O V I

Ako se nalazimo u situaciji kad imamo veći broj elemenata, kojima želimo manipulisati više puta u programu, poželjno je koristiti strukturu koja je poznata pod nazivom niz. Nizovi u memoriji predstavljaju grupu memorijskih lokacija kojima se pristupa na osnovi imena i indeksa. Prvi element niza ima indeks nula, a interesantno je napomenuti da ime niza predstavlja pokazivač na prvi, nulti element niza. Čak šta više to ime predstavlja konstantni pokazivač na nulti član niza. Na taj način se uspostavlja veza između imena niza i njegovih komponenata.Iako je uobičajeno da svi članovi niza budu istog tipa, to nije i obavezno. Moguće je kreirati niz elemenata, kad kombinujemo strukture i unije. Iako se u toj implementaciji zauzima prostor u memoriji, koliko zauzima i najveći tip, u suštini teško manipulišemo nizovima koji su takvi, moguće je i to uraditi. Ove činjenice mogu biti previše za početnika, ali neka zna da može i to. U memoriji, elemente niza čuvamo na uzastopnim memorijskim lokacijama, kao na sledećoj ilustraciji.

Neke od uobičajenih operacija koje izvodimo na nizovima su: unos, prikazivanje, pristupanje i modifikovanje komponenata niza. Prije nego što upotrebimo elemente niza, moramo ga i deklarisati.Potrebno je uneti, ne više od 100 elemenata nekog niza, te prikazati njegove članove i pronaći najveći element.

PRIMER:#include <iostream>using namespace std;

#define DIMENZIJA 100

intmain(void){

int iNiz[ DIMENZIJA];//Koliko elemenata niza imamo

int iN; cout<<"Koliko elemenata->"; cin>>iN;system("CLS");

//Unos elemenata nizafor(int i=0;i<iN; ++i){

cout<<i<<" element niza->"; cin>>iNiz[i]; system("CLS");}

58

Page 59: UVOD U C++ I DODATAK ZA C++11

//Pretpostavimo da je nulti element najveci//najveci ce biti pronadjen u ostatku niza

int iMaksimalniElement=iNiz[0];for(int i=1; i<iN; ++i)

if( iNiz[i]>iMaksimalniElement){ iMaksimalniElement=iNiz[i];}

cout<<"ISIPS ELEMENATA NIZA"<<endl;for(int i=0; i<iN; ++i){

cout<<"Niz["<<i<<"]= "<<iNiz[i]<<endl;}

cout<<"Najveca vrednost u nizu iznosi=" <<iMaksimalniElement <<endl;

system("PAUSE");return EXIT_SUCCESS;}

Danas ne moramo koristiti gore navedene oblike for naredbe za kretanja kroz elemente niza, moguće je koristiti i odgovarajuću for naredbu za opsege, ova naredba je uvedena u C++11 standardu, i preporučujem je kao kompakniji način izražavanja, o ovoj instrukciji više saznajte u dodatku.Testirajte prethodni program, razmislite kad mogu nastupiti problemi u rešavanju prethodnog problema. Pronadjite najmanji element niza za vežbu.Prethodni primer rezerviše prostor u memoriji za sto elemenata, za to smo koristili makro: #define DIMENZIJA 100, dok smo niz deklarisali na sledeći način: int iNiz[ DIMENZIJA]. Elementima niza smo pristupali pomoću imena i indeksa niza iNiz[i]. Mana prethodnog primera je to što pre početka programa moramo odrediti prostor za elemente niza. Može se desiti da nam ne treba 100 elemenata, a još veći problem nastaje kad trebamo više od predviđenog broja članova niza. Ukoliko je potrebno komponente niza možemo inicirati na sledeći način:int iNiz[]={0, 1, 2, 3, 4, 5, 6, 7}; Moguće je upotrebiti ovakve inicijalizacije, recimo ukoliko želimo upotrebiti niz da bi čuvali podatke o broju dana za određeni mesec. Jedini problem je februar, zato što u toj situaciji moramo ispitati da li je godina prestupan ili nije.

Kao što smo videli možemo deklarisati niz u memoriji i na taj način zauzeti dovoljan prostor za sve elemente, ovaj način manipulacije sa nizovima nije najsretniji izbor u velikom broju situacija. Neki od problema ovog tipa se mogu prevazići upotrebom dinamičkih nizova. Iako se dinamički nizovi mogu upotrebiti u nekim situacijama, ovaj problema najelegantnije prevazilaze vektori, ali zato što su deo STL-a nećemo o njima detaljno govoriti.

PRIMER:Potrebno je formirati i prikazati niz prema sledećem šablonu:1, 2, 4, 8, 10, 20, 22…

59

Page 60: UVOD U C++ I DODATAK ZA C++11

Korisnik će nam odgovoriti koliko elemenata ima niz.

PRIMER:#include <iostream>using namespace std;

intmain(void){

cout<<"Koliko elemenata niza zelite videti?";int iN; cin>> iN;system("CLS");

//Rezervisanje prostora za iN int-ovaint* iPtr = new int[iN];

//Formiranje niza prema sablonu 1, 2, 4, 8, 10, 20, 22…

iPtr[0]=1;for(int i=1 ; i< iN; ++i)

(i%2==0)? iPtr[i]= iPtr[i-1]+2: iPtr[i]= iPtr[i-1]*2;

//Pristupanje elementima niza preko pokazivacafor(int *ptrP = iPtr; ptrP< iPtr+iN; ptrP++)

cout<<*ptrP<<", ";

system("PAUSE");return EXIT_SUCCESS;}

Prethodni primer pokušajte da uradite primnom for naredbe za opsege i lambda funkcije.

Sa aspekta upotrebe memorije, prvi primer je rezervisao prostor u memoriji i zauzimao memoriju, od momenta kada je definisan do kraja programa. Ovo je bio problem kod pisanja programa, jer ste bukvalno morali da pogodite koliko maksimalno elemenata u memoriji će Vam biti potrebno. Na taj način ste gubili dosta prostora u memoriji, a ukoliko Vam je zatrebao prostor za jedan element Vi niste mogli da uradite ništa razumno sa vašim programomo. Ovo je u suštini bila osnovna motivacija za uvođenje dinamičkih struktura. Drugim rečima ukoliko ste znali da Vam treba ne više od 100 elemenata koristite niz, a ukoliko taj broj elemenata može bitno da varira, upotrebite neku dinamičku strukturu. Drugi primer ilustruje upotrebu dinamičkog niza, na taj način možete da, prema potrebi zauzimate određeni prostor u memoriji, a ukoliko Vam elementi niza više nisu potrebni možete da ih iz memorije uklonite pomoću operatora delete.Problem koji uočavamo kod predhodnog primera je činjenica da se elementi ne mogu dodavati prema potrebi. Mogli bi, ali to je naporan proces, deklarisati pomoćni niz koji bi nam služio kao pomoć za čuvanje određenih elemenata, a prema potrebi bi ih iskopirali, te na taj način kreirali strukturu koja bi mogla rasti prema potrebi. Na svu sreću danas postoji i vektor, koji je dio STL-a.

60

Page 61: UVOD U C++ I DODATAK ZA C++11

Uradimo sledeći primer. Naš zadatak je da odredimo medijanu skupa, medijanu računama prema matematičkoj, a ne statističkoj definiciji, a broj elemenata niza nije unapred poznat. Podsetimo se samo da je medijana tačka koja skup deli na dva dela ukoliko imamo neparan broj elemenata. Pola elemenata skupa je manje, dok je pola veće od te tačke. Ako skup ima paran broj elemenata, tad postoje dve medijane, takve da skup dele na dva dela, pola tačaka je manje dok je pola veće od te dve medijane.

PRIMER:

#include <iostream>#include <vector>#include <algorithm>

using namespace std;

intmain(void){

vector<int> iVektor;

do{ char cOdgovor; cout<<"Da li zelite da dodajeta novi element(d/n)->"; cin>>cOdgovor; system("CLS"); if((cOdgovor == 'n')|| (cOdgovor == 'N')) break;

int iElement; cout<<endl

<<"Sledeci elemtn->"; cin>>iElement; iVektor.push_back(iElement); system("CLS");

}while(true);

sort(iVektor.begin(),iVektor.end());

int iVelicinaVektora = iVektor.size();int iPozicija = iVektor.size() / 2;

if( iVelicinaVektora==0) cout<<"U Vektoru ne postoje elementi"<<endl;else if( iVelicinaVektora % 2 == 1) cout<<"Postoji jedna medijana i iznosi"<<endl <<iVektor.operator [](iPozicija)<<endl;else cout<<"Postoje dve medijane "<<endl <<iVektor.operator[](iPozicija-1)<<endl

<<iVektor.operator[](iPozicija)<<endl;

61

Page 62: UVOD U C++ I DODATAK ZA C++11

system("PAUSE");return EXIT_SUCCESS;

}

Da bi u potpunosti razumeli gore prikazani primer, morali bi razumeti objektno programiranje. Prvo u memoriji zauzimamo prostor za elemente niza, naravno pošto nismo uneli ni jedan element veličina niza je nula.Nakon toga unosimo elemente niza jedan po jedan, ukoliko završimo sa unosom niz sortiramo, te ispisujemo odgovarajuće rezultate.Nećemo detaljno ulaziti u smisao ovog primera, jer koristi metodu sortiranja, preopterećeni operator za pristup elementima niza, ali da znate da se i ovako može kodirati u C++, ali ako uključimo podršku za STL, to smo uradili tako što smo uključili biblioteku <vector>, dok smo sortiranje vektora omogućili uključivanjem biblioteke <algorithm>.

PREPORUKE ZA DALJE UČENJE: Pogledajte: sortiranje i pretrage nizova, kao i različite probleme koji govore o formiranju niza i slično.

Specijalni oblik nizova kojima ćemo posvetiti posebnu pažnju su nizovi karaktera. Da razgraničimo pojmove, recimo da postoje nizovi u stilu jezika C, kao i tip string koji predstavlja objekat. Na taj način otvaramo jedno interesantno poglavlje ovog jezika, članovi niza mogu biti jednobajtni karakteri, ali i višebajtni simboli, koji se u tom slučaju moraju drugačije koristiti. Ukoliko deklarišemo i iniciramo članove niza, to u memoriji izgleda ovako.

Prvi element je jednobajtni znak ‘A’, zatim ‘B’, ..., bitno je da postavimo marker za kraj stringa‘\0’. Ukoliko taj znak ne postoji na kraju niza karaktera, većina programa koje pišemo neće moći da odrede krajnju poziciju. Problem nastaje kako u funkcijama koje mi razvijamo, tako i u napisanim funkcijama koje dodajmo pomoću cstring biblioteke.Ukoliko iniciramo string pomoću dvostrukih navodnika, ovaj znak se automatski dodaje. Može se desiti da neko ne razume kako se znak za kraj reda zameni sa ovim znakom, ali odmah da Vam kažem da se to uglavnom odvija automatski, tako da Vi i ne morate da vodite računa o tome.

Ako hoćemo da radimo sa nizovima karaktera u stilu jezika C, koristimo cstring biblioteku, koja je standardna C-ova string.h biblioteka, a ukoliko želite da radite sa stringovima, kao klasama potrebno je uključiti string biblioteku. Na taj način uključujemo podršku za klasu stringova. O klasi string nećemo dalje pisati u ovoj knjizi, ali da znate da i to postoji.Da bi u potpunosti razumeli kako ovo funkcioniše morate da naučite klase, templejte i STL. Mnogi programeri u svojim programima koriste beneficije objektno orjentisanog programiranja, ali ne shvataju kako to sve u suštini i funkcioniše. Naravno, nije neophodno razumeti implementaciju neke metode da bi je mogli upotrebiti, ali dobro dođe razumevanje, bar osnovnih principa.

62

Page 63: UVOD U C++ I DODATAK ZA C++11

Pogledajte sledeći primer, i razmislite malo o njemu.

PRIMER:#include <iostream>using namespace std;

intmain(void){

char* ptrIme= "Marko";char* ptrVoli= " voli";char* ptrPoruka1= " kolace";char* ptrPoruka2= " limunadu";

cout<< ptrIme << ptrVoli<< ptrPoruka1 <<" i "<< ptrPoruka2<<endl;

system("PAUSE");return EXIT_SUCCESS;}

Hajde da vidimo kako da uradimo sličan primer koristeći wchar_t

PRIMER:#include <iostream>#include <wchar.h>using namespace std;

intmain(void){

wchar_t* ptrPoruka= L"Danas je lep dan!!!";fputws( ptrPoruka,stdout);

system("PAUSE");return EXIT_SUCCESS;}

Upotrebili smo wchar biblioteku, i njenu funkciju fputws. Pomoću ove funkcije možemo raditi sa široko bajtnim nizovima karaktera. Preporučujemo čitaocu da proveri sadržaj ove biblioteke, a ukoliko mu je potrebna detaljnija pomoć Internet obiluje ovim primerima.

Uradimo sledeći problem i analizirajmo rad programa.63

Page 64: UVOD U C++ I DODATAK ZA C++11

PRIMER:#include <iostream>#include <cstring>using namespace std;

intmain(void){

//Nije neophodno da navedete dimenziju, niza//jer se ona moze samostalno odreditichar str[]="Ana voli Milovana";puts(str);cout<<"Milovan se naljutio na Anu"<<endl;

memset(str,'*',3);puts(str);

system("PAUSE");return EXIT_SUCCESS;}

Uočavamo da prvo deklarišemo string str, nakon toga prikazujemo elemente niske na standardnom izlazu. Pogledajmo sad funkciju memset, pomoću koje možemo postaviti određene vrednosti na uzastopnim memorijskim lokacijama. Učinili smo sledeće, od konstantnog pokazivača str smo postavili tri zvezdice. Osim ove naredbe mogu nam biti od interesa i sledeće naredbe: memmove, memchr, memcmp, memcpy, kao i njihove ekvivalente sa w prefiksom. Postoje funkcije koje su napisane sa ciljem olakšavanja rada sa nizovima u stilu jezika C. Napomenimo još jednom da se može sresti i klasa string. Postoje i neki drugi tipovi stringova sa kojima nećemo sad raditi, ali da znate da se koriste, pogotovo kad radite sa windows.h bibliotekom.

PRIMER:#include <iostream>#include <cstring>using namespace std;

intmain(void){

//Dva nacina kako mozemo deklarisati stringove//prvi nacin deklarise niz cPoruka, elemetni niza su karakteri, na kraju se automatski dodaje ’\0’char cPoruka[]={"Ljudi vole sladoled"};

//Za razliku od prethodnog stringa, ne kreiramo konstantan pokazivac, tj adresa grupe karaktera //moze da se promeni

char *cNiz ={"Ljudi ne vole sladoled"};

64

Page 65: UVOD U C++ I DODATAK ZA C++11

//Moguce je koristiti i funkciju putsputs(cPoruka);puts(cNiz);

cout<<endl;

//Znak \n se automatski dodaje na kraj stringa cout<<"Duzina prve pruke ="<< strlen(cPoruka)<<endl;

cout<<"Duzina druge poruke="<< strlen(cNiz)<<endl;

//Ukoliko trazimo pojavu znaka u stringu//to mozemo uraditi na sledeci nacin

char cZnak;cout<<"Unesite znak koji trazimo u prvom stringu"<<endl <<"Znak koji trazimo->"; cin>> cZnak;

cout<<"Znak "<<cZnak;if (strchr( cPoruka,cZnak)!= NULL)

cout<<" postoji u";else

cout<<" ne postoji u stringu=";cout<<" "<< cPoruka<<endl;

system("PAUSE");return EXIT_SUCCESS;}

Ovde je neophodno da se razume i razlika između: char cPoruka[]={"Ljudi vole sladoled"},i char *cNiz ={"Ljudi ne vole sladoled"}.

Prvi oblik je deklarisao niz karaktera u memoriji, a ime niza predstavlja konstantan pokazivač. Kao što vidimo imamo 19 znakova, dok ukoliko navedete dvostruke navodnike, automatski dodajemo znak za kraj stringa ‘\0’. Drugi način nam deklariše običan pokazivač na char tip podatka, na kraju se pridodaje znak za kraj stringa. Kad koristimo znak za prelazak u novi red piše se znak ‘\n’, a za pretvaranje u ‘\0’ znak za novi red ne moramo da brinemo, to će C++ uraditi za nas. Potrebno je da pogledate odgovarajuću tablicu ASCII znakova. Biblioteka koja koristi funkcije za rad sa niskama u stilu jezika C, se poziva sa cstring, dok C++ biblioteku string možete da koristite, ali samo da znate da tad već imate posla sa objektima.Znak ’\0’, predstavlja marker za kraj niza karaktera. Osim ovog specijalnog karaktera postoje: ‘\t’ kao znak za tabulaciju, zatim postoj ‘\\’ koji se piše u okviru stringa da bi ispisali jednu kosu crtu.Da bi lakše manipulisali stringovima uvedeni su i sirovi stringovi, o ovom obliku strniga pročitajte u dodatku za C++11 standard.Nemojte zaboraviti da postoji razlika između:

65

Page 66: UVOD U C++ I DODATAK ZA C++11

▪ ".▪ "".

Ukoliko u okviru jednostrukog navodnika ne navedemo ništa imamo posla sa praznim znakom, dok ukoliko navedete dvostruke navodnike, na kraj se automatski dodaje marker za kraj stringa. Blanko simbol se takođe razlikuje od praznog znaka, blanko simbol ima svoj kod, koji označava da se na nekom mestu u memoriji čuva znak koji prestavlja blanko simbol, ovi simboli služe da zabilježe praznine u tekstu. Uradimo primer koji će nadovezati dva stringa jedan na drugi, u ovom slučaju nećmo koristiti funkcije za rad sa strnigovima iz biblioteka cstring.

PRIMER:#include <iostream>

#define DIMENZIJA 14#define REZULTAT 2*DIMENZIJA

using namespace std;

intmain(void){

char cPrviString[DIMENZIJA] ="Prvi string!";char cDrugiString[DIMENZIJA]="Drugi string!";

cout<<"Prvi string="<<endl<<cPrviString <<endl;

cout<<"Drugi string="<<endl<<cDrugiString <<endl<<endl;

char cRezultat[REZULTAT],*ptrRezultat;

ptrRezultat =cRezultat;char *ptrPrvi = cPrviString, *ptrDrugi = cDrugiString;

while(*ptrPrvi) *ptrRezultat++=*ptrPrvi++;while(*ptrDrugi) *ptrRezultat++=*ptrDrugi++;*ptrRezultat++='\0';

cout<< cRezultat;

system("PAUSE");return EXIT_SUCCESS;

}

Drugo rešenje koristi odgovarajuće funkcije iz cstring bibloteke.66

Page 67: UVOD U C++ I DODATAK ZA C++11

PRIMER:

#include <iostream>#include <cstring>

#define DIMENZIJA 14#define REZULTAT 2*DIMENZIJA

using namespace std;

intmain(void){

char cPrviString[DIMENZIJA] ="Prvi string!", *ptrPrvi = cPrviString;

char cDrugiString[DIMENZIJA]="Drugi string!", *ptrDrugi = cDrugiString;

cout<<"Prvi string="<<endl <<cPrviString <<endl;

cout<<"Drugi string="<<endl <<cDrugiString <<endl<<endl;

char cRezultat[REZULTAT], * ptrRezultat=cRezultat;

strcpy(ptrRezultat,ptrPrvi);strcat(ptrRezultat,ptrDrugi);

cout<< cRezultat;

system("PAUSE");return EXIT_SUCCESS;

}

Primeri koje smo do sada uradili su interesantni, i prikazuju neke od mogućnosti koje pružaju stringovi u stilu jezika C. Svi primeri su radili sa stringovima koji su imali stringove definisane u programu, mana ovog pristupa je to što možemo da radimo sa predefinisanim porukama. Lepo bi bilo da možemo da saznamo ime korisnika, te da mu uputimo personalnu poruku.Potpuno isti primer možemo da uradimo i koristeći funckije za rad sa stringovima.

Zamislite samo kad dobijete mejl, a tamo pise Vaše ime i mejl, drugim rečima mora da postoji način kako da od korisnika uzmemo neki string, te da taj niz karaktera upotrebimo u programu, na taj način dobijamo i na interaktivnosti naših programa.Uradite sledeći program: unoste ime i prezime, te prikazujete poruku o datumu i vremenu, valuti koja se koristi na računaru i prostoru na hard disku.

PRIMER:67

Page 68: UVOD U C++ I DODATAK ZA C++11

#include <iostream>#include "dos.h"#include <cstring>#include <locale.h>#include <ctime>

using namespace std;

intmain(void){

char cIme[20], cPrezime[20];cout<<"Upisite vase ime->"; cin.getline(cIme,19); cout<<endl;cout<<"Upisite vase prezime->"; cin.getline(cPrezime,19); cout<<endl;

system("CLS");cout<<"Dobar dan, "

<<cIme<<" "<<cPrezime<<endl;

time_t t= time(NULL);tm *tm_ptr =localtime(&t);cout<<"Vreme je(hh:mm:ss)="

<<tm_ptr->tm_hour<<":"<<tm_ptr->tm_min <<":"<<tm_ptr->tm_sec <<endl;

cout<<"Datum je(day:month:year)="<<tm_ptr->tm_mday<<":"<<tm_ptr->tm_mon+1<<":"<<tm_ptr->tm_year+1900<<endl;

struct lconv* lc;setlocale(LC_ALL,"");lc=localeconv();cout<<"Simbol za valutu je="

<<lc->currency_symbol<<endl;

struct diskfree_t naDiskuSlobodno;_getdiskfree(3,&naDiskuSlobodno);

unsigned long slobodnogHardDiska= naDiskuSlobodno.total_clusters * naDiskuSlobodno.sectors_per_cluster * naDiskuSlobodno.bytes_per_sector;

cout<<"Slobodnog prostora na disku ima="<<slobodnogHardDiska<<" B"<<endl;

system("PAUSE");return EXIT_SUCCESS;

}

68

Page 69: UVOD U C++ I DODATAK ZA C++11

U prethodnom primeru ste videli kako možete da očitate neke bitne podatke o računaru, ali da znate za profesionlnu upotrebu se koriste API funkcije. Pomoću ovih funkcija možete da uradite većinu interesantnih primera, koji omogućavaju rad sa važnim resursima računara. Pogledajte o API funkcijama na Internetu, ali biće vam potrebni i neki drugi stringovi, o njima sad nećemo govoriti, ali da znate da i oni postoje. Osim API funkcija danas se koriste i dll datoteke, one predstavljaju neke korisne delove koda, koje možete i dinamički učitavati u Vaš program. Ove datoteke predstavljaju važnu mogućnost, danas je gotovo ne moguće zamisliti iole ozbiljniji profesionalno razvijen program bez njih. Problem mogu da kreiraju dll datoteke istog imena. One se u suštini razlikuju, ali su različite verzije iste dll datoteke.

Iako to nekom može biti zbunjujuće, kad naučite objektno programiranje sve će leći na svoje mesto. Ne mogu da Vam u ovome momentu razjasnim sve tipove stringova kao što su:▪ TCHAR.▪ WCHAR.▪ LPSTR.▪ LPWSTR.▪ LPCTSTR...

Mislim da je dobro da imate predstavu o tome da postoje i neki drugi tipovi podataka, ali da sad još niste spremni da ih razumete. Učenje jezika je donekle slično video igricama, prolazite sa jednog na drugi nivo. Iako mislite da toga još nema mnogo, C++ Vam zaista garantuje doživotnu zabavu.

Došli smo do matrica, niza nizova, ili višedimenzionalnih nizova. One se u memoriji čuvaju red po red na uzastopnim memorijskim lokacijama. Pogledajte o matricama, ukoliko niste upoznati sa ovim terminom u linearnoj algebri, pretražite Internet.Ako imamo problem koji logično zahteva od nas upotrebu dve dimenzije, kao raspored časova npr, možemo koristiti matrice. Potrebno je, na osnovu šablona kojeg korisnik odabira, prikazati jednu od dve moguće matrice uzorci mogu biti 0 ili 1. Ukoliko je šema 0 prikazuje se sledeći izlaz na monitoru:1111000011110000

Kada odaberemo šablon 1 treba prikazati sledeću matricu:0000111100001111.

Kao vežbu možete pokušati da jedinice postavljate po kolonama, a ne redovima. Postoje i druge mogućnosti, predlažem Vam da eksperimentišete sa matricama.

69

Page 70: UVOD U C++ I DODATAK ZA C++11

Primer možete da uradite na sledeći način, nemojte zaboraviti da eksperimentišete sa različitim načinima rešavanja problema.Iako je ovaj primer urađen na ovaj način, to ne znači da je to i najoptimalnije rešenje.

PRIMER:#include <iostream>

# define DIMENZIJA 10

using namespace std;

intmain(void){

cout<<"Kolika je dimenzija, neki broj manji od 10->";int iDimenzija; cin>>iDimenzija; system("CLS");

cout<<"Odaberi jedan od dva sablona 0 ili 1->"; int iSablon; cin>>iSablon; system("CLS");

//rezervisemo prostor za 10*10 elemenata kvadratne matriceint iMatrica[DIMENZIJA][DIMENZIJA];

//popunimo elemente matricefor(int i=0; i< iDimenzija; ++i)

for(int j= 0; j< iDimenzija; ++j)if(iSablon==0)

(i %2==0)? iMatrica[i][j]=1: iMatrica[i][j]=0;else

(i %2==0)? iMatrica[i][j]=0: iMatrica[i][j]=1;

//prikaz elemenata matricefor(int i=0; i< iDimenzija; i++)

for(int j=0; j<iDimenzija; j++)if(j== iDimenzija-1) cout<<iMatrica[i][j]<<endl;else cout<<iMatrica[i][j];

system("PAUSE");return EXIT_SUCCESS;}

Za vežbu probajte odrediti neke od jenostavnijih operacija sa matricama kao što su:▪ Sabiranje.▪ Oduzimanje.▪ Množenje.▪ Množenje realnim brojem.

70

Page 71: UVOD U C++ I DODATAK ZA C++11

▪ Pronađite najveći element svakog reda i kolone.▪ Odrednite linearnu kombinaciju dve matrice.

Ovo su samo neki od problema za koje koristimo matrice. Postoji veliki broj važnih matrica, ovde ih ne možemo sve pomenuti. Mogli bi ste na Internetu pronaći neke od osnovnih pojmova iz ove oblasti.

Napuniti matricu slučajnim ciframa od 0 do 9. Nakon toga uneti neku koordinatu u granicama od 0 do 50. Krećući se levo, desno, gore i dole, dok smo u granicama matrice, ili dok je tekući element matrice manji ili jednak od elementa sa unesenim koordintama.

PRIMER:#include <iostream>#include <ctime>

#define DIM 50

using namespace std;

intmain(void){

srand(time(NULL));int iMatrica[DIM][DIM];

for(int i= 0; i<DIM; ++i)for(int j=0; j<DIM; ++j)

iMatrica[i][j]= rand()%10; cout<<"Unesite kordinate tacke,"<<endl <<"takve da x< 50, y<50!"<<endl;

int iX=0, iY=0;do{

cout<<"Koordinate x,y->"; cin>> iX>>iY;}while(!(((iX>=0)&&(iX<DIM))&&((iY>=0)&&(iY<DIM))));

int iTemp= iMatrica[iX][iY], iTackaX=iX+1,iTackaY=iY;cout<<"Vrednost u tacki "<<iX<<","<<iY<<"="<<iTemp<<endl;

cout<<"Desno po horizontali"<<endl;while(( iTemp>= iMatrica[iTackaX][iTackaY])

&& iTackaX< DIM){ cout<< iMatrica[iTackaX++][iTackaY]<<" ";}

71

Page 72: UVOD U C++ I DODATAK ZA C++11

cout<<"Lijevo po horizontali"<<endl;iTackaX=iX-1,iTackaY=iY;while(( iTemp>= iMatrica[iTackaX][iTackaY])

&& iTackaX>0){ cout<< iMatrica[iTackaX--][iTackaY]<<" ";}

cout<<"Gore po vertikali"<<endl;iTackaX=iX,iTackaY=iY+1;while(( iTemp>= iMatrica[iTackaX][iTackaY])

&& iTackaY>0){ cout<< iMatrica[iTackaX][iTackaY--]<<" ";}

cout<<"Dole po vertikali"<<endl;iTackaX=iX,iTackaY=iY-1;while(( iTemp>= iMatrica[iTackaX][iTackaY])

&& (iTackaY< DIM)){ cout<< iMatrica[iTackaX][iTackaY++]<<" ";}

system("PAUSE");return EXIT_SUCCESS;}

Razmislite kako da program napišete koristeći funkcije. Upotreba funkcija značajno može smanjiti prethodni program. Još jedan predlog je, da složene iskaze poput:!(((iX>=0)&&(iX<DIM))&&((iY>=0)&&(iY<DIM)))), pokušate da ih zamenite nekim makroom.

Navedimo primer koji će ilustrovati rad sa matricama. Potrebno je brojeve prikazati na zaslonu računara prema sledećem šablonu.

0 1 2 3 41 2 3 4 52 3 4 5 6 3 4 5 6 74 5 6 7 8

Kad napišemo indekse matrice dobićemo jednostavnu ideju, iMatrica[i][j] gde i i j predstavljaju indekse matrice.Ukoliko saberemo indekse matrice, prema formuli i +j, dobićemo gore prikazani šablon.Naravno, možemo ići i unazad kroz matricu, drugim rečima polazimo od elementa koji prima vrednost 8, a to u ovom slučaju predstavlja poslednji element, te idući unazad prolazimo kroz elemente matrice.Druga ideja nastaje tako što posmatramo dijagonale matrice, uočavamo dijagonale gde su svi elementi 0, zatim uočavamo dijagonalu gde su svi elementi 1, ..., i na kraju uočavamo poslednju dijagonalu na kojoj se nalazi broj 8.Sledeća ideja nam može biti sledeća, posmatrajte vertikale 0,1,2,3,4, nakon toga analiziramo drugu vertikalu 1,2,3,4,5, itd....Sledeća ideja bi mogla biti implementirana uočavanjem dijagonala: 0,2,4,6,8, zatim 1,3,5,7, .. 3,5 i 4, dok uočavamo i dijagonale ispod 1, 3, 5, 7, i sličnodo 4.

72

Page 73: UVOD U C++ I DODATAK ZA C++11

Moguće je primer rešiti na više načina, neki se nameću kao ubrzanja, uočimo li neku simetriju nećemo morati prolaziti kroz celu matricu, nego samo deo da obradimo, a ostale elemente postavimo slično.Potrebno je znati da se elementi matrice u memoriji čuvaju red za redom, te se na taj način mogu najbrže i adresirati, na taj način se pristupa elementima matrice na najbrži način.Drugim rečima, umetnute dve for naredbe, na način na koji ih najčešće možemo naći implementirane, su takve zbog brzine. Na taj način kreiramo i najbrži kod.Pokušajte da unesete matricu, te da napišete njoj transponovanu matricu. Ispitati da li je matrica simetrična u odnosu na glavnu, ili/i sporednu dijagonalu. Ispitajte da li je matrica simetrična u odnosu na srednji red, srednju kolonu, kao i da li su simetrične u odnosu na srednji red i srednju kolonu.Implementirajte gore navedene algoritme, te ih analizirajte, pokušajte da uočite kolio se vremenski razlikuju te implementacije. Iako je brzina najbitnija u današnjim primenama, ali uvek je dobro primer uraditi na što više načina, čisto zbog gimnastike uma. Potrebno je formirati i ispisati matricu dimenzije ne veće od 20 prema sledećem šablonu.1000101010001000101010001

PRIMER:#include <iostream>#include <ctime>

#define DIM 20

using namespace std;

intmain(void){

//Deklarisemo matricuint iMatrica[DIM][DIM];

//Dimenzija kvadratne matricecout<<"Unesi dimenzije (0,20) n->"; int iN; cin>>iN;

//Napunimo matricufor(int i= 0; i<iN; i++)

for(int j=0; j<iN; j++)if(( i==j)||(i+j+1==iN))

iMatrica[i][j]=1;else

iMatrica[i][j]=0;

//Prikazimo matricufor(int i= 0; i<iN; i++)

73

Page 74: UVOD U C++ I DODATAK ZA C++11

{for(int j=0; j<iN;cout<<iMatrica[i][j++]);cout<<endl;

}

system("PAUSE"); return EXIT_SUCCESS;}

Unapredite prethodni problem tako što ćete upotrebiti funkcije.

Prethodni primer je radio sa elementima gde su članovi matrice tipa int , uradimo sad primer koji koristi matricu čiji su elementi tipa char.

PRIMER:#include <iostream>

# define RED 2# define KOL 10

using namespace std;

intmain(void){

//rezervisimo prostor za osnovnu srafuruchar cMatrica[RED][KOL]={{'/','\\','/','\\','/','\\','/','\\','/','\\'},

{'\\','/','\\','/','\\','/','\\','/','\\','/'}}; //ovaj znak pisemo vise puta;

char cVertikalniZnak ='|', cMinus ='-';

//ispisujemo hedercout<<'+';for(int i=0; i<KOL; cout<<cMinus,i++);cout<<'+'; cout<<endl;

//prikakaz dva reda kosih crtafor(int i=0; i< RED; i++){

cout<<cVertikalniZnak;for(int j=0; j< KOL; j++){

cout<<cMatrica[i][j];}cout<<cVertikalniZnak<<endl;

} //ispisujemo futer

cout<<'+';for(int i=0; i<KOL; cout<<cMinus,i++);cout<<'+'; cout<<endl;

74

Page 75: UVOD U C++ I DODATAK ZA C++11

system("PAUSE"); return EXIT_SUCCESS;}

Prethodni primer pokušajte da unapredite tako da koristi sirove stringove. Ukoliko ne znate na šta mislimo, pogledajte onaj znak '\\', u Vašem programu pokušajte da upotrebite samo jedan znak, a ne dva kao što se to ranije moralo pisati.

Neke situacije od nas očekuju da čuvamo tablicu imena: {“Ponedeljak“, „Utorak“, „Sreda“, “Četvrtak“, „Petak“, „Subota“, „Nedelja“}. Ukoliko bi kreirali matricu karaktera trebalo bi nam 7 redova i 10 kolona. Ponedeljak je najduži niz karaktera, i ima ukupno 10 znakova. Na taj način gubimo dosta prostora, jer ostali dani imaju daleko manje znakova. Da bi ovaj problem adekvatnije rešili uvedeni su nizovi pokazivača. Hajde da vidimo u narednom primeru kako možemo koristiti nizove pokazivača.

PRIMER:#include <iostream>

# define DANA 7

using namespace std;

intmain(void){

int iRedniBroj[]={1,2,3,4,5,6,7};int * ptrInt[DANA];

//nije neophodno ni navodidi dimenzijuchar* cDani[]={"Ponedeljak", "Utorak", "Sreda",

"Cetvrtak", "Petak", "Subota", "Nedelja"};

//Uspostavimo vezu pokazivaca na int i int nizfor(int i=0; i<DANA; ++i)

ptrInt[i]=& iRedniBroj[i]; //Prikazujemo elemente na koje pokazuju nizovi pokazivaca

for(int i=0; i< DANA; ++i)cout<< cDani[i]<<" je "<<*ptrInt[i]<<" po redu"<<endl;

system("PAUSE"); return EXIT_SUCCESS;}

75

Page 76: UVOD U C++ I DODATAK ZA C++11

Zamislite kako bi koristili matrice za kreiranje igrica: sudoku, iks oks, ukrštene reči i slično. Nisu matrice pogodne samo za jednostavne igrice, mogu se koristiti u matematici, za čuvanje ranga timova u nekom takmičenju i slično. Nemojmo zaboraviti ni šah.Ovo su samo neki od predloga koji bi mogli ulepšati bilo koju veb stranicu, zabaviti nas dok čekamo devojku, ili recimo kad nam treba neka kursna lista.

Sledeći primer kombinuje upotrebu nizova i funkcija. Potrebno je zameniti mesta m-tom i n-tom elementu niza.

PRIMER: #include <iostream>

using namespace std;

//Deklaracija zaglavlja funkcija, nije neophodno navoditi imena promjenljivihvoid UnesiNiz( int* , int );void ZameniMesta( int* , int , int , int );void PisiNiz( int* , int);

intmain(void){

cout<<"Koliko elemenata niza imate->";int iDimenzija;cin>>iDimenzija;

//Kreirajmo nizint* ptrNiz = new int[iDimenzija];

UnesiNiz(ptrNiz, iDimenzija);

int iN, iM; cout<<"Unesi n i m->"; cin>>iN>>iM;ZameniMesta( ptrNiz,iDimenzija, iN, iM);

PisiNiz( ptrNiz, iDimenzija);

system("PAUSE");return EXIT_SUCCESS;}

void UnesiNiz( int* iNiz, int n ){

for(int* ptrTemp=iNiz; ptrTemp< iNiz+n; ptrTemp++){cout<<"sledeci element niza->"; cin>>*ptrTemp;}

}

76

Page 77: UVOD U C++ I DODATAK ZA C++11

void ZameniMesta( int iNiz[], int n, int iN, int iM)

{int iTemp = iNiz[iN]; iNiz[iN]=iNiz[iM]; iNiz[iM]=iTemp;

}

void PisiNiz( int* iNiz, int n){

for(int* ptrTemp=iNiz; ptrTemp< iNiz+n; ptrTemp++){cout<<*ptrTemp<<endl;}

}

Koristili smo dve osnovne tehnike uvlačenja niza u funkcije. Dve funkcije: unesi i pisi niz, koriste pokazivače da bi ih uneli u tela funkcije. Dok Zameni mesta koristi malčice drugačiji način unošenja niza u funkciju. Razmislite o tome, zašto smo ovaj primer uradili baš na ovaj način.Nemojte zaboraviti da osmislite i uradite primer koji vraća pokazivač kao rezultat funkcije. Recimo da, ukoliko nemate ideju, možete realizovati funkciju koja pronalazi prvu pojavu nekog znaka u nizu karaktera. Ako se znak ne pojavi u nizu, možete vratiti NULL kao rezultat, ili nullptr.

77

Page 78: UVOD U C++ I DODATAK ZA C++11

8 . D AT O T E K E

Ukoliko ugasimo računar, podaci koji su se nalazili u RAM-u, nepovratno nestaju. Drugim rečima, sve što nije pohranjeno na hard disku, ili nekoj drugoj vrsti trajne memorije, nestaje. Da bi rezultati do kojih smo došli ostali nakon rada programa, mogu se koristiti datoteke. Datoteke, za korisnika predstavljaju grupu povezanih podataka. Prilikom rada sa fajlovima moramo znati ime, tip, dozvolu pristupa i neke druge parametre. Svojstva datoteke najlakše saznamo ako desnim tasterom pritisnemo fajl i odaberemo opciju propertis. Moguće je koristiti neki od programa, a danas ih ima dosta na tržištu. Moguće je iz comandnog prozora, pomoću naredbi odrediti ili promeniti neka od svojstava datoteke.Na taj način možemo saznati neka svojstva teke. Šematski to možemo da zamislimo na sledeći način.

Treba znati da Windows datoteke deli na binarne ili tekstualne.Mogu postojati i neke specifičnosti za datoteke, na različitim operativnim sistemima. Daleko je lakše za raditi sa standardizovanim objektima, nego na proizvoljno odabranim pravilima, koja su nekad nekome bila najlogičnija. Ono što je nekom najpraktičnije, Vama ne mora da bude, jer ipak se ljudi razlikuju. Prilikom ispisa tekstualne datoteke na monitoru, Windows koristi dva reda da bi prikazo endl, drugim rečima koriste se dva ASCII simbola, CR i LF. CR predstavlja carrige return što u prevodu znači prelazak na početak reda, dok LF je skraćenica od line fed ili prelazak u novi red. Kada se ova dva znaka upisuju u datoteku oni se pretvaraju u marker za kraj stringa. Prilikom prebacivanja iz datoteke oni se, ukoliko radimo sa tekstualnim datotekam automatski zamenjuju sa dva znaka za prikaz na monitoru.

Uradimo sledeći primer. Ulazna datoteka se sastoji od redova ne dužih od 1024 znaka. Nije unapred poznato koliko redova ima datoteka. Potrebno je izračunati i prikazati dužinu svakog od redova, izbrojati i prikazati koliko ukupno redova ima datoteka i odrediti ukupan broj slova Znak za novi red se ne računa kao karakter. Odrediti koliko prosječno ima slova po redu.

PRIMER:#include <iostream>

//#include <cstdio>

#include <cstring>

//maksimalna duzina reda datoteke

78

Page 79: UVOD U C++ I DODATAK ZA C++11

#define MAXIMALNI_RED 1024

using namespace std;

int

main(void)

{

int iBrojRedova=0, iUkupnoZnakova=0;

//Pokazivac na datotekuFILE *ptrNaDatoteku;

//Prihvatni baferchar UlazniBafer[MAXIMALNI_RED]="";

//Iniciranje pokazivaca, omoguceno samo ocitavanjeptrNaDatoteku=fopen("UlaznaDatoteka.txt","r");

//citanje datoteke string po stringwhile(fgets(UlazniBafer,MAXIMALNI_RED,ptrNaDatoteku)!=NULL){

iBrojRedova++;int iBrojZnakovaURedu= strlen(UlazniBafer);iUkupnoZnakova+=iBrojZnakovaURedu;cout<<"Red"<<iBrojRedova<<"

"<<iBrojZnakovaURedu-1<<endl;}

//Nemojete zaboraviti zatvoriti datotekufclose(ptrNaDatoteku);

//Prikaz rezultatacout<<"Broj redova="<<iBrojRedova<<endl;cout<<"Ukupno znakova u datoteci="<<iUkupnoZnakova<<endl;

cout<<"Prosjecno znakova u redu="<<iUkupnoZnakova/double(iBrojRedova)<<endl;

system("PAUSE");return EXIT_SUCCESS;

}

Bitno je napomenuti da moramo uspostaviti vezu sa određenom datotekom, preko pokazivača na fajl. Komanda koja nam koristi da bi se uspostavila veza sa tekom je fopen, sa svojim argumentima. Na kraju rada je neophodno zatvoriti datoteku naredbom fclose. Redove fajla čitamo pomoću fgets naredbe.Ukoliko sa datotekama radimo na ovaj način, u Linuxu se kreiraju tri toka:▪ stdout.▪ stderr.▪ stdin.

Windows podržava:▪ stdout.

79

Page 80: UVOD U C++ I DODATAK ZA C++11

▪ stderr.▪ stdin.▪ stdprn.▪ stdaux.

U prethodnom primeru smo koristili cout naredbu, ali preporučljivo je da se koristi printf, a umesto cin da upotrebite scanf.Da bi više saznali o pokazivaču koji se kreira na vašu datoteku pronađite gde je u datoteci stdio.h, deklarisan FILE struktura.Ova struktura je prilično samoopisujuća tako da nećemo gubiti vreme na njenu detaljnu analizu, preporučuje se programeru da ovu definiciju detaljno razmotri.

Uradimo sledeći primer. Potrebno je ulaznu, tekstualnu datoteku prepisati u izlaznu datoteku.

PRIMER:#include <iostream>

//#include <cstdio>

#include <cstring>

//maksimalna duzina reda datoteke

#define MAXIMALNI_RED 1024

using namespace std;

int

main(void)

{

//Pokazivac na ulaznu i izlaznu datotekuFILE *ptrNaUlaznuDatoteku, *ptrNaIzlaznuDatoteku;

//Prihvatni baferchar UlazniBafer[MAXIMALNI_RED]="";

//Iniciranje pokazivaca, omoguceno samo ocitavanjeptrNaUlaznuDatoteku=fopen("UlaznaDatoteka.txt","r");

//Iniciranje pokazivaca, na IzlaznuDatotekuptrNaIzlaznuDatoteku=fopen("IzlaznaDatoteka.txt","w");

while(fgets(UlazniBafer,MAXIMALNI_RED,ptrNaUlaznuDatoteku)!=NULL){

fputs(UlazniBafer,ptrNaIzlaznuDatoteku);}

//Nemojete zaboraviti zatvoriti datotekefclose(ptrNaUlaznuDatoteku);

fclose(ptrNaIzlaznuDatoteku);

80

Page 81: UVOD U C++ I DODATAK ZA C++11

system("PAUSE");return EXIT_SUCCESS;

}

Pomenimo neke od funkcija za čitanje stringova: fgets, gets, wgets.Za pisanje stringova možemo koristiti sledeće funkcije: fputs, puts, fptws.Ukoliko radimo sa karakterima možemo koristiti: fgetc, getc, getchar, kao i fgetwc, getwc ili getwchar. Slično kao i za stringove, postoje odgovarajuće funkcije za pisanje znakova u datoteke. Napomenimo da smo do sada radili sa sekvencijalnim tekstualnim datotekama.

Podaci iz datoteke se mogu čitati na binarnom principu, tada se koristi slovo b, kao naznaka da sa fajlom radimo na binarnom principu. Da bi se datoteka otvorila binarno, i da bi se radilo na binarnom principu moramo da razumemo kako su ove datoteke organizovane. Na početku fajla se obično postavi heder, u okviru kojeg, obično pronalazimo bitne informacije o datoteci. Nakon hedera dolaze bajti, koje očitavamo na osnovu informacija koje smo našli u hederu teke. Možete kreirati bmp datoteku pomoću Vašeg programa, za vežbu. Zamoran posao, ali samo da znate može se i tako kreirati slika, direktno iz programa kojeg pišete pomoću C++-a. Poželjno je da pronađete odgovarajuće informacije o datoteci u hederu, a ostalo možete pronaći na Internetu, a moguće je i pisati vlastite aplikacije. Za Vašu informaciju, možete kreirati odgovarajuću klasu za rad sa bmp datotekama, a nakon toga koristiti ovu klasu u narednim primerima. Interesantno, nema šta. Komplikovano, verujte. Ukoliko ne verujete, proverite.

Uradimo sledeći primer koji zapisuje nekoliko redova u spoljnu datoteku.

PRIMER:#include <iostream>

#include <cstring>

typedef struct{int iRedniBroj;

char cIme[20]; double dBodova;} ZapisTakmicara;

using namespace std;

int

main(void)

{

ZapisTakmicara ztNiz[5]={

{1,"Janko",12.7},{2,"Marko", 13.21},{3,"Pero", 17.71},{4,"Haso", 12.21},{5,"Ziko", 19.345}

};

FILE *ptrNaDatoteku=fopen("IzlaznaDatoteka.dat","wb");

81

Page 82: UVOD U C++ I DODATAK ZA C++11

for(int i=0; i< 5; ++i){

fwrite(ztNiz+i,sizeof(ZapisTakmicara),1,ptrNaDatoteku);}

fclose(ptrNaDatoteku);

system("PAUSE");return EXIT_SUCCESS;

}

Bitno je da razumemo kako se koriste fwrite i fread funkcije. Očitajte prethodnu datoteku, i prikažite njen sadržaj na monitoru.

Pređimo na formatirani zapis, pomoću printf i scanf funkcija.U narednom primeru ćemo videti, kako možemo pronaći broj čiji je kvadrat manji od nekog graničnog broja. Traženi broj je najveći od svih brojeva čiji je kvadrat manji od granice.

UlaznaDatoteka.in se sastoji od pozitivnih int brojeva. Potrebno je pronaći, za svaki broj iz ulazne datoteke, poslednji celi broj čiji je kvadrat manji od pročitanoga broja.

PRIMER:#include <iostream>

using namespace std;

int

main(void)

{

FILE* ptrNaUlaznuDatoteku, * ptrNaIzlaznuDatoteku;

ptrNaUlaznuDatoteku = fopen("UlaznaDatoteka.in", "r");ptrNaIzlaznuDatoteku = fopen("IzlaznaDatoteka.out", "w");

int iBroj, iKvadrat=0;while(fscanf(ptrNaUlaznuDatoteku,"%d",&iBroj)!=EOF){

int i=0; iKvadrat=i;while( iKvadrat< iBroj){

i++; iKvadrat=i*i;}iKvadrat=(i-1)*(i-1);fprintf(ptrNaIzlaznuDatoteku,"%d\n",iKvadrat);

}

fclose( ptrNaUlaznuDatoteku);fclose( ptrNaIzlaznuDatoteku);

82

Page 83: UVOD U C++ I DODATAK ZA C++11

system("PAUSE");return EXIT_SUCCESS;

}

Uradimo sledeće primere, koji će nam ilustrovati moderniji pristup čitanju datoteka, koristićemo takozvane tokove: istream, ostream ili fstream. Zadržimo se malo na tokovima. Kad razmislimo o reči tok, obično nam se pred očima stvori slika nekog potoka, toka saobraćaja, grananja struje, ili nešto slično.

Ukoliko razmišljamo o tokovima podataka, zgodno je da zamislimo čašu soka(datoteka) iz koje uzimamo podatke(pijemo sok), dok nam slamka predstavlja tok kojim putuju podaci do našeg programa(žednih usta). Ne kažem da morate o tokovima svaki put razmišljati na taj način, ali meni je bila od pomoći ta mentalna slika. Interesantno je poređenje vodokotlića sa baferom. Ponekad se vodokotlić zaglavi, i moramo primeniti flush(stdin), ovo se desi zbog „\n” na krajevima stringova. No, da ne dužimo pričama o datotekama, pređimo na primer. Potrebno je UlaznaDatoteka.txt, u kojoj se nalaze cifre heksadecimalnog broja, pretvoriti u binarni broj. Broj može imati proizvoljno mnogo cifara.

PRIMER:#include <fstream>

using namespace std;

int

main(void)

{ ifstream fin;fin.open("UlaznaDatoteka.txt");

ofstream fout;fout.open("IzlaznaDatoteka.txt");

char cUlazniZnak[10];

while(!fin.eof()){

fin.getline(cUlazniZnak,10);char cZnak=(char)cUlazniZnak[0];if(cZnak== '0'){ fout<<'0'<<'0'<<'0'<<'0'<<endl; continue;}if(cZnak== '1'){ fout<<'0'<<'0'<<'0'<<'1'<<endl; continue;}if(cZnak== '2'){ fout<<'0'<<'0'<<'1'<<'0'<<endl; continue;}if(cZnak== '3'){ fout<<'0'<<'0'<<'1'<<'1'<<endl; continue;}if(cZnak== '4'){ fout<<'0'<<'1'<<'0'<<'0'<<endl; continue;}if(cZnak== '5'){ fout<<'0'<<'1'<<'0'<<'1'<<endl; continue;}if(cZnak== '6'){ fout<<'0'<<'1'<<'1'<<'0'<<endl; continue;}if(cZnak== '7'){ fout<<'0'<<'1'<<'1'<<'1'<<endl; continue;}if(cZnak== '8'){ fout<<'1'<<'0'<<'0'<<'0'<<endl; continue;}if(cZnak== '9'){ fout<<'1'<<'0'<<'0'<<'1'<<endl; continue;}if(cZnak== 'A'){ fout<<'1'<<'0'<<'1'<<'0'<<endl; continue;}if(cZnak== 'B'){ fout<<'1'<<'0'<<'1'<<'1'<<endl; continue;}if(cZnak== 'C'){ fout<<'1'<<'1'<<'0'<<'0'<<endl; continue;}

83

Page 84: UVOD U C++ I DODATAK ZA C++11

if(cZnak== 'D'){ fout<<'1'<<'1'<<'0'<<'1'<<endl; continue;}if(cZnak== 'E'){ fout<<'1'<<'1'<<'1'<<'0'<<endl; continue;}if(cZnak== 'F'){ fout<<'1'<<'1'<<'1'<<'1'<<endl; continue;}

}

fin.close();fout.close();

system("PAUSE");return EXIT_SUCCESS;

}

Primer je ilustrovao kako možemo čitati iz ulaznog toka(fin) i upisivati u izlazni tok(fout). Čitali smo liniju po liniju teksta i izdvajali prvi znak linije. Napomenimo da se cifre heksadecimalnog broja nalaze linija za linijom, drugim rečima prva cifra se nalazi u prvom redu datoteke, druga cifra u drugom redu datoteke itd...Da bi poboljšali čitljivost programa, možemo dio sa određivanjem cifre heksadecimalnog broja, izdvojiti u posebnu funkciju. Problem sa ovim rešenjem je smanjenje brzine. Česta pozivanja funkcije usporavaju progame, a u našem primeru imamo petlju while koja bi više puta pozivala odgovarajuću funkciju. Uočimo da cifre možemo da podelimo u dva skupa, one koje su cifre broja ili one koje su slova, ovo se može upotrebiti za ubrzanje koda,ali na taj način kreiramo teže čitljiv program, zato sam primer uradio na gore prikazani način.

Jedna od prvih upotreba računara je bila u proračunu leta topovskog đuleta.Mi ćemo uraditi nešto jednostavniji primer, jer ćemo zanemariti uticaj vazduha na đule, kako vetra tako i otpora koji vazduh kreira, pretpostavićemo da su bitni početna brzina koju upisuje korisnik, a izražava je u metrima po sekundi, kao i ugao koji se izražava u stepenima. Nećemo razmatrati situaciju kada g menja svoju vrednost zbog promene visine, drugim rečima uzimamo da g iznosi 9.81 metara u sekundi na kvadrat.

Tabeliramo let u zavisnosti od koraka tabelacije, a vrednost se unosi u sekundama.

PRIMER:

#include <iostream>#include <cmath>#include <fstream>

#define IME_DATOTEKE "KosiHitac.txt"#define PI 3.141592#define UGAO_U_RADIJANIMA (180.0/PI)

using namespace std;

intmain(void){

cout<<"Unesite ugao u stepenima->"; double dUgao; cin>>dUgao;system("CLS");cout<<"Unesite pocetnu brzinu ->"; double dPocetna; cin>>dPocetna;system("CLS");

if((dUgao <=0) ||(dUgao>=90)){

84

Page 85: UVOD U C++ I DODATAK ZA C++11

cout<<"Ugao van opsega!!!"<<endl;system("PAUSE");return EXIT_FAILURE;

}

double dDuzinaLeta =(dPocetna*sin(dUgao/UGAO_U_RADIJANIMA)) /(9.81*0.5);

ofstream datLet(IME_DATOTEKE);

double dInterval=0.0; cout<<"Svakih sekundi tabeliramo->"; cin>> dInterval;

datLet<<"KOSI HITAC "<<endl <<"Pocetna brzina="<<dPocetna<<endl <<"Ugao ="<<dUgao<<" stepeni "<<endl;

datLet<<"--------------------------------------------"<<endl;

double dVreme =0.0;while( dVreme <= dDuzinaLeta){ datLet<<" Vreme od pocetka ="<<dVreme<<endl;

datLet<<" Brzina po x="<<dPocetna*cos(dUgao/UGAO_U_RADIJANIMA)<<endl <<" Lokacija po x="<<dPocetna*dVreme*cos(dUgao/UGAO_U_RADIJANIMA)<<endl;

datLet<<" Brzina po y="<<dPocetna*sin(dUgao/UGAO_U_RADIJANIMA)-9.81*dVreme<<endl <<" Lokacija po y="<<dPocetna*dVreme*sin(dUgao/UGAO_U_RADIJANIMA)-

0.5*9.81*dVreme*dVreme<<endl;

datLet<<endl;

dVreme+=dInterval;}

system("PAUSE");return EXIT_SUCCESS;

}

Za vežbu uradite nekoliko primera sa matricama, nizovima i slično. Moguće je datoteku otvoriti za binarno čitanje i pisanje, ali tad je potrebno koristiti ios::binary mod.Neke od nardbi koje mogu biti od koristi za rad sa tekstualnim datotekama su:▪ open.▪ close.▪ is_open.▪ seekg.▪ seekp.▪ tellg.▪ i tellp.

Navedimo i indikatore datoteke:▪ ios::binary.▪ ios::in.▪ ios::out.

85

Page 86: UVOD U C++ I DODATAK ZA C++11

▪ ios::ate.▪ ios::app.▪ ios::trunc.

Dok kao indikatore smera možemo da navedemo :▪ ios::beg.▪ ios::cur.▪ ios::end.

Da bi omogućili upotrebu odgovarajućih naredbi za rad sa datotekama koristimo sledeću naredbu:#include <fstream>Deklaracija toka se načini tako što se navede sledeća naredba:fstream ImeFajla( ImeDatoteke, ios::binary | ios::out); U predhodnoj liniji smo deklarisali binarnu datoteku u koju je moguće upisivati. Moguće je povezati više indikatora datoteke, na gore prikazani način.

Nakon što smo kreirali binarnu datoteku, možemo proveriti da li je datoteka otvorena na odgovarajući način, to možemo da uradimo jednom if naredbom, na sledeći način.if(! ImeFajla){

cout<<” Nismo uspeli da otvorimo datoteku za operaciju citanja” <<ImeFajla << endl;

return EXIT_FAILURE;}

Bitno je da znamo koji je tip podatka koji upisujemo u datoteku, pisanje u datoteku možemo učiniti na sledeći način:ImeFajla.write( (char *) (&imePromjenljive), sizeof(imePromjenljive)),dok ako upisujemo stringove to radimo na sledeći način:ImeFajla.write( nekiString, sizeof(nekiString) ).

Prema tipu podatka znamo šta očitavamo, i napomenim da se svi podaci ponavljaju prema tipu, drugim rečima: piši int, string, string, double, zatim opet ide drugi blok, treći i tako dalje. Ukoliko datoteka ima neki poznati, ranije prihvaćeni format, negde na Internetu pronađite informacije kako se taj tip datoteke orgranizuje, te prema tim informacijama kreirajte Vaš kod.Danas se koriste i gotova rešenja, koja omogućavaju daleko udobniji rad. Obično se kreira neka klasa, koja ima specificirane metode kojima se pristupa određenom tipu datoteka. Jasno je zašto ne možemo svakoj binarnoj datoteci pristupati na isti način.

Ako želimo čitati podatke iz datoteke to možemo uraditi na sledeći način:ImeFajla.read( (char *) (&imePromjenljive), sizeof(imePromjenljive)), dok ako radimo sa stringovima to možemo uraditi na sledeći način:ImeFajla.read( nekiString, sizeof(nekiString) ).

Ukoliko Vam ne odgovara (char *) način kastanja možete to uraditi pomoću reinterpret_cast, naredbe. Napomenimo da se kroz binarnu datoteku možemo kretati sa direktnim pristupom koristeći naredbe:seekp, seekg, tellp, i tellg.

Poželjno je otvorenu datoteku i zatvoriti, to radimo pomoću naredbe:ImeFajla.close().Važno je znati da postoje:▪ ofstream, koji se koriste za izlazne tokove.▪ ifstream, se primjenjuju za ulazne tokove.

86

Page 87: UVOD U C++ I DODATAK ZA C++11

▪ fstream, je moguće očitavati, upisivati ili oboje, potrebno je navesti šta želite da radite sa tom datotekom.

Sad ćemo da vidimo još jedan način rada sa datotekama, koristićemo Windows.h datoteku.

PRIMER:#include <windows.h>intmain(void){ HANDLE out= CreateFile(L"Primer.txt",

FILE_WRITE_DATA, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);

int n; char s[]="Ovo je primer kako pisemo stringove!!!";

WriteFile(out,s, sizeof(s),(LPDWORD)&n,NULL);

CloseHandle(out);

system("PAUSE");return EXIT_SUCCESS;

}

Ukoliko želite da pišete kod koji je više u stilu C++11 standarda možete da uvrstite i sledeće promene u Vaš kod.

auto imeDatoteke = L”C:\\NekiFolder\\TekstualnaDatoteka.txt”;auto kreiraniFajl = CreateFile( imeDatoteke,

FILE_WRITE_DATA, 0, nullptr, CREATE_ALWAYS,

FILE_ATTRIBUTE_NORMAL, nullptr);

Možete ime datoteke deklarisati pomoću sirovih literala na sledeći način, a kasnije probajte da upotrebite i širokobajtne znakove:char imeDatoteke[] = R(”C:\NekiFolder\TekstualnaDatoteka.txt”);

Nadam se da imate dovoljno podataka o radu sa datotekama, tako da nakon pretrage na Internetu i urađenih primera, možete početi koristiti i datoteke, ukoliko to do sada niste.

87

Page 88: UVOD U C++ I DODATAK ZA C++11

9 . D I N A M I Č K E S T R U K T U R E P O D ATA K A

Videli smo kako možemo da radimo sa nizovima, ali oni ne mogu da zadovolje sve naše potrebe po pitanju većih količina podataka koji se čuvaju u memoriji. Ovde ni ne pominjemo probleme koje rešavaju datoteke ili baze podataka. Navedimo neke od češće korištenih dinamičkih struktura: ▪ Stek.▪ Red.▪ Binarno drvo i modifikacije.▪ Dvostruko povezana lista.▪ Kružna lista.▪ Dek.▪ Mapa.▪ Multimapa i slične strukture.

Napomenimo da možemo koristiti vektore, koji su deo STL-a, oni omogućavaju udobnu upotrebu strukture, te sa njom radimo kao i sa nizom, ali za razliku od do sada pomenutih nizova, vektori mogu dobro da se proširuju na kraju. Ovo je naprednija tema, i da bi je u potpunosti razumeli moramo savladati objektno orjentisano programiranje i upotrebu templejta.

Uradimo reprezentativan primer, koji nam je svima poznat. Potrebno je celi dekadni broj pretvotriti u binarni broj. Ovaj algoritam je poznat, tako da nećemo gubiti vreme na detaljisanje, ali ukratko, delimo celi broj dvojkom i pamtimo ostatke, na kraju je potrebno ispisati sve ostatke naopako. Mislim da je upravo stek taj primer koji ilustruje upotrebu dinamičkih struktura.

Pre nego što uradimo gore pomenuti primer, razmotrićemo gotove stekove, koji se nalaze u STL-u. Na ovaj način ćemo, ne brinući o implementaciji, razumeti kako stek funkcioniše.

PRIMER:#include <iostream>#include <stack>

using namespace std;

intmain(void){

//Deklarisemo prostor za stekstack <int> iStek;cout<<"Punimo stek brojevima 12345"<<endl;iStek.push(1);iStek.push(2);iStek.push(3);iStek.push(4);iStek.push(5);

88

Page 89: UVOD U C++ I DODATAK ZA C++11

//Prikazujemo velicinu stekacout<<"Na steku imamo "

<<iStek.size()<<" elemenata!"<<endl;

//Pisemo poruku da li je stek prazan true/false cout<<"Stek je prazan="

<<boolalpha <<iStek.empty()<<endl;

//Uzimamo element sa steka(top), i skidamo element(pop)cout<< iStek.top(); iStek.pop();

cout<< iStek.top(); iStek.pop();cout<< iStek.top(); iStek.pop();cout<< iStek.top(); iStek.pop();cout<< iStek.top(); iStek.pop();cout<<endl;

//Ispitujemo da li je stek prazancout<<"Stek je prazan=" <<boolalpha

<<iStek.empty() <<endl;

system("PAUSE");return EXIT_SUCCESS;}

Nakon što smo deklarisali stek, elementi su celi brojevi(int). Ostaje da se stek napuni brojevima. Nakon toga prikazujemo veličinu steka i ispitujemo da li je prazan.

Operacije koje možemo da vršimo na steku su: push, top, pop, size, i empty.

Videli smo koji je princip rada steka. Podaci se nabacuju na stek, a zatim se uzimaju po principu poslednji dodani element ide sa steka. Vidimo da se stekovi mogu lepo koristiti u situacijama, kad ne znamo koliko elemenata ima struktura, a potrebno je elemente strukture ispisati naopaoko.Napomenimo da smo koristili stek koji je dio STL-a, na taj način ne moramo ništa da znamo o načinu implementacije ove strukture.

Da bi stekli prestavu o stekovima može da vam pomogne i sledeća ilustracija.

89

Page 90: UVOD U C++ I DODATAK ZA C++11

Vratimo se našem primeru, pretvaranja dekadnog broja u binarni.

PRIMER:#include <iostream>#include <stack>

typedef unsigned long long int KonvertovaniBroj;

using namespace std;

intmain(void){

//Deklarisemo prostor za stekstack <int> iBinarniBroj;

//Rezervisemo prostor KonvertovaniBroj kbUlazniBroj;cout<<"Unesite broj koji zelite pretvoriti->";cin>>kbUlazniBroj;

//Izdvajamo cifre binarnog broja i odbacujemo cifrewhile(kbUlazniBroj){

int iCifra = kbUlazniBroj%2;iBinarniBroj.push(iCifra);kbUlazniBroj=kbUlazniBroj/2;

}

//ispisujemo stek naopakowhile(!iBinarniBroj.empty()){

(iBinarniBroj.top()==1)?cout<<'1':cout<<'0';iBinarniBroj.pop();

}

system("PAUSE");return EXIT_SUCCESS;

}

90

Page 91: UVOD U C++ I DODATAK ZA C++11

Kreiraćemo stek samostalno.

Prva datoteka, u kojoj čuvamo implementaciju steka, nazovimo Stek1.h, a sadržaj je sledeći:

//Deklarisemo strukturutypedef struct cvor{

int iPodatak;struct cvor* iPrethodni;

} CVOR;

//Deklarisemo pokazivac na odgovarajucu strukturutypedef CVOR* ptrNaStek;

void NaVrhSteka(ptrNaStek & vrh,

int iNovi){

ptrNaStek novi;novi = new CVOR;novi->iPodatak=iNovi; novi->iPrethodni=vrh;vrh = novi;

}

int SaVrhaSteka(ptrNaStek &vrh){

ptrNaStek temp;temp= vrh;int x=vrh->iPodatak;vrh=vrh->iPrethodni;delete temp;return x;

}

Glavni program bi mogao da izgleda ovako:#include <iostream>#include "Stek1.h"

using namespace std;

intmain(void){

91

Page 92: UVOD U C++ I DODATAK ZA C++11

ptrNaStek vrh=NULL;

int n;cout<<"Koliko podataka stavljate na stek->";cin>>n;for(int i=0; i<n; i++){

cout<<"Unesi novi broj->";int iNoviBroj; cin>> iNoviBroj;NaVrhSteka(vrh,iNoviBroj);

}

for(int i=0; i<n; i++){cout<<SaVrhaSteka(vrh);}

system("PAUSE");return EXIT_SUCCESS;}

Ukoliko imate problema sa NULL pokazivačem, možda je lakše zamisliti da se radi o nultoj adresi, tj ako ne pokazujemo ni na jednu memorijsku lokaciju, poželjno je pokazivaču dodeliti NULL, ili nullptr. Ako postavite NULL u pokazivačku promjenljivu, možete ovu činjenicu iskoristiti da ispitate jeste li došli do kraja liste. Za vežbu potpuno isti primer uradite pomoću STL steka, i Vašeg kojeg ste naučili kako da napravite. Zatim upišite veliki broj podataka, mogli bi učitati neke znakove iz datoteke, te uporedite ove dve implementacije.Umesto običnih pokazivača, mogli bi koristiti i deljenje pokazivače, na taj način možete neke stvari da odradite malo brže, ako recimo imamo deo strukture koji nam više ne treba, ukoliko je deklarisan kao deljeni pokazivač, možemo brže da se otarasimo ne potrebnih delova strukture.

Za razliku od stekova moguće je koristiti i redove(queue), koji za razliku od stekova, podatke prikazuju onako kako su i uneseni. Drugim rečima, prvi podatak koji je unesen biće i prvi prikazan. Napravimo sad red da vidimo kako to funkcioniše. Uzgred pogledajte šta možete naći na Internetu o LIFO i FIFO pojmovima.

Potrebno je uneti pozitivni broj, koji ima unapred nepoznat broj cifara.

PRIMER:Kreirajmo dve datoteke Red.h, sledećeg sadržaja:

//Povezana struktura se sastoji od cife i pokazivacatypedef struct cvor{

int iBroj;struct cvor* sledeci;

} CVOR;

//Deklarisemo tip pokazivca na strukruretypedef CVOR* ptrNaRed;

//Dodajemo nove cifre u brojvoid

92

Page 93: UVOD U C++ I DODATAK ZA C++11

UbaciCifruURed(int iN, ptrNaRed& ptrPrvi, ptrNaRed& ptrPoslednji)

{//Rezervisi prostor za novu cifru

ptrNaRed novaCifra = new CVOR;

//Popuni odgovarajuce podatkenovaCifra->iBroj=iN;novaCifra->sledeci=NULL;

//Pokazi na odgovarajucu cifru(ptrPrvi==NULL)?ptrPrvi=novaCifra:ptrPoslednji->sledeci=novaCifra;

//ptrPoslednji pokazuje na novu cifruptrPoslednji=novaCifra;

}//Uzimamo cifre iz broja

voidNovaCifra(ptrNaRed& ptrPrvi,int& iCifra){

//Odrovarajuci pokazivacptrNaRed SledecaCifra;

//Uzimamo cifruiCifra= ptrPrvi->iBroj;

//Pokazivaci SledecaCifra i ptrPrvi pokazuju//na istu adresu

SledecaCifra=ptrPrvi;

//Prebaci ptrPrvi na sledecu lokaciju u reduptrPrvi=ptrPrvi->sledeci;

//Obrisi ne potrebnu vrednostdelete SledecaCifra;

}

Glavni program:#include <iostream>#include "Red.h"

using namespace std;

intmain(void){

93

Page 94: UVOD U C++ I DODATAK ZA C++11

ptrNaRed ptrPrvi=NULL, ptrPoslednji;

cout<<"Koliko cifara ima broj->"; int iUkupnoCifara; cin>>iUkupnoCifara;

for(int i= 0 ; i< iUkupnoCifara; i++){

cout<<"Unesi sledecu cifru->"; int iNovaCifra; cin>>iNovaCifra;UbaciCifruURed(iNovaCifra, ptrPrvi, ptrPoslednji);

}

for(int i=0; i<iUkupnoCifara; i++){int iNovaCifra;NovaCifra(ptrPrvi,iNovaCifra);cout<<iNovaCifra;}

system("PAUSE");return EXIT_SUCCESS;}

Moguće je napravi program koji ne bi zahtevao podatak koliko imamo cifara u našem broju. Ako Vam je dosadno, ili ukoliko zaista volite da programirate, eto ideje koju možete pretočiti u progam.Kao ilustracija strukture reda, može da pomogne sledeće grafika.

Da li ste čuli za palindrom? Palindromi se čitaju isto od početka ili od kraja. Primeri palindroma su: madam, kajak, ili Ana voli Milovana. Činjenica je da A nije isto kao i a kao karakter, želite li da unapredite program možete kreirati primer koji neće razlikovati mala i velika slova, a možete uvesti i pojam pravi palindrom, koji će napraviti razliku između malog i velikog slova.Za ovaj primer ćemo upotrebiti stek i red, iako ne savršeno rešenje, može poslužiti kao šlagvort za sledeću dinamičku strukturu.

94

Page 95: UVOD U C++ I DODATAK ZA C++11

PRIMER:#include <iostream>#include <stack>#include <queue>

using namespace std;

intmain(void){

printf("Program razlikuje velika i mala slova!!!\n");stack <char> StekKaraktera;queue <char> RedKaraktera;

printf("Unosite red teksta koji se zavrsava '.'\n");printf("Unesi te red teksta->");char cSledeciZnak;

while((cSledeciZnak=getchar())!='.'){

StekKaraktera.push(cSledeciZnak);RedKaraktera.push(cSledeciZnak);

}

bool bJestePalindrom=true;while(!StekKaraktera.empty()){

char cSteka= StekKaraktera.top(); char cReda = RedKaraktera.front();if(cSteka!=cReda){ bJestePalindrom=false; break;}StekKaraktera.pop();RedKaraktera.pop();

}

if(bJestePalindrom) printf("Jest palindrom!!!");else printf("Nije palindrom!!!");

system("PAUSE");return EXIT_SUCCESS;

}

Prethodni zadatak je ilustrovao najočigledniju razliku između reda i steka. Primedba koju imamo na rešenje prethodnog problema, na gore ilustrovani način, je nepotrebno čuvanje istih podataka više puta. Da bi rešili

95

Page 96: UVOD U C++ I DODATAK ZA C++11

ovaj primer, možemo koristiti dvostruko povezane liste, koje se sastoje od još jednog pokazivača. Na taj način u listi možemo da se krećemo napred ili unazad.Analizirajte sledeći program, koji naizmenično dodaje brojeve sa leva ili desna. Nakon toga formirana lista se ispisuje sa leva i desna.

Potrebno je kreirati dve datoteke:DvostrukoPovezanaLista.h

PRIMER:#include <iostream>

using namespace std;

//Struktura dvostruko povezane listetypedef struct cvor{

int iBroj;struct cvor * NaLevo;struct cvor * NaDesno;

} CVOR;

//Deklaracija pokazivaca na cvortypedef CVOR* ptrNaCvor;

void ZapocniListu(ptrNaCvor& ptrS_Leva,

ptrNaCvor& ptrS_Desna){

ptrNaCvor novi;novi = new cvor;novi->iBroj=1;novi->NaDesno=NULL; novi->NaLevo=NULL;ptrS_Leva=ptrS_Desna= novi;

}

void DodajS_Leva( int i, ptrNaCvor& ptrS_Leva)

{ ptrNaCvor novi;

novi = new cvor;novi->iBroj=i;novi->NaLevo=NULL;novi->NaDesno=ptrS_Leva;ptrS_Leva->NaLevo=novi;ptrS_Leva=novi;

96

Page 97: UVOD U C++ I DODATAK ZA C++11

}

void DodajS_Desna(int i, ptrNaCvor& ptrS_Desna)

{ ptrNaCvor novi;

novi = new cvor;novi->iBroj=i;novi->NaDesno=NULL;novi->NaLevo=ptrS_Desna;ptrS_Desna->NaDesno=novi;ptrS_Desna=novi;

}

void IspisiS_Leva(ptrNaCvor& ptrS_Leva){

ptrNaCvor temp;temp=ptrS_Leva;cout<<"Ispis sa Leva"<<endl;do{cout<< temp->iBroj;temp=temp->NaDesno;}while( temp!=NULL);cout<<endl;

}

void IspisiS_Desna(ptrNaCvor& ptrS_Desna){

ptrNaCvor temp;temp=ptrS_Desna;cout<<"Ispis sa Desna"<<endl;do{cout<< temp->iBroj;temp=temp->NaLevo;}while( temp!=NULL);cout<<endl;

}

I datoteku glavnog programa:#include <iostream>#include "DvostrukoPovezanaLista.h"

97

Page 98: UVOD U C++ I DODATAK ZA C++11

using namespace std;

intmain(void){

//Potrebna su dva pokazivaca na praznoptrNaCvor ptrS_Leva =NULL,

ptrS_Desna=NULL;

//Napravimo listu naizmenicno dodajuci//elemente sa leva i desna

ZapocniListu(ptrS_Leva, ptrS_Desna);

cout<<"Unesi neki celi broj veci od 1->"; int iN;cin>>iN;for(int i= 2; i<=iN; ++i){(i%2==0)? DodajS_Leva( i, ptrS_Leva):DodajS_Desna(i,ptrS_Desna);}

//Kao argument uzimamo pokazivac ptrS_Leva IspisiS_Leva(ptrS_Leva);

//Kao argument uzimamo pokazivac ptrS_Desna IspisiS_Desna(ptrS_Desna);

system("PAUSE");return EXIT_SUCCESS;}

Videli smo neke od struktura kao što su stek, red ili dvostruko povezana lista. Problem koji je evidentan, za ove strukture, je problem pretrage. Da bi neki podatak našli u listi, moramo se kretati od početka do traženog elementa, pa do, u najlošijem slučaju, kad traženi element ne postoji u dinamičkoj strukturi. Ovaj problem donekle rešavaju sortirane strukture, te ukoliko dođemo do elementa koji je veći od traženog, a na drugom kraju strukture su svi elementi koji su veći po vrednosti od traženog broja, možemo da tvrdimo da taj broj ne postoji u strukturi. Za većinu problema, ukoliko je potrebno umetati nove elemente, liste obično funkcionišu brže od nizova.Za vežbu kreirajte vlastitu listu i listu iz STL biblioteke, uporedite koja je brža za umetanja na kraj i početak, umetanja negde između početka i kraja, kao i ispis.

Da bi kreirali određenu vizuelizaciju može da posluži i sledeći prikaz.

98

Page 99: UVOD U C++ I DODATAK ZA C++11

Ali da se vratimo problemu pretrage, koji smo malo pre spomenuli. Binarno drvo razrešava probleme pretrage. Za vežbu pokušajte da kreirate strukturu binarnog drveta, ukoliko budete imali probleme, rešenje možete potražiti na nekom od mnogobrojnih foruma ili nekom od sajtova koji se bave ovom problematikom.Načinimo malu digresiju, koja je nadam se prikladna u ovome momentu. Razmislite o binarnoj pretrazi niza, i sekvencijalnoj. Prvi put kad sam praktično testirao, razliku brzina sekvencijalne i binarne pretrage bio sam zaista začuđen. Za primer možete da pokušate da pogodite broj iz minint do maxint intervala, primenom sekvencijalnog algoritma, idući od minint do maxint, ili primenom polovljanja intervala. Dobro razmislite, koja je razlika u ovom pitanju. STL nam omogućava da upotrebimo hip, koji je interesantna zamena za neke primere koji od nas zahtevaju upotrebu strukture binarnog drveta. Grafička reprezentacija drveta.Recimo da postoji veliki broj modifikacija ove strukture, a ona u svom izvornom obliku se retko koristi.

99

Page 100: UVOD U C++ I DODATAK ZA C++11

1 0 . C + + 11

Kad govorimo o standardizovanom proizvodu, to bi značilo da možemo napisati program u bilo kojem programu, zatim ga iskopirati, i prebaciti u bili koje radno okruženje, a kao rezultat bi dobili program koji radi, ukoliko je radio i u prvom radnom okruženju. Ovo bi umnogome olakšalo pisanje softvera, jer u tom slučaju možete da razvijate aplikacije nezavisno od proizvođača. Postoje i još neke prednosti, ali mi sada nećemo gubiti vreme na objašnjavanje prednosti standardizacije, i njene mane. Nedavno je usvojen novi standard C++ 11, koji je doneo neke promene. Ali odmah da napomenemo, kod koji ste pisali na nekom od ranijih važećih standarda, mislim da ih je bilo bar dva 98 i 03, može da se prevede i pomoću novijih radnih okruženja, koja delomično ili potpuno podržavaju ovaj standard. Možete da na sledećoj adresi pogledate kako neke od prevodioca implementiraju mogućnosi koje su uvedene: cpprocks.com/c11-compiler-support-shootout-visual-studio-gcc-clang-intel/

Iskreno govoreći neke od promena su važne, dok neke mane i dalje nisu popravljene ni u ovoj obnovljenoj verziji. Mi ćemo napomenuti samo neke od promena. Kao što ste videli nisam pisao o objektnom programiranju, niti o programiranju koje koristi grafički interfejs. To ostavljam za neke druge knjige.

No, da ne duljimo, vratimo se na promene:▪ Naredba for za opseg.▪ Ključne reč auto.▪ Ključna reč decltype.▪ Ključna reč nullptr.▪ Nabrojive klase.▪ Sirovi literali.▪ Lambda izrazi.▪ Pametni pokazivači.▪ Poravnavanja.▪ Atributi.▪ Noexcept.▪ Operatori za eksplicitnu konverziju.▪ Inicijalizacione liste.▪ Inlajn imenski prostor.▪ Rvrednoste reference i pomeri semantika.▪ Static_assert.▪ Alijasi templejta.▪ Promjenljivi tamplate.▪ Sintaksa sufiksnih povratnih tipova.▪ Weak_ptr.

Razmotrimo sad ove promene, nadam se da ćete usvojiti neke od gore navedenih pro[irenja u Vašim programima.

Naredba for za opseg

Ovaj oblik naredbe for, su kreirali da bi olakšali rad sa kontejnerima podataka. Drugim rečima, ukoliko radite sa nizom, nekom komponentom iz STL-a, možete koristiti ovu naredbu.

100

Page 101: UVOD U C++ I DODATAK ZA C++11

Uvedena je pod uticajem nekih drugih jezika. Kao što vidite C++ ne utiče samo na druge jezike, nego i drugi jezici izvrše uticaj na C++.Navedimo sad dva oblika: uz referencu i po vrednosti.Uz referencufor( tipPromjenljive& Promjenljiva:Kontejner)

naredba;

Ili pomoću vrednosti:for(tipPromjenljive Promjenljiva:Kontejner)

Naredba;

Navedimo konkretne primere za niz od 8 elemenata.int iNiz[8];for(int& iIndeks : iNiz) i=0;

for(int iIndeks: iNiz) cout<<iIndeks<<endl;Nije spektakularno ali u nekim situacijama može biti korisno.

Hajde da vidimo zašto je uvedena ključna reč auto

Kada koristite neku promjenljivu, koja treba u zavisnosti od konteksta, da odredi vrstu promjenljive. Ako recimo pri inicijalizaciji dodelite neku konstantu znakovnog tipa, naša promjenljiva će biti char, a ukoliko dodelite neki celi broj, promjenljiva će biti celobrojna.auto aPromjenljiva1= ‘c’;auto aPromjenljiva2= 13.31;auto aPromjenljiva3= 8;Napomenimo da određivanje tipa može da zauzme par ciklusa, tako da ukoliko ste sigurni koji tip promjenljiva mora da primi, nemjte koristiti auto oznaku.auto FilePath = L”C:\\NekiFolder\\NekaDatotek.txt”U ovom slučaju znate da imate posla sa wchar_t tipom stringa, na taj način gubite malo procesorskih ciklusa na pretvaranje u određeni tip.

Sledeća ključna reč decltype

Ako želite da proverite kojeg je tipa promjenljiva, možete upotrebiti decltype. U nekim situacijama ova naredba može biti korisna. Recimo da se nalazimo u situaciji da imamo char ili wchar_t karaktere, a možemo da proverimo kojeg je tipa ova promjenljiva, i u zavisnosti od tog tipa primenimo adekvatnu funkciju.decltype(cZnak);Ako želite možete i deklarisati proizvoljnu promjenljivu da bude istog tipa kao i neka druga prmjenljiva.

Ključna reč nullptr

Ukoliko želimo da navedemo da pokazivač ne pokazuje na neku memorijsku lokaciju možemo koristiti NULL ili 0. Uz ove mogućnosti, danas možete koristiti i nullptr.

101

Page 102: UVOD U C++ I DODATAK ZA C++11

Nabrojive klase

Ako je potrebno da tip poprima neke vrednosti kao što su: pon, uto, sre, cet, pet, sub, ned. Postoji opcija da koristite i nabrojive klase:enum class Dan{ Ponedeljak , Utorak , Sreda , Cetvrtak , Petak , Subota, Nedelja}.Dan nekiDan = Dan::Ponedeljak;

Sirovi literali

Do sad smo se sretali sa char i wchat_t znakovima, a da najavim, da ako budete radili sa nekim windows.h datotekama, siguran sam da ćete upoznati i ostale karaktere, tj stringove.char stringPoruka[]=R”(Primer nekog “kompleksnog” stringa \napomena može sad i ovako)”;Sirovi literali kreiraju stringove u kojima nema specijalnih karaktera, tj specijalni karakteri se tretiraju kao i ostali znakovi, bez nekog posebnog značenja.Podsetimo se, da bi naveli putanju do određene datoteke moramo navesti i ‘\’, no kako ovaj karakter ima posebni tretnan on se mora dva puta pisati ‘\\’, često se dešava da se koristi u Windows okruženju.Daleko je pogodnije upotrebiti sirovi literal u takvoj situaciji.

Pametni pokazivači

Pomoću pametnih pokazivača, omogućava se praćenje svih adresiranja neke komponente u dvostrukoj listi, te ukoliko više nemamo referenciranja na ovaj deo liste možemo jednim potezom izbrisati sve nepotrebne komponente.Sintaksa bi bila sledeća:shared_ptr<TipPokazivaca> ptrPokazivacNaNesto;Ponekad ova naredba može biti od velike koristi kod dinamičkih struktura. Jer ako se neki čvor više ne koristi, a na ostale elemente liste ništa ne pokazuje, možemo obrisati i te preostale repove.

Lambda izrazi

U C++, lambda izrazi su kao anonimne funkcije koje održavaju stanje i koje mogu pristupati varijablama u odgovarajućem opsegu.

Neki drugi programski jezici su podržavali mogućnost bezimenih funkcija, koje imaju telo, ali nemaju ime. Sledeći dio koda koristi STL objekat <vector>, što predstavlja niz.

...

#include <vector>

...

vector<int> v;

...

int iBrojacParnih=0;for_each(v.begin(), v.end(), [&iBrojacParnih](int i) if( i % 2 ==0) iBrojacParnih++;

102

Page 103: UVOD U C++ I DODATAK ZA C++11

Alignement

Povremeno, prilikom pisanja koda koji manipuliše sirovom memorijom, moramo specificirati poželjno poravnjanje. Navedimo primer:alignas(double) unsigned char [1024];alignas(16) char[100];Prvi primer predstavlja niz karaktera, poravnatih na odgovarajući način za double tip podatka.Drugi primer poravnanje 16 bajtnog prema granici.Pomenimo da postoji i alignof operator, kji će vratiti poravnanje svojih argumenata, a koji moraju biti neki tipovi.Kao ilustraciju navedimo constexpr int n=alignof(int);

Attributes

Atributi su pokušaj da se prevaziđe nered koji kreiraju proizvođači sa svojim spečnim naredbama kao što su:__attribute__, __declspec, i #pragma.Atributi koje propagira C++11 se razlikuju od postojeće sintakse tako što se mogu primeniti u svim situacijama. Navedimo primervoid f[[ noreturn]](){

throw “error”; }U predhodnom primeru f() nikad neće vratiti rezultat pomoću returna, dok throw je prihvatljivo. Atributi se moraju ubaciti u dvostruke zagrade.

noexcept prevencija propagacije izuzetaka

Ako funkcija ne može da izazove izuzetak ili program nije pisan da obrađuje izuzetke koji su kreirani pomoću funkcije, tad funkciju možemo da deklarišemo kao noexcept funkciju.Navedimo primer:

extern “C” double sqrt(double) noexcept

Na ovaj način funkcija nikada neće kreirati izuzetak „throw“, iako bi uobičajeno mišljenje bilo da se reč prevede kao baciti. Moguće je kreirati i uslovno noexcept funkciju koja neće kreirati izuzetke ako je u pitanju templejt.Ako funkcija koja je deklarisana kao noexcept pokuša da kreira izuzetak, program se terminira, tako što se načini poziv terminate().

Operatori za eksplicitnu konverziju

Standard 98 je podražvao eksplicitne i implicitne konstruktore, konverzija deklarisana pomoću explicit konstruktora može biti upotrebljen samo za eksplicitnu upotrebu, dok ostali konstruktori mogu biti upotrebljeni za implicitnu upotrebu.Primer:struct Struktura{ Struktura(int);} Struktura S(iArgument);Struktura S1=1;void Primer(S);Primer(1);

103

Page 104: UVOD U C++ I DODATAK ZA C++11

Dali smo nekoliko primera običnih konstruktora, inače ovo je pojam koji se češće koristi u objektnom programiranju, ali klase predstavljaju evoluirane strukture, sa tehničke tačke gledišta.struct Struktura{ explicit Struktura(int);};Struktura S(1);

ostali načini deklarisanja, kao kod implicitne bi generisali grške, iako to ponekad ne bi očekivali.

Inače konstruktor nije jedini mehanizam za definisanje konverzije. Ako ne možemo da modifikujemo klasu, možemo da deklarišemo konverzioni operator iz druge klase. Ovaj dio zalazi detaljnije u objektno orjentisano programiranje tako da nećemo detaljisati po tome pitanju.Na žalost ne postoje eksplicitni konverzioni operatori, C++11 to implementira tako što dozvoljava konverziju operatora koji su eksplicitni.

Inicijalizacione liste

Inicijalizacione liste nisu samo za nizove, a ovo je odavno trebalo uvesti jer se tako nešto što je primjenljivo u jednoj situaciji može primeniti i u sličnim situacijama. Primer:vector<double> v={1, 4, 7, 8, 12.3, 3.4}Navedimo da ukoliko želite kreirati vektor vektora ne morate više odmicati „>>“, kao nekada i pisati nasledeći način“> >“, ovo je zbog toga što se operator koji smo koristili sa cin>>, pisao na ranije objašnjeni način,tako da se prilikom prevođenja u tokene morao odvojiti ovaj zapis.

Inlajn imenski prostor

Prilikom rada na programu, pišu se različite verzije istih biblioteka, drugim rečima može se desiti da neki imenski prostor ima raniju i noviju verziju, a problem može da iskrsne zbog toga što nam nekad trebaju stare verzije, a nekada nove verzije imenskog prostora. Inače imenski prostori se mogu koristiti za objedinjavanje više funkcija u okviru jedne grupe, a sad možemo imati i više verzija istog imenskog prostora.Primer:inline namespace V99{ }namespace V98{ }

Nakon što ova dva imenska prostora kreiramo u datotekama V99.h i V98.h, možemo ih objediniti, i kasnije upotrebiti iz novog imenskog prostora.

namespace Zajedno{#include “V99.h”#include “V98.h”}

Da bi upotrebili novi imenski prostor potrbno je, kao što je to uobičajeno navesti direktivu prevodiocu sa :#include Zajedno.h, naravno imenski prostor Zajedno je deklarisan u Zajedno.h heder fajlu, kao što je to i uobičajeno.Ako želimo da specificiramo kojoj verziji se pristupa potrebno je uključiti Zajedno imenski prostor, te navesti kojoj verziji funkcije pristupamo, to tehnički izvodimo na sledeći način:

using namespace Zajedno;...

V98::NekaFunkcija(iArgument);V99::NekaFunkcija(iArgument);

104

Page 105: UVOD U C++ I DODATAK ZA C++11

Rvalue reference i pomjerajuću semantikuRazlika između lvrednosti i rvrednosti je tašto lvrednosti mogu biti sa lijeve, dok rvrednsti sa desne strane izraza. Problem se javlja kod non-const rvrednosi. Ovo je problem menjanja vrednosti privremenih vrednosti koje se unište pre nego što se njihove nove vrednosti uvedu.Primer:void uvecaj(int& a){ ++a;}int i=0;uvecaj(i); uvecaj(0);

Prvi poziv funkcije je u redu, dok drugi nije odgovarajući. Ako ne vidite zašto, recimo da 0 nije lvrednost. Za pomjerajuću semantiku, uzmimo naprimer dva stringa s1 i s2. Ako želimo da izvršimo kopiranja, a znamo da stringovi mogu imati dosta elemenata, nećemo vršiti celokupna kopiranja nego uzimamo reprezentacij izvora i zamenimo sa efikasnom operacijski jeftinom radnjom.U slučaju menjanja dva stringas1 i s2, kopija ne bi vršili kopiranja stringa s2, nego bi prepustili da s1 tretira te karaktere kao njegove. To možemo da uradimo pomoću move konstruktora, a prikazat ćemo na primeru swap funkcije koja menja poziciju dva elementa niza. Ako imamo veliki broj komponenata, ova operacija može biti zahtevna, tj veliki broj komponenata se pomera i na taj način gubimo dosta vremena.

template< class T> swap( T& a, T&b){T tmp(a);a=b;b=tmp;}se može zameniti na sledeći način.

template< class T> swap( T& a, T&b){T tmp= move(a);a=move(b);b=move(tmp);}Ova move nam označava da se vrednost može tretirati kao rvrednost.

static_assertStatički( u vreme kompajliranja) deklaracija se sastoji od konstantnog izraza i string literala.

static_assert( izraz, string);Kompajler procenjuje izraz i piše string kao eror poruku ako je izraz pogrešan.

static_assert( sizeof(long) >= 8, „ Potreban 64 binti kod generator za ovaj biblioteku“);

template aliasRanije su bili poznati pod nazivom template typedef.

suffix return type syntaxRazmotrimo

template< class T, class U>returnTipe mul(T x, U y){ return x*y;}

rešenje se nameće gotovo samostalno:105

Page 106: UVOD U C++ I DODATAK ZA C++11

template< class T, class U>auto mul(T x, U y)->decltype(x*y){ return x*y;}Drugim rečima tip će biti kasnije određen.

weak_ptr Slabi pokazivači se često objašnjavaju kao pokazivači na nešto čemu moramo da pristupimo samo ukoliko postoji, mogu biti obrisani od strane nečega, i moraju imati svoje destruktore pozvane nakon što se poslednji put pozovu.

Jedan od interesantnih noviteta, koji se može upotrebiti u objektnom progrmiranju, ne to ne znači da ih nećete moći upotrebljavati kad Vam zatrebaju, su promjenljivi templejti. Oni nam omogućavaju da u neku ruku kombinujemo templejte i funkcije sa nepoznatim brojem argumenata. Na taj način kreiramo jednu od moćnijih alatki, koja se na ovaj način koristi daleko kompaktnije, zato što se obično koristi za objektno programiranje nećemo detaljisati o tome ovde. Primer sintakse:

template<typename... Args>

bool NekaFunkcija( const wchar_t wZnak, Args& ...args)

Izvorni naziv Variadic template.

Pomoću templejta krerate objekte koji ne ovise od tipa podatka, dok pomoću promjenljivog broja argumenata radimo nešto slično što imamo u funkcijama sa promjenljivim brojem argumena.

NEKOLIKO PRIMERA U STILU C++ 11

Primer koji koristi tuple, ovaj pojam omogućavaju grupisanje većeg broja podataka u okviru jednog dela. Uveden je pod uticajem nekih drugih jezika.

PRIMER:#include <iostream>#include <tuple>#include <vector>#include <string>#include <algorithm>

using namespace std;

intmain(void){

vector< tuple<int,string,double>> v;

v.emplace_back( 1019, "Jir 1", 13.2309);v.emplace_back( 1007, "Mak 2", 13.1111);v.emplace_back( 1001, "Mik 1", 12.2309);v.emplace_back( 1018, "Jom 3", 11.4507);v.emplace_back( 1011, "Mik 2", 19.2389);

106

Page 107: UVOD U C++ I DODATAK ZA C++11

sort(v.begin(), v.end());

cout<<"Kljuc , Sifra , Vrednost"<<endl;for( auto p:v){

cout<<get<0>(p)<<" " <<get<1>(p)<<" " <<get<2>(p)<<endl;

}

system(“PAUSE”);

return EXIT_SUCCESS;

}

REZULTAT:Kljuc, Sifra, ,Vrednost1001, "Mik 1", 12.23091007, "Mak 2", 13.11111011, "Mik 2", 19.23891018, "Jom 3", 11.45071019, "Jir 1", 13.2309

Sledeći primer ilustruje upotrebu stringova u kombinaciji sa lambda funkcijom.

PRIMER:#include <iostream>#include <vector>#include <algortihm>#include <cctype>

using namespace std;

intmain(void){

char cString[]="Primer nekog StRiNgA";

auto VelikihSlova=0LL;for_each( cString, s+sizeof(s), [&VelikihSlova](char c){

if(isupper(c))VelikihSlova++;

});

cout<<"Velikih slova ima="<<VelikihSlova<<endl;

}

REZULTAT:Velikih slova ima=5

107

Page 108: UVOD U C++ I DODATAK ZA C++11

Analizirajte sledeći primer.

PRIMER:#include <iostream>

#define DIMENZIJA 10

using namespace std;

intmain(void){

//Deklarisemo prostor za elemente nizaint iNiz[DIMENZIJA];

//Unosimo elemente niza, modifikujemo ihfor(int& n: iNiz){

cout<<"Unesite element->"; cin>>n; system("CLS");}

cout<<"Elementi niza su"<<endl;//Prikaz elemenata niza, ne modifikujemo ihfor(int n: iNiz)

cout<< n <<endl;

system("PAUSE");return EXIT_SUCCESS;}

U predhodnom primeru smo videli kako možemo unositi i prikazivati elemente niza koristeći for za opsege, a sada ćemo prikazati kako se lambda funkcija može koristiti u kombinaciji sa nizovima.

PRIMER:#include <iostream>#include <vector>#include <algorithm>

using namespace std;

intmain(void){

//Trazimo dimenziju nizaint iN;vector <int> Niz;

//Unosimo element nizfor(int i=0; i< iN; ++i)

108

Page 109: UVOD U C++ I DODATAK ZA C++11

{ cout<<" Sledeci elemnt->"; int iBroj; cin>> iBroj;Niz.push_back(iBroj);system("CLS");

}

for_each(Niz.begin(), Niz.end(),

[&PrikazBrojeva] (int n) {

cout<<n<<" "; if(n%3==0) cout<<"Ostatak 0"<<endl; else if(n%3==1) cout<<"Ostatak 1"<<endl; else cout<<"Ostatak 2"<<endl;

} );

system("PAUSE");return EXIT_SUCCESS;}

Sledeći primer omogućava korisniku da unese neki broj u granicama od 0 do 7, zatim program ispisuje koja je planeta u pitanju. Ukoliko unesete nula poruka je Sunce.Nemojte da zaboravite Pluton više nije planeta, sem ako se drugačije ne dogovore.

PRIMER:#include <iostream>#include <string>

#define DIMENZIJA 7

using namespace std;

enum class Planete_I_Sunce { Sunce, Merkur, Venera, Zemlja, Mars, Saturn, Uran, Neptun};

string Imena_Planeta[DIMENZIJA]={

“Sunce”, “Merkur”, “Venera”,

“Zemlja”, “Mars”,

“Saturn”,“Uran”,“Neptun”};

109

Page 110: UVOD U C++ I DODATAK ZA C++11

intmain(void){

cout<<“Izaberite redni broj planete ili Sunca->“int iOdabir;cin>>iOdabir;system("CLS");

if(( iOdabir<0)||(iOdabir> DIMENZIJA)){cout<<“Greska broj van opsega!!!“;system("PAUSE");return EXIT_FAILURE;}

switch( iOdabir){case 0:

Planete_I_Sunce planetaOdabrana = Planete_I_Sunce::Sunce;break;

case 1:Planete_I_Sunce planetaOdabrana = Planete_I_Sunce::Merkur;break;

case 2:Planete_I_Sunce planetaOdabrana = Planete_I_Sunce::Venera;break;

case 3:Planete_I_Sunce planetaOdabrana = Planete_I_Sunce::Zemlja;break;

case 4:Planete_I_Sunce planetaOdabrana = Planete_I_Sunce::Mars;break;

case 5:Planete_I_Sunce planetaOdabrana = Planete_I_Sunce::Saturn;break;

case 6:Planete_I_Sunce planetaOdabrana = Planete_I_Sunce::Uran;break;

case 7:Planete_I_Sunce planetaOdabrana = Planete_I_Sunce::Neptun;break;

default: exit(EXIT_FAILURE);}

cout<<“Na „ << iOdabir <<“ mestu, se nalazi „ << Imena_Planeta[iOdabir] <<endl;

110

Page 111: UVOD U C++ I DODATAK ZA C++11

system("PAUSE");return EXIT_SUCCESS;}

U prethodnom primeru smo proveravali da li je korisnik uneo broj iz opsega, u praksi bi morali koristiti izuzetke, jer na taj način kreiramo stabilnije aplikacije.

Možete koristiti i assert biblioteku, ali ona je ne dovoljna za profesionalnu upotrebu, tako da ukoliko se želite programiranjem baviti nakon što izučite ovu knjigu, preporučujem da se prihvatite OOP-a, ili kako bi se to popularno reklo objektno orjentisanog progamiranja. Ova je knjiga pisana da bude uvod u tu oblast programiranja, a nemojte ni da je preskočite jer je postala ne zaobilazna u repertoaru svakog profesionalnog programera, a bogami i većine hobi programera.

Prethodni primer proširite tako da omogućite čuvanje podataka o:▪ Prosečnoj, najvećoj i najmanjoj udaljenosti od sunca.▪ Težini planete.▪ Koliko traje godina.▪ Broj meseca.

Preporuka je da pokušate da upotrebite strukture ili tuples.

111

Page 112: UVOD U C++ I DODATAK ZA C++11

11 . U R A Đ E N I P R I M E R I

ZADATAK 1:Potrebno je napisati program za igricu „Nim“. Postoje različite varijacije ove igrice, a mi ćemo uraditi jednu od mogućih varijanti. Da ne dužimo, pređimo na pravila. Na početku imamo pet žetona, prvo igra čovek, a zatim računar. Jednim potezom možemo uzeti: 1, 2 ili 3 žetona. Izgubio je onaj igrač koji uzme zadnji žeton.

ANALIZA:Spomenimo da za drugog igrača postoji pobjednička strategija. Za vežbu nacrtajte, i analizirajte na drvetu partije koji su svi mogući ishodi. U suštini drugi igrač ima pobedničku strategiju, i poenta je pustiti da oponent odabere da on igra prvi, a pobednička strategija prvog igrača je da prepusti protivniku da odigra prvi, i samim tim zasigurno izgubi.

Pobednička strategija drugog igrača je sledeće:▪ Prvi igrač uzima 1 žeton, drugi igrač pokupi tri žetona, ostao je jedan žeton, te je prvi igrač

primoran da uzme poslednji žeton.( 1 + 3 + 1 = 5)▪ Ako prvi igrač izabere dva žetona, drugi igrač će odabrati dva tokena, tad je prvi igrač

ponovo primoran da uzme preostali žeton.( 2 + 2 + 1 = 5)▪ Postoji još samo jedna relevantna situacija. Prvi igrač izabira 3 žetona, drugi učesnik povlači

jedan žeton, nakon ovih poteza prvi igrač je ponovo prisiljen da uzme jedini ostali žeton.( 3 + 1 + 1 = 5)

KOD PROGRAMA:

#include <iostream>

using namespace std;

//Zaglavlje funkcijevoid PisiPravila(void);

int main(void){

//Prikazujemo pravila korisnikuPisiPravila();

//Igrac prvi bira koliko zetona uzimacout<<"Koliko zetona uzima prvi igrac->";int iKolikoZetona; cin>> iKolikoZetona;

//racunar reaguje na igracev odabirif((iKolikoZetona<1)||(iKolikoZetona>3)){

cout<<"Automatski gubite!!!"<<endl <<"Pokusavate da varate."<<endl;

system("PAUSE");112

Page 113: UVOD U C++ I DODATAK ZA C++11

return EXIT_SUCCESS;}else if( iKolikoZetona==1){

cout<<"Odabrali ste 1 zeton, kompjuter 3,"<<endl <<"ostao je jedan zeton!!!";}else if( iKolikoZetona==2){cout<<"Odabrali ste 2 zeton, kompjuter 2,"<<endl <<"ostao je jedan zeton!!!";}else if( iKolikoZetona==3){cout<<"Odabrali ste 3 zeton, kompjuter 1,"<<endl <<"ostao je jedan zeton!!!";}

cout<<"\n\nZao mi je, prisiljeni ste da uzmete poslednji zeton!!!"<<endl <<"Vi gubite!!!\n";

system("PAUSE");return EXIT_SUCCESS;

}

voidPisiPravila(void){

cout<<"IGRICA NIM"<<endl;for(int i=0; i<=30; cout<<"-", i++); cout<<endl;

cout<<"Imate pet zetona o,o,o,o,o"<<endl <<", Vi igrate prvi!"<<endl;

cout<<"Mozete uzeti 1, 2, ili 3 zetona."<<endl<<endl;}

TESTIRANJE:

Unesite vrednosti: 1, 2, i 3 za prvog igrača. Zatim pokušajte da unesete neke vrednosti van opsega: 8, -4 i slično. Ostaje samo da probate da unesete neke karaktere, ili realne brojeve.

Pokušajte da pronađete i neke druge vrijante ove igrice. Napišite programe za njih. Ne igrajte ovu igricu sa prijateljima, jer će Vas omrznuti, a sa neprijateljima jednom i bežite posle koliko Vas noge nose.

ZADATAK 2:113

Page 114: UVOD U C++ I DODATAK ZA C++11

Korisnik unosi otpore tri otpornika, koja se mogu vezati: tri otopornika serijski, tri otpornika paralelno, prvi otpornik u seriji sa dva paralelna otpornika, dva paralelna u seriji sa trećim otpornikom. Otpori mogu da prime neku long double veličinu kao vrednost.

ANALIZA:Korisnik unosi vrednosti za tri otpornika, neki long double broj. Nakon toga, biramo jednu od četiri moguće konfiguracije:▪ Ukoliko korisnik odabere konfiguraciju 1, imamo tri serijski vezana otpornika.▪ Ako izaberemo broj 2, tri otpornika će biti vezana paralelno.▪ Prilikom odabira broja 3, imamo strukturu, gde je prvi otpornik vezan za dva paralelno

vezana otpornika.▪ Za odabir broja 4, raspored otpornika je takav, da se prvo nalaze dva paralelno vezana

otpornika, a zatim dolazi treći, serijski veazan otpornik. Poželjno bi bilo, da samostalno skicirate ove kombinacije, a napredniji programeri, bi trebalol da pokušaju da pronađu koje bi mogle još kombinacije da se kreiraju.Prilikom razmatranja, govorimo o jednostavnom kolu, koje ima jedan izvor, i analiziramo je u smeru kretanja kazaljke na satu.

Rešenje se sastoji od glavnog programa(main.cpp), i heder fajla(Funkcije_I_Deklaracije.h).

KOD PROGRAMA:

main.cpp:

#include <iostream>#include "Funkcije_I_Deklaracije.h"

using namespace std;

intmain(void){cout<<PORUKA1<<endl;long double ldR1,

ldR2, ldR3;

cin>>ldR1>>ldR2>>ldR3;

cout<<PORUKA2<<endl;short int siOdabir;cin>>siOdabir;

if((siOdabir<1)||(siOdabir>4)){ system("CLS"); cout<<ERROR_1<<endl; system("PAUSE"); return EXIT_FAILURE;}else

114

Page 115: UVOD U C++ I DODATAK ZA C++11

{ PrikaziRezultat( ldR1, ldR2, ldR3, siOdabir);

}

system("PAUSE");return EXIT_SUCCESS;}

Funkcije_I_Deklaracije.h:

//Poruke smo izvojili kao makroe zbog //citljivosti programa.#define PORUKA1 "Unesite vrednosti tri otpora->"#define PORUKA2 "Unesite konfiguraciju: 1, 2, 3, ili 4->"#define ERROR_1 "Morate uneti jednu od cetiri vrednosti(1,2,3,4)"

//Cetiri funkcije//Serijska veza

void Konfiguracija1(double R1, double R2, double R3){ std::cout<<R1+R2+R3;}

//Paralelna vezavoid Konfiguracija2(double R1, double R2, double R3){ std::cout<<(R1*R2*R3)/(R2*R3+R1*R3+R1*R2);}

//serija R1 i paralelno R2 i R3void Konfiguracija3(double R1, double R2, double R3){ std::cout<<((double)R1+(R3*R2)/((double)(R3+R2)));}

//paralelno R1 i R2 u seriji sa R3void Konfiguracija4(double R1, double R2, double R3){ std::cout<< ((double)R3+(R1*R2)/((double)(R1+R2)));}

//Racunamo ekvivalentni otpor//na osnovu tri otpornosti i oznake za konfiguracijuvoidPrikaziRezultat( long double& R1,

long double& R2, long double& R3, short int& i)

{ switch(i) { case 1: Konfiguracija1(R1, R2, R3);

break; case 2: Konfiguracija2(R1, R2, R3);

break; case 3: Konfiguracija3(R1, R2, R3);

break; case 4: Konfiguracija4(R1, R2, R3);

break;}}TESTIRANJE:

115

Page 116: UVOD U C++ I DODATAK ZA C++11

Prilikom testiranja pokušajte da unesete sledeće otpore R1=1, R2=1, R3=1, kao i konfiguracije: 1, 2, 3, ili 4. Nakon ove grupe primera, pokušajte sa nekim realnim vrednostima: R1=0.13, R2=0.125, R3=2.126, kao i gore pomenutim konfiguracijama.

Razmislite o tome kako se otpornici mogu označiti sa četiri trake, šta mislite da li bi se ovaj primer mogao nadograditi, tako da bude primjenljiv u praksi.

Za vežbu možete uraditi i sledeći primer. Korisnik unosi neki otpor koji se može prikazati kao razlomak. Potrebno je pomoću dva otpora, koja su vezana paralelno, dobiti unesenu otpornost.

ZADATAK 3:Treba kreirati aplikaciju koja će reprezentovati usmeren graf, od n čvorova. Za čuvanje grafa, koristite matricu, kojoj ne znamo dimenziju, dok je korisnik ne unese. Zatim, nakon što smo postavili matricu povezanosti u grafu, potrebno je testirati, da li postoji put od početnog čvora do krajnjeg čvora, na način kako je to uneo korisnik. Napomenimo da se put može sastojati od m koraka, gde je m neki pozitivan celi broj, u okviru niza brojevi će predstavljati čvorove kroz koje se krećemo.Neke karakteristike posmatranog grafa:▪ Nije simetričan graf. Drugim rečima, ako postoji veza od čvora 3 do čvora 7, to ne znači da su

povezani i čvorovi 7 i 3. ▪ Moguće je da čvor bude povezan sam sa sobom, dok ukoliko nije, 2-2 ne može da se ostvari

kao put u jednom ciklusu.

ANALIZA:Graf predstavimo dinamičkom matricom dimenzije n*n, gde se čvorovi označavaju brojevima od 0 do n-1. Matrica je popunjena 1-cama ili 0-ma. Ukoliko postoji put od 2 do 3, to znači da je na poziciji MatricaPuta[2][3] postavljena 1-ca, dok ukoliko ne postoji veza od 3 do 2, to označavamo MatricaPuta[2][3]=0.Ako je čvor povezan sam sa sobom to označavamo MatricaPuta[5][5]=1, i u tom slučaju je moguće napraviti 5-5 vezu u jednome koraku.Nakon što unesemo matricu, prelazimo na ispitvianje puteva kroz istu. Korisnik unosi broj čvorova kroz koje prolazimo, a zatim ispitujemo da li naznačeni put postoji. Ukoliko put postoji pišemo odgovarajuću poruku, dok ukoliko ne postoji prikazujemo poruku da putanja ne postoji.

Program se sastoji iz dve datoteke:main.cpp i PomocnaDatoteka.h .

KOD PROGRAMA:

main.cpp

#include <iostream>#include "PomocnaDatoteka.h"

using namespace std;

intmain(void){

116

Page 117: UVOD U C++ I DODATAK ZA C++11

Matrica Graf;

cout<<PORUKA_1;int iDimenzijaG; cin>>iDimenzijaG;

system("CLS");

NapraviGraf( iDimenzijaG, Graf);PopuniGraf ( iDimenzijaG, Graf);

while(true){

cout<<PORUKA_2<<endl;char cIzbor;cin>>cIzbor;

if((cIzbor=='n')||(cIzbor=='N')){ exit(1);}

cout<<PORUKA_3;int iDimenzija; cin>>iDimenzija;int* iNiz= new int[iDimenzija];

UnesiNiz(iDimenzija, iNiz);

if(IspitajPut(iDimenzija, iNiz, iDimenzijaG, Graf))cout<<PUT_POSTOJI;

elsecout<<PUT_NEPOSTOJI;

}

system("PAUSE");return EXIT_SUCCESS;

}

PomocnaDatoteka.h:

#include <iostream>

using namespace std;

#define PORUKA_1 "Unesite dimenziju matrice->"#define PORUKA_2 "Da li zelite ispitujete put(d/n)->"#define PORUKA_3 "Unesite koliko tacaka put ima->"#define PORUKA_4 "Postoji li put(0/1)->"#define PORUKA_5 "Sledeci element puta->"

#define PUT_NEPOSTOJI "Put unesen u nizu je neostvariv u grafu"#define PUT_POSTOJI "Postoji put kroz graf"

typedef struct Matrica{

int **koren;int iDimenzija;

};

117

Page 118: UVOD U C++ I DODATAK ZA C++11

void NapraviGraf( int n, Matrica& mat)

{//Pravimo niz pokazivaca na redove matricemat.koren = new int*[n];//Dodajemo redovefor(int i=0; i<n; i++)

mat.koren[i]=new int[n];//Postavimo dimenziju matricemat.iDimenzija=n;

}

void PopuniGraf ( int n, Matrica& mat)

{for(int i=0; i<n; i++)

for(int j=0; j<n; j++){

cout<<PORUKA_4<<i<<" "<<j;cin>> mat.koren[i][j];cout<<endl;

}}

void UnesiNiz(int n, int mat[])

{for(int i=0; i<n; i++){

cout<<PORUKA_5; cin>>mat[i];

cout<<endl;}

}

bool IspitajPut(int iN, int iNiz[], int iG, Matrica& G ){

for(int i=1; i<iN; i++)if( G.koren[iNiz[i-1]][iNiz[i]]==0) return false;

return true;}

TESTIRANJE:

Unesite sledeći graf:

1,1,0,0,0

0,0,1,0,1

118

Page 119: UVOD U C++ I DODATAK ZA C++11

1,0,0,1,0

0,0,1,0,1

0,1,0,0,1

I puteve:

0,0,1,4 koji postoji

0,0,2 koji ne postoji ugrafu.

Pokušajte da unapredite program, tako da ispitujete koji je najkraći put od čvora A do čvora B, ukoliko postoji. Odrediti da li je moguće obići kompletan graf, od čvora A do čvora B, bez povrataka u čvorove, i sa povracima u čvorove.Ispitati koji od čvorova su putno povezani sa svim čvorovim.Prikazati koji su najkraći, od svih mogućih puteva, između dva čvora.Proširite program, tako da radi i za druge tipove grafova.

ZADATAK 4:Potrebno je napisati program, koji će izvršiti retrificiranje krive. Zadatak je izračunati dužinu krive u intervalu od a do b, za sledeće funkcije: ex, ln(x), i x.Zatim unosimo i korak tabelacije funkcija, u našem slučaju neki delta.

ANALIZA: Da bi izračunali dužinu krive, koristićemo metodu aproksimacije. Izračunamo vrednost funkcije u takčki f(x) i f(x+delta), funkciju aproksimiramo pomoću duži, u intervalu x, x+delta.Da bi izračunali udaljenost ove dve tačke, koristimo poznatu formulu za računanje udaljenosti dve tačke d= sqrt(pow(( xa-xb),2) +pow((ya-yb),2)).

KOD PROGRAMA:

Program se sastoji od dve datoteke: main.cpp i Funkcije.h

Kod main.cpp:

#include "Funkcije.h"

using namespace std;

intmain(void){

double dA, dB, dDelta;

if(UnesiParametre( dA, dB, dDelta)){TabelirajFunkciju( dA, dB, dDelta);}else{

cout<<ERROR_MESSAGE1;}

119

Page 120: UVOD U C++ I DODATAK ZA C++11

system("PAUSE");return EXIT_SUCCESS;

}

Kod Funksije.h:

#include <iostream>#include <cmath>

#define PORUKA_1 "Unesi tacku a->"#define PORUKA_2 "Unesi tacku b->"#define PORUKA_3 "Unesi korak(delta) ->"

#define ERROR_MESSAGE1 "Neodgovarajuci ulazni podaci!!!"

using namespace std;

//Ispitujemo da li su ulazni podaci odgovarajucibool Proveri( double& a, double& b, double& eps){ if((a<b)&&(eps>(a-b))) return true; else return false; }

boolUnesiParametre( double & a,

double & b,double & eps)

{

cout<<PORUKA_1<<endl; cin>> a;cout<<PORUKA_2<<endl; cin>>b;cout<<PORUKA_3<<endl; cin>>eps;return Proveri(a,b,eps);

}

void TabelirajFunkciju(double& a,

double& b, double& d)

{ system("CLS");

double dExp = 0.0, dLin = 0.0, dLn = 0.0;

double dx = a, dF = exp(a), dG = log(a);

for(double dX= a+d; dX <= b; dX+=d) {

120

Page 121: UVOD U C++ I DODATAK ZA C++11

dExp += sqrt( pow(d,2) + pow((dF-exp(dX)),2)); dLin += sqrt( 2.0*pow(d,2) ); dLn += sqrt( pow(d,2) + pow((dG-log(dX)),2));

dx=dX; dF=exp(dX); dG=log(dX);

} cout<<"Duzine luka funkcija" <<" od "<<a<<" do "<<b<<endl;

cout<<"Duzina eksponencijalne=" <<dExp <<endl <<"Duzina linearnie =" <<dLin <<endl <<"Duzina logaritamske =" <<dLn <<endl;}

TESTIRANJE:

Kao početnu tačku uzmite 1, a kao krajnju tačku intervala odaberite 2. Korak može biti 0.001.

Razmislite malo o programu, napišite program za različite funkcije i njihove inverzne funkcije. Testirajte primer za različite vrednosti.

ZADATAK 5:Potrebno je kreirati aplikaciju koja će ispitivati ponašanje funkcije x2+y2+x*y u okolini neke tačke. Tačku korisnik proizvoljno unosi.Ponašanje funkcije se analizira pomoću nizova: ▪ 1/n.▪ 1/n2.▪ i 1/sqrt(n).

Korisnik ima mogućnost da unese alfa, na osnovu čega računamo vrednost beta, koja se koristi da bi odredili ugao približavanja. Bitno je napomenuti da važi alfa + beta=1.

ANALIZA:Prvo ćemo od korisnika tražiti da unese tačku u kojoj želimo vršiti analizu ponašanja funkcije. Ne zaboravite da je tačka u dvo dimenzionom prostoru.Nakon toga tražimo da se unese alfa,vrednost beta se računa kao 1-alfa. Na ovaj način omogućavamo promenu ugla, pod kojim se približavamo tački koju ispitujemo.Koristimo nizove za približavanje tački po koordinatama, drugim rečima:▪ alfa* 1/i + beta*1/i.▪ alfa* 1/i2 + beta*1/i2

▪ alfa* 1/sqrt(i) + beta*1/sqrt(i).

Ukoliko preferirate izlaz u datoteku, možete rezultate ispisivati u fajl.Nemojte zaboraviti da unesete n, na osnovu kojeg znamo kad se zaustavljamo. Recimo samo da ćemo koristi funkcije koje ispituju da li je vrednost funkcije u tački konačna?

KOD PROGRAMA:121

Page 122: UVOD U C++ I DODATAK ZA C++11

Rešenje se sastoji iz dve datoteke main.cpp i Funkcije_I_Deklaracije.h.

Kod main.cpp:

#include <iostream>#include "Funkcije_I_Deklaracije.h"

using namespace std;

intmain(void){

double dX, dY;

cout<<PORUKA_1<<endl;cin>>dX>>dY;

double dAlfa,dBeta;

cout<<PORUKA_2<<endl;cin>> dAlfa;

dBeta= 1.0-dAlfa;double dZnakAlfa=1, dZnakBeta=1;cout<<PORUKA_3<<endl;cin>>dZnakAlfa>>dZnakBeta;

dAlfa=dZnakAlfa*dAlfa; dBeta=dZnakBeta*dBeta;

cout<<PORUKA_4<<endl;int iN; cin>> iN;

TabelirajFunkciju(dX, dY, dAlfa, dBeta, iN);

system("PAUSE");return EXIT_SUCCESS;

}

Kod Funkcije i deklaracije:

#include <iostream>#include <cmath>#include <iomanip>

#define PORUKA_1 "Koordinate tacke (x,y)->"#define PORUKA_2 "Unesite alfa , a<=1, b<=1, i a+b=1"#define PORUKA_3 "Unesite dva puta 1 ili -1"#define PORUKA_4 "Koliko tacaka niza ispitujemo"

#define FUNKCIJA(x, y)( (x)*(x) + (y)*(y) + (x)*(y))

122

Page 123: UVOD U C++ I DODATAK ZA C++11

void PisiZaglavlje( double x, double y,

double a, double b){

std::cout<< "U tacki (x,y)"<<std::endl << x<<std::endl

<< y<<std::endl << "Pod uglom koji odredjumo alfa + beta=1"<<std::endl << "alfa= "<<a<<" beta="<<b<<std::endl << "f(x,y)= x^2+y^2+x*y"<<std::endl;

for(int i= 0; i< 40; std::cout<<"=",i++);std::cout<<std::endl;

}

void TabelirajFunkciju(double X,double Y,

double a,double b, int n )

{

PisiZaglavlje(X,Y,a,b);

for(int i=1; i<= n; i++){ double dTackaX= X+ 1.0/double(i), dTackaY=Y+1.0/double(i); dTackaX= a*dTackaX; dTackaY=b*dTackaY;

double dTackaXX= X+ 1.0/double(i*i), dTackaYY=Y+1.0/double(i*i); dTackaXX= a*dTackaXX; dTackaYY=b*dTackaYY;

double dTackaXR= X+ 1.0/sqrt(double(i)), dTackaYR=Y+1.0/sqrt(double(i)); dTackaXR= a*dTackaXR; dTackaYR=b*dTackaYR;

//ponekad mogu biti od koristi i funkcije //isinf, isnan, isfinite std::cout<<FUNKCIJA(dTackaX,dTackaY)

<<" " << FUNKCIJA(dTackaXX, dTackaYY) <<" " << FUNKCIJA(dTackaXR, dTackaYR) <<std::endl;

}

TESTIRANJE:

Pokušajte sa različitim tačkama (2,3) i alfa=0.123. Kasnije možete da probate i neke druge funkcije. Nemojte da mislite da program neće kolabrirati ukoliko izračuna beskonačnu vrednost. Da bi ste se zaštitili od ovih problema unesite i neke promene, koristite funkcije isinf, isnan, isfinite. Ako želite da napravite ozbiljnu aplikaciju, pokušajte i neke druge nizove.

Razmislite kako bi se ova metoda mogla koristiti i u višedimanzionalnim situacijama.

123

Page 124: UVOD U C++ I DODATAK ZA C++11

ZADATAK 6:Čitajući knjigu „Strast za matematikom“ gospodina Kliforda A. Pikovera, našao sam na jednu interesantnu dilemu. Potrebno je ispitati da li se razlomak 1630 / 4542, može transformisati u neki drugi razlomak, tako da dve cifre iz brojnika zamene mesta sa dve cifre u nazivniku, ali tako da vrednost razlomka iznosi 1/3. ANALIZA:Problem ćemo rešiti tako što ćemo formirati dva niza, iGore i iDole za čuvanje cifara razlomaka. Zatim ćemo napisati sve moguće promene cifara razlomaka. Pošto imaju po četiri cifre, menjamo nultu i prvu sa nultom i prvom, zatim nultu i prvu menjamo sa nultom i drugom, ... , i na kraju ostaje da se treća i druga cifra zamene sa trećom i drugom cifrom.Gore opisani postupak nam omogućuju dve umetnute for naredbe, jedna sa i, a druga sa j promjenljivom. Nakon što smo zamenili cifre u razlomku, ostaje da izračunamo vrednost razlomka, i proverimo da li izračunata vrednost iznosi 1/3. KOD PROGRAMA:

#include <iostream>

using namespace std;

typedef struct{

int levi;int desni;

}Kombinacija;

intmain(void){

int iGore[4]={ 1, 6, 3, 0},iDole[4]={ 4, 5, 4, 2};

double iRazlomak= 1.0/3.0;Kombinacija K[]={ {0,1}, {0,2}, {0,3}, {1,0}, {1,2}, {1,3}, {2,0}, {2,1}, {2,3}, {3,0}, {3,1}, {3,2}};

for(int i=0; i<=11; i++)for(int j=0; j<=11; j++){int iGoreZ[4]; for(int k=0; k<=3; iGoreZ[k]=iGore[k++]);int iDoleZ[4]; for(int k=0; k<=3; iDoleZ[k]=iDole[k++]);

int temp=iGoreZ[K[i].desni]; iGoreZ[K[i].desni]=iDoleZ[K[j].desni];iDoleZ[K[j].desni]=temp;

temp=iGoreZ[K[i].levi]; iGoreZ[K[i].levi]=iDoleZ[K[j].levi];iDoleZ[K[j].levi]=temp;

124

Page 125: UVOD U C++ I DODATAK ZA C++11

double iGoreB=1000*iGoreZ[0] + 100*iGoreZ[1] + 10*iGoreZ[2] + iGoreZ[3]; double iDoleB=1000*iDoleZ[0] + 100*iDoleZ[1] + 10*iDoleZ[2] + iDoleZ[3];

double iBroj= iGoreB/iDoleB;

if (iBroj == iRazlomak) {

for(int i=0; i<=3; cout<<iGoreZ[i++]); cout<<endl;for(int i=0; i<=4; cout<<"-", i++); cout<<endl;for(int i=0; i<=3; cout<<iDoleZ[i++]); cout<<endl;

}}

system("PAUSE");return EXIT_SUCCESS;

}

TESTIRANJE:

Moji rezultati su:

1534

-----

4602

1534

-----

4602

Press any key to continue . . .

Ovaj je rezultat logičan zbog toga što 4542 ima dve četvorke, ukoliko promenimo prvu, trebamo dobiti sličan rezultat i sa analognom promenom druge kombinacije.Interesantan zadatak, možete gore naučeni trik primeniti u različitim problemima. Ukoliko ste shvatili primer i želite malo da se zabavite, proširite program tako da dozvoljava da se cifre brojnika i nazivnika permutiraju. Možete da vidite, da li postoje i brojevi koji menjaju po jednu, ili tri cifre, kao i slučaj sa zamenom sve četiri cifre.

ZADATAK 7:Potrebno je ispisati ciklične permutacije. Drugim rečima, ukoliko unesemo broj pet, ciklične permutacije do broja pet su:1, 2, 3, 4, 52, 3, 4, 5, 13, 4, 5, 1, 24, 5, 1, 2, 35, 1, 2, 3, 4

125

Page 126: UVOD U C++ I DODATAK ZA C++11

ANALIZA:Razmotrimo gore prikazani izlaz. Zaključujemo da imamo 5 redova. Uo;avamo da ako imamo n brojeva, tad imamo i n redova. Da bi nešto ponovili n puta koristićemo jednu for naredbu.Unutar ove for naredbe koristićemo i dve for naredbe, prvu koja ispisuje brojeve od i do iN, i drugu koja ispisuje brojeve od 1 do i.Ovaj primer možemo da uradimo na različite načine. Rezultat možemo čuvati, u nizu, matrici, ili datoteci. Nemojmo zaboraviti ni dinamičke strukture.

KOD PROGRAMA:

#include <iostream>

using namespace std;

intmain(void){

cout<<"PRIKAZ CIKLICNIH PERMUTACIJA"<<endl;cout<<"Unesite dimenziju, neki pozitivni broj n->";int iN; cin>>iN;

cout<<"CIKLICNE PERMUTACIJE"<< iN <<endl;int j, k;for(int i=1; i<=iN; i++){

for(j=i ; j<= iN; cout<< j++);for(k=1 ; k< i ; cout<< k++);cout<<endl;

}

system("PAUSE");return EXIT_SUCCESS;

}

TESTIRANJE:

PRIKAZ CIKLIČNIH PERMUTACIJA

Unesite dimenziju, neki pozitivni broj n->7

CIKLICNE PERMUTACIJE7

1234567

2345671

3456712

4567123

5671234

6712345

126

Page 127: UVOD U C++ I DODATAK ZA C++11

7123456

Možete ovu tehniku da primenite u različitim situacijama. Recimo da je potrebno ispitati da li je moguće ispisati niz u rastućem redosledu , ali ne pomerajući članove niza, tako da prikazujemo sve kružne permutacije niza. Koristićemo izlaze, kao indekse niza. Postoje mnogi zadaci kod kojih je potrebno vršiti cikličke permutacije.

ZADATAK 8: Potrebno je ispisati sva stanja brojača, koji ima proizvoljan broja elemenata, gde se prva komponenta menja od od a1...b1, drugi element se menja od a2..b2, ... , i n-ti deo se menja od an do bn.

ANALIZA:Rešenje je implementirano rekurzivnom funkcijom

KOD PROGRAMA:

#include <iostream>

using namespace std;

#define N 100

int dGranica[N], gGranica[N];

voidispisKombinacije (int n, int x[]){

for (int i=0; i<n; i++){

cout<<x[i]<<" ";}cout<<endl;

}

void kombiniranjeKotura(int k, int n, int x[]){

int i;for(i=dGranica[k];i<=gGranica[k];i++){

x[k]=i; if(k==n){

ispisKombinacije(n,x);}else{

kombiniranjeKotura(k+1,n,x);}

}}

127

Page 128: UVOD U C++ I DODATAK ZA C++11

intmain(void){

int k=1, n, x[100];cout<<"unesi n->"; cin>>n;for(int i=0; i<n; i++){

cout<<"d["<<i<<"]="; cin>>dGranica[i];cout<<"g["<<i<<"]="; cin>>gGranica[i];

if(dGranica[i]>gGranica[i]) { return(EXIT_FAILURE); }}

kombiniranjeKotura(0,n,x);

system("PAUSE");

}

TESTIRANJE:

unesi n->3d[0]=1 g[0]=3d[1]=2 g[1]=5d[2]=7 g[2]=9

1 2 7, 1 2 8, 1 2 9, 1 3 7, 1 3 8, 1 3 9, 1 4 7, 1 4 8, 1 4 9, 1 5 7, 1 5 8, 1 5 92 2 7, 2 2 8, 2 2 9, 2 3 7, 2 3 8, 2 3 9, 2 4 7, 2 4 8, 2 4 9, 2 5 7, 2 5 8, 2 5 93 2 7, 3 2 8, 3 2 9, 3 3 7, 3 3 8, 3 3 9, 3 4 7, 3 4 8, 3 4 9, 3 5 7, 3 5 8, 3 5 9

Izlaz je donekle modifikovan, da bi rezultati bili pregledniji.Kao korisnu ideju, navedimo i malu modifikaciju gore prikazanog problema. Moguće je izvršiti mapiranja stanja elemenata. Ako recimo imamo primer Sudoku solvera, možemo da iskoristimo gore prikazanu ideju. Osim Sudoku rešavača, ideja se može koristiti u različitimo problemima koji od nas zahtevaju neke vrste provera.Prilikom rešavanja možemo koristiti i gore prikazanu tehniku, ali ukoliko rešavamo problem koji ima puno elemenata, zaključujemo da ovo i nije baš najbolji način rešavanja problema. Potrebno je eliminisati sve ne potrebne provere, da bi to uradili možemo koristiti i bektrek ili dinamičko programiranje.

ZADATAK 9:Potebno je kreirati brojač, koji će vršiti jednostavna brojanja. Primer ako imamo 3 elementa u brojaču, brojač treba da prikaže sledeći izlaz:000001002...997998999

128

Page 129: UVOD U C++ I DODATAK ZA C++11

ANALIZA: Prilikom rešavanja se koristi jednostavna ideja, sabiranja brojeva. Drugim rečima, počinjemo od kombinacije kod koje su svi elementi niza postavljeni na nule, a završavamo tako što dosegnemo stanje kod kojeg su svi elementi postavljeni na 999.

Iz prethodnog stanja, prelazimo u sledeće stanje, tako što dodajemo 1, na trenutno stanje elemenata.

KOD PROGRAMA:

#include <iostream>

using namespace std;

# define N 100

void postaviKoture( int a[], int n){

for(int i=0;i<n;i++) { a[i]=9;}}

void postaviPocetnoStanje( int a[], int n){

for(int i=0;i<n;i++) { a[i]=0;}}

void postaviKeca(int a[], int n){

for(int i=0; i<n; i++)if (i == (n-1)) {a[i]=1;} else {a[i]=0;}

}

bool uporediNizove( int a[], int c[], int na){

int i;bool jesuIsti = true;for(i=na-1;i>=

0;i--){if(a[i]!=c[i]) { jesuIsti=false;}

}return jesuIsti;

}

void uvecajZaJedan(int a[], int na, int b[],int nb, int c[],int *nc)

{int i, p=0,d=0;for(i=na-1; i>=0; i--){

129

Page 130: UVOD U C++ I DODATAK ZA C++11

int d=p;if (i<na){ d+=a[i];}if (i<nb){ d+=b[i];}if (d>=10){ p=1; d-=10;} else{p=0;}c[i]=d;

}

*nc=na;

}

void pisiNiz( int a[], int n){

for(int i=0;i<n;i++) { cout<<a[i];}cout<<endl;

}

void main(void){int a[N] , b[N] , c[N];int na, nb , nc;

cout<<"Koliko kotura imamo na->"; cin>>na;nc=nb=na;postaviKoture( a, na);postaviPocetnoStanje(c,nc);

postaviKeca(b,nb);

do{

pisiNiz(c,na);uvecajZaJedan(c,nc, b,nb, c,&nc);//system("PAUSE");

}while( !uporediNizove(a,c,na));

pisiNiz(a,na);

system("PAUSE");}

TESTIRANJE:

Pokušajte da kombinujete ideju pretodnog primera, tako da dozvoli brojanje od a[i] do b[i]. Možete primer uraditi tako da brojite za po dva, ili nešto slično.

Za uneseno n=3(kotura), izlaz je kao u definiciji programa

ZADATAK 10:

130

Page 131: UVOD U C++ I DODATAK ZA C++11

Trebate da razvijete aplikaciju koja će korisniku prikazati sve n-to cifrene binarne brojeve, koji imaju samo dve jedinice u binarnom zapisu.Za n= 4, potrebno je prikazati sledeći izlaz:001101010110100110101100

ANALIZA: Analizirajmo gornji prikaz, ali tako što ćemo prikaz podeliti u grupe:

0011

01010110

100110101100

Zaključujemo da se broj 2 cifrenih binarnih brojeva uvećava, kako se uvećava predposlednja cifra. Da bi postigli gore prikazani efekat, možemo uvesti dve promenljive i i j, i postavimo na n-1, dok j postavimo na n.

Kada j dosegne i, i smanjimo za 1, dok j ponovo postavimo na n.

KOD PROGRAMA:

#include <iostream>

using namespace std;

void Pisi( int , int, int);

void main(void){

int iN;cout<<"Koliko cifara ima binarni broj->";cin>>iN;

int i= iN-1, j= iN;while(!((i==1)&&(j==2))){

Pisi( i, j, iN);

if(i==j-1)

131

Page 132: UVOD U C++ I DODATAK ZA C++11

{i--; j=iN; cout<<endl;

}else{

j--;}

}

cout<<"11"; for(int i=2; i<iN; cout<<'0',i++);cout<<endl;

system("PAUSE");}

void Pisi( int i, int j, int n){

for(int k=1; k<= n; k++)if( (k==i)||(k==j))

cout<<'1';else

cout<<'0';cout<<endl;

}

TESTIRANJE:

Kao n unesite 7, trebali bi dobiti sledeći izlaz:

Koliko cifara ima binarni broj->7

0000011

00001010000110

000100100010100001100

0010001001001000101000011000

010000101000100100100

132

Page 133: UVOD U C++ I DODATAK ZA C++11

01010000110000

100000110000101000100100100010100001100000Press any key to continue . . .Za vežbu možete da ispisujete i binarne brojeve koji imaju tri jedinice, četiri jedinice, koje su simetrične u odnosu na centralnu cifru i slično.

Dobra gimnastika za um, a to je i svrha primera.

ZADATAK 11:Poznata je rečenica: „the quick brown fox jumps over the lazy dog“. Prevod ove rečenice bi bio sledeći:“ brza braon lisica preskače preko lenjog psa“. Rečenica iako nije spektakularna, ima jedno vrlo važno svojstvo, upotrebljena su sva slova engleske abecede. Rečenice koje sadrže sva slova nekog jezika su poznate kao pangrami. Za naš sledeći primer, neće nam biti dovoljan pangram, biće nam neophodan perfektan pangram. Perfektan pangram, je takav pangram da se svako slovo pojavljuje samo jedan put.Ovo je interesantno svojstvo koje možemo da iskoristimo u sledećem primeru. Potrebno je u matrici, koja se sastoji od svih slova engleske abecede i nekoliko znakova *, pronaći put, ali tako da se u okolini svakog slova nalazi sledeće. Pod pojmom, „u okolini svakog slova“, podrazumevam da u odnosu na jedno slovo rečenice, možemo da se krećemo horizontalno, vertikalno, ili po dijagonali, s tim da su slova udaljena jedno od drugog za ne više od jednog razmaka, horizontalnog, vertikalnog, ili dijagonalnog. U suštini se možemo kretati uvek za po jedno slovo od trenutne pozicije. U okolini svakog slova mora da bude traženo slovo, a moguće je napraviti 8 poteza. Rečenica koju ćemo postavi u matricu je: „D. V. Pike flung J. Q. Schwartz my box“. U rečenici ćemo izbaciti velika i zameniti ih mala slovima, a razmake ćemo izbaciti i naravno specijalne znake. O smislu rečenice nećemo raspravljati, jer to nam nije ni cilj.

ANALIZA: U matrici 5*6=30, ima mesta za 30 slova, rečenica koju želimo da postavimo u matricu se sastoji od 26 slova. Drugim rečima, imamo četiri ne popunjena mesta u matrici, ta mesta ćemo popuniti znakovima ‘*’, putanju ćemo sačuvati u matrici koja ima dve dimenzije za oba indeksa.

Pokušaćemo da primer uradimo koristeći funkcije iz windows.h datoteke, inače na ovaj način možemo da koristimo neke interesantne funkcije.

Izgled matrice je sledeći:

* V I E *D P K F LX O B N UZ M Y G JT R W S Q* A H C *

133

Page 134: UVOD U C++ I DODATAK ZA C++11

Dok je niz rečenice popunjen na sledeći nači: „dvpikeflungjqschwartzmybox“. Na žalost nisam uspeo da pronađem neku bolju rečenicu koja je perfektni pangram.

KOD PROGRAMA:

Program se sastoji od dve datoteke:

main.cpp

#include <iostream>#include <windows.h>#include "DatotekaFunkcija.h"

using namespace std;

intmain( void){

//Povecaj prozor tako da moze //zauzeti maksimalnu velicinu

PovecajProzor();

//Objasnimo korisniku sta radimo u programu cout<<PORUKA_1<<endl; PisiMatricu(DIM_RED,DIM_KOL,cMatrica); cout<<PORUKA_2<<endl;PisiNiz(DIM_RED*DIM_KOL-4,cPerfektniPangram); cout<<endl; //Pronadjimo koordinate pocetnog slova Dint xPocetak=0, yPocetak=0;NadjiPocetak( xPocetak, yPocetak,DIM_RED,DIM_KOL,cMatrica); //Napunimo pocetnu vrednost niza koordinata

//koordinatom koju smo pronasli u funkciji //nadji pocetak.

int Koordinate[DIM_RED*DIM_KOL-4][2];Koordinate[0][0]=xPocetak; Koordinate[0][1]=yPocetak;PronadjiKoordinatePutanje(DIM_RED*DIM_KOL-4,Koordinate,

DIM_RED*DIM_KOL-4,cPerfektniPangram, DIM_RED, DIM_KOL, cMatrica,

xPocetak, yPocetak);

system("PAUSE");return EXIT_SUCCESS;

}

DatotekaFunkcija.h:

#include <iostream>

#define DIM_RED 6#define DIM_KOL 5

134

Page 135: UVOD U C++ I DODATAK ZA C++11

#define UKUPNO_RECI 26

#define PORUKA_U_PROZORU L"PERFEKTNI PANGRAM"#define PORUKA_1 "U matrici"#define PORUKA_2 "Trazimo niz"

char cMatrica[DIM_RED][DIM_KOL]={{'*', 'V', 'I', 'E', '*'}, {'D', 'P', 'K', 'F', 'L'}, {'X', 'O', 'B', 'N', 'U'}, {'Z', 'M', 'Y', 'G', 'J'}, {'T', 'R', 'W', 'S', 'Q'}, {'*', 'A', 'H', 'C', '*'}};

char cPerfektniPangram[]={'D','V','P','I','K', 'E','F','L','U','N',

'G','J','Q','S','C', 'H','W','A','R','T', 'Z','M','Y','B', 'O','X'};

void PovecajProzor(void){

HANDLE hConsole; COORD velicina;

HWND hWnd;

hConsole = GetStdHandle(STD_OUTPUT_HANDLE);velicina = GetLargestConsoleWindowSize(hConsole);SetConsoleScreenBufferSize(hConsole, velicina);

SetConsoleTitle(PORUKA_U_PROZORU);hWnd = FindWindow(NULL,PORUKA_U_PROZORU);

SendMessage(hWnd, WM_SYSKEYDOWN, VK_RETURN, 0xFF0000FF);ShowWindow(hWnd, SW_MAXIMIZE);

}

voidPisiMatricu( int i, int j, char cMatrica[DIM_RED][DIM_KOL]){for(int i=0; i<DIM_RED; i++)

{for(int j=0; j<DIM_KOL; j++)

std::cout<<cMatrica[i][j];std::cout<<std::endl;

}}

void

135

Page 136: UVOD U C++ I DODATAK ZA C++11

PisiNiz( int n, char cNiz[]){

for(int i=0; i< n; std::cout<<cNiz[i++]<<" ");}

voidNadjiPocetak( int& iX, int& iY,

int i, int j, char cMatrica[DIM_RED][DIM_KOL])

{for(i=0; i<DIM_RED; i++)

for(j=0; j<DIM_KOL; j++)if( cMatrica[i][j]=='D') {

iX=i; iY=j; break;}

}

boolURedu( int i, int j){

bool bResult=true;if((i<0)||(i>=6)) bResult =false;if((j<0)||(j>=5)) bResult =false;return bResult;

}

voidPronadjiKoordinatePutanje(int iDimenzija ,

int Koordinate[DIM_RED*DIM_KOL-4][2], int iPangram ,

char cPerfektniPangram[DIM_RED*DIM_KOL], int iRed,

int iKol, char cMatrica[DIM_RED][DIM_KOL], int xPocetak,

int yPocetak){

for(int i=1; i< DIM_RED*DIM_KOL-4; i++){

char cTrazeni=cPerfektniPangram[i];

int x=xPocetak, y=yPocetak;if( URedu(++x,++y)&&(cTrazeni == cMatrica[x][y])){

Koordinate[i][0]=x; ++xPocetak;Koordinate[i][1]=y; ++yPocetak;continue;

}

x=xPocetak, y=yPocetak;if(URedu(--x,--y)&&( cTrazeni == cMatrica[x][y]))

136

Page 137: UVOD U C++ I DODATAK ZA C++11

{Koordinate[i][0]=x; --xPocetak;Koordinate[i][1]=y; --yPocetak;continue;

}

x=xPocetak, y=yPocetak;if(URedu(++x,--y)&&(cTrazeni == cMatrica[x][y])) {

Koordinate[i][0]=x; ++xPocetak;Koordinate[i][1]=y; --yPocetak;continue;

}

x=xPocetak, y=yPocetak;if(URedu(--x,++y)&&( cTrazeni == cMatrica[x][y])) {

Koordinate[i][0]=x; --xPocetak;Koordinate[i][1]=y; ++yPocetak;continue;

}

x=xPocetak, y=yPocetak;if( URedu(--x,y)&&(cTrazeni == cMatrica[x][y])) {

Koordinate[i][0]=x; --xPocetak;Koordinate[i][1]=y; continue;

}

x=xPocetak, y=yPocetak;if(URedu(++x,y)&&(cTrazeni == cMatrica[x][y])){

Koordinate[i][0]=x; ++xPocetak;Koordinate[i][1]=y;continue;

}

x=xPocetak, y=yPocetak;if(URedu(x,++y)&&(cTrazeni == cMatrica[x][y])) {

Koordinate[i][0]=x;Koordinate[i][1]=y; ++yPocetak;continue;

}

x=xPocetak, y=yPocetak;if( URedu(x,--y)&&(cTrazeni == cMatrica[x][y]) ){

Koordinate[i][0]=x;Koordinate[i][1]=y; --yPocetak;continue;

137

Page 138: UVOD U C++ I DODATAK ZA C++11

}}

std::cout<<"Koordinate tacaka su"<<std::endl;for(int i=0; i< DIM_RED*DIM_KOL-4; i++)

std::cout<<Koordinate[i][0]<<" "<<Koordinate[i][1]<<std::endl;}

TESTIRANJE:

U matrici

*VIE*DPKFLXOBNUZMYGJTRWSQ*AHC*

Trazimo nizD V P I K E F L U N G J Q S C H W A R T Z M Y B O X

Koordinate tacaka su1 0, 0 1,1 1,0 2,1 2,0 3,1 3,1 4,2 4,2 3,3 3,3 4,4 4,4 3,5 3,5 2,4 2,5 1,4 1,4 0,3 0,3 1,3 2,2 2,2 1,2 0Press any key to continue . . .

Predhodni primer smo uradili tako što smo proveravali okolinu svake tačke i pronalazili sledeće slovo iz poruke.

Da bi ovaj zadatak mogli da uradimo koristili smo činjenicu da se svako slovo javlja jedan put, ukoliko se od jednog slova ne može doći do drugog na jedinstven način ne bi mogli da upotrebimo gore prikazani algoritam.

Rešavanje takvog problema bi od nas zahtevalo daleko kompleksniji algoritam, recimo samo da se može primeniti potpuno isti algoritam koji se koristi za pronalazk puta kroz lavirint. Ovaj postupak se najčešće implementira pomoću rekurziju, i globalno definisane matrice.

Iako je rekurzija daleko najelegantnija ona nije i najbrža, zato možete uvek da razmislite o alternativnim rešenjima. Iako je brzina, uobičajeno glavni kriterij, to nije jedini od mogućih kriterija koji se mogu postaviti pred programera, ali zahvaljujući razvoju računara postaje jedan od najvažnijih kriterija u procesu optimizacije koda.

Pokušajte da razmislite kako bi mogli optimizirati gore urađeni primer, nije ovo jedini, a ni najbolji način da se uradi ovaj primer.

138

Page 139: UVOD U C++ I DODATAK ZA C++11

1 2 . Z A D A C I Z A S A M O S TA L N U V E Ž B U

GRUPA ZADATAKA UZ POGLAVLJA: 2, 3, i 4.1. Potrebno je definisati promjenljive tipa int, long int, long long int, unsigned int.

2. Treba deklarisati dve promjenljive logičkog tipa i dodeliti im početne vrednosti.

3. Deklarisati promjenljive tipa: float, double i long double.

4. Pomoću strukture definisati promjenljive krug, elipsa, parabola.

5. Pomoću strukture definisati promjenljivu tipa razlomak.

6. Pomoću strukture definisati promjenljivu tipa greda sa dva oslonca.

7. Deklarisati promjenljivu tipa otpornik sa četiri trake.

8. Definisati enum tip podatka koji opisuje dane u sedmici.

9. Definisati enum tip podatka koji opisuje mjesece u godini.

10. Definisati enum tip podatka koji opisuje planete sunčevog sistema.

11. Definisati enum tip podatka koji opisuje hemijske elemente u periodnom sistemu.

12. Definisati enum tip podatka koji opisuje horoskopske znakove.

13. Opisati kako se menjaju vrednosti tri promjenljive po koracima:

int iBroj1=0, iBroj2=1, iBroj3=2;

iBroj1++;

iBroj2= iBroj2*3+2*iBroj3;

iBroj3+=3;

14. Opisati kako se menjaju vrednosti tri promjenljive po koracima:

int iBroj1=2, iBroj2=1, iBroj3=2;

++iBroj3;

iBroj1= iBroj1*iBroj2+2*iBroj3;

iBroj2*=3;

15. Opisati kako se menjaju vrednosti tri promjenljive po koracima:

bool bIskaz1=true, bool bIskaz2=false, bIskaz3=true;

bool bResult1 = bIskaz1 && bIskaz2;

bool bResult2 = bIskaz2 || bIskaz3;

139

Page 140: UVOD U C++ I DODATAK ZA C++11

bool bResult3 = !bIskaz1 && (bIskaz2 || !bIskaz3);

16. Izračunati promene izraza:

float fBroj1=1.23, fBroj2= 3.389, fBroj3=2.38, fBroj4=1.23;

double dResult = (double)fBroj1+ 3* static_cast<double> fBroj3;

float fResult = 3.12*fBroj1 + 13.31 + fBroj1*fBroj2+ 7/13;

17. Izračunati promene izraza:

double dBroj1 = 0.123, dBroj2 = 12.3, dBroj3 = 1.12;

double dResult = dBroj1=1.1234;

double dResult2 = dBroj3/dBroj2;

float fResult = dBroj1+3;

GRUPA ZADATAKA UZ POGLAVLJE: 5.1. Potrebno je analizirati a*x+b, u zavisnosti od a i b.

2. Prikazati poruku o rešenjima kvadratne jednačine.

3. Na osnovu podataka o zvezdi, formulu o nastanjivoj zoni pronađite na Internetu, ispišite poruku da li

se planeta nalazi u nastanjivoj zoni.

4. Korisnik unosi celi broj koji predstavlja redni dan u sedmici, počinjemo brojati od 1 što predstavlja

Ponedeljak, ispisati poruku da li je ulazna vrednost prihvatljiva. Možete program proširiti tako da

odgovara i drugim kulturama.

5. Na osnovu rednog broja meseca, ispisujemo poruku koji je mesec u pitanju.

6. Korisnik unosi redni broj planete, potrebno je ispisati koja je to planeta.

7. Unosimo broj stranica višeugaonika ili duži, ispisati poruku kako se višeugao ili duž nazivaju.

8. Ispisati poruku da li je uneseni broj paran ili neparan.

9. Nakon unosa broja ispitati da li je uneseni broj:

a. Deljiv sa 3 ili 5.

b. Deljiv sa 7 i 11.

c. Nije deljiv sa 3 i 4.

d. Nije deljiv sa 6.

140

Page 141: UVOD U C++ I DODATAK ZA C++11

10. Kreiraj funkciju kojom računamo porez. Ukoliko je prihod manji od 10 111 ne postoji porez, ako je

prihod veći od 10 111 a nije prešao 23 244 porez iznosi 7%, dok ako je zarada u granicama od 23

244 do 55 609 porez iznosi 11%, imamo li prihod veći od 55 609 porez predstavlja 13% od ukupnog

primanja.

11. U intervalu [a..b], ispitati koliko je parnih brojeva.

12. U intervalu [a..b], ispitati koliko je brojeva :

a. Deljivo sa 3 ili 5.

b. Deljivo sa 7 i 11.

c. Nije deljivo sa 3 i 4.

d. Nije deljivo sa 5.

13. Izračunati:

a. 1+2+3+...+n.

b. 2+4+6+...+2*n ili 1+3+5+...+2*n+1, u zavisnosti da li je broj koji smo uneli paran ili neparan.

c. n!

d. 1 * 3 * 5 *...* 2n+1 ili 2 * 4 * 6*... *2n, u zavisnosti od parnosti unesenog broja.

e. 1+3+6+8+16...

f. 1+2+4+...

g. 1+3+9+...

h. 1*2 + 2*3 + 3*4 +...

Koristeći for, while, do while i naredbe grananja.

14. Pronaći koji je najbliži kvadratni broj, ukoliko postoje dva takva broja ispisati oba.

15. Unosimo stranice pravougaonika i računamo sumu njihovih površina, poznato je da unosimo bar

jedan pravougaonik. Unos zaustavljamo kad unesemo dimenzije koje mogu kreirati kvadrat.

16. Poluprečnik kruga prima sledeće vrednosti: 1, 3, 5, 15, 17, ...

a. Izračunati ukupni obim svih krugova, takvih da poluprečnik nije veći od nekog graničnog

broja.

b. Ukupna površina je manja od nekog graničnog broja.

141

Page 142: UVOD U C++ I DODATAK ZA C++11

c. Pronaći prvi krug za koji važi da je suma obima svih manjih krugova duplo veća od nekog

graničnog broja.

d. Koliko pravougaonika ima površinu veću ili jednaku a, i manju ili jednaku b.

17. Ispitati da li je uneseni broj prost.

18. Razbiti broj na proste činioce, i ispisati rastavljanje.

19. Izračunati vrednost funkcije exp(x) i ln(x).

20. Rastaviti broj na sumu: 3, 5 i 11. Prikazati sva moguća rastavljanja, a*3 + b*5 + c*11=iBroj.

21. Koliko je celih brojeva iz intervala x ∈ [a..b], y ∈ [c..d], takvih da se nalazi u krugu čiju jednačinu

korisnik unosi. Jednačina je oblika (x – x1)2 + (y-y1)2 = r2

22. Meta se sastoji iz tri koncentrična kruga poluprečnika 1, 2 i 3. Potrebno je ipitati koliko je tačaka sa

koordinatama x i y pogodilo koju od oblasti, a koliko promašilo.

23. Izračunati koren nekog broja koristeći formulu xn=0.5*( x n-1+x0/x n-1), na zadatu tačnost epsilon, koju

unosi korisnik. x0= brojCijiKorenTrazimo.

24. Ispitati koji broj iz intervala od a do b ima najviše prostih činioca.

25. Tabelirati kretanje dva vozila koja se kreću u susret iz mesta A ka mestu B. Prvo vozilo se kreće

ravnomerno, dok drugo ubrzava. Proceniti koliko vremena treba da prođe dok se vozila ne sretnu.

26. Pomoću brojeva a, b, c i d, koji su svi celobrojni, pronaći zbir za koji je suma a, b, c, d, a+a, a+b,...

a+a+a+a,...a+b+c+d, ..., d+d+d+d najpribližnija nekoj vrednosti k.

27. Pronaći najbliži broj oblika 2n, koji je veći od unesenog broja l.

28. Ispisati sve dvocifrene brojeve za koje važi da je suma cifara parna, a da je prva cifra iz intervala

3..7, dok je druga cifra duplo veća od prve cifre.

29. Odrediti koliko ima trocifrenih brojeva koji su kubovi nekog broja.

30. Ispisati na koliko se načina neki broj može napisati pomoću zbira tri cela broja.

GRUPA ZADATAKA UZ POGLAVLJE: 6.1. Na osnovu koordinata krajnjih tačaka duži, izračunati njenu dužinu.

2. Ispitati da li na osnovu unesenih dužina stranica trougla možemo konstruisati trougao.

142

Page 143: UVOD U C++ I DODATAK ZA C++11

3. Korisnik unosi vrednost temperature izmerene u Celzijusima, pretvoriti vrednost u Kelvine, napraviti

i funkciju koja konvertuje Kelvine u Celzijuse. Proširite aplikaciju tako da dozvoljava rad sa

Fahrenhajtovom skalom.

4. Ispitati da li se tačka u 2D, 3D, prostoru nalazi na duži krajnjih tačaka A i B.

5. Izračunati determinantu na osnovu matrice dimenzije 2*2.

6. Izračunati površinu kruga i obim u jednoj funkciji.

7. Odrediti koji je broj od dva unesena bliži, a koji dalji od trećeg broja.

8. Izračunati: aritmetičku, geometrijsku i harmonijsku sredinu tri broja.

9. Ukoliko je unesna jedna cifra ispisati pomocu znakova: ‘_’, ‘|’, ili ‘ ‘ prikaz na digitalnom časovniku

tražene cifre.

10. Unose se dva vremenska trenutka u istome danu, poznate su hh, mm, ss izračunati koliko je sekundi

proteklo od prvog do drugog intervala. Razmotriti oba oblika 0-24, ili 0-12.

11. Izračunati broj pi, koristeći neku od poznatih formula za računanje ovog broja. Nakon toga uporediti

koja od formula brže konvergira ka broju pi.

12. Korisnik unosi broj tipa int, short int ili long int potrebno je izračunati kvadrat unesenog broja i

rezultat vratiti kao tip double.

13. Nakon unesenog broja tipa int ili float izračunati kvadrat, kub ili kvadratni koren unesenog broja, a

povratna vrednost je istog tipa kao i uneseni broj.

14. Na osnovu vrednosti dva otpornika izračunaj koliko iznosi paralelna, a koliko redna otpornost u istoj

funkciji.

15. Koristeći rekurziju izračunaj:

a. 1+2+3+...+n.

b. 1*2*3*...*n.

c. 1+3+5+...+2n+1 ili 2+4+6+...+2n u zavisnosti od parnosti unesenog broja.

16. Ispitati da li je broj dobar.

Broj je dobar ukoliko je suma cifara parna, a ukoliko je suma neparna broj nije dobar.

17. Ukoliko u broju postoji cifra 3, suma cifara se ne računa, a ukoliko je suma parna rezultat se duplira,

ako je suma cifara neparna sumi oduzmemo 1, i podelimo dobijeni broj sa 2.

143

Page 144: UVOD U C++ I DODATAK ZA C++11

18. Izračunati 1 * 2 * 3 *...* n koristeći funkcije sa promjenljivim brojem argumenata. Poznato je n.

19. Izračunati 1 + 3 + 5 +...+ 2*n-1 koristeći funkcije sa promjenljivim brojem argumenata. Poznato je n.

20. Korisnik unosi koordinate dva topa, ispitati da li su vrednosti odgovarajuće. Dva topa ne mogu imati

iste koordinate, niti mogu biti van granica šahovske table, a zatim ispitati da li se oni napadaju.

Primer uradite i za druge figure, a možete i kombinovati figure, kao recimo lovac i skakač.

21. Korisnik unosi tri, četiri, ili pet tačaka koji predstavljaju izlomljenu liniju u 2D, izračunari koliko je

dugačka ova izlomljena linija.

22. Korisnik unosi merne vrednosti poluprečnika kruga i stranicu kvadrata. Ispitati odnose obima i

površina. Zanemariti dimenzije, i porediti brojne vrednosti.

23. Ispitati odnos dve duži, ako su poznate njihove dve krajnje tačke.

24. Korisnik unosi karakter ispitati:

a. Da li je znak cifra.

b. Veliko slovo.

c. Malo slovo.

d. Veliko ili malo slovo.

e. Interpunkcijski znak.

f. Suglasnik.

GRUPA ZADATAKA UZ POGLAVLJE: 7.1. Korisnik unosi niz dimenzije ne veće od 100. Svi elementi su celi brojevi.

Potrebno je:a. Izračunati koliko ima parnih i neparnih brojeva u nizu.b. Odrediti maksimalnu i minimalnu vrednost u nizu.c. Prebrojati koliko je članova niza u intervalu od 17 do 71.d. Izbrojati koliko je brojeva u nizu koji se nalaze na parnim indeksima niza, takvih da su deljivi

sa tri, a nisu deljivi sa sedam.e. Odrediti srednju vrednost niza.f. Prebrojati koliko elemenata niza je manje, koliko veće, a koliko elemenata ima istu vrednost

kao i aritmerička sredina.

2. Korisnik unosi elemente niza, kopira sve elemente u novi niz i svaki element parnog indeksa menja sa odgovarajućim, za jedan većim neparnim indeksom ukoliko ovaj postoji.

144

Page 145: UVOD U C++ I DODATAK ZA C++11

3. Na osnovu niza a čija dimenzija nije veća od 1000, kreirati niz kod kojeg se elementi kreiraju tako da je vrednost niza -1, ako je odgovarajući član niza a negativan, nula ako je element niza 0, ili 1 ukoliko je odgovarajući element niza a veći od nule.

4. Potrebno je formirati niz, nije poznato koliko elemenata imamo, već taj podatak tražimo od korisnika , prema sledećem šablonu:

a. 1, 3, 5, ...b. 2, 1, 4, 3, 6, ...c. 1, 4, 8, 6, 9, 18, 16, ...d. 1, 3, 9,...e. 6, 7, 6, 7, 8, 6, 7, 8, 9, ...f. 1, 2, -1, 3, -2, ...

5. Potrebno je formirati dva niza, niz projekcije x i y koji predstavljaju kurs broda. Nakon toga unosimo stvarni kurs. Ispitati koliko je ukupno odstupanje od projektovanog kursa.

6. Formirati niz ako korisnik unese vrednosti nizova a i b. Ukoliko su odgovarajući elementi nizova a[i] + b[i] parni sumu delimo sa dva, dok ako dobijemo neparan broj novi element niza dobijamo kao proizvod a[i]*b[i].

7. Praćena je prodaja nekog proizvoda u prethodnih n dana. Uočeno je da prodaja ima neke cikluse ponavljanja prema danima u sedmici. Pokušajte pogoditi prodaju za sledeću sedmicu. Predviđanje je srednja vrednost za protekle dane.

8. Korisnik unosi niz karaktera, koji se završavaju znakom EOF ili “.”:a. Odrediti koliko je dugačak niz znakova.b. Odrediti koliko se puta pojavljuje slovo a ili A.c. Koliko je malih slova u nizu karaktera ili velikih znakova.d. Koliko se u nizu karaktera pojavljuje cifara.e. Koji znak je najčešći, ne razlikujući velika i mala slova.f. Ispitati da li uneseni niz znakova može predstavljati mejl.g. Izbaciti višestruke blanko simbole.h. Ispitati da li je u pitanju ime i prezime osobe, kada ime i prezime pišemo velikim početnim

slovima, a imamo dva dela popunjenja znakovima.

9. Nadovezati dva niza karaktera.

10. Ispitati da li se određeni znak pojavljuje u nizu karaktera.

11. Koliko se puta pojavljuju cifre, u nekom stringu u stilu jezika C. String unosi korisnik.

12. Ispitati da li je niz karaktera celi broj.

13. Ispitati da li je niz karaktera možda realni broj. Ne zaboravite, broj može biti pozitivan, negativan ili ne označen.

14. Moguće je uneti samo stringove čiji su elementi slova a, b, c, d ili f.

15. Potrebno je uneti kvadratnu matricu dimenzije ne veće od 10*10:

145

Page 146: UVOD U C++ I DODATAK ZA C++11

a. Pronaći najveći član i-tog reda, i j-te kolone.b. Odrediti članove na glavnoj i sporednoj dijagonali.c. Uporediti odgovarajuće članove glavne i sporedne dijagonale.

16. Uneti matricu A i B te:a. Sabrati matrice.b. Oduzeti A i B.c. Izračunati proizvod unesenih matrica.

17. Predstaviti raspored časova u srednjoj školi. Omogućiti ispis časova po: danima, časovima, ili predmetima. Učenik ima ne više od 8 časova dnevno i ne više od 12 predmeta.

18. Korisnik unosi matricu čiji su elementi tipa double, ispitati da li su svi susedni elementi veći/manji u odnosu na posmatrani element.

19. Uneti tablicu neke funkcije, ispitati koja je maksimalna, minimalna i prosečna vrednost u merenim tačkama.

20. Zameniti članove k-tog i l-tog reda, kolone.

21. Kreirati listu pesama sa ne više od 100 numera, naslova ne dužeg od 255 karaktera.

22. U matrici se čuvaju tri koordinate tačke i masa. Potrebno je odrediti centar masa.

23. Korisnik unosi koordinate topa, ispisati koja polja top napada, i na kojoj se lokaciji top nalazi.

24. Pronaći put kroz lavirint.

25. Ispitati Sudoku, Da li je rešen ispravno?

26. Kreirati ukrštene reči sa rešenjem.

27. Odrediti naj optimalnije rešenje problema ruksaka i lopova. Predmeti imaju celobrojne mase, a vrednosti predmeta su poznate, lopov ima ruksak u koji može da stane celobrojna masa. Odabrati šta bi trebalo ukrasti, da bi torbu popunili na najoptimalniji način za kriminalca.

28. Kreiraj matricu deli, koja deli pet različitih karata. Karte imaju četiri znaka i vrednosti od 1 do kralja.

29. Kreiraj matricu koja čuva podatke: o šahovskom turniru sistema svako sa svakim, fudbalskom turniru sa sistemom eliminacija, kriket meču. Prikazati konačan plasman, i ostale relevantne podatke.

30. Ispitati da li je matrica simetrična u odnosu na dva reda ili dve vrste. Korisnik unosi vrednosti l i k, koji određuju redove koje posmatramo.

31. Iz proizvoljne tačke u matrici čije su koordinate (red,vrsta) možemo da se krećemo gore, dole, levo ili desno. Potrebno je, dok ne izađemo iz granica matrice formirati novu matricu koja pamti koliko smo se puta pozicionirali na određenom mestu u matrici.

146

Page 147: UVOD U C++ I DODATAK ZA C++11

GRUPA ZADATAKA UZ POGLAVLJE: 8.1. Potrebno je sadržaj UlaznaDatoteka.txt, a njeni elementi su slova i specijalni znakovi, pretvoriti u

MorzeovaDatoteka.txt. Ukoliko želite da koristite i Windows.h datoteku, možete i odsvirati ove kodove, koristite Api funkciju PlaySound.

2. Ulazna datoteka CifreU_Datoteci.txt, se sastoji od cifara. Potrebno je prebrojati koliko se koja cifra pojavljuje u datoteci, zatim prebrojati koliko se puta ukupno pojavljuje parnih, neparnih, a koliko nula.Nakon toga potrebno je izračunati koliko se ukupno pojavljuju cifre u datoteci, te izračunati koliko se prosječno puta svaka od cifara pojavljuje. Izračunati i verovatnoću da se neka cifra pojavi.

3. Ispisati tabelu funkcije f(x) od a do b. Korisnik može da izabere neku od predloženih funkcija:a. lox(x).b. ex.c. (a*x+b)/(c*x+d).d. x + 1/x.e. x2+y2+x*y.

4. Korisnik unosi elemente matrice, dimenzije ne veće od 100*100, potrebno je ispisati matricu u izlaznu datoteku Matrica.txt. U drugu datotekeku Transponovana.txt, ispisati matricu ali tako da je originalna matrica transponovana.

5. Ulazna datoteka Osobe_Podaci, čuva podatke o osobama: Redni_Broj, Ime, Prezime, Visina, Težina i Pol.Izračunati koliko iznosi prosečna visina, i težina. Izračunati koliko iznosi prosečna težina muškaraca i žena. Izračunati koliko iznosi visina najviše žene i najnižeg muškarca.

6. Tabelirati karakteristiku diode, u provodnom i neprovodnom smeru. Na osnovu ove tabele i neke metode aproksimacije izračunati vrednosti koje nisu u tabeli izračunate, drugim rečima pronaći neku aproksimaciju koja opisuje vredonsti u među tačkama. Moguće jezadatak uraditi, za više različitih elektronskih komponenti.

7. Napisati aplikaciju koja će uneti osnovne note iz datoteke Note.txt, i odsvirati ove tonove.

8. Ispisati tablicu množenja u izlaznu datoteku.

9. Korisnik unosi tabelu neke funkcije u intervalu a do b, aproksimirati određene vrednosti funkcije u međutačkama.

10. Prilikom prenosa datoteke osmobitnih cifara binarnih brojeva,kreirati i pomoćnu binarnu datoteku BitPariteta, koja izračunava broj jedinica u bajtu. Potrebno je kreirati određenu datoteku koja će UlaznuDatoteku.txt prepisati u IzlaznaDatoteka.txt ali tako da se greške dešavaju sa nekom verovatnoćom koju korisnik unese. Potrebno je proceniti koliko je grešaka uspeo da pronađe paritiBit.

11. Prilikom upravljanja nekim sistemom javlja se jedna karakteristična funkcija. Aproksimirati ovu funkciju tabelom, te izračunati karakteristične vrednosti.

147

Page 148: UVOD U C++ I DODATAK ZA C++11

12. Poznat je izvod iz tahometra autobusa, izračunate su pređene udaljenosti i poznati vremenski intervali. Proceniti prosečnu brzinu kretanja u intervalima. Izračunati ukupnu prosečnu brzinu.

13. Korisnik unosi vrednosti polinoma iz datoteke KoeficjentiPolinoma.txt, polinom ima manje od 100 koeficjenata. DaotekaTacaka.txt ima nepoznat broj tačaka. Izračunati vrednosti polinoma u tim tačkama.

14. UlaznaDatoteka.txt sadrži slova. Potrebno je šifrovati svako slovo, ali tako da je moguće na osnovu ključa odrediti izvorni sadržaj datoteke. Poželjno je napisati što kompleksniji metod enkripcije, tako da statistički napad ne može jednostavno da izvrši dekripciju šifrovane datoteke.

GRUPA ZADATAKA UZ POGLAVLJE: 9.1. Korisnik unosi liniju teksta, linija se završava “.”, kao znakom za kraj rečenice. Potrebno je unesenu

rečenicu ispisati naopako.

2. Ulazna datoteka se sastoji od nepoznatog broja linija teksta. Linije se završavaju tačkom. Potrebno je ulaznu datoteku šifrovati tako što će se sve rečenice napisati naopako.

3. Unosimo koeficjente polinoma, nije unapred poznato koliko koeficjenata unosimo. Izračunati vrednost polinoma u nekoj tački.

4. Na osnovu koeficjenata polinoma, koji se nalaze u KoeficjentiPolinoma.txt datoteci, i vrednosti u tački, tačke se nalaze u DatotekaTačaka, izračunati vrednosi polinoma u tačkama.

5. Karte se modifikuju na sledeći način:1, 2, 3, 4, 5, 6, 7, 8.1, 8, 3, 6, 5, 4, 7, 2.Upotrebom dvostruko povezane liste UlaznuDatoteka.txt, u kojoj se u redu nalaze brojevi, transformisati na gore prikazani način. Rezultat prikazati u TransformisanaDatoteka.txt.

6. Na osnovu dvostruko povezane liste formiramo red, ali tako da sabiramo prvi i zadnji element liste, nakon toga sabiramo drugi i predzadnji element liste. Ukoliko u lisiti imate neparan broj elemenata srednji element uduplajte. Formirajte stek na sličan način.

7. Na osnovu dvosturko povezane liste formirajete stek, ali tako da ćete u stek upisivati samo parne elemente dvostruko povezane liste. Red formirajte tako da u nju upisujete neparne elemente. Omogućiti ispis reda i steka.

8. Kreirajte sortiranu listu.

9. Napravite binarno drvo, koje će se koristiti za izračunavanje izraza. Sadržaj čvora može biti znak operacije ili neki broj.

10. Pokušajte da kreirate svoju dinamičku strukturu, koja bi se mogla koristiti u nekim praktičnim primenama. Razmislite, zašto bi neko koristio takvu strukturu, i koje su prednosti, a koje mane.

148

Page 149: UVOD U C++ I DODATAK ZA C++11

S P I S A K L I T E R AT U R E :1. Dragan Milićev, OOP NA JEZIKU C++, Mikro knjiga, 1995.

2. Peter Princ i Tony Crwford, C ZA PROGAMERE, Mikro knjiga, 2006.

3. Dragan Urošević, ALGORITMI U PORGRAMSKOM JEZIKU C, Mikroknjiga 1996.

4. Augie Hansen, PROGRAMIRANJE NA JEZIKU C, Mikroknjiga 1991.

5. Laslo Kraus, PROGRAMSKI JEZIK C++, Akademska misao 2007.

6. Laslo Kraus, REŠENI ZADACI IZ PROGRAMSKOG JEZIKA C++, Akademska misao 2011.

7. Mendaš, Milutinović, Ignjatijević, 100 NAJKORISNIJIH FORTRANSKIH PROGRAMA, Mikroknjiga

1991.

8. Zoran Vlašić, PASKAL, Tehnička knjiga 1985.

9. Radunović, Samardžić, Marić, NUMERIČKE METODE, Akademska misao 2005.

10. Lippman, Lajoje, C++ IZVORIK, CET 2000.

11. Pappas, Murray, C/C++ VODIČ ZA PROGRAMERE, Mikro knjiga 1995.

12. Stojković, Tošić, ZBIRKA ZADATAKA IZ PROGRAMSKOG JEZIKA BASIC, Naučna knjiga 1989.

13. Bojić, Gligorić, Nikolić, ZBIRKA ZADATAKA IZ EKSPERTSKIH SISTEMA, Akademska misao

2009.

14. Kliford A. Pikover, STRAST ZA MATEMATIKOM, NNK internacional 2007.

15. Brian Overland, C++ OPUŠTENO, CET 2012.

16. http://cplus.about.com//Library/downloads/blog/darts.cpp

17. Škarić, Radović, OSNOVI PROGRAMSKOG JEZIKA C.

18. Milan Čabarkapa, C++ OSNOVE PROGRAMIRANJA, CET 2007.

19. Čabarkapa, Spalević, METODIČKA ZBIRKA ZADATAKA IZ PROGRAMSKOG JEZIKA PASKAL,

SA REŠENIM ZADACIMA U PASKALU, KNJIGA 1.

20. Čabarkapa, Spalević, Matković, METODIČKA ZBIRKA ZADATAKA IZ PASKALA, KNJIGA 2.

149