close

Enter

Log in using OpenID

1. Osnovna struktura C++ programa

embedDownload
1. Osnovna struktura C++ programa
Uobičajeno je da svaka priča o programskom jeziku C++ počinje opisom kratkog programa koji
ispisuje pozdravnu poruku na ekranu. Stoga će naš prvi program izgledati ovako:
// Ovaj program ispisuje pozdravnu poruku
#include <iostream>
using namespace std;
int main()
{
cout << "Zdravo narode!";
return 0;
}
Čak i u ovako kratkom programu, moguće je uočiti nekoliko karakterističnih elemenata:
// Ovaj program ispisuje pozdravnu poruku
Komentar
#include <iostream>
Zaglavlje standardne biblioteke
using namespace std;
Deklaracija standardnog imenika
int main()
{
cout << "Zdravo narode!";
return 0;
}
Zaglavlje funkcije
Naredba 1
Naredba 2
Funkcija
Znak “//” označava komentar. Prilikom prevođenja programa, kompajler potpuno ignorira sve što je
napisano iza znaka za komentar do kraja tekućeg reda. Svrha komentara je da pomogne ljudima koji
analiziraju program da lakše shvate šta program ili njegovi pojedini dijelovi rade. Komentari su obično
kratki. Postoji još jedan način za pisanje komentara, naslijeđen iz jezika C. Sve što se nalazi između
oznaka “/*” i “*/” također se tretira kao komentar. Ovakav način pisanja komentara može biti pogodan
za pisanje komentara koji se protežu u više redova teksta, kao na primjer u sljedećem programu:
/* Ovo je veoma jednostavan C++ program.
On ne radi ništa posebno, osim što ispisuje pozdravnu poruku.
Međutim, od nečeg se mora početi. */
#include <iostream>
using namespace std;
int main()
{
cout << "Zdravo narode!";
return 0;
}
// Ispisuje tekst "Zdravo narode!"
// Vraća 0 operativnom sistemu
Glavninu programa sačinjava cjelina nazvana funkcija. Funkcije predstavljaju funkcionalne cjeline
programa koje objedinjavaju skupine naredbi koje su posvećene obavljanju nekog konkretnog zadatka.
Prikazani program ima samo jednu funkciju. Iole složeniji programi gotovo uvijek imaju više funkcija, jer
je veće programe mnogo lakše pisati ukoliko se prethodno razbiju na manje funkcionalne cjeline koje se
kasnije izvode kao različite funkcije. U svakom C++ programu mora postojati tačno jedna funkcija koja se
zove “main”. Ova funkcija se naziva glavna funkcija, i to je ona funkcija koja će se prva početi izvršavati
kada program započne sa radom. U našem primjeru, to je ujedno i jedina funkcija u programu. Drugim
riječima, program uvijek započinje izvršavanje od prve naredbe glavne funkcije.
Funkcije u programskom jeziku C++ uvijek započinju zaglavljem (engl. function heading) koje pored
imena funkcije sadrži spisak parametara funkcije (engl. parameter list), i tip povratne vrijednosti (engl.
return type). Parametri su podaci koje pozivaoc funkcije treba da proslijedi pozvanoj funkciji, sa ciljem
preciziranja zadatka koji funkcija treba da obavi. Popis parametara se navodi u zagradama neposredno iza
imena funkcije. Pošto se main funkcija poziva neposredno iz operativnog sistema, eventualne parametre
ovoj funkciji može proslijediti jedino operativni sistem. Stoga je najčešći slučaj da funkcija main nema
nikakvih parametara, što se označava praznim zagradama (odsustvo parametara se ponekad označava i
navođenjem riječi “void“ unutar zagrada, što je zastarjela praksa nasljeđena iz jezika C). O parametrima
ćemo detaljnije govoriti u kasnijim poglavljima.
Ispred imena funkcije navodi se tip povratne vrijednosti funkcije. Povratna vrijednost je vrijednost
koju funkcija vraća pozivaocu funkcije. Vraćanje vrijednosti obavlja se pomoću naredbe “return”, koja
tipično predstavlja posljednju naredbu unutar funkcije, i iza koje se navodi povratna vrijednost. U slučaju
funkcije “main”, povratna vrijednost se vraća operativnom sistemu. Po dogovoru, vrijednost “0” vraćena
operativnom sistemu označava uspješan završetak programa, dok se vrijednosti različite od nule vraćaju
operativnom sistemu isključivo kao signalizacija da iz nekog razloga program nije uspješno obavio
planirani zadatak (značenje ovih vrijednosti zavisi od konkretnog operativnog sistema). Stoga je
posljednja naredba funkcije “main“ u gotovo svim slučajevima naredba
return 0;
Sve naredbe jezika C++ obavezno završavaju znakom “;”, koji označava kraj naredbe (jedna od
najčešćih sintaksnih grešaka u C++ programima je upravo zaboravljanje završnog tačka-zareza na kraju
naredbe). Riječ “int“ ispred imena funkcije označava da je vrijednost koju ova funkcija vraća cijeli broj,
kao što će biti jasnije iz sljedećeg poglavlja.
Kako je povratna vrijednost iz “main“ funkcije gotovo uvijek nula, mnogi kompajleri dopuštaju da se
naredba “return“ potpuno izbaci iz “main“ funkcije. Tako nešto ne smatra se dobrom programerskom
praksom. Također, ranije verzije kompajlera za C++ dozvoljavale su da se naredba “return“ izbaci i da
se tip povratne vrijednosti “int“ zamijeni sa “void”, što označava da se nikakva povratna vrijednost ne
vraća. Standard ISO C++98 zabranio je ovakvu praksu, i strogo naredio da funkcija “main“ kao povratni
tip može imati samo “int”, i ništa drugo.
Nakon zaglavlja funkcije, slijedi tijelo funkcije (engl. function body). Tijelo funkcije počinje znakom
“{“ a završava znakom “}”, odnosno tijelo funkcije uvijek je omeđeno vitičastim zagradama. Kasnije
ćemo vidjeti da se vitičaste zagrade koristimo kada god treba objediniti neku skupinu naredbi u jednu
kompaktnu cjelinu. U ovom slučaju ta cjelina će biti upravo tijelo funkcije. Pod naredbama
podrazumijevamo upute koje govore računaru kakvu akciju treba da preduzme, odnosno naredbe opisuju
algoritam. Kao što vidimo, program se ne sastoji samo od naredbi. Na primjer, komentar ili zaglavlje
funkcije nisu naredbe, jer ne dovode do nikakve konkretne akcije. Program u našem primjeru je toliko
jednostavan da ima samo dvije naredbe, od kojih je druga naredba praktično trivijalna. Analizirajmo stoga
jedinu netrivijalnu naredbu u programu, koja glasi:
cout << "Zdravo narode!";
“cout“ (skraćenica od engl. console out) predstavlja objekat tzv. izlaznog toka podataka (engl. output
stream), koji je povezan sa standardnim uređajem za ispis. Standardni uređaj za ispis je tipično ekran,
mada ne mora biti (C++ uopće ne podrazumijeva da računar na kojem se program izvršava mora
posjedovati ekran). Znak “<<” predstavlja operator umetanja (engl. insertion) u izlazni tok, koji
pojednostavljeno možemo čitati kao “šalji na”. Tekst "Zdravo narode!" koji se nalazi između
navodnika, predstavlja niz znakova koji šaljemo na (odnosno umećemo u) izlazni tok. Takav niz znakova
nazivamo stringovni literal (ili neimenovana stringovna konstanta). O stringovnim literalima i
stringovima općenito će kasnije biti više govora, a za sada će nam stringovni literali služiti samo za ispis
fiksnog teksta na izlazni uređaj. Dakle, gornja naredba može se interpretirati kao:
Pošalji niz znakova “Zdravo narode!” na izlazni uređaj (tipično ekran).
Uz pretpostavku da smo uspješno kompajlirali i pokrenuli program (tačan postupak kako se to radi
ovisi od upotrijebljenog kompajlera), na ekranu bi se trebao pojaviti ispis poput sljedećeg:
Zdravo narode!
U slučaju da radite pod nekim grafičkim operativnim sistemom (poput Windows-a), ovaj tekst će se
tipično pojaviti u posebnom prozoru nazvanom konzolni prozor. Moguće je da u slučaju kompajlera sa
kojim radite nećete biti u stanju da vidite nikakav tekst, jer se konzolni prozor obično automatski zatvara
nakon završetka programa, čime i ispisani tekst odlazi u nepovrat. O načinima za prevazilaženje ovog
problema govorićemo u narednom poglavlju, a u međuvremenu, djelimično rješenje može biti ubacivanje
sljedeće naredbe neposredno ispred naredbe “return”:
cin.get();
Ubacivanjem ove naredbe postići ćemo da se program neće završiti prije nego što korisnik pritisne tipku
ENTER, čime smo odložili zatvaranje konzolnog prozora. Ovo nije zapravo pravi smisao ove naredbe. već
smo se ovdje oslonili na jednu njenu propratnu pojavu. O njenom tačnom smislu govorićemo u kasnijim
poglavljima.
Objekat “cout“ ne mora nužno prihvaćati samo stringovne literali, nego i mnoge druge tipove
podataka o kojima će biti više riječi kasnije. Na primjer, pored stringovnih literala, biće prihvaćeni i
brojevi (brojčani literali), tako da možemo pisati:
cout << "Proba";
cout << 1234;
cout << 12.34;
U gornjem primjeru “12.34” je decimalni broj. Primijetimo da se za odvajanje decimala od cijelog dijela
ne koristi zarez nego tačka. O pravilima za pisanje brojeva govorićemo detaljnije u poglavljima koja
slijede.
Operator umetanja u tok može se primijeniti više puta zaredom na “cout“ objekat, tj. možemo pisati
cout << "Broj je " << 10;
Ovo će proizvesti sljedeći ispis na izlazni uređaj:
Broj je 10
Veoma je bitno da se na samom početku shvati razlika između objekata kao što su 10 i "10". Objekat
10 je broj i nad njim se mogu vršiti računske operacije poput sabiranja itd. S druge strane, objekat "10" je
niz znakova (stringovni literal) koji se slučajno sastoji od dvije cifre (1 i 0), i nad njim se ne mogu vršiti
nikakve računske operacije (npr. telefonski broj je sigurno sastavljen od cifara, ali teško kome će pasti na
pamet da sabira dva telefonska broja zajedno). Ova razlika će biti mnogo jasnija nešto kasnije. Ipak, sa
aspekta ispisa ova dva objekta se ponašaju identično, tako da bi isti efekat proizvela i sljedeća naredba:
cout << "Broj je " << "10";
ili prosto
cout << "Broj je 10";
Stringovni literali mogu sadržavati potpuno proizvoljan niz znakova, tako da je npr. "! ?@ #"
sasvim legalan stringovni literal, iako je njegov smisao upitan. Grubo rečeno, može se shvatiti da
navodnici označavaju “bukvalno to”, “baš to” itd. Kada god nisu upotrijebljeni navodnici, kompajler za
C++ će pokušati da interpretira smisao onog što je napisano prije nego što se izvrši ispis (o čemu će
kasnije biti više riječi), dok kada se upotrijebe navodnici, na izlazni uređaj se bukvalno prenosi ono što je
napisano između njih. Tako npr. ako napišemo
cout << "2+3";
na ekranu ćemo dobiti ispis
2+3
dok ako napišemo
cout << 2+3;
prikaz na ekranu će biti
5
Naravno, naredba poput
cout << @#!&&/3++;
dovešće do prijave greške od strane kompajlera, jer je kompajler pokušao (bezuspješno) da interpretira
smisao napisanih znakova, dok je s druge strane,
cout << "@#!&&/3++";
posve legalna naredba. Da bismo ovo još jednom istakli, uzmimo da želimo da ispišemo telefonski broj sa
crticom. Moramo pisati
cout << "453-728";
a ne nipošto
cout << 453-728;
jer će u posljednjem slučaju “-” biti shvaćen kao znak za oduzimanje, tako da ćemo umjesto telefonskog
broja imati ispisan rezultat oduzimanja (tj. -275).
Ovim još nismo objasnili sve elemente našeg prvog programa. Prvi red programa ne računajući
komentar je glasio:
#include <iostream>
Naredba “#include“ predstavlja uputu (tzv. direktivu) kompajleru da u program uključi tzv.
zaglavlje biblioteke (engl. library header) sa imenom “iostream”. Naime, sve funkcije i objekti u jeziku
C++ grupirani su u biblioteke, i na početku svakog programa obavezno se uključuju sve biblioteke koje
sadrže funkcije i objekte koje koristimo u programu. Biblioteka “iostream“ (skraćeno od engl. inputoutput stream), između ostalog, definira objekat “cout“ koji koristimo za pristup izlaznom toku podataka.
Tako, npr. ako pišemo matematički program, na početku programa će također stajati i
#include <cmath>
a ako pišemo program koji radi sa grafikom, vjerovatno ćemo imati i nešto poput:
#include <graphics.h>
Ideja svega ovoga je da se program ne opterećuje bespotrebno objektima i funkcijama koji se neće
koristiti unutar programa. Npr. bespotrebno je program opterećivati grafičkim objektima ako program
neće koristiti grafiku. Standard ISO C++98 jezika C++ predviđa da se kao sastavni dio jezika C++
obavezno moraju nalaziti sljedeće biblioteke:
algorithm
ciso64
csignal
ctime
functional
iterator
bitset
climits
cstdarg
cwchar
iomanip
limits
cassert
clocale
cstddef
cwtype
ios
list
cctype
cmath
cstdio
deque
iosfwd
locale
cerrno
complex
cstdlib
exception
iostream
map
cfloat
csetjmp
cstring
fstream
istream
memory
new
stack
valarray
numeric
stdexcept
vector
ostream
streambuf
queue
string
set
typeinfo
sstream
utility
U starijim verzijama kompajlera za C++ sva zaglavlja biblioteka imala su nastavak “.h“ na imenu,
tako da se umjesto zaglavlja “iostream“ koristilo zaglavlje “iostream.h”. Novi kompajleri još uvijek
podržavaju stara imena zaglavlja, ali njihovo korištenje se ne preporučuje, jer će podrška za stara imena
biti izbačena u doglednoj budućnosti. Kompajler ima pravo da upozori programera na to da se upotreba
starih zaglavlja ne preporučuje emitiranjem poruke upozorenja. Sve biblioteke čija imena počinju slovom
“c” osim “complex“ naslijeđena su iz jezika C, u kojima su imali imena zaglavlja bez početnog slova “c”
i sa nastavkom “.h“ (npr. ”math.h” umjesto “cmath”). I u ovom slučaju, stara imena zaglavlja se još
uvijek mogu koristiti, ali tu praksu treba izbjegavati.
Pored navedenih 50 standardnih biblioteka, mnogi kompajleri za C++ dolaze sa čitavim skupom
nestandardnih biblioteka, koje ne predstavljaju propisani standard jezika C++. Tako, na primjer,
biblioteka za rad sa grafikom sigurno ne može biti unutar standarda jezika C++, s obzirom da C++ uopće
ne podrazumijeva da računar na kojem se program izvršava mora imati čak i ekran, a kamoli da mora biti
u stanju da vrši grafički prikaz. Također, biblioteka sa zaglavljem “windows.h“ koja služi za pisanje
Windows aplikacija ne može biti dio standarda C++ jezika, jer C++ ne predviđa da se programi moraju
nužno izvršavati na Windows operativnom sistemu. Zaglavlja nestandardnih biblioteka gotovo uvijek
imaju i dalje nastavak “.h“ na imenu, da bi se razlikovala od standardnih biblioteka. Treba napomenuti i
to da se nestandardne biblioteke za razne namjene često mogu nabaviti i kod neovisnih proizvođača
softvera, ili besplatno skinuti sa Interneta. Očigledno su nestandardne biblioteke često itekako potrebne,
ali ne mogu da uđu u dio standarda jezika C++, s obzirom da standard jezika ne smije da sadrži nikakve
pretpostavke o hardverskim osobinama računara na kojem se program izvršava, niti o operativnom
sistemu koji se izvršava na računaru.
Strogo uzevši, direktiva “#include“ ne čini sastavni dio jezika C++, nego čini tzv. naredbu
pretprocesora. Pretprocesor je program koji vrši početnu obradu C++ programa još prije nego što C++
program uopće bude prihvaćen od strane kompajlera. Kako je pretprocesor obično tijesno vezan za
kompajler, korisnik najčešće nije svjestan ove činjenice (i ne mora da bude svjestan, osim u veoma
naprednim primjenama). Sve naredbe pretprocesora počinju znakom “#” koji se, inače, čita kao “heš”
(engl. hash).
Preostaje još da objasnimo red programa koji je glasio:
using namespace std;
Ovaj programski red govori programu da koristi imenik (engl. namespace) nazvan “std”. Imenici su
osobina jezika C++ koja je uvedena tek nedavno. Naime, pojavom velikog broja nestandardnih biblioteka
različitih proizvođača bilo je nemoguće spriječiti konflikte u imenima koje mogu nastati kada dvije
različite biblioteke upotrijebe isto ime za dva različita objekta ili dvije različite funkcije. Zbog toga je
odlučeno da se imena svih objekata i funkcija razvrstavaju u imenike. Dva različita objekta mogu imati
isto ime, pod uvjetom da se nalaze u različitim imenicima. Standard propisuje da se svi objekti i sve
funkcije iz standardnih biblioteka moraju nalaziti u imeniku “std”. Pomoću navedenog programskog reda
govorimo kompajleru da želimo da sve funkcije i objekti iz ovog imenika budu vidljivi u našem programu.
Bez ovog reda, objektu “cout“ bismo morali pristupati pomoću konstrukcije “std::cout”, koja znači
“objekat cout iz imenika std”. Alternativno bismo umjesto prethodnog programskog reda mogli pisati
i sljedeći red:
using std::cout;
Ovim bismo naglasili da želimo pristupati objektu “cout“ iz imenika “std“ (bez kasnijeg stalnog
navođenja imena imenika pri svakom pristupu cout objektu), bez potrebe da “uvozimo” čitav imenik
“std”.
Da uočimo još neke osobine objekta “cout”, napisaćemo ponovo program koji radi istu stvar kao i
program iz prvog primjera, ali na nešto drugačiji način:
#include <iostream>
using namespace std;
int main()
{
cout << "Zdravo ";
cout << "narode!";
return 0;
}
Ovaj program proizvodi potpuno isti ispis kao i prethodni program, jer svaka sljedeća naredba za ispis
nastavlja sa ispisom tačno od onog mjesta gdje se prethodna naredba za ispis završila. Razmak iza “o” u
prvoj naredbi je bitan. Naime, i razmak je dio stringovnog literala, i kao takav biće ispisan na izlazni
uređaj. Da smo izostavili taj razmak, tj. da smo glavnu funkciju napisali ovako:
int main()
{
cout << "Zdravo";
cout << "narode!";
return 0;
}
tada bi ispis na ekran izgledao otprilike ovako:
Zdravonarode!
Važno je napomenuti da su svuda osim unutar stringova i šiljatih zagrada (<>), dodatni razmaci
potpuno nebitni, i kompajler ih ignorira, što omogućava programeru stiliziranje izgleda programa u svrhu
poboljšanja njegove čitljivosti. Zapravo, isto vrijedi ne samo za razmake nego i za sve tzv. bjeline (engl.
whitespaces), u koje osim razmaka spadaju tabulatori i oznake za kraj reda. Tako se naredbe koje čine
tijelo funkcije obično pišu neznatno uvučeno, da se vizuelno istakne početak i kraj tijela. Razmaci unutar
šiljastih zagrada nisu dozvoljeni, tj. sljedeća direktiva je neispravna:
#include < iostream >
Unutar stringovnih literala mogu se naći i neki specijalni, tzv. kontrolni znakovi. Jedan od
najkorisnijih je znak “\n” koji predstavlja znak za “novi red” (kasnije ćemo upoznati i neke druge
kontrolne znakove). Tako, ako napišemo
cout << "Zdravo\nnarode!";
ispis na ekranu će biti:
Zdravo
narode!
Naravno, mogli smo istu stvar pisati i kao 2 naredbe:
cout << "Zdravo\n";
cout << "narode!";
Ovakav način pisanja početnicima obično bude jasniji.
Biblioteka “iostream“ definira objekat nazvan “endl”, koji je u logičkom smislu sinonim za string
"\n" (mada u izvedbenom smislu postoje značajne razlike) tako da smo istu naredbu mogli pisati i kao:
cout << "Zdravo" << endl << "narode!";
ili je raščlaniti na dvije naredbe kao:
cout << "Zdravo" << endl;
cout << "narode!";
Važno je napomenuti da stil pisanja programa (razmaci, novi redovi, uvlačenje redova, itd.) ni na koji
način ne utiču na njegovo izvršavanje. Novi red ne označava kraj naredbe, nego je kraj naredbe isključivo
tamo gdje se nalazi znak tačka-zarez. Tako bi sljedeći program proizveo isti efekat kao i program iz prvog
primjera:
#include <iostream>
using namespace std;
int main(){cout<<"Zdravo narode!";return 0;}
Još gore, isti rezultat bi proizveo i ovakav program:
#include <iostream>
using
namespace
std;int
main(
){ cout
<<
"Zdravo narode!"
;return
0
;}
Naravno, radi čitljivosti programa treba paziti na stil pisanja. Treba napomenuti da se stringovi ne
smiju prelamati u više redova. Na primjer, nije dozvoljeno pisati:
cout << "Zdravo
narode!";
Šta će se dogoditi ukoliko napišemo nešto slično, zavisi od konkretnog kompajlera. Neki kompajleri će
prijaviti grešku, dok će neki prihvatiti ovakvu naredbu, i smatrati da string sadrži znak za novi red “\n” na
mjestu preloma. Čak i uz pretpostavku da je ovo dozvoljeno u Vašoj verziji kompajlera, ne trebate koristiti
tu mogućnost, jer ona nije podržana standardom.
Pretprocesorske naredbe se također moraju pisati u jednom redu, tako da nije dozvoljeno pisati:
#include
<iostream>
Pored toga, pretprocesorske naredbe se, kao što ste već vjerovatno primijetili, ne završavaju
tačka-zarezom.
Author
Document
Category
Uncategorized
Views
0
File Size
1 319 KB
Tags
1/--pages
Report inappropriate content