Struktura programa Vjerovatno najbolji način da se počne učiti programiranje je pisanje programa. Dakle, ovo je vaš prvi program: // moj prvi program u C++ #include <iostream> using namespace std; int main () { cout << "Zdravo!"; return 0; } Zdravo! Prvi panel prikazuje izvorni kod vašeg prvog programa. Drugi pokazuje rezultat kompajliranog i izvršenog programa. Prethodni program je tipični program koji programer početnik napiše prvi put i njegov rezultat je isprintan na ekranu u rečenici „Zdravo!“ (drugi panel). To je jedan od najednostavnijih programa koji može biti napisan u C++, ali sadrži glavne komponente koje svaki program sadrži. Pogledat ćemo liniju po liniju koda koji je napisan: // moj prvi program u C++ Ovo je linija komentara. Sve linije koje počinju sa dva slash znaka "//" sadrže komentar koji nema nikakvog uticaja na izvršenje programa. Programer je može iskoristiti da uključi kratko objašnjenje ili primjedbu unutar svog izvornog koda. U ovom slučaju, linija je kratko objašnjenje šta je naš program. #include <iostream> Linije koje počinju znakom "#" su pretprocesorske direktive. Ovo nijesu redovne linije koda sa izrazima ali su indikacija za kompajlerov pretprocesor. U ovom slučaju prethodno navedena naredba govori pretprocesoru da uključi iostream standardni fajl. Specifični fajl (iostream) uključuje deklaracije osnovnih standardnih input-output biblioteka u C++, i on je uključen jer će njegove funkcionalnosti biti iskorišćene kasnije u programu. using namespace std; Svi elementi standardne C++ biblioteke su deklarisani unutar takozvanog namespace-a, koji se naziva std. U cilju pristupa ovim funkcionalnostima deklarišemo ga prethodno navedenim izrazom da bi koristili ove entitete. int main() Ova linija odgovara početku definicije main funkcije. Main funkcija je mjesto gdje svi C++ programi počinju svoje izvršenje, nezavisno od pozicije unutar izvornog koda. Nije važno da li su druge funkcije sa drugim imenima definisane prije ili posle nje, naredbe definisane unutar ove funkcije će uvijek biti prve koje će se izvršiti u bilo kom C++ programu. Iz tog razloga, neophodno je da C++ program ima main funkciju. Riječ main prati u kodu par zagrada (). To je zbog deklaracije funkcije. Naime, u C++, ono što razlikuje deklaraciju funkcije od drugih tipova izraza su zagrade koje prate ime funkcije. Opciono, unutar zagrada može biti zadata lista parametara. Poslije ovih zagrada slijedi tijelo main funkcije unutar zagrada {}. Ono što je između {} zagrada funkcija radi prilikom izvršenja. cout << "Zdravo!"; Ova linija je C++ naredba. Naredba se može definisati kao izraz koji proizvodi neki efekat. Činjenica je da prethodno navedena naredba izvršava akciju koja generiše vidljivi efekat u našem prvom programu. cout predstavlja standardni izlazni tok u C++ i značenje čitave naredbe je da proslijedi niz 1 karaktera (u ovom slučaju "Zdravo!") u standardni izlazni tok (koji je obično na ekranu). cout je deklarisan u iostream standardnom fajlu unutar std namespace. Primijetimo da se naredba završava sa ";". Ovaj karakter se koristi da označi kraj naredbe i činjenica je da mora biti uključen na kraju svih naredbi u C++ programima (jedna od najednostavnijih sintaksnih grešaka je upravo zaboravljanje karaktera ";" na kraju naredbe). return 0; Naredba return uslovljava završetak main funkcije. Naredba return može biti praćena return kodom. U našem primjeru return je praćeno nulom, što se generalno tumači da program radi očekivano bez grešaka tokom izvršavanja. Ovo je najčešći način da se završi C++ konzolni program. Možemo primijetiti da se sve linije programa ne izvršavaju kada se kod izvršava. Ima linija koje sadrže samo komentare (one počinju sa "//"). Ima linija koje su direktive za kompajlerov pretprocesor (one počinju sa "#"). Zatim ima linija koje počinju sa deklaracijom funkcije (u ovom slučaju, main funkcije) i na kraju linije naredbi (cout << "Zdravo!";), koje su unutar bloka obuhvaćenog zagradama {} main funkcije. Program je struktuiran po linijama tako da bude čitljiviji, ali u C++ mi nemamo striktna pravila kako da razdvojimo naredbe u različite linije. Na primjer, umjesto int main () { cout << "Zdravo!"; return 0; } Možemo napisati: int main (){cout << "Zdravo!"; return 0;} Sve zapisano u samo jednoj liniji imalo bi potpuno isti značenje kao prethodni kod. U C++, separator izmedju naredbi je specificiran sa ";" na kraju svake od njih, ali separator u različitim linijama koda nije bitan uopšte za ovu namjenu. Možemo pisati više naredbi u jednoj liniji ili pisati pojedinačne naredbe koje uzimaju više linija koda. Dijeljenje koda u različite linije služi da kod učini preglednijim. Da dodamo još jednui instrukciju u naš prvi program: // moj drugi program u C++ #include <iostream> using namespace std; int main () { cout << "Zdravo!"; cout << "Ja sam C++ programer!"; return 0; } Zdravo!Ja sam C++ programer! U ovom slučaju, izvršavamo dva umetanja u cout u dvije različite naredbe. Još jednom, formatiranje koda na prikazani način je izvršeno samo zbog bolje preglednosti. Naravno, validno je i sljedeće: int main (){cout << "Zdravo!"; cout << "Ja sam C++ programer!"; return 0;} Takođe smo bili slobodni da podijelimo kod u više linija ako smatramo da je pogodnije: 2 // moj drugi program u C++ #include <iostream> using namespace std; int main () { cout << "Zdravo!"; cout << "Ja sam C++ programer!"; return 0; } Rezultat bi bio potpuno isti kao u prethodnim slučajevima. Direktive pretprocesora (one koje počinju sa "#") su van ovog generalnog pravila jer nijesu naredbe. One moraju biti specificirane u jednoj liniji i ne završavaju se sa ";". Komentari Komentari su dio izvornog koda koje kompajler ne uzima u obzir. Svrha je da omogući programeru da upiše odgovarajuću bilješku ili objašnjenje unutar izvornog koda. Komentare je moguće umetnuti u kod na dva načina: // komentar u jednoj liniji /* blok komentara*/ Prvi od njih odbacuje sve što od znaka "//" do kraja linije. Drugi, poznat kao blok komentara, odbacuje sve između para karaktera "/*" i prvog pojavljivanja para karaktera "*/", sa mogućnošću uključenja više od jedne linije u komentar. Dodaćemo komentare za naš drugi program: // moj drugi program u C++ #include <iostream> using namespace std; int main () { cout << "Zdravo!"; //Ispisuje Zdravo! cout << "Ja sam C++ programer!"; // Ispisuje Ja sam C++ programer! return 0; } Zdravo!Ja sam C++ programer! Ako uključimo komentare unutar izvornog koda bez korišćenja odgovarajućih kombinacija karaktera "//","/*" ili "*/", kompajler će ih posmatrati kao C++ izraze, i najvjerovatnije prikazati poruku o grešci. Promjenljive. Tipovi podataka. Postavlja se piatnje da li je prethodni primjer uopšte koristan. Morali smo da napišemo nekoliko linija koda, kompajliramo ih, izvršimo program da bi dobili jednostavnu rečenicu napisanu na ekranu kao rezultat. Sigurno bi bilo mnogo brže da iskucamo izlaznu rečenicu. Međutim, programiranje nije ograničeno samo na ispis teksta na ekranu. Da bi otišli dalje i postali sposobni da napišemo program koji bi obavljao korisne zadatke koji će nam olakšati rad neophodno je uvesti koncept varijable. Dozvolite da zamislimo da vam tražim da zapamtite broj 5 i broj 2 u isto vrijeme. Vi treba da skladištite dvije različite vrijednosti u memoriji. Sada, ako vas zamolim da dodate 1 prvom broju, znači da ćete zapamtiti brojeve 6 (5+1) i 2. Memorisane vrijednosti možemo sada na primjer oduzeti i 3 dobiti broj 4 kao rezultat. Proces koji smo upravo uradili u vašoj memoriji je upoređen sa time što kompjuter može da radi sa ove dvije varijable. Čitav proces može biti prikazan u C++ sljedećim setom instrukcija: a = 5; b = 2; a = a + 1; result = a - b; Očigledno, ovo je vrlo jednostavan primjer dok koristimo male cjelobrojne vrijednosti, ali zapamtite da vaš računar može čuvati milione brojeva u isto vrijeme i sprovesti razne matematičke operacije nad njima. Dakle, mi možemo definisati varijablu kao dio memorije za čuvanje određene vrijednosti. Svaka varijabla traži identifikator koji je razlikuje od drugih, na primjer, u prethodnom kodu identifikatori su a, b i result, ali mi možemo nazvati promjenljivu imenom kojim želimo, sve dok su identifikatori validni. Identifikatori Validan identifikator je niz jednog ili više slova, cifara ili karaktera "_". Karakter " ", znaci interpunkcije i simboli ne mogu biti dio identifikatora. Samo slova, cifre i jedna donja crta su validni. Dodatno, identifikatori počinju slovom ili donjom crtom, ni u kom slučaju cifrom. Drugo pravilo koje morate uzeti u obzir kada smišljate svoje identifikatore je da se oni ne mogu poklapati sa ključnim riječima C++ jezika, niti sa nekim rezervisanim riječima specifičnim za kompajler. Standardne rezervisane riječi su: asm, auto, bool, break, case, catch, char, class, const, const_cast, continue, default, delete, do, double, dynamic_cast, else, enum, explicit, export, extern, false, float, for, friend, goto, if, inline, int, long, mutable, namespace, new, operator, private, protected, public, register, reinterpret_cast, return, short, signed, sizeof, static, static_cast, struct, switch, template, this, throw, true, try, typedef, typeid, typename, union, unsigned, using, virtual, void, volatile, wchar_t, while Alternativni oblici nekih operatora se takođe ne mogu koristiti kao identifikatori, jer oni predstavljaju rezervisane riječi pod određenim okolnostima: and, and_eq, bitand, bitor, compl, not, not_eq, or, or_eq, xor, xor_eq Vaš kompajler takođe uključuje nekoliko dodatnih specifičnih ključnih riječi. Veoma važno: C++ jezik je "case sensitive". To znači da postoji razlika između malog i velikog istog slova. Tako, na primjer, RESULT promjenljiva nije ista kao result promjenljiva ili Result promjenljiva. To su tri različita identifikatora. Osnovni tipovi podataka Kada programiramo, mi čuvamo varijable u memoriji računara, ali kompjuter treba da zna koju vrstu podataka želimo da sačuvamo, kako bi rezervisao memorijski prostor adekvatan odgovarajućem podatku. Memorija računara je organizovana u bajtima. Bajt je minimalna količina memorije kojim možemo upravljati u C++. Bajt može čuvati malu količinu podataka: jedan karakter ili mali cio broj (generalno cijeli broj u opsegu 0 do 255). Pored toga, kompjuter može manipulisati kompleksnijim tipovima podataka, kao što su "dugi" brojevi ili "ne-cijeli" brojevi. U tabeli je dat pregled osnovnih tipova podataka u C++, kao i odgovarajući opseg vrijednosti: 4 Promjenljiva char short int (short) int long int (long) bool float double long double wchar_t Opis Veličina Karakter ili "mali" cio broj 1 bajt "Kratki" cio broj 2 bajta Cio broj 4 bajta "Dugi" cio broj 4 bajta Boolean vrijednost. On može imati dvije vrijednosti: tačno ili netačno Broj sa pokretnim zarezom Broj sa pokretnim zarezom sa dvostrukom preciznošću "Dugi" broj sa pokretnim zarezom sa dvostrukom preciznošću "Široki" karakter Opseg označen: -128 do 127 neoznačen: 0 do 255 označen: -32768 do 32767 neoznačen: 0 do 65535 označen: -2147483648 do 2147483647 neoznačen: 0 do 4294967295 označen: -2147483648 do 2147483647 neoznačen: 0 do 4294967295 1 bajt tačno ili netačno 4 bajta +/- 3.4e +/- 38 (~7 cifara) 8 bajtova +/- 1.7e +/- 308 (~15 cifara) 8 bajtova +/- 1.7e +/- 308 (~15 cifara) 2 ili 4 bajta 1 široki karakter Treća i četvrta kolona u prethodnoj tabeli zavise od sistema za koji je program kompajliran. Vrijednosti prikazane gore odgovaraju većini 32-bitnih sistema. Ali za druge sisteme, opšta pravilo je da int ima prirodnu veličinu predloženu od arhitekture sistema (jedna "riječ") i četiri tipa integera char, short, int i long moraju svaki od njih biti najmanje veliki kao onaj prethodni, sa char koji uvijek zauzima 1 bajt. Isto se primjenjuje i za brojeve sa pokretnim zarezom tipa float, double i long double, gdje svaki mora obezbijediti najmanje barem onoliku preciznost kao prethodni. Deklaracija varijabli Da bi koristili varijablu u jeziku C++, moramo prvo da je deklarišemo specificirajući koji tip podatka želimo da bude. Sintaksa da deklarišemo novu varijablu je da napišemo specifikator željenog tipa podatka (kao int, bool, float) i potom validnu oznaku varijable (identifikator). Na primjer: int a; float mynumber; Ovo su validne deklaracije varijabli. Prva deklariše promjenljivu a tipa int. Druga deklaracija promjemljive mynumber je tipa float. Ako želite da deklarišete više od jedne varijable istog tipa, možete ih deklarisati sve u jednoj naredbi dijeleći njihove oznake zarezima. Na primjer: int a, b, c; Na ovaj način deklarisane su tri cjelobrojne promjenljive a, b i c. Isto se moglo postići i na sljedeći način: int a; int b; int c; Cjelobrojni tipovi podataka char, short, long i int mogu biti označeni ili neoznačeni zavisno od veličine brojeva koje želimo da predstavimo. Označeni tipovi mogu predstavljati i pozitivne i negativne vrijednosti, a neoznačeni tipovi mogu reprezentovati samo pozitivne vrijednosti (i nulu). Ovo može biti specificirano korišćenjem oznake signed ili unsigned prije tipa. Na primjer: unsigned short int BrojSestara; signed int BalansRacuna; 5 Ukoliko ne specificiramo signed ili unsigned, većina kompajlera će pretpostaviti da je tip označen, što znači da umjesto druge deklaracije gore možemo pisati: int BalansRacuna; sa potpuno istim značenjem. Izuzetak od opšteg pravila je char tip, koji postoji sam po sebi i smatra se drugačijim osnovnim tipom podatka od signed char i unsigned char, koji je namijenjen za čuvanje karaktera. Potrebno je koristiti bilo signed ili unsigned char ako namjeravate čuvati numeričke vrijednosti u char veličini promjenljive. short i long može biti sam korišćen kao tip specifikatora. U ovom slučaju, oni se odnose na njihove odgovarajuće cjelobrojne osnovne tipove. Deklaracije sljedeće dvije varijable su ekvivalentne: short Godina; short int Godina; Konačno, signed i unsigned mogu biti korišćeni kao samostalni tip specifikatora, značeći isto što i signed int i unsigned int redom. Sljedeće dvije deklaracije su iste: unsigned SljedecaGodina; unsigned int SljedecaGodina; Da vidimo kako deklaracije izgledaju u okviru rada programa, iskoristićemo primjer sa početka poglavlja: // rad sa promjenljivima #include <iostream> using namespace std; int main () { // deklaracija promjenljivih: int a, b; int result; // proces: a = 5; b = 2; a = a + 1; result = a - b; // ispis rezultata: cout << result; // zavrsetak programa: return 0; } 4 Vidljivost varijabli Sve promjenljive koje namjeravamo koristiti u programu moraju biti deklarisane u ranijoj tački koda, kao što je urađeno u prethodnom primjeru gdje su na početku funkcije main deklarisane cjelobrojne promjenljive a, b i result. Varijable mogu biti globalne ili lokalne. Globalna promjenljiva je promjenljiva deklarisana izvan svih funkcija, dok je lokalna varijabla deklarisana unutar tijela funkcije ili bloka. 6 #include <iostream> using namespace std; globalne promjenljive int CijeliBroj; char Karakter; unsigned int BrojSinova; int main () { lokalne promjenljive unsigned short Godine; float Broj; instrukcije cout << "Upisite godine:"; cin >> Godine; ... } Globalne promjenljive mogu biti pozvane iz bilo kog dijela programa nakon deklaracije, čak i unutar funkcija. Vidljivost lokalnih varijabli je ograničena na blok unutar zagrada {} gdje su varijable deklarisane. Na primjer, ako su varijable deklarisane na početku tijela funkcije (kao u main funkciji) njihova vidljivost je od tačke deklaracije do kraja funkcije. U primjeru gore, ovo znači da ako postoji druga funkcija osim main funkcije, lokalne varijable deklarisane u main-u ne mogu biti pozvane iz druge funkcije i obrnuto. Inicijalizacija varijabli Kada deklarišemo običnu lokalnu promjenljivu, njiena vrijednost je neodređena. Ali vi ćete možda željeti da dodijelite konkretnu vrijednost promjenljivoj u istom momentu kada je deklarišete. Da bi to uradili, možete inicijalizovati promjenljivu. Postoje dva načina u C++ da to uradimo: Prvi način podrazumijeva dodavanje znaka jednako koga prati vrijednost na koju će varijabla biti inicijalizovana: type identifier = initial_value ; Na primjer, ako želimo deklarisati cjelobrojnu promjenljivu a i inicijalizovati je vrijednošću 0 u trenutku kada se deklariše, možemo pisati: int a = 0; Drugi način inicijalizacije varijabli, poznat kao konstruktor za inicijalizaciju, podrazumijeva umetanje inicijalne vrijednosti između zagrada (): type identifier (initial_value) ; Na primjer: int a(0); Oba načina inicijalizacije su važeća i ekvivalentna u C++. 7 // inicijalizacija varijabli #include <iostream> using namespace std; int main () { int a = 5; // inicijalna vrijednost = 5 int b(2); // inicijalna vrijednost = 2 int result; // inicijalna vrijednost neodredjena a = a + 3; result = a - b; cout << result; return 0; } 6 Uvod u stringove Promjenljive koje čuvaju ne-numeričke vrijednosti duže od jednog karaktera poznate su kao stringovi. Biblioteka C++ jezika obezbjedjuje podršku stringovima kroz standardnu string klasu. Ovo nije fundamentalni tip podatka, ali se ponaša na sličan način kao fundamentalni tip prilikom rada u većini osnovnih upotreba. Prva razlika u odnosu na fundamentalne tipove podataka je da prilikom deklarisanja i upotrebe objekata (promjenljivih) ovog tipa treba da uključimo dodatni header fajl u izvorni kod: <string> i imamo prolaz do std namespace-a (koji već imamo u svim našim prethodnim programima zahvaljujući using namespace naredbi). // moj prvi string #include <iostream> #include <string> using namespace std; int main () { string mystring = "Ovo je string"; cout << mystring; return 0; } Ovo je string Kao što možete vidjeti u prethodnom primjeru, stringovi mogu biti inicijalizovani bilo kojim nizom karaktera kao što numerički tipovi promjenljivih mogu biti inicijalizovani bilo kojim važećim numeričkim literalom. Oba formata inicijalizacije su važeća sa stringovima: string mystring = "This is a string"; string mystring ("This is a string"); Nad stringovima se mogu izvršavati sve ostale osnovne operacije kao i nad osnovnim tipovima podataka, tako stringovi mogu biti deklarisani bez inicijalne vrijednosti i može im biti dodijeljena vrijednost tokom izvršavanja: // moj prvi string #include <iostream> #include <string> using namespace std; int main () { string mystring; mystring = "Inicijalna vrijednost stringa"; cout << mystring << endl; mystring = "Druga vrijednost stringa"; cout << mystring << endl; return 0; } Inicijalna vrijednost stringa Druga vrijednost stringa 8 Konstante Konstante su izrazi sa fiksnom vrijednošću. Literali Literali se koriste da izraze određene vrijednosti unutar izvornog koda programa. Mi smo ih već koristili ranije da damo konkretne vrijednosti promjenljivima, ili da izrazimo poruke koje želimo da naš program ispiše. Na primjer, pisali smo: a = 5; 5 je u ovom dijelu koda literal konstanta. Literal konstante se mogu podijeliti na cijele brojeve, brojeve sa pokretnim zarezom, karaktere, stringove i boolean vrijednosti. Cijeli brojevi 1776 707 -273 Ovo su numeričke konstante koje predstavljaju cjelobrojne vrijednosti u dekadnom brojnom sistemu. Primijetimo da se za izražavanje numeričkih konstanti ne moraju pisati navodnici ("), ili neki specijalni karakteri. Ako želimo da prikažemo oktalni broj mora mu prethoditi karakter "0", u slučaju da želimo da prikažemo heksadecimalni broj moramo prije njega staviti karaktere "0x". Sljedeći literali konstanti su međusobno ekvivalentni: 75 0113 0x4b Svi oni predstavljaju istu vrijednost u tri brojna sistem (75 - dekadno, 113 - oktalno, 4b heksadecimalno). Podrazumijeva se da literal konstante, kao i promjenljive, imaju određeni tip podatka. Cjelobrojni literali su tipa int. Međutim, možemo ih učiniti neoznačenim dodavanjem karaktera "u", ili long dodavanjem karaktera "l": 75 // int 75u // unsigned int 75l // long 75ul // unsigned long U oba slučaja sufiks se može zadati korišćenjem bilo malog, bilo velikog slova. Brojevi sa pokretnim zarezom Oni predstavljaju brojeve sa decimalama i/ili eksponentima. Oni uključuju decimalnu tačku ili e karakter (puta 10 na stepen x, gdje je x cjelobrojna vrijednost koja prati karakter e), ili oba i decimalnu tačku i e karakter: 3.14159 // 3.14159 6.02e23 // 6.02x10^23 1.6e-19 // 1.6x10^-19 3.0 // 3.0 9 Prvi broj je , drugi broj je Avogadrov broj, treći je naelektrisanje elektrona (ekstremno mali broj) svi su aproksimirani i na kraju je broj tri predstavljen kao numerički literal sa pokretnim zarezom. Default-ni tip za literale sa pokretnim zarezom je double. Ako eksplicitno želite da prikažete float ili long double numerički literal, možete koristiti f ili l sufikse respektivno: 3.14159L // long double 6.02e23f // float Bilo koje slovo koje može biti dio numeričke konstante sa pokretnim zarezom (e, f, l) može biti napisano korišćenjem malog ili velikog slova bez razlike u njihovom značenju. Karakteri i string literali Takođe, postoje ne-numeričke konstante, kao: 'z' 'p' "Zdravo" "Kako ste" Prva dva izraza predstavljaju konstante od jednog karaktera, dok sljedeća dva predstavljaju string literale sastavljene od nekoliko karaktera. Primijetimo da predstavljanje jednog karaktera zatvaramo jednim navodnikom ('), dok string (koji obično sadrži više karaktera) zatvaramo između duplih navodnika ("). Kada zapisujemo jedan karakter ili string literale, neophodno je staviti ih između znakova navoda kako bi se napravila razlika od identifikatora promjenljive ili rezervisanih riječi. Primijetimo razliku između ova dva izraza: x 'x' x samo se odnosi na promjenljivu čiji identifikator je x, dok 'x' (zatvoreno sa jednim znacima navoda) bi se odnosilo na karakter konstantu. Karakter i string literali imaju određene osobenosti, kao escape kodovi .Ovo su specijalni karakteri koje je teško ili nemoguće izraziti na drugi način u izvornom kodu u programu, kao novi red (\n) ili tab (\t). Svakoj od njih prethodi backslash (\). Data je lista nekih takvih kodova: \n \r \t \v \b \f \a \' \" \? \\ newline carriage return tab vertical tab backspace form feed (page feed) alert (beep) single quote (') double quote (") question mark (?) backslash (\) Na primjer: '\n' '\t' "Left\tRight" "one\ntwo\nthree" 10 Takođe, bilo koji karakter možete izraziti njegovim numeričkim ASCII kodom stavljajući karakter '\' kojeg prati ASCII kod u oktalnimom ili heksadecimalnom zapisu. U prvom slučaju (oktalno) cifre moraju neposredno pratiti backslash (na primjer \23 ili \40), u drugom slučaju (heksadecimalno), karakter x mora biti napisan prije ASCII koda (na primjer \x20 ili \x4A). String literali se mogu proširiti na više od jedne linije koda stavljajući karakter '\' na kraju svake nezavršene linije. "String zapisan u \ dvije linije" Možete takođe sastaviti nekoliko string konstanti razdvajajući ih jednim ili sa nekoliko praznih mjesta, tabulatora, novih linija ili nekim drugim važećim praznim karakterom: "ovo predstavlja" "samo jedan" "string" "karaktera" Na kraju, ako želimo da se string literal sastoji od wide karaktera, umjesto karaktera (char), možemo prije konstante koristiti prefiks L: L"ovo predstavlja string širokih karaktera" Široki karakteri se koriste uglavnom da prikažu ne-engleske ili egzotične setove karaktera. Boolean literali Postoje samo dvije važeće boolean vrijednosti: true i false. Mogu se izraziti u C++ kao vrijednost tipa bool korišćenjem boolean literala true i false. Definisane konstante (#define) Možete definisati svoja imena za konstante koje koristite veoma često bez upotrebe promjenljivih, jednostavno korišćenjem #define pretprocesor direktive. Njen format je: #define identifier value Na primjer: #define PI 3.14159 #define NEWLINE '\n' Ovo definiše dvije nove konstante: PI i NEWLINE. Jednom definisane, vi ih možete koristiti u ostatku koda kao bilo koje regularne konstante, na primjer: // definisane konstante: racunanje obima kruga #include <iostream> using namespace std; #define PI 3.14159 #define NEWLINE '\n' int main () { double r=5.0; // poluprecnik double circle; circle = 2 * PI * r; cout << circle; cout << NEWLINE; return 0; } 31.4159 U stvari, jedino što radi kompajler pretprocesora kada naiđe na #define direktivu je da zamijeni svako pojavljivanje njihovog identifikatora (u prethodnom primjeru, to su PI i NEWLINE) kodom kojim su definisane (3.14159 i \n, respektivno). 11 #define direktiva nije C++ naredba, već direktiva za pretprocesor. Podrazumijeva cijelu liniju i ne zahtijeva ';' na kraju. Deklarisane konstante Sa prefiksom const možemo deklarisati konstante specifičnog tipa na isti način kao što bi uradili sa promjenljivim: const int pathwidth = 100; const char tabulator = '\t'; Ovdje su pathwidth i tabulator dva tipa konstanti. One se tretiraju kao regularne promjenljive osim što njihove vrijednosti ne mogu biti modifikovane nakon definicije. Operatori Kada znamo da postoje promjenljive i konstante, možemo početi operacije sa njima. Za tu svrhu, C++ posjeduje operatore. Za razliku od drugih jezika čiji operatori su uglavnom ključne riječi, operatori u C++ su najčešće napravljeni od znakova koji nijesu dio alfabeta ali su raspoloživi o okviru svih tastatura. Ovo čini C++ kod kraćim i više internacionalnim, manje se oslanja na engleske riječi, ali zahtijeva malo napora za učenje u početku. Operator dodjele (=) Operator dodjele dodjeljuje vrijednost promjenljivoj. a = 5; Ova naredba dodjeljuje varijabli a vrijednost 5. Dio koji se nalazi lijevo od znaka '=' je poznat kao lvalue (lijeva vrijednost), dok se dio desno od znaka '=' označava kao rvalue (desna vrijednost). Lvalue mora da bude promjenljiva dok rvalue može biti konstanta, promjenljiva, rezultat neke operacije. Najvažnije pravilo kod operatora dodjele je pravilo "s desna u lijevo": Operacija dodjele se uvijek izvršava s desna u lijevo: a = b; Naredba izjednačava promjenljivu a (lvalue) sa vrijednošću koju sadrži promjenljiva b (rvalue). Vrijednost koju sadrži promjenljiva a do tog momenta nije uzeta u obzir u ovoj operaciji, i u stvari ova vrijednost će biti izgubljena. Treba uzeti u obzir da u momentu operacije dodjele mi dodjeljujemo vrijednost promjenljive b promjenljivoj a, a da se kasnije promjene promjenljive b neće odražavati na promjenljivu a. Na primjer, pogledajmo sljedeći kod: // operator dodjele #include <iostream> using namespace std; int main () { int a, b; // a:?, b:? a = 10; // a:10, b:? b = 4; // a:10, b:4 a = b; // a:4, b:4 b = 7; // a:4, b:7 cout << "a:"; cout << a; cout << " b:"; cout << b; return 0; } a:4 b:7 12 Kod nam daje rezultat da je vrijednost promjenljive a jednaka 4 i da je vrijednost promjenljive b jednaka 7. Primijetimo da na a ne utiče poslednja promjena b. Prednost koju C++ jezik ima u odnosu na druge programske jezike je da se operacija dodjele može koristiti kao rvalue (ili dio rvalue) za drugu operaciju dodjele. Na primjer: a = 2 + (b = 5); je isto što i: b = 5; a = 2 + b; Sljedeći izraz je takodje validan u C++: a = b = c = 5; Dodjeljujemo 5 promjenljivima a, b i c. Aritmetički operatori Pet aritmetičkih operatora podržanih u C++ programskom jeziku su: + * / % sabiranje oduzimanje množenje dijeljenje moduo Operacije sabiranja, oduzimanja, množenja i dijeljenja korespondiraju sa svojim matematičkim operatorima. Jedini od njih koji možda nijesmo navikli često da koristimo je moduo čiji je operator znak procenta (%). Moduo je operacija koja daje ostatak pri dijeljenju dvije vrijednosti. Na primjer, pišemo: a = 11 % 3; Promjenljiva a će sadržati vrijednost 2, jer je 2 ostatak pri dijeljenju 11 sa 3. Operatori složene dodjele (+=, -=, *=, /=, %=, >>=, <<=, &=, ^=, |=) Kada želimo da mijenjamo vrijednost promjenljive primjenjujući određenu operaciju nad tom vrijednošću, možemo koristiti složene operatore dodjele: izraz value += increase; a -= 5; a /= b; price *= units + 1; Ekvivalentan izraz value a = a a = a price = / = value + increase; 5; b; price * (units + 1); i tako za sve ostale operatore. Na primjer: 13 // operatori "slozene" dodjele #include <iostream> using namespace std; int main () { int a, b=3; a = b; a+=2; // ekvivalentno sa a=a+2 cout << a; return 0; } 5 Inkrementiranje i dekrementiranje Operator inkrementiranja (++) i operator dekrementiranja (--) povećavaju ili smanjuju za jedan vrijednost koja se čuva u promjenljivoj. Oni su ekvivalentni sa +=1 i -=1, respektivno. Tako su: c++; c+=1; c=c+1; su ekvivalentni u svojoj funkcionalnosti - povećavaju za jedan vrijednost promjenljive c. Karakteristika ovog operatora je da može biti korišćen kao prefiksni i kao sufiksni operator. Ovo znači da on može biti napisan bilo prije oznake promjenljive (++a) i poslije (a++). Iako u jednostavnim izrazima kao a++ i ++a oba imaju isto značenje, u složenijim izrazima značenje se može znatno razlikovati. Primijetimo razliku: primjer 1 primjer 2 B=3; A=++B; // A sadrzi 4, B sadrzi 4 B=3; A=B++; // A sadrzi 3, B sadrzi 4 U primjeru 1, vrijednost promjenljive B je uvećana prije izvršenja operacije dodjele, dok je u primjeru 2 vrijednost promjenljive B iskopirana u A i tek onda je B uvećano za jedan. Operatori poređenja (==, !=, >, <, >=, <=) Da bi izvršili poređenje dva izraza možemo koristiti operatore poređenja. Rezultat relacione operacije je boolean vrijednost koja može biti true ili false. Data je lista operatora poređenja koji se mogu koristiti u C++: == != > < >= <= jednako nije jednako veće manje veće ili jednako manje ili jednako Evo nekoliko primjera: (7 (5 (3 (6 (5 == 5) // false > 4) // true != 2) // true >= 6) // true < 5) // false Naravno, umjesto korišćenja samo numeričkih konstanti, možemo koristiti važeće izraze, uključujući promjenljive. Pretpostavimo da je a=2, b=3 i c=6, (a == 5) // false, jer a nije jednako 5. (a*b >= c) // true, jer (2*3 >= 6) je tacno. 14 (b+4 > a*c) // false, jer (3+4 > 2*6) je netacno. ((b=2) == a) // true. Budite oprezni! Operator '=' (jedan znak jednako) nije isti kao operator '==' (dva znaka jednako), prvi je operator dodjeljivanja (dodjeljuje vrijednost sa lijeve na desnu stranu) i drugi je operator koji ispituje jednakost. Tako, u poslednjem izrazu ((b=2) == a), prvo dodjeljujemo 2 promjenljivoj b i onda ga upoređujemo sa a, koji takodje čuva vrijednost 2. Logički operatori (!, &&, II) Operator '!' izvršava boolean operaciju NOT, ima samo jedan operand i jedina stvar koju on radi je da invertuje vrijednost operanda, daje false ako je njegov operand true i true ako je njegov operand false. Dakle, on vraća suprotnu boolean vrijednost od vrijednosti njigovog operanda. Na primjer: !(5 == 5) // false jer je (5 == 5) true. !(6 <= 4) // true jer je (6 <= 4) false. !true // false !false // true. Operator '&&' odgovara logičkom operatoru AND. Rezultat je true ako su oba operanda true, i false u svim ostalim slučajevima. Sljedeća tabela prikazuje rezultat operatora '&&' prilikom izvršavanja izraza a&&b: && Operator a b a && b true true false false true false true false true false false false Operator '||' odgovara logičkom operatoru OR. Rezultat je true ako je jedan od operatora true, tako da će biti false onda kada su oba operanda false. Sljedeća tabela prikazuje rezultat operatora '||' prilikom izvršavanja izraza a||b: || Operator a b a || b true true false false true false true false true true true false Na primjer: ( (5 == 5) && (3 > 6) ) // false ( true && false ). ( (5 == 5) || (3 > 6) ) // true ( true || false ). Uslovni operator (?) Uslovni operator provjerava istinitost izraza i vraća jednu vrijednost ako je izraz true, ili drugu vrijednost ako je izračunati izraz false. Njegov format je: condition ? result1 : result2 Ako je uslov (condition) istinit izraz će vratiti result1, a ako nije vratiće resault2. 7==5 ? 4 : 3 // vraca 3, jer 7 nije jednako 5. 7==5+2 ? 4 : 3 // vraca 4, jer je 7 jednako 5+2. 5>3 ? a : b // vraca a, jer je 5 vece od 3. 15 a>b ? a : b // vraca vecu vrijednost, a ili b. // uslovni operator #include <iostream> using namespace std; int main () { int a,b,c; a=2; b=7; c = (a>b) ? a : b; cout << c; return 0; } 7 U ovom primjeru a je 2 i b je 7, tako da uslov koji se ispituje (a>b) nije tačan. Slijedi da je prva vrijednost specificirana posle znaka pitanja (a) odbačena u korist druge vrijednosti (b). Operator zarez (,) Operator zarez (,) se koristi da razdvoji dva ili više izraza na mjestu gdje je samo jedan izraz očekivan. Na primjer: a = (b=3, b+2); Prvo će vrijednost 3 biti dodijeljena promjenljivoj b, a onda će b+2 biti dodijeljeno promjenljivoj a. Na kraju će promjenljiva a sadržati vrijednost 5 dok će promjenljiva b sadržati vrijednost 3. Operatori nad bitovima ( &, |, ^, ~, <<, >> ) Operatori nad bitovima modifikuju promjenljive na bit-nivou. operator ekvivalentna operacija & | ^ ~ << >> AND OR XOR NOT SHL SHR opis unarni komplement shift lijeo shift desno Eksplicitna konverzija Operatori konverzije daju mogućnost da konvertujete dati tip u željeni. Postoji nekoliko načina da se to uradi u C++. Najednostavniji način, naslijeđen iz programskog jezika C, je dodavanje novog tipa u okviru zagrada () ispred izraza koji se želi konvertovati: int i; float f = 3.14; i = (int) f; Prethodni kod konvertuje broj sa pokretnim zarezom 3.14 u cjelobrojnu vrijednost (3), ostatak je izgubljen. Drugi način da uradimo istu stvar u C++ je: i = int (f); Oba načina konverzije su validna u C++. sifeof() 16 Operator prihvata jedan parametar, koji može biti bilo tip podatka, bilo promjenljiva i vraća veličinu u bajtima toga tipa ili objekta: a = sizeof (char); Promjenljiva a će imati vrijednost 1 jer tip char zauzima jedan bajt. Vrijednost koju vraća operator sizeof je konstanta. Ostali operatori Kasnije ćemo se upoznati sa više operatora, kao oni koji se odnose na pointere ili nek specifične za objektno orjentisano programiranje. Svaki od njih je objašnjen u odgovarajućem dijelu. Prioritet operatora Kada pišemo kompleksne izraze sa nekoliko operanada, možemo imati dilemu oko toga koja operacija se izvršava prije, a koja kasnije. Na primjer, u izrazu: a = 5 + 7 % 2; imamo dilemu da li to znači: a = 5 + (7 % 2); // rezultat je 6, ili a = (5 + 7) % 2; // rezultat je 0 Ispravan odgovor bi bio prvi od dva izraza, sa rezultatom 6. Prioritet operacija je definisan, ne samo aritmetičkih operacija, već za sve operatore koje možemo sresti u C++. Od najvišeg do najnižeg prioriteta, redosljed prioriteta je sledeći: nivo 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 operator :: () [] . -> ++ -++ -- ~ ! sizeof new delete (type) .* ->* * / % + << >> < > <= >= == != & ^ | && || ?: = *= /= %= += -= >>= <<= , * & &= ^= + - |= opis operator dosega postfix prefix konverzije pointer-to-member množenje, dijeljenje, moduo sabiranje, oduzimanje shift relacioni (ne)jednakost AND nad bitima XOR nad bitima AND nad bitima logičko AND logičko OR uslovni operator operatori dodjele U slučaju da imamo nekoliko operatora istog nivoa u jednom izrazu, prioritet operacija se definiše grupisanjem. Korišćenjem zagrada () se može manipulisati prioritetom operacija, a mogu se izbjeći i nedoumice, kao u primjeru: a = 5 + 7 % 2; može biti napisano kao: 17 a = 5 + (7 % 2); ili a = (5 + 7) % 2; zavisno od toga kojoj operaciji treba da damo prednost. Ako želite da pišete komplikovanije izraze i nijeste potpuno sigurni oko prioriteta, uvijek koristite zagrade. Takođe, kod će postati pregledniji. Osnovni Ulaz/Izlaz Do sada, primjeri programa u prethodnim sekcijama obezbjeđuju vrlo malu interakciju sa korisnikom, ako je uopšte ima. Koristeći standardne ulazne i izlazne biblioteke, bićemo u stanju da vršimo interakciju sa korisnikom štampajući poruke na ekranu i uzimajući korisnikov ulaz sa tastature. C++ koristi abstrakciju koja se zove tokovi da izvrši ulazne i izlazne operacije upotrebom medija kao što su ekran i tastatura. Tok je objekat gdje program bilo šalje ili prima karaktere prema/iz medija. Ne moramo voditi računa o mnogim specifikacijama o fizičkom mediju u vezi sa tokom – mi samo treba da znamo da se karakteri prosljeđuju sekvencijalno. Standardna C++ biblioteka uključuje header fajl iostream, gdje su standardni ulazni i izlazni tokovi deklarisani. Standardni izlaz (cout) Po default-u, standardni izlaz programa je ekran. C++ tok za pristup ekranu je cout. cout se koristi sa operatorom insertovanja '<<', primjer: cout << "Ispis"; // stampa Ispis na ekranu cout << 120; // stampa 120 na ekranu cout << x; // stampa vrijednost promjenljive x na ekranu Oerator '<<' insertuje podatke koji ga prate u tok koji mu prethodi. U prethodnom primjeru on insertuje konstantni string Ispis, numeričku konstantu 120 i vrijednost promjenljive x u standardni izlazni tok cout. Primijetimo da je rečenica u prvoj naredbi zatvorena sa duplim znacima navoda (") zato što je njen sadržaj niz karaktera. Uvijek kada želimo koristiti konstantan niz karaktera moramo ga staviti izmedju navodnika (") tako da on može biti razlikovan od imena promjenljive. Na primjer, ovo su dvije rečenice koje imaju različite rezultate: cout << "Zdravo"; // stampa Zdravo cout << Zdravo; // stampa vrijednost promjenljive Zdravo Operator insertovanja može biti korišćen više puta u jednoj naredbi: cout << "Zdravo, " << "ja sam " << "C++ naredba"; Prethodna naredba štampa poruku Zdravo, ja sam C++ naredba na ekranu. Korisnost ponavljanja operatora (<<) pokazuje se kada želimo da štampamo na ekranu kombinaciju promjenljivih i konstanti ili više od jedne promjenljive: cout << "Zdravo, imam " << age << "godina i moj zipkod je " << zipkod; 18 Ako pretpostavimo da promjenljiva age sadrži vrijednost 24 i da promjenljiva zipcode sadrži 90064 izlaz prethodne naredbe će biti: Zdravo, imam 24 godina i moj zipkod je 90064 Važno je primijetiti da cout ne prelazi u novi red poslije ispisa ukoliko eksplicitno ne ukažemo na to. Naredne naredbe: cout << "Recenica1."; cout << " Recenica2."; na ekranu će prikazati: Recenica1. Recenica2. U C++ programskom jeziku prelazak u novi red se ostvaruje zadavanjem '\n': cout << "Recenica1.\n"; cout << "Recenica2.\nRecenica3."; Prethodne naredbe proizvode sljedeći izlaz: Recenica1. Recenica2. Recenica3. Dodatno, da dodamo novu liniju, možemo koristiti endl manipulator. Na primjer: cout << "Recenica1." << endl; cout << "Recenica2." << endl; će štampati: Recenica1. Recenica2. Osim prelaska u novi red endl manipulator ima dodatno svojstvo kada se koristi sa baferovanim tokovima: bafer je prazan. Standardni ulaz (cin) Standardni ulazni ure]aj obično je tastatura. Obrada standardnog ulaza u C++ programskom jeziku urađena je primjenom preklopljenog operatora '>>' sa cin tokom. Operator '>>' prati promjenljiva koja čuva podatke iz ulaznog toka. Na primjer: int age; cin >> age; Prva naredba deklariše promjenljivu age tipa int, druga čeka ulaz iz cin (tastatura) u cilju da ga sačuva u age. cin prosljeđuje ulaz sa tastature kada je RETURN tipka pritisnuta. Morate uzeti u obzir tip promjenljive koju ćete koristiti da prihvati ono što prosljeđuje cin. Ako zahtijevate cijeli broj, dobićete cijeli broj, ako zahtijevate karakter dobićete karakter i ako zahtijevate string dobićete string. 19 // i/o primjer #include <iostream> using namespace std; int main () { int i; cout << "Unesite cijeli broj: "; cin >> i; cout << "Broj koji ste unijeli je " << i; cout << " njegova dvostruka vrijednost je " << i*2 << ".\n"; return 0; } Unesite cijeli broj: 702 Broj koji ste unijeli je 702 njegova dvostruka vrijednost je 1404 Korisnik programa može biti jedan od faktora koji generiše greške čak u najjednostavnijim programima koji koriste cin (kao prethodni primjer). Ako zahtijevate cjelobrojnu vrijednost, a korisnik unese ime (koje je generalno niz karaktera), program može pogrešno funkcionisati. Dakle, ako koristimo ulazni podatak dobijen preko cin toka, moramo vjerovati da će korisnik programa biti kooperativan i da neće unijeti svoje ime ili nešto slično kada se traži cjelobrojna vrijednost. Malo kasnije, kada budemo obrđivali stringstream klasu vidjećemo moguće rješenje za greške koje su uzrokovane pogrešnim unosom korisnika. Takođe možete koristiti cin da zahtijevate više od jednog ulaznog podatka od korisnika: cin >> a >> b; što je ekvivalentno sa: cin >> a; cin >> b; U oba slučaja korisnik mora dati dva podatka, jedan za promjenljivu a i drugi za promjenljivu b koje mogu biti razdvojene bilo kojim validnim blanko separatorom. cin i stringovi Možemo koristiti cin da preuzmemo string sa operatorom '>>' kao što radimo sa osnovnim tipovima podataka: cin >> mystring; Međutim, kao što je rečeno, preuzimanje podataka prestaje čim naiđe prazni karakter, tako je u ovom slučaju moguće dobiti samo jednu riječ. Ovo ponašanje jeste ili nije ono što mi želimo. Na primjer ako je cilj da dobijemo rečenicu sa više od jedne riječi od korisnika, nećemo dobiti ono što želimo na ovaj način. Kako bi dobili čitav red, možemo koristiti funkciju getline u kombinaciji sa cin: /// cin sa stringovima #include <iostream> #include <string> using namespace std; int main () { string mystr; cout << "Vase ime? "; getline (cin, mystr); cout << "Zdravo " << mystr << ".\n"; cout << "Omiljeni tim? "; Vase ime? Marko Iliic Zdravo Marko Ilic. Omiljeni tim? Mogren Ja volim Mogren takodje! 20 getline (cin, mystr); cout << "Ja volim " << mystr << " takodje!\n"; return 0; } Primijetimo kako u oba poziva getline koristimo isti string identifikator (mystr). Što program radi u drugom pozivu je jednostavna zamjena prethodnog sadržaja novim kojim je unešen. Stringstream Standardni header fajl <sstream> definiše klasu koja se zove stringstream koja dopušta da stringbaziran objekat bude tretiran kao tok. Sada možemo vršiti procesiranje stringova, što je posebno korisno za konverziju stringova u numeričke vrijednosti i obrnuto. Na primjer, ako želimo dobiti cijeli broj iz stringa možemo pisati: string mystr ("1204"); int myint; stringstream(mystr) >> myint; Ovo deklariše string objekat sa vrijednošću "1024" i int objekat. Koristimo stringstream-ov konstruktor da konstruišemo objekat ovog tipa iz string objekta. Kako možemo koristiti stringstream objekte kao da su tokovi, možemo dobiti cijeli broj iz njega kao što možemo uraditi sa cin primjenom operatora '>>'. // stringstreams #include <iostream> #include <string> #include <sstream> using namespace std; int main () { string mystr; float price=0; int quantity=0; cout << "Unesi cijenu: "; getline (cin,mystr); stringstream(mystr) >> price; cout << "Unesi kolicinu: "; getline (cin,mystr); stringstream(mystr) >> quantity; cout << "Ukupna cijena: " << price*quantity << endl; return 0; } Unesi cijenu: 22.5 Unesi kolicinu: 7 Ukupna cijena: 157.5 U ovom primjeru, dobijamo numeričku vrijednost sa standardnog ulaza indirektno. Umjesto procesiranja numeričke vrijednosti direktno sa standardnog ulaza, prihvatamo red sa standardnog ulaza (cin) u string objekat (mystr), a potom prosljeđujemo cjelobrojnu vrijednost iz ovog stringa u promjenljivu tipa int (quantity). Koristeći ovaj metod, umjesto direktnog procesiranja cjelobrojnih varijabli, imamo više kontrole nad onim šta se dešava sa ulaznim numeričkim vrijednostima koje korisnik unosi, pošto smo razdvojili proces dobijanja unosa korisnika (mi sada jednostavno preuzimamo linije) od interpretacije toga unosa. Dakle, ovaj metod se češće koristi za dobijanje numeričkih vrijednosti od korisnika u programima koji podrazumijevaju intenzivnu interakciju sa korisnikom. 21
© Copyright 2024 Paperzz