Professional Documents
Culture Documents
2 Bazat e Gjuhës Programuese C++
2 Bazat e Gjuhës Programuese C++
Bekteshi 3
C++
Përpunuar nga:
Dr. Sadik Bekteshi
Bazat e gjuhës programuese C++ S. Bekteshi 4
Përmbajtja
7. MATRICAT ............................................................................................................................. 76
Matricat njëdimensionale..........................................................................................................76
Deklarimi i matricës............................................................................................................76
Inicializimi i matricës .........................................................................................................77
Klasifikimi i matricave .......................................................................................................78
Matricat dhe funksionet ............................................................................................................79
Matricat shumëdimensionale ....................................................................................................80
Inicializimi i matricave shumëdimensionale ............................................................................80
8. TREGUESIT ........................................................................................................................... 84
Ruajtja e adresës në tregues ......................................................................................................84
Deklarimi i treguesve ................................................................................................................84
Operatori i adresës ....................................................................................................................85
Operatori i indireksionit............................................................................................................86
Shprehjet dhe aritmetika me ndryshore të tipit tregues ............................................................86
do të jep 3008 (3000+2*4) nëse një integer është ruatur në 4 bajt të memorjes.................87
Marrëdhënja në mes të matricave dhe treguesve ......................................................................87
Treguesit në funksione ..............................................................................................................88
9. STRINGJET............................................................................................................................ 89
Bazat e gjuhës programuese C++ S. Bekteshi 6
Para se të shkruhet një pogram për zgjidhjen e një problemi është me rëndësi që problemi të
kuptohet plotësisht dhe zgjidhja e tij të planifikohet me kujdes. Zgjidhja e një problemi duhet të
definohet në formë të një procedure të caktuar.
Agoritmi paraqet procedurën ose metodën e zgjidhjes së një problemi në bazë të:
- aksioneve që do të ekzekutohen dhe
- radhës sipas të cilit këto aksione do të ekzekutohen.
Përcaktimi i radhës sipas të cilës do të ekzekutohen në programin e kompjuterit quhet kontrolla
e programit. Në formimin e algoritmeve përdoret një gjuhë artificiale dhe informuese që i ndihmon
programuesit që quhet pseudokod.
Shembull: Të supozojmë se duhet të caktojmë se cili nga numrat pozitiv a dhe b e ka vlerën më të
madhe. Pseudokodi është si vijon:
numri b të zbritet nga numri a respektivisht të gjendet a-b;
nëse ndryshimi a-b është më i madh se zero atëhere numri a është më i madh se numri b;
nëse ndryshimi a-b është më i barabartë me zero atëhere numri a është i barabartë me
numrin b;
nëse ndryshimi a-b është më i vogël se zero atëhere numri a është më i vogël se numri b.
Kompjuteri nuk e kupton pseudokodin (algoritmin tekstual) e këtillë. Pseudokodet nuk
ekzekutohen në kompjuter. Ato vetëm i ndihmojnë programuesit të “mendojë” për programin para
se ta shkruaj atë. Pseudokodi i përgaditur me kujdes lehtë mund të shëndrrohet në program thjesht
duke i zëvendësuar urdhëresat e pseudokodit me ekuivalentet e tyre të C++. Pseudokodi përmban
vetëm urdhëresat ekzekutabile.
1. // prg5
2. #include <iostream.h>
3. int main()
4. {
5. int num1, num2; // deklarata
6. cout << "Shtypni dy numra: "; // kërkon
7. cin >> num1 >> num2; // ti shtypim dy numra
8. if ( num1 == num2 )
9. cout << "Numrat janë të barabartë." << endl;
10. if ( num1 > num2 )
11. cout << num1 << " është më i madh." << endl;
12. if ( num2 > num1 )
13. cout << num2 << " është më i madh." << endl;
14. return 0;
15. }
Dalja: Shtypni dy numra 3 8
8 është më i madh
mungojnë dhe përdoren vetëm rrathë të vegjël që quhen simbolet lidhëse. Prej të gjitha simboleve
ndoshta më i rëndësishmi është simboli diamond i cili quhet edhe simbol i vendosjes që tregon për
vendimet që do të mirren. Për këtë simbol do të bëhet fjalë edhe më vonë.
Diagramin e rrjedhjes duhet t’a vizatojmë në atë mënyrë që një vizatim të paraqes një tërësi
të plotë. Nëse programi është i madh ai duhet të ndahet në nënprograme ose “blloqe” të cilat
vizatohen tërësisht në vizatime të veqanta.
Diagrami i rrjedhjes paraqet dokumentin
themelor që duhet të jetë i detajuar në mënyrë që të
mundemi drejpërdrejt nga ai të shkruajmë programin. I shton shumën vlerës vlera=vlera+shuma;
Është mirë që në diagramin e rrjedhjes të shënohen
sqarime ose vërejtje të cilat në program do të
paraqiten si komente. Kjo ndihmon shumë gjatë I shton 1 sasisë Sasia= Sasia +1;
testimit dhe përpunimit të programit.
Përveç simboleve të theksuara mund të
përdoren edhe simbole tjera simbas zgjedhjes
personale duke pasur parasysh ato që u theksuan më Fig.2
lartë.
Bazat e gjuhës programuese C++ S. Bekteshi 10
Gjuhët programuese me të cilat mund të programohet ndahen në disa tipe në varshmëri nga
urdhëresat që disponojnë.
- Gjuhët e makinës
- Gjuhët assembler
- Gjuhët të nivelit të lartë
Gjuha e makinës është gjuha themelore. Gjuha e makinës është “gjuha natyrore” e çdo
kompjuteri, është e vetmja gjuhë të cilën e “kupton” kompjuteri dhe të cilën e realizon. Ajo është e
definuar nga dizajni hardverik i kompjuterit. Gjuhët e makinës gjithmonë përmbajnë vargjet e
numrave ( të 1-ve dh 0-ve) që e udhëzon kompjuterin që të kryejnë operacionet e tyre elementare
një nga një. Gjuhët e makinës janë gjuhë të varura nga makina që dmth se një gjuhë specifike e
makinës mund të përdoret vetëm në një tip të kompjuterit. Programimi në gjuhën e makinës është i
vështirë për përdorim dhe mundëson gabime të shumta.
Gjuha assembler - në vend që të përdoren vargjet e numrave shumë më e përshtatshme është që
të përdoren fjalë (anglishte) që paraqesin operacionet elementare të kompjuterit. Këto fjalë kanë
formuar bazën e gjuhëve assembler. Gjuha assembler ose gjuha simbolike mundëson shfrytëzimin
më të lehtë të gjuhës së makinës me futjen e emrave simbolik për urdhëresa dhe adresa të
lokacioneve të memorjes Programet përkthyese të quajtura assemblerë ishin zhvilluar që të kthejnë
instruksionet e shkruara në gjuhën assembler në urdhëresa të gjuhës së makinës. Në gjuhët
assembler korrespondenca ndërmjet gjuhës assembler dhe gjuhës së makinës është 1 me 1.
Programuesi i përdor urdhëresat e kompjuterit në të cilin punon dhe për këtë arsye programi nuk
mund të bartet në kompjuter tjetër (programi nuk mund të ekzekutohet në kompjuter tjetër pa u
riprogramuar).
Gjuhët programuese të nivelit të lartë (Fortran, Basic, Pascal, Cobol etj) i eliminojnë këto
probleme. Gjuha porgramuese e nivelit të lartë nuk varet nga kompjuteri. Programet e shkruara në
këto gjuhë janë të bartshëm (programi mund të ekzekutohet në kompjuter tjetër pa u riprogramuar)
kështu që programi mund të ekzekutohet në tipe të ndryshme të kompjuterëve. Kësaj i ka kontribuar
edhe standardizimi i sintaksës së gjuhës së lartë. Një urdhëresë e gjuhës së nivelit të lartë është
ekuivalente me grup të urdhëresave të gjuhës së makinës. Për këtë arsye është paraqitë nevoja që të
automatizohet procesi i përkthimit të urdhëresave të gjuhës së lartë në urdhëresat e gjuhës së
makinës.
Programet përkthyese që quhen compilers e konvertojnë gjuhën e nivelit të lartë në gjuhën e
makinës. Gjuhët e nivelit të lartë i lejojnë programuesit ti shkruajnë instruksionet në anglishte dhe
përmbajnë notacionin e zakonshëm matematik. Gjuhët C dhe C++ janë gjuhët ndër gjuhët më të
fuqishme dhe që përdoren më së shumti. Procesi i kompajllimit të gjuhës së nivelit të lartë në
gjuhën e makinës zakonisht merr një kohë të caktura. Programet interpreter i ekzekutojnë
drejtpërsëdrejti programet në gjuhën e nivelit të lartë pa pasur nevojë për kompajllimin e këtyre
programeve në gjuhën e makinës.
Programet, assemblerët dhe përkthyesit ekzekutohen në kompjuter në praninë e rrethinës së
caktuar. Këtë rrethinë e përcakton sistemi operues. Siç kemi thënë edhe më parë sistemi operues
është tërësi e programeve të cilat udhëheqim me resurset dhe serviset e sistemit kompjuterik siç
janë: memorjet, procesorët, pajisjet hyrëse/dalëse etj. Programi në mënyrë implicite ose eksplicite
me ndihmën e urdhëresave të sistemit ooperues mund t’i shfrytëzoj resurset e sistemit kompjuterik.
Në këtë mënyrë mundësohet dhe realizohet ekzekutimi i programit.
Bazat e gjuhës programuese C++ S. Bekteshi 11
Në figurën 3 është paraqitur një proces tipik i futjes, përkthimit dhe ekzekutimit të
programit të shkruar në gjuhën e nivelit të lartë. Programi i cili duhet të përkthehet duhet të futet në
kompjuter dhe të vendoset në mediumet e memorjes në formë të fajllit. Kjo realizohet me ndihmën
e editorit të tekstit e cila i përmban urdhëresat me ndihmën e të cilave e shtypim tekstin e programit.
Si rezultat i editorit është fajlli në formën burimore të programit e cila quhet programi burimor.
Hyrja në përkthyes është programi burimor. Rezultati ose dalja e përkthyesit fajlli me
programin e përkthyer burimor që quhet program i objektit.
Përkthimi kryhet më së shpeshti në dy faza. Faza e parë është përkthimi i programit burimor
në program ekuivalent assembler ndërsa e dyta
assemblimi i programit të fituar në program të
Fillimi i procesit
makinës. Disa përkthyes në mënyrë automatike e
thërrason assemblerin pas fazës së parë e disa jo. Në
rastin e dytë, programuesi duhet në mënyrë Futja e programit
eksplicite të jep urdhëresën për assenblim. Gjatë (editori)
përkthimit të programit burimor përkthyesi mund të
sinjalizoj prezencën e gabimeve në programin Përkthimi
burimor. Programi i objektit është hyrje në linker
(lidhës).
Linkeri është program sistemor që ka për Gabimi
detyrë që programin e objektit e eventualisht
programet e objekteve nga biblioteka sistemore si
edhe programet e përkthyera më parë t’i lidh me Biblioteka sistem. Linkimi (lidhja)
programin ekzekutues të cilin kompjuteri (sistemi
operativ) mund t’a ekzekuton. Linkeri mund të Ekzekutimi
thirret automatikisht në fazën e përkthimit. Në disa
sisteme kjo mundësi nuk ekziston kështu që linkimi
duhet të kryhet me urdhëresë eksplicite nga sistemi Gabimi
operativ.
Programi ekzekutues i fituar pas fazës së
linkimit është i gatshëm për ekzekutim. Programi Mbarimi i procesit
ekzekutues starton me urdhëresë nga sistemi
operues. Gjatë kësaj kohe ai pranohet nga mbushësi Fig.3
i cili programin e vendos në memorjen operuese
RAM, i rezervon resurset e sistemit dhe programin ekzekutues ia dorëzon sistemit operues.
Programi ekzekutues në zhvillimet e mëtejshme është nën kontrollën e sistemit operues.
Nëse programi gjatë ekzekutimit nuk jep rezultatet e kërkuara duhet që të përmirsohet
programi burimor dhe përsëri të kryhet përkthimi dhe lidhja.
Bazat e gjuhës programuese C++ S. Bekteshi 12
Tërësia e karaktereve
Fjalët e rezervuara
Fjalët e rezervuara (keywords) kanë një kuptim të definuar që më parë, kështu që nuk mund
të përdoren në konteste tjera. Fjalët e rezervuara nuk lejohet të përdoren si identifikatorë si psh
emër i ndonjë ndryshoreje. Karakteristikë e gjuhës C++ është përdorimi vetëm i shkronjave të vogla
për shkruarjen e fjalëve të rezervuara. Kjo gjuhë ka një numër relativisht të vogël të fjalëve të
rezervuara në krahasim me gjuhët tjera por me këtë mundëstë e saj nuk janë zvogluar (tabela.2).
Emërtimet
Shprehja
Çdo gjë që jep si rezultat një vlerë paraqet shprehje në C++. Të gjitha shprehjet janë
urdhëresa. Kombinimi i operandëve (ndryshoreve dhe konstanteve) dhe operatorëve formon
shprehjen. Shprehja i kryen llogaritjet dhe jep një rezultat i cili shkakton një aktivitet. Një shprehje
thuhet se e kthen vlerën.
Shembull: Shprehja:
1. 3.2 // e kthen vlerën 3.2
2. PI // e kthen vlerën 3.14
3. x = a + b;
Shprehja e fundit, përkundër algjebrës, nuk domethanë se x është i barabartë me a+b por
vlera e a e mbledhë me vlerën e b dhe rezultati i fituar i jipet x. Pasi kemi të bëjmë me shprehje ajo
e kthen vlerën e x.
Urdhëresa
Në C++ urdhëresa kontrollon radhën e ekzekutimit, e zhvillon (evaluates) një shprehje ose
nuk bën asgjë (urdhëresa null). Pikëpresja është shenja për fundin (mbarimin) e urdhëresës.
Urdhëresë themelore është shprehja pas të cilës vjen pikëpresja dhe klasifikohet si urdhëresë e tipit
të shprehjes..
Urdhëresat sipas rregullës ekzekutohen sipas radhës së paraqitjes së tyre në program. Radha
e ekzekutimit megjithate mund të ndryshohet me urdhëresat të cilat e bartin rrjedhjen e programit
në një pjesë tjetër ose jasht programit.
Urdhëresa e përbërë e cila poashtu quhet edhe blok urdhëresë është mekanizëm i cili grupon
disa urdhëresa në një tërësi sintaksore. Grupi i urdhëresave që formojnë blok urdhëresën duhet të
futet brenda kllapave të mëdha. Blok urdhëresa trajtohet si një urdhëresë nga kompajlleri i C++.
Bloqet mund të jenë të përfshira dhe secili mund të përmbaj pos urdhëresave ekzekutuese,
deklaratat dhe inicializimet vetjake.
Shembull: Një blok urdhëresë që është e vendosur brenda kllapave të mëdha {}e ka formën:
for(. . .) {
s3 = s1 + s2;
mul = s3 * c;
mbetja = shuma % c;
}
1. prg1
2. #include <iostream.h>
3. int main()
4. {
5. cout << "Programi im i pare ne C++!\n";
6. return 0; /*tregon se programi përfundon me sukses*/
7. }
Dalja: Programi im i pare ne C++!
Funksionet main dhe cout janë emrat e funksioneve sistemore. Funksioni main e informon
sostemin se ku fillon ekzekutimi i programit ndërsa kllapat () tregojnë se funksioni main nuk ka
argumente. Në programin C++ duhet të ekzistoj vetëm një main() sepse programi nuk mund të filloj
ekzekutimin në disa vende njëkohsisht. Fjala e rezervuar int majtas main tregon se main “kthen”
vlerë të tipit int (numër të plotë). Kllapa e madhe { e fillon trupin e çdo funksioni; në këtë rast edhe
të funksionit main kurse kllapa e madhe e djathtë } tregon mbarimin e trupit respektivisht fundin e
funksionit main.
cout (lexo si-out) është funksion për shtypjen e vargut të karaktereve që gjenden në mes të
thojzave në ekran, në rastin tonë të lajmërimit “Programi im i parë në gjuhën C++”.
cout << “Programi im i parë në gjuhën C++”; është një urdhëresë dhe paraqet përpunimin
elementar të cilin duhet t’a kryej programi. Karakteri << quhet operatori i futjes së stream-it. Kur
programi ekzekutohet, vlera që gjendet djathtas operatorit, operandi i djathtë, futet në stream-in
dalës. Karakteret që gjenden në operandin e djathtë shtypen saktë ashtu si paraqiten brenda
thojzave. Karakteri pikëpresje“;” e luan rolin e terminatorit të urdhëresës.
Bazat e gjuhës programuese C++ S. Bekteshi 15
1. //prg2
2. #include <iostream.h> int main(){cout << "Programi im i pare ne C++!\n";
3. return 0; // tregon se programi përfundon me sukses }
Natyrisht programet nuk duhet të shkruhen në këtë stil për hirë të lexueshmërisë dhe
dokumentimit të programit.
Në iostream.h janë të definuara cout dhe cin. Nëse ky fajll header është i përfshirë atëhere
mund të kryhen H/D me cout dhe cin. cout dhe cin quhen objekte. Në terminologjinë e C++ objekti
është i ngjashëm me ndryshoren, në këtë rast tipi i të dhënave është fajlli në vend të një integeri ose
karakteri. cout përdoret së bashku me karakterin << ndërsa cin me operatorin >>. Operatori <<
quhet operator i dhënjes sepse i jep të dhënat në ekran (i fut të dhënat në te) ndërsa operatori >>
quhet operator i nxjerrjes sepse i nxjerr nga tastatura (i mmerr të dhënat prej saj)
Opsionet e daljes – Me anë të cout shtypim në ekran tipin e të dhënave integer, float si dhe vargun
e karaktereve brenda thojzave.
Shembull: b) Një ndryshore e tipit float gjithëmonë ka saktësinë prej gjashtë shifrave kështu që
kur të shtypet 4.5 si:
cout << 4.5;
C++ shtyp 4.500000.
Shembull: c) Që të sigurojmë zeron e lëvizhne duhet të vendoset shenja (flag) e cout. Psh:
cout.setf(ios::fixed); // vendos shenja (flag) e cout për pike fikse
cout.setf(ios::showpoint); // Gjithëmonë e paraqet pikën dhjetore
cout.precision(2); // Dy shifra dhjetore
cout << 4.5;
shtyp 4.50 në ekran.
cin.ignore(80, '\n'); // Ifshin të dhënat hyrëse
Nëse saktësia është ndryshuar me precision(), saktësia e zakonshme prej gjashtë numrash
kthehet me urdhëresëm:
cout.precision(0); // E rikthen saktësinë e nënkupruar prej gjashtë numrash
ose
cout.precision(6); // E vendos saktësinë e nënkupruar prej gjashtë numrash
Shembull: d) Psh dy hapësia të daljes për dy numra, tri hapësira të daljes për tre numra etj.
Manipulatori () përdoret për shtimin e hapësirave në dalje. Urdhëresat vijuese cout tregojnë se çka
është e mundshme me width():
cout.setf(ios::fixed);
cout.setf(ios::showpoint);
cout << 4.56 << endl;
cout.width(12);
cout << 4.56 << endl;
cout.width(8);
cout << "xyz" << endl;
cout.width(6);
cout << 12 << endl;
Këto katër urdhëresa për dalje japin në dalje:
4.560000
4.560000
xyz
12
Të theksojmë se secila vlerë është shtyp brenda gjërësisë së përcaktuar. Ose urdhëresat:
Bazat e gjuhës programuese C++ S. Bekteshi 17
cout.width(10);
cout << 123 << endl;
cout.width(10);
cout << 12345 << endl;
cout.width(10);
cout << 1234567 << endl;
Këto tri urdhëresa për dalje japin në dalje:
123
12345
1234567
Opsionet e hyrjes - cin vepron ngjashëm me tastaturën dhe e kombinuar me operatorin >> , cin
pauzon programin dhe pret nga shfrytëzuesi ti jep të dhënat nga tastatura. Me një cin, mund të
mirret një ose më shumë vlera (ngjashëm me cout me të cilin mund të paraqiten një ose më shumë
vlera), ku çdo vlerë në cin ndahet me nga një operator >> .
Shembull. Urdhëresa vijuese merr inputet nga shfrytëzuesi dhe i vendos në ndryshoren Rezultati:
cin >> Rezultati; // Mundëson shfrytëzuesin të shtyp vlera në Rezultati
Duhet theksuar se marrja e vlerave të shumëfishta bëhet me shtypjen e blank karakterit (çdo
hapësirë, butoni tab ose butoni enter).
Marrja e rreshtit të të dhënave - Nëse duhet të marrim një rresht nga hyrja atëhere përdoret
funksioni getline(). Ky funksion përdoret kur dëshirojmë ti fusim një string të të dhënave në vargun
e karaktereve. Përderisa cin e ndal leximin e të dhënave nga hyrja kur të mbërrin hapësira e parë,
getline() mbaron vetëm kur shfrytëzuesi e shtyp enter.
Bazat e gjuhës programuese C++ S. Bekteshi 18
Shembull: Ekzistojnë disa forma të getline(), por ajo që përdoret më së shpeshti e ka formën:
cin.getline(vargkarak, num);
ku vargkarak është çfardo vargu i karaktereve më parë i definuar që mban stringun hyrës. num është
numri maksimal i karaktereve që duhet të lexohen me getline(). cin. Nuk është pjesë e emrit
getline(). Më saktë, në këtë mënyrë objekti cin e merr rreshtin nga tastatura.
getline() gjithëmonë e përfundon leximin e të hyrave nga shfrytëzuesi kur numri maksimal i
karaktereve të plotësohet. getline() gjithashtu e rezervon për zeron që nevoitet për përfundimin e
stringut. Prandaj, getline() lejon që shfrytëzuesi të shtyp saktë numrin maksimal të karaktereve (
karakteri për rreshtin e ri kurrë nuk ruhet brenda stringut.) prg.23.
Me getline() mirret stringu nga shfrytëzuesi. cin pa getline() e merr vetëm një fjalë për një
herë prg.24
24: return;
25: }
Dalja:
Cili eshte artikulli? Libri Fizika
Sa ëdhtë cmimi i artikullit? 3.44
Përshkrimi:
Artikulli: Libri Fizika
Cmimi: 3.44
Analizë: Në rreshtin 9 është definuar vargu prej 25 karaktereve, dhe getline() në rreshtin 12 i merr
vlerat e vargut nga shfrytëzuesit. Pasi të shtypet çmimi në rreshtin 15, të dhënat shtypen përsëri në
rreshtin 17 deri 23.
Rreshtat 20, 21, dhe 22 sigurojnë që as më shumë e as më pak se dy decimale të shtypen për
çmimin. Pa këta manipulatorë H/D çmimi do të shtypej me gjashtë decimale.
Bazat e gjuhës programuese C++ S. Bekteshi 20
Një ndryshore është një lokacion në memorjen e kompjuterit në të cilin mund të ruhet një
vlerë dhe prej të cilit më vonë mund të mirret përsëri ajo vlerë. Kur të definohet një ndryshore në
C++ në këtë rast i tregohet kompajllerit se e çfarë lloji është ndryshorja: një integer (numër i ploë),
një karakter e kështu me radhë. Njëherit i tregohet kompajllerit se sa vend të rezervohet në memorje
dhe çfarë lloji të vlerës ruhet në ndryshore.
Krijimi ose definimi i një ndryshoreje bëhet duke e shkruar tipin, lihet një ose më shumë
vende të zbrazëta pastaj emri (identifikatori) i ndryshores dhe në fund vie pikëpresja.
tipi emri_dryshores;
Bazat e gjuhës programuese C++ S. Bekteshi 21
Në çdo kompjuter, çdo ndryshore zë vend të caktuar në memorje. Kjo dmth se psh një
integer në një kompjuter mund të jetë dy bajt kurse në tjetrin katër bajt por vlera e tij do të mbetet
gjithnjë e njejtë në secilin kompjuter. (Tabela 1.)
Vërejtje: Madhësitë e ndryshoreve mund të jenë të ndryshme nga këto që janë paraqitur në
tabelën e mësipërme që varet nga kompjuteri dhe kompajlleri që ju e përdorni.
Shembull:
E dhëna Numri i bajtëve
që kërkohen
Shkronja x 1
Numri 800 2
Numri 123.123 4
Fjalia Te mesojme C++ 15
Një faqe e shtypur Afërsisht 3,000
Konstantet njësoj si edhe ndryshoret janë lokacione të memorjes për ruajtjen e të dhënave.
Dallimi me ndryshoret siç tregon edhe vet emri është se janë konstante dnth nuk ndryshohen. Posa
të krijohen atyre duhet t’iu jipet vlera dhe ato vlera nuk mund të ndryshohen.
Kemi dy lloje të konstanteve: literal dhe simbolik.
Krijimi ose definimi i një konstanteje literal bëhet duke e shkruar tipin, lihet një ose më
shumë vende të zbrazëta pastaj emërtimi (identifikatori) i konstantes që shoqërohet nga shenja e
barazimit pas së ciës vjen vlera e konstantës dhe në fund vie pikëpresja.
tipi emrindryshores = vlera;
Konstanta simbolike është konstanta që paraqitet me një emër (simbol).
C++ i ka dy metoda për definimin e konstanteve simbolike duke i përdor fjalët e rezervuara
#define dhe const.
Tipi int
Të dhënat e tipit int janë vlerat e numrave të plotë. Në këtë kategori të të dhënave marrin
pjesë: konstantet, ndryshoret, shprehjet dhe funksionet. Në vazhdim do të japim rregullat për
shkruarjen dhe deklarimin e konstanteve dhe ndryshoreve që marrin vlera të numrave të plotë.
Duke u bazuar në atë që thamë më lartë, deklarimi i një ndryshoreje të tipit int bëhet duke e
shkruar tipin (int në këtë rast), lihet një ose më shumë vende të zbrazëta pastaj emri i ndryshores
dhe në fund vie pikëpresja.
int emri_ndryshores;
Për vënjen e emrave të ndryshoreve vlejnë të njejtat rregulla si për identifikatorët.
Nëse duhet ti deklarojmë dy ose më shumë (tri në rastin tonë) ndryshore atëhere:
int emri_ndryshores1;
int emri_ndryshores2;
int emri_ndryshores3;
ose në formën:
int emri_ndryshores1, emri_ndryshores2, emri_ndryshores3;
shpejtesia = 0;
Duhet theksuar se “shpejtesia=0” nuk kuptohet si në formën algjebrike “shpejtesia e
barabartë me zero” por si “ jepja vlerën 0 ndryshores shpejtësia”. Kjo më mirë do të kuptohej sikur
të paramendoni në vend të shenjës së “barazimit” të ishte shigjeta me kahje në të majtë ( ←).
Inicializimi i ndryshores mund të bëhet edhe me rastin e deklarimit të saj. Në këtë rast pas
emrit të ndryshores vendoset shenja e barazimit e cila shoqërohet me vlerën fillestare që dëshirohet,
psh:
int x=0, y=5, z=0; - me vlerë fillestare 0 për x, 5 për y dhe 0 pë z.
int matja1=0, matja2, matja3=123; matja1 me vlerë 0, matja3 me vlerë 123 dhe matja e
dytë nuk është inicializuar.
Të gjitha tipit integer mund të jenë signed ose unsigned.Tipi signed int i
përmbanë ose numrat pozitiv ose numrat negativ. Unsigned int janë gjithnjë pozitive. Pasi
numri i bajtëve signed int dhe unsignet int, numri më i madh që mund të ruhet në
signed int është dy herë më i madh se numri më i madh që ruhet si unsigned int.Nëse
ndyshorjet integer nuk deklarohet me signed ose unsigned nënkuptohen se janë signed.
Varësisht se vlerat që iu japim ndryshoreve janë të vogla ose të mëdha përdoret short ose
long. Një integer unsigned short mund të përdorë numra prej 0 deri në 65 535. Gjysma e
numrave që paraqiten me signed short janë negativ kështu që unsigned short mund të
përfaqson numrat prej -32 768 deri 32 768. unsogned long mund të ruaj numrin deri
4,294,967,295. Nëse ju duhet të ruani numra edhe më të mëdhej duhet të përdoren float dhe
double mirëpo me këtë rast humb saktësia sepse vetëm 7 ose 19 numrat e parë janë me rëndësi në
shumicën e kompjuterëve, shifart tjera rrumbullaksohen.
Duhet theksuar se gjatë inicializimit, vlerat e ndryshoreve nuk guxojnë ti tejkalojnë rangun e
vlerave të cilat i përmbajnë sepse rezultatet do të jenë papritura.
Bazat e gjuhës programuese C++ S. Bekteshi 24
typedef
Duhet theksuar se përdorimi i fjalës së rezervuar typedef nuk krijon tip të ri të dhënave ( i
cili është i mundshëm në C++ dhe për të cilin do të shohim më vonë) por e krijon një sinonim për
frazën e cila gjendet pas saj prg.20.
Analizë: Në rreshtin 5, unsigned short int. është zëvendsuar me sinonimin USHORT duke
përdor fjalën e rezevuar typedef dhe USHORT është përdor pastaj çdokund në program në vend
të unsigned short int..
Numrat me presje dhjetore janë tip tjetër i të dhënave në C++. Numrat me presje dhjetore
gjithashtu quhen edhe numra realë. Numri me presje dhjetore përcaktohet me fjalën e rezervuar
float ose double. Ndryshoret e tipit float dhe double ruajnë vlerat e numrave realë respektivisht
numra me presje dhjetore. Duhet theksuar se numrat decimal shkruhen me pikë ( jo me presje)
dhjetore kështu që për hirë të praktikës do t’a përdorim shprehjen “presje dhjetore” edhepse
faktikisht është pikë dhjetore.
Bazat e gjuhës programuese C++ S. Bekteshi 25
Ngjashëm me numrat ineger, numrat me presje dhjetore kanë një rang të kufizuar.
Stamdardi ANSI kërkon që rangu të jetë së paku plus ose minus 1.0*1037. Natyrisht, një numër me
presje dhjetore paraqitet me 32 bite. Prandaj, një numër me presje dhjetore është me saktësi gjashtë
shifrore (ose vende decimale) në anën e djathtë të presjes dhjetore. Një numër me presje dhjetore
nëse nuk e ka sufiksin (float) është i tipit të nënkuptuar double. Dallimi ndërmjet tipit float dhe
double është në saktësinë e paraqitjes së numrave realë. Saktësia e paraqitjes së numrave real është
në numrin e shifrave mbas presjes dhjetore të cilat mund të ruhen në hapsirën e memorjes
Ndryshoret e deklaruara të tipit double, thënë vrazhdë, mund të ruajnë afër dy herë më shumë shifra
decimale se ndryshoret e tipit float. Numri i saktë i shifrave varet nga lloji i kompjuterit.
Sqarim: Në Pentium, ndryshoret e tipit float mund të ruajnë përafërsisht 7 shifra decimale, ndërsa
ato të tipit double rreth 15 shifra decimale.
Përkundër pjestimit të numrave integer ku rezultati është i cunguar dhe pjesa thyesore nuk
paraqitet, pjestimi i numrave me presje dhjetore jep numër tjetër me presje dhjetore. Pjestimi me
numër me presje dhjetore kryhet kur pjestuesi ose i pjestueshmi janë numra me presje dhjetore ose
njëri nga ata është numër me presje dhjetore.
Shembull: Nëse 571.2 / 10.0 jep numrin tjetër me presje dhjetore 57.12. E njejta gjë vlen edhe për
571.2 / 10 si dhe 5712 / 10.0.
#define
Njëra prej metodave për definimin e konstanteve simbolike është nëpërmes direktives
preprocesorike #define e cila përdoret në mënyrën si vijon:
#define EMRIKONSTANTES literali
Bazat e gjuhës programuese C++ S. Bekteshi 26
Në këtë mënyrë krijohet konstanta me emrin EMRIKONSTANTES (për të cilin vlejnë të njejta
rregulla si për identifikatorë) me vlerën e literalit. Literali paraqet një konstantë literale të
përshkruara më parë. Duhet të theksojmë se #define nuk përfundon me pikëpresje (;).
Direktiva preprocesorike #define e udhëzon kompajllerin si vijon: ” Në kodin burimor
zëvendsoje EMRIKONSTANTES me literali”. Efekti është i njejtë sikur me dorë të bëheshin këto
zëvendsime në kodin burimor. Urdhëresa preprocesorike #define mund të vendoset kudo në kodin
burimor (zakonish në fillim të kodit para main) ndërsa efekti i saj është në pjesën e programit
burimor pas saj.
Zakonisht emrat e konstanteve simbolike shënohen me shkronja të mëdha në mënyrë që më
lehtë të dallohen nga emrat e ndryshoreve (të cilat zakonisht shkruhen me shkronja të vogla).
const
Metoda tjetër për definimin e konstanteve simbolike është nëpërmes fjalës së rezervuar
const. const përdoret në çdo deklarim të ndryshoreve. Një ndryshore e deklaruar si const nuk mund
të ndryshohet gjatë ekzkekutimit të programit. Nëse një gjë e tillë provohet në program, kompajlleri
lajmëron për gabim.
Duhet theksuar se dallimi ndërmjet direktives preprocesorike #define dhe fjalës së rezervuar
const shihet qartë te treguesit dhe fushëveprimi i ndryshoreve për të cilat do të bëhet fjalë më vonë)
Notacioni shkencor
Konstantet e tipit int, float dhe double mund të paraqiten në notacionin e zakonshëm dhe atë
shkencor. Gjatë shkruarjes së tyre në notacionin e zakonshëm mund të mos shkruhen pjesë para dhe
pas presjes dhjetore. Në notacionin shkencor një numër mund të paraqitet me kombinimin e
mantisës e shoqëruar nga shkronja e ose E dhe eksponentit si vijon:
[mantisa]e[exponenti],
dhe
[mantisa]E[exponenti].
Bazat e gjuhës programuese C++ S. Bekteshi 27
Shembull: 5000 në notacionin shkencor mund të paraqitet si 5e3 (5*10 3), -300 si –3E2 (-3*102),
dhe 0.0025 si 2.5e-3 (2.5*10-3).
Në tab janë paraqitur rutinat themelore të gjuhës C++ të cilat i kryejnë llogaritjet dhe
konverzionet matematike
1. prg19.
2. #include <iostream.h>
3. #include <conio.h>
4. #include <math.h>
5. int main ()
6. {
7. int x=253, y=463;
8. double z=pow(x,2)-3*y ;
9. cout <<"Te zgjidhet shprehja:\n\n";
10. cout <<"pow(x,2)="<<pow(x,2)<<"\n\n";
11. cout <<"3*y="<<3*y<<"\n\n";
12. cout <<"Zgjidhje\n\n";
13. cout <<"z=pow(x,2)-3*y="<<z<<"\n\n";
14. getch ();
15. return 0;
16. }
Dalja: Te zgjidhet shprehja:\
Zgjidhje
z=pow(x,2)-3*y=
Tipi char
Ndryshoret dhe konstantet e tipit char ruajnë karakteret, Në deklarata të këtilla përdoret fjala
e rezervuar char. Ndryshoret e tipit karakter (tipi char) janë zakonisht 1 bajt që mjafton të mbaj 256
vlera. Tipi char mund të interpretohet si numër i vogël (0-256) ose si numër i grupit ASCII
(American Standard Code for Information Interchange).
Shumica e kompjuterëve dhe të gjithë PC shfrytëzojnë kodin standard ASCII (Amerikan
Standard Code for Information Interchange) në të cilin çdo karakter është i koduar me vlerën 8
bitëshe që jep mundësinë e kodimit të 256 karaktereve të ndryshme
Sqarim: Kompjuterët nuk dijnë për shkronjat, shenjat e pikësimit ose për fjalitë. Krejt çka kuptojnë
ata janë numrat. Në të vërtetë ata dijnë sa ka apo nuk ka sasi të mjaftueshme të elektricitetit në
lidhje të caktuara të përquesve. Kjo paraqitet me 1, nëse ka dhe me 0 nëse nuk ka. Me grupimin e
njësheve dhe zerove kompjuteri është në gjendje të gjeneroj modele të cilat mund të interpretohen si
numra dhe këta me radhë mund të paraqiten si dhkronja ose shenja të pikësimit.
Në kodin ASCII, shkronja “a” ka vlerën 97. të gjitha shkronjat e vogla dhe të mëdha, të
gjithë numrat dhe të gjitha shenjat e piksimit kanë vlerat në mes 1 dhe 128. 128 shenjat dhe
simbolet tjera janë të rezervuara për përdorim të prodhuesve të kompjuterit
Kodi komplet ASCII është dhënë në shtesën. Në diskutimet e mëtejme do të përdorim vetëm kodin
ASCII.
Pasi karakteret janë të koduar me numra të plotë dhe mund të shqyrtohen si vlera të “vogla “
të plota dhe mund të definohet sistemi në mes të tyre .Prg.21. Vlera kodike e ”A” është më e vogël
Bazat e gjuhës programuese C++ S. Bekteshi 28
se vlera kodike e ”B” dhe mund të themi se “A” është më e vogël ss “B”. Ky sistemim quhet
sistemim leksigrafik dhe mundson sortimin e karaktereve, fjalëve dhe rreshtave .
Ndryshorja e cila mund të paraqes karaktere të ndryshme quhet ndryshore e tipit karakter
ose shkurt ndryshore karakter. Forma e përgjithshme e deklarimit të ndryshores karakter është:
char emri_ndryshores;
ku emri_ndryshores është identifikatori dmth vendi ku vendoset emri i ndryshores.
Një karakter i kufizuar me thojza të njëfishta (‘) quhet konstante e tipi karakter ose shkurt
konstant karakter . Psh “a”, “A”, “b”, “B” janë të gjitha konstante karaktere që kanë vlerat e tyre
unike në grupin e karaktereve ASCII.. (çdo karakter i vetëm kufizohet me thojza të njëfishta.
Thojzat e dyfishta në gjuhën C++ përdoren për të paraqitur stringun e karaktereve i cili ka kuptim
krejt tjetër). Deklarimi i konstantes karakter bëhet në formën:
char emri_konstantes =’karakteri’;
Shembull: Konstantet e tipit char fitohen me vendosjen e karakterit në mes të thojzave të njëfishta
char ca =’A’, cb=’B’, iniciali=’S’ ;
Bazat e gjuhës programuese C++ S. Bekteshi 29
Nga grupi i karaktereve ASCII mund të gjendet vlera (dekade) unike numerike e `A', `a',
`B', dhe `b' është 65, 97, 66, dhe 98, përkatsisht. Prandaj për ndryshoren karakter të dhënë x
deklaratat e poshtë shënuara janë ekuivalente
:x = `A';
x = 65;
si dhe deklaratat vijuese:
x = `a';
x = 97;
Operatori cast
Operatori cast i konverton të dhënat nga një tip në tjetrin. Operatori cast shkruhet në atë
mënyrë që para tipit të të dhënave që dëshirojmë ta konvertojmë futet nën kllapa tipi i të dhënave në
të cilin dëshirojmë ta ndryshojmë si: (char), (int), (float) dhe (double). Për konvertimin e vlerave të
tipit të të dhënave në tjetër tip të të dhënave operatori cast vendoset mu para vlerës (ndryshores,
shprehjes, literalit).
Shembull: Konvertimi nga tipi float psh në integer bëhet ashtu që operatori cast integer
vendoset mu para ndryshores të tipit float.
int i = 8;
int rezultati;
float f = 6.9;
resultati = i * (int)f; // Konverton tipin e f para shumëzimit
f bëhet integer 6. Pa operatorin cast 8.0 shumëzohet me 6.9 dhe fitohet rezultati 55.2 para se të ruhet
55 në ndryshoren integer. Me operatorin cast 8.0 shumëzohet me 6 dhe fitohet 48 dhe 48 ruhet në
ndryshoren rezultati
Me operatorin cast lehtë mund të bëhet pjestimi me integer që jep rezultat me presje dhjetore
Shembull: Të shqyrtojmë edhe njëherë problemin pjestimit me integer që jep rezultat me numër të
plotë edhepse duhet me presje dhjetore. Për të fituar pjestim real përdoret operatori cast:
int koha,ngjarjet;
float mesatare;
mesatare = (float)koha / ngjarjet;
Tani C++ jep pjestim me numër me presje dhjetore.
Operatori cast nuk e ndryshon vlerat e tipit të të dhënave përgjithmonë. Vlera ndryshohet
për lokacionin e vetëm të operatorit cast.
Dizajnerët e C++ kanë dëshiruar që C++ të bazohet në gjihën C. Në C++, operatori cast
shkruhet në formën e notacionit të funksioneve. Në vend që të futet tipi i të dhënave nën kllapa, në
kllapa futet vlera që duhet të konvertohet
Në të gjitha programet e deritanishme deklaratat janë ekzekutaar një herë dhe vetëm një herë
sipas radhës së paraqittjes në program. Programet e këtilla janë tepër të thjeshtë sepse nuk
përmbajnë struktura logjike kontrolluese siç janë testet për përcaktimin së një kusht i caktuar a
është plotësuar duke përsëritur ekzekutimin e grupit të deklaratave ose pjesa e seleketuar r një grupi
të deklaratave nga disa të mundshme. Shumë programe në interes praktik në mënyrë intenzive i
shfrytëzojnë mundësitë e tilla.
Operatorët
Një operator është një simbol që e udhëzon C++ të kryej disa operacione ose aksione në një
ose më shumë operandë. Operand quhet çdo gjë në të cilën vepron operatori. Në C++ të gjithë
operandët janë shprehje. Operatorët ndahen në:
Operatori i dhënjes së vlerave,
Operatorët aritmetik.
Operatorët krahasues (relacional)
Operatorët logjik.
Operatori për dhënjen e vlerave (+) edhepse e ka shenjën e barazimit në aritmetikë, kuptimii
i tij është plotësisht tjetër. Deklarata për dhënjen e vlerave ka formën :
Operandi-majtë = Operandi-djathtë
dhe shkakton që Operandit-majtë i jipet (shënohet, shkruhet) vlera e Operandi-djathtë.
Në të vërtetë në këtë rast vlera e Operandi-djathtë i jipet (shënohet, shkruhet) në lokacionin e
memorjes të Operandi-majtë. Karakteri “=” paraqet operatorin e dhënjes së vlerave.
Shembull: Urdhëresa:
a = 5;
e shkruan vlerën e operatori-djathtë (5) në lokacionin e memorjes të ndryshores integer a (e cila
është operand-majtë në këtë rast). Ose urdhëresa:
b = a = 5;
i jep së pari vlerën 5 mdryshores integer a, dhe pastaj ndryshores integer b. Pas ekzekutimit të
urdhëresës edhe a edhe b e kanë vlerën 5.
Operatori i dhënjes së vlerave (=) asesi nuk dihet të ngatrrohet me operatorin e barazimit
(==) sepse kanë kuptime plotësisht të ndryshme. Urdhëresa e lartëshënuar nuk tregon se “a është e
barabartë me 5” por “vlera 5 i jipet a”
Shembull: Si rezultat i pjestimit 1/3 fitohet 0, 2/3 fitohet 1, 16/3 fitohet 5 etj.
Operatori i pjestimit sipas modulit zakonisht zbatohet në numrat e plotë pozitiv. Si rezultat i
operatorit % fitohet mbetja pas pjestimit të numrave të plotë.
Shembull: Psh 9%2 jep 1, 10%3 jep 1, 26&9 jep 8 e kështu me radhë.
Shembull: Në shprehjen:
a*b+c/d
operatorët * dhe / kanë priorite ndaj + kështu që së pari shumëzohet a me b pastaj pjestohet c me d e
pastaj mblidhen rezultatet e shumëzimit dhe pjestimit. Në shprehjen:
a*b/c
operatorët * dhe / kanë prioritet të njejtë kështu që tani në bazë të asociativitetit ( nga e majta në të
djathtë e këtyre operatorëve) së pari zbatohet shumëzimi e pastaj pjestimi.
Në shembullin vijues janë dhënë operatori i shumëzimit, modulit, mbledhjes dhe zbritjes:
Algjebrike z=pr%q+v/x -y
C++ z=p*r%q+v/q-y
6 1 2 4 3 5
Numrat e rrumbullaksuar tregojnë radhën e ekzekutimit të operatorëve. Operatori i
shumëzimit, modulit dhe pjestimit kryhen së pari pasi kamë prioritet të njejtë ndërsa asociativiteti
është nga e majta në të djathtë.
x *= y; është ekuivalente me x = x * y;
x /= y; është ekuivalente me x = x / y;
x %= y; është ekuivalente me x = x % y;
Të theksojmë se urdhëresa:
z = z * x + y; nuk është ekuivalente me urdhëresën z *= x + y;
sepse
z *= x + y është e njejtë me z = z * (x + y);
Operatori minus unar (-) përdoret për ndërrimin e parashenjes së ndryshores. Quhet unar
sepse i nevoitet vetëm një operand. Nuk duhet të ngatrrohet me operatorin e zbritjes (-) edhepse e
ka të njejtin simbol.
Operatori sizeof si rezultat e jep vlerën e tipit int e cila është e barabartë me numrin e
bajtëve që nevojiten për ruajtjen e operandëve. .Forma e përgjithshme e këtij operatori është :
sizeof (tipi_te_dhënave)
Shembull: sizeof(int)
jep si rezultat numrin e bajtëve të cilat zauzima tipi int i të dhënave .
Bazat e gjuhës programuese C++ S. Bekteshi 34
Operatorët krahasues (Tabela 6) bëjnë krahasimin në mes operandit të majtë dhe të djathtë.
Për të përcaktuar se kur janë të barabartë ose njëri më i madh se
tjetri. Operandët mund të jenë shprehje të çfardoshme. Të gjithë Tabela.6 Operatorët krahasues
operatorët krahasues janë binarë. Çdo urdhëresë krahasuese
rezulton në një (e saktë) ose zero (e pasaktë). < me i vogël se
Në C++, zeroja konsiderohet e pasaktë ndërsa të gjitha > me i madh se
<= me i vogël ose i barabartë
vlerat tjera konsiderohen të saktë edhepse e saktë zakonisht
>= me i madh ose i barabartë
paraqitet me një. Kështu nëse një shprehje është e pasaktë, ajo == i barabartë
është e barabartë me zero dhe nëse një shprehje është e barabartë != jo barabartë
me zero ajo është e pasaktë. Nëse një urdhëresë është e saktë kjo
dmth se ajo është e ndryshme nga zero dhe çdo urdhëresë e
ndryshme nga zero është e saktë
Shembull:
Të shqyrtojme rastin a>b.
- nëse vlera e a është më e madhe se b, atëhere shprehja a>b është e saktë dhe shprehja a>b jep
vlerën 1 të tipit int,
- nëse a është më e vogël ose e barabartë se b shprehja a>b jep rezultatin zero të tipit int.
Dmth janë të mundshme dy vlera për shprehjen a>b, 1 të tipit int , nëse shprehja është e
saktë dhe 0 të tipit int nëse shprehja është e pasaktë .
Disa shembuj për operatorët krahasues:
Barabartë == 100 == 50; Pasaktë
50 == 50; Saktë
jo e barabartë != 100 != 50; Saktë
50 != 50; Pasaktë
Më e madhe se > 100 > 50; Saktë
50 > 50; Pasaktë
Më e madhe ose e barabartë se >= 100 >= 50; Saktë
50 >= 50; Saktë
Më e vogël se < 100 < 50; Pasaktë
50 < 50; Pasaktë
Më e vogël ose e barabartë se <= 100 <= 50; Pasaktë
50 <= 50; Saktë
Shprehja:
1 / 2 + 1 / 2 == 1
nga pikëpamja algjebrike është e saktë dhe supozohet të kthej vlerë. Shprehja megjithate kthen 0 që
dmth se shprehja e mësipërme nuk vlen. Kjo ndodh për shkak të pjestimit me integer sepse ½ jep 0
e jo 0.5.
Operatorët krahasues <, <=, >, >= kanë prioritet me të lartë ndaj == dhe !=. Operatorët ==
dhe != kanë prioritet të njejtë. Operatorët aritmetik janë me prioritet më të madh ndaj operatorëve
krahasues .
Pra operatorët krahasues (<, >, <=, >=) përdoren që të testojnë se shprehjet a janë të
barabarta apo jo të barabarta. Nëse deklarata është e saktë atëhere ajo kthen karakter jozero;
përndryshe ajo kthen të pasaktë (0)
Bazat e gjuhës programuese C++ S. Bekteshi 35
Shembull: Nëse x është shprehje matematike atëhere për operatorin e negacionit matematik vlenë:
jo(jo x)=x
Nëse x ka vlerë jo zero të cilitdo tip atëhere për operatorin e negacionit logjik vlen :
!(!x)= 1
Në anën tjetër nëse shprehja x ka vlerën 0 atëhere për operatorin e negacionit logjik vlen;
!(!x)=0
Operatori ! ka prioritet dhe asociativitet (nga e djathta në të majtë) si dhe të gjithë operatorët
tjerë unarë .
Operatori && (logjik EDHE) jep si rezultat vlerën 1 ose 0 të tipi int. Operatorin && jep si
rezultat vlerën 1 nëse të dy operandët kanë vlerë jo zero. Në të kundërtën rezultati është 0.
Semantika e këtij operatori është dhënë në tabelën.
Një urdhëresë logjike EDHE i shqyrton dy shprehje dhe vetëm nëse të dy shprehjet janë të
sakta urdhëresa logjike Edhe është e saktë. Në shprehjet logjike, llogaritja ndërpritet. posa rezultati i
tërë shprehjes të mund të caktohet në bazë të llogaritjes së deriatëhershme psh në shprehjen :
shprehja1 && shprehja2.
shprehja2 nuk do të llogaritet nëse shprehja1 e ka vlerën zero.
Prioriteti i këtij operatori është më i ultë se ata unarë, aritmetik dhe krahasues kurse
asociativiteti i tij është nga e majta në të djathtë.
Shembull: Operatori EDHE - Kushti që studenti i vitit të dytë të kaloj klasën është që numri i
kredive të jetë më i madh ose i barabartë me 30.
Viti==2&&kredia>=30
Bazat e gjuhës programuese C++ S. Bekteshi 36
Kushti para operatorit EDHE logjik (Viti==2) ekzekutohet i pari sepse operatori == është me
prioritet se operatori &&. Pastaj ekzekutohet kushti pas operatorit EDHE logjik (kredia>=30) sepse
operatori >= është me prioritet se operatori &&.
Shprehja e mësipërme është e saktë nëse dhe vetëm nëse të dy kushtet janë të sakta (Viti==2
dhe kredia>=30). Çdo kombinim tjetër për shprehjen e mësipërme jep vlerë të pasaktë.
Duhet të theksojmë se ana e djathtë ekzekutohet vetëm nëse ana e majtë është e saktë.
Operatori || (logjik OSE) mund të jep poashtu dy vlera 0 ose 1. Ky operator jep si rezultat
vlerën zero nëse të dy operandët kanë vlerë zero. Në të kundërtën jep vlerën 1.: Një operator logjik
Ose evaluates dy shprehje. Nëse vetëm njëra prej tyre është e saktë shprehja shprehja është e saktë.
shprehja1 || shprehja2
shprehja2 nuk do të llogaritet nëse shprehja1 ka vlerën 0
Prioriteti i operatorit II është i njejtë me && dhe ka prioritet me të ultë se operatorët unarë,
aritmetik, dhe krahasues. Asociativiteti i tij është nga e majta në të djathtë.
Shembull: Operatori OSE - Nota me të cilën vlersohet studenti është: më e vogël se 11 ose më e
madhe se 4:
(Nota < 11 || Nota > 4)
1. //prg.11
2.
3. #include <iostream.h>
4. #include <conio.h>
5.
6. main ()
7. {
8. int j=0, x, I=0, y=0;
9.
10. cout<<"Kuptimi i opratorit &&\n";
11. x=1&&(I=10);
12. cout<<"x= "<<x<<"\tdhe\tI= "<<I;
13.
14. cout<<"Kuptimi i opratorit II\n";
15. y=0.&&(j=100);
16. cout<<"\ny= "<<y<<"\tdhe\tj= "<<j;
17.
18. getch();
19. return 0;
20. }
Dalja:
Kuptimi i operatorit &&
x= 0 dhe j= 0
Kuptimi i operatorit II
y= 0 dhe j= 0
Bazat e gjuhës programuese C++ S. Bekteshi 37
kushti është shprehje e çfardoshme, më së shpeshti shprehje krahasuese, i cili llogaritet i pari nëse
kushti është i saktë atëhere llogaritet shprehja1 dhe ky rezultat e definon vlerën e tërë shprehjes së
kushtëzuar. Në të kundërtën nëse kushti është jo i saktë atëhere llogaritet shprehja2 dhe ai rezultat e
përcakton vlerën e tërë shprehjes së kushtëzuar. Shprehja e kushtëzuar funksionon si urdhëresa if-
else për të cilën do të mësojmë më vonë.
Ky operator përdoret me së tepërmi që ndryshores t’i jipet njëra nga të dy vlerat e
mundshme. Në varshmëri nga kushti i caktuar. Të shqyrtojmë programin vijues prg22:
1. //prg.22
2.
3. #include <iostream.h>
4. #include <conio.h>
5.
6. main ( )
7. {
8. int ndrysh1, ndrysh2, minimum;
9.
10. cout<<"Vlera e ndryshores së parë: /";
11. cin >> ndrysh1;
12.
13. cout<<"Vlera e ndryshores së dytë:";
14. cin >> ndrysh2;
15.
16. minimum=(ndrysh1<ndrysh2)?ndrysh1:ndrysh2;
17. cout<<"\nVlera minimale eshte:%d"<<minimum;
18.
19. getch();
20.
21. return 0;
22. }
Dalja:
Vlera e ndryshores së parë 4
Vlera e ndryshores së dytë 3
Vlera minimale eshte 3
Ndryshores minimum ia jep vlern ndrysh1 nëse kushti minimum është i saktë ose vlerën
ndrysh2 nëse kushti ndrysh1>=ndrysh2 i saktë. Kllapat shkruhen që të rritet lexueshmeria dhe nuk
janë të domosdoshme. Në mënyrë analoge kemi për max .:
minim=(ndrysh1<ndrysh 2)?ndrysh1:ndrysh2
Prioriteti i operatorit të shprehjes të kushtëzuar është me i ultë se i operatorit të dhënjes së
vlerave (=) dhe operatorit krahasues (<)
Nëse shprehja pas dy pikave është shprehje e kushtëzuar atëhere fitojmë:
S=(numri <0)?-1 : (numri=0)?-0:1)
(arrihet efekti i if-else-if për të cilin do të mësojmë më vonë )
Nëse vlera e ndyshores numri është më e vogël së zero ndryshores i jipet vlera 1 në të
kundërtën kryhet shprehja tjetër e kushtëzuar. Nëse në shprehjen e dytë të kushtëzuar ndryshorja
numri e ka vlerën zero ndryshorja e fiton vlerën 0. Në rastin kur vlera e ndryshores numri është më
e madhe së zero ndryshes e fiton vlerën 1. Kllapat nuk janë të nevojshme pasi asociativiteti i
operatorit të kushtëzimit është nga e djathta në të majtë, dmth shprehja e kushtëzuar :
u1? v1: u2? :v3
llogaritet si :
u1?v1:u2?v2:v3
Operatori i shprehjes së kushtëzuar trajtohet si çdo shprehje ose operator tjetër dhe për këtë
arsye ai mund të shkruhet çdokund ku mund të shkruhen edhe shprehjet dhe operatorët tjerë.
Përfundim:
Të gjitha programet pa marr parasysh së a janë të thjeshta apo të komplikuara paraqesin një
rrjedhje të ekzekutimit të urdhëresave.
Strukturat e kontrollit
Kur urdhëresat në program ekzekutohen në radhë njëra pas tjetrës ashtu siç janë shkruar kemi të
bëjmë me ekzekutimin sekuencial. Urdhëresa të ndryshme të C++ i mundësojnë programuesit të
përcaktoj ekzekutimin e ndonjë urdhërese tjetër e cila mund të jetë edhe jashtë radhës. Kjo paraqet
transferin e kontrollës. Të gjitha programet mund të shkruhen në bazë të vetëm tri strukturave
kontrolluese:
- Struktura sekuenciale
- Struktura zgjedhëse dhe
- Struktura përsëritëse.
Struktura sekuenciale është e inkorporuar në C++. Kompjuteri i ekzekuton urdhëresat e C++ në
radhë njëra pas tjetrës ashtu siç janë shkruar përveç se nëse urdhërohet ndryshe.
Në C++ i kemi tri tipe të strukturave të zgjedhjes: if, if-else dhe switch. Struktura e zgjedhjes if
ose e kryen (e zgjedh një aksion nëse kushti është i saktë (true) ose e kalon e kalon një aksion nëse
kushti është i pasaktë (false). Struktura e zgjedhjes if-else e kryen një aksion nëse kushti është i
saktë ose kryen aksione tjera nëse kushti është i pasaktë. Struktura e zgjedhjes switch e kryen njërin
nga disa aksione varsisht nga vlera e shprehjes. Struktura e zgjedhjes if quhet strukturë zgjedhëse e
njëfishtë sepse ajo zgjedh ose e injoron (kalon) vetëm një aksion. Struktura e zgjedhjes if-else quhet
strukturë zgjedhëse e dyfishtë sepse ajo zgjedh në mes të dy aksioneve të ndryshme. Struktura e
zgjedhjes switch quhet strukturë zgjedhëse e shumëfishtë sepse ajo zgjedh aksionin që e kryen nga
shumë aksione tjera të ndryshme.
Në C++ i kemi tri tipe të strukturave të përsëritjes: while, do-while dhe for.
Shumë probleme të programimit zgjidhen me veprime të përsëritura në të njejtat të dhëna. Kjo
arrihet me dy mënyra : rekursion dhe iteracion. Iteracioni dmth kur e bëjmë të njejtën gjë prap dhe
prap. Metoda kryesore e iteracionit është cikli.
Struktura zgjedhëse if
urdhëresa
Kushti duhet të jetë nën kllapa. Paraqitja e rreshtit të dytë është konvencionale. vetëm sa për
të theksuar se urdhëresa është e nënshtruar. Në rrjedhjen e ekzekutimit të programit ndikon vlera
Kushti i cili duhet të jetë shprehje skalare. Të përkujtojmë së vetëm shprehjet skalare (aritmetike
ose treguesore) japin rezultate të cilat mund të krahasohen me zero. Kur përcaktohet vlera e kushtit
mund të fitohet vlera e barabartë ose ndryshme nga zero .Vlera zero si vlerë e kushtit është jo e
saktë logjike ndërsa vlera e ndryshme nga zero është e saktë logjike
Urdhëresa e nënshtruar nga urdhëresa e thjeshtë if do të ekzekutohet nëse kushti e ka vlerën
e saktë. Nëse kushti e ka vlerën e pasaktë, urdhëresa kapërcehet, kurse ekzekutimi i programit
vazhdon nga urdhëresat e tjera me radhë.
Diagrami i urdhëresës if është paraqitur në fig. 4. Ky diagram përmban simbolin e vendosjes
i cili përmban një shprehje në formë kushti i cili mund të jetë ose i saktë ose i pasaktë. Simboli i
vendosjes i ka dy vija të rrjedhjes të cilat dalin nga ai. Njëra tregon drejtimin që e merr kur kushti
është i saktë ndërsa tjetra kur kushti është i pasaktë. Vendimi mirret duke u bazuar në kushtet e
operatorëve relacional, të barazimit ose të çfardo kushti – nëse kushti merr vlerën zero ai trajtohet si
i pasaktë ndërsa nëse kushti merr vlerë të ndryshme nga zero ai trajtohet si i saktë.
Zbatimi i urdhëresës if është paraqit në kodin prg5.
1. // prg5
2. #include <iostream.h>
3. int main()
4. {
5. int num1, num2; // deklarata
6.
7. cout << "Shtypni dy numra: "; // kërkon
8. cin >> num1 >> num2; // ti shtypim dy numra
9. if ( num1 == num2 )
10. cout << "Numrat janë të barabartë." << endl;
11. if ( num1 > num2 )
12. cout << num1 << " është më i madh." << endl;
13. if ( num2 > num1 )
14. cout << num2 << " është më i madh." << endl;
15. return 0;
16. }
Theksuam më parë se urdhëresa if e kryen një aksion vetëm në rastin kur shprehja drejtuese
është e saktë përndryshe aksioni is dropped. Urdhëresa if-else e lejon programuesin të përcaktojë se
cili nga aksionet do të kryhet në rastin kur shprehja drejtuese është e saktë dhe cili aksion do të
kryhet kur shprehja është e pasaktë. Sintaksa e urdhëresës if else është:
if (Kushti)
urdhëresa1;
else
urdhëresa2
Nëse vlera logjike e kushtit është e saktë ekzekutohet urdhëresa1 ndërsa kur kjo vlerë është
e pasaktë ekzekutohet urdhëresa2. Diagrami i rrjedhjes i urdhëresës if-else është paraqitur në fig. 5.
Bazat e gjuhës programuese C++ S. Bekteshi 41
Fillimi
Pasaktë Saktë
urdhëresa2 Kushti urdhëresa1
Fundi
Për ilustrim do të japim kodin i cili e kërkon numrin e satelitëve të Jupiterit dhe në bazë të numrit të
dhënë jipet lajmërimi se numri i dhënë është i saktë ose i pasaktë.
Urdhëresat e përfshira (nested) shërbejnë për testimin e rasteve të shumëfishta me vendosjen
e urdhëresave if-else brenda urdhëresave if-else. Përfshirja në degën e pasaktë është mjaftë e
shpeshtë në programet e C++. Ja si duket forma e përgjithshme :
if (shprehja1)
urdhëresa1;
else
if (shprehja2)
urdhëresa2;
else
urdhëresa3
…………..
kjo urdhëresë e drejtimit shumëkahësh mund të shprehet në formë më të qartë dhe më kompakte në
formën:
if (shprehja1)
urdhëresa1;
else if (shprehja2)
urdhëresa2;
else
urdhëresa3
…………..
Anëtari opcional është dega e cila nënkuptohet (angl. “default”) respektivisht dega në të
cilën shkohet nëse njëra ose asnjëra nga shprehjet drejtuese nuk jep vlerën e saktë. Nëse për atë rast
nuk është i paraparë asnjë aktivitet atëhere anëtari else është i panevojshëm.
Siç shihet nga fig.5 rrjedhja e programit shkon nëpër vargun e shprehjeve drejtuese. Nëse
njëra nga këto shprehje jep vlerën e saktë atëhere ekzekutohet urdhëresa përkatëse e saj dhe
programi vazhdon nga urdhëresa e cila është pas urdhëresës if.
Struktura zgjedhëse if e pret vetëm një urdhëresë në trupin e saj. Në rastin kur kemi më
shumë urdhëresa ato duhet të futen brenda kllapave të mëdha {}. Urdhëresat e tilla quhen urdhëresa
Bazat e gjuhës programuese C++ S. Bekteshi 42
të përbëra. Në shembullin e mëposhtëm është dhënë një shembull i urdhëresës së përbërë në pjesën
else:
if (shprehja1)
urdhëresa1;
else
{
urdhëresa2;
urdhëresa3
}
Në fund duhet theksuar se urdhëresa if-else është mjaft e ngjashme me operatorin e
shprehjes së kushtëzimit
Bazat e gjuhës programuese C++ S. Bekteshi 43
Formulimi i algoritmeve
Të theksojmë se llogaritja e mesatares në program jep vlerë të tipit int. Në të vërtetë shuma e
poenave psh 855 kur pjestohet me 10 jep 85.5 pra numër me presje dhjetore. Tregoni se si duhet të
veprojmë me numra me presje dhjetore (floating point numbers).
Bazat e gjuhës programuese C++ S. Bekteshi 45
Në gjuhën C++ kemi edhe urdhëresa të cilat e kthejnë degëzimin prapa, që quhen urdhëresa
(cikle) të përsëritjes. Cikli while mundëson që ekzekutimi
të bartet prapa në ndonjë urdhëresë të mëparshme. Qëllimi Fillimi
i ciklit while është që të mundësoj ekzekutimin e trupit të
ciklit përderisa vlera në kusht të mbetet e saktë. Strukturat
përsëritëse i mundësojnë programuesit që të përcaktojnë
Saktë
një aksion i cili do të përsëritet përderisa kushti të mbetet i Kushti Urdhëresa
saktë.
Forma e përgjithshme e ciklit while është: Pasaktë
while (kushti)
Fundi
urdhëresa;
Fig.6. Diagrami i rrjedhjes së
Kushti i cili testohet në ciklin while mund të jetë
strukturës përsëritëse while
çfardo shprehje që vlen në C++. Përderisa kushti është i
saktë ciki while do të vazhdoj.
Shembull: Të shqyrtojmë pjesën e programit e cila ka për detyrë të fitoj numrin e parë pas 1000 që
fitohet me ngritjen në fuqi të 2. Të supozojmë se ndryshorja e tipit integer prodhimi është
inicializuar në 2. kur cikli while vijues përfundon do ta kemi rezultatin e dëshiruar
int prodhimi=2;
while (prodhimi<=1000)
prodhimi=2*prodhimi;
Kur fillon cikli while vlera e prodhimi është 2. Ndryshorja prodhimi shumëzohet me 2 në
mënyrë të përsëritur duke fituar vlerat 2, 4, 8, 16, 32, 64, 128, 256 dhe 1024. Kur prodhimi bëhet
1024 kushti i cikli while prodhimi<=1000 bëhet i pasaktë. Në këtë rast përsëritja ndërpritet dhe
prodhimi merr vlerën përfundimtare 1024. Ekzekutimi i programit vazhdon në urdhëresën e parë
pas ciklit while.
Urdhëresat që e përbëjnë strukturën while e formojnë trupin e while. Trupi i strukturës while
mund të jetë vetëm një urdhëresë ose një urdhëresë e përbërë. Në rastin kur kushti bëhet i pasaktë,
përsëritja ndërpritet dhe urdhëresa e parë pas strukturës while.
Diagrami i rrjedhjes (fig. 6) e ilustron rrjedhjen e kontrollës së strukturës while. Diagrami i
rrjedhjes në mënyrë të qartë e paraqet përsëritjen. Vija e rrjedhjes e cila del nga katrori kthehet
prapa në vendosje që testohet çdo herë nëpër cikël përderisa kushti të jetë i pasaktë kushti është i
pasaktë. kontrolla kalon në urdhëresën në vazhdim të programit.
Cikli while e verifikon kushtin në “maje” të ciklit (shiqo fig.8). kjo dmth se trupi i
urdhëresës nuk do të ekzekutohet nëse përcaktimi i vlerës së kushtit jep rezultatin zero. Nëse
përcaktimi i vlerës jep rezultat të ndryshëm nga zero, urdhëresa ekzekutohet.
Shembull:
while (shprehja)
paraqet kreun e strukturës while. Struktura do-while pa kllapa rreth trupit me një urdhëresë duket:
do
urdhëresa
while (shprehja);
mund të keqkuptohet. Rreshti i fundit while (shprehja); mund të keqkuptohet si një strukturë while
me një urdhëresë të zbraztë. Kështu struktura do-while me një urdhëresë shkruhet duke i përdorë
kllapat në mënyrë që ti shmangemi keqkuptimeve.
do
{
urdhëresa
}
while (shprehja);
Ciklet e përfshira
Ciklet mund të jenë të përfshira (angl. nested) dmth kur një cikël gjendet në trupin e ciklit
tjetër. Në këtë rast njëri cikël mund ta kontrolloj ciklin tjetër duke e zmadhuar fuqinë e cikleve.
Ciklet e përfshira mundësojnë ekzekutimin e ciklit më shumë se
një herë (cikël i cikleve). Shembëll për ciklet e përfshira mund të
jetë odometri (matësi i kilometrave të automjetit) i cili është i
ngjashëm me pesë-gjashtë cikle të përfshira for secili prej të
cilëve mund të merr vlera prej 0 – 9. Me lëvizjen e automjetit
numri i parë në të djathtë i odometrit ndërrohet më së shpejti nga
0 – 9. Kur ciklet janë të përfshira, cikli i jashtëm ciklohet më a) b)
ngadal se cikli i brendshëm ashtu si numrat odometrit në të
Fig. 8 Kombinimet
djathtë ndryshojnë më shpejtë se ata të majtë. Cikli i jashtëm
a) e lejuara, b) të palejuara
ndryshon vetëm asi cikli i brendshëm plotësisht të përfundoj.
Nëse kemi disa cikle do-while atëhere lejohet që brenda një cikli do-while të gjenden një ose më
shumë cikle tjera do-while (fig. 8a). Nuk lejohet që ciklet do-while të nyjëzohen (fig.8b).
Bazat e gjuhës programuese C++ S. Bekteshi 48
n 1 2
x
Llogaritja e vlerës së funksionit: y 2i
i 3i
Fillimi
// Programi Prg2_9
#include <iostream> x, n
#include <cmath>
return 0; Fundi
}
Dalja:
Shuma s=317.778
Bazat e gjuhës programuese C++ S. Bekteshi 49
i
x k
23
Llogaritja e vlerës së funksionit: y 2 x Fillimi
3 i i
x, k
// Programi Prg2_9
#include <iostream>
#include <cmath> s=0
int main()
{ i=1
int k,i;
double x,s,y;
i
cout << "Vlerat hyrëse x dhe k: "; 23
cin >> x>> k; s sx
s=0; i
i=1;
i=i+1
do
{ Po
s=s+pow(x+2./i,i/3.); i≤k
i=i+1; Jo
}
while (i<=k); x
y 2s
y=x/3+2*s; 3
n 1
2 x 3 j 2 x 2 për x 4.5
Llogaritja e vlerës së funksionit: y j 1
2
3x 2 x 1 për x 4.5
else y 2 x 3s y 3x 2 2 x 1
y=3*pow(x,2)+2*x-1;
cout << "Vlera e funksionit y="<< y << "\n";
return 0; y
}
Dalja:
Vlerat hyrëse n dhe x: 3 3.5 Fundi
Vlera e funksionit y=1105
Bazat e gjuhës programuese C++ S. Bekteshi 51
Nganjëherë shprehja1 dhe shprehja2 është listë e ndarë me presje. Presja siç është përdor në
këtë rast paraqet operatorin presje dhe garanton që shprehjet do të ekzekutohen nga e majta në të
djathtë me radjë. Operatori presje ka prioritetin më të ultë ndaj të gjithë operatorëve të C++. Vlera
dhe tipi i listës së shprehjeve të ndara me presje është vlera
dhe tipi i shprehjes e cila gjendet në pozitën më të djathtë Fillimi
ndaj të gjitha të tjerave. Përdorimi parësor i operatorit
presje në strukturën for është që të mundsoj inicializimin e
shumëfishtë të shprehjeve dhe/ose inkrementimin e shprehja1
shumfisht të shprehjeve. P.sh. kur kemi disa ndryshore të
kontrollit vetëm në një strukturë for të cilat duhet të
inicializohen dhe inkrementohen.
Tri shprehje në strukturën for janë opcionale. Nëse
Saktë
mungon shprehja2, C++ supozon se kushti i vazhdimit të Shprehja2 shprehja3
ciklit është i saktë kështu që krijohet një cikël infinit. Nëse
ndryshorja e kontrollit është inicializuar diku tjetër në Pasaktë
program ajo mund të mungoj në strukturën for. shprehja3
mund të mungoj nëse nuk ka nevojë për inkrementim ose Fundi
nëse është llogaritë nga urdhëresat në trupin e strukturës
for. Megjithate dy pikëpresje duhet të jenë në strukturën Fig.9 Diagrami i rrjedhjes së
for. strukturës for
Pjesa e inicializimit, kushtit për vazhdimin e ciklit dhe e inkrementimit/dekrementimit mund
të përmbajnë shprehje matematikore.
Bazat e gjuhës programuese C++ S. Bekteshi 52
Shembull: Nëse x=2 dhe y=10 dhe nëse x dhe y nuk modifikohen në trupin e strukturës for atëhere
deklarata:
for (int j=x\; j<=2*x*y; j+=y/x)
Është ekuivalente me:
for (int j=2; j<=80; j+=5)
Nëse kushti për vazhdimin e ciklit që në fillim është i pasaktë atëhere trupi i strukturës for
nuk ekzekutohet; ekzekutimi kalon në urdhëresën e parë pas strukturës for. Nëse kemi më shumë se
një urdhëresë në trupin e strukturës for, kllapat nevojiten që të definohet trupi i ciklit.
Diagrami i rrjedhjes i strukturës for (fig. 9) është i ngjashëm me ate të strukturës while fig.
6. Nga diagrami shihet qartë se inicializimi ndodh vetëm një herë ndërsa inkrementimi ndodh çdo
herë kur ekzekutohet trupi i urdhëresës. Diagrami i rrjedhjes për rastin e mësipërm është dhënë në
fig. 10
Llogaritja e vlerës numerike të faktorielit: F=n! nëse është dhënë vlera e variablës n.
Fillimi
// Programi Prg5_1
#include <iostream> n
int main()
{ F=1
int n,i;
double F;
cout << "Vlera hyrëse n: "; i=1
cin >> n;
F=1;
F=Fi
for (i=1;i<=n;i++)
F=F*i;
cout << "Faktorieli F="<< F<< "\n"; i=i+1
return 0;
Po
} i≤n
Jo
Dalja:
Vlerat hyrëse n: 3 F
Faktorieli F=6
Fundi
n
i
Të llogaritet vlera e funksionit: y 3 x 2 n 2 ! nëse janë dhënë vlerat e variablave x dhe
i 1 3
n. Fillimi
x,n
1 2 n
y 3x 2n 2 ! n 2 ! ...n 2 ! F=1
3 3 3
i=1
// Programi Prg5_11
Fundi
Bazat e gjuhës programuese C++ S. Bekteshi 55
Deri më tash kemi diskutuar strukturën e zgjedhjes së njëfishtë if dhe strukturën e zgjedhjes
së dyfishtë if-else. Nganjëherë algoritmet mund të përmbajnë vargun e vendimeve në të cilat
testohen ndaras ndryshorja ose shprehja për çdo vlerë konstante që mund të supozohet dhe aksione
të ndryshme që mund të mirren.
Struktura switch përbëhet nga vargu i rasteve case dhe case-it opcional default.
Shembulli.8
Diagrami i rrjedhjes së strukturës së zgjedhjes së shumëfishtë switch është dhënë në fig. 11.
Fillimi
Saktë case a
case a break
aksioni(et)
Pasaktë
Saktë case a
case b break
aksioni(et)
Pasaktë
Saktë case a
case c break
aksioni(et)
Pasaktë
aksioni
default
Fundi
Urdhëresa break kur ekzekutohet në strukturat while, do-while, for dhe switch shkakton
daljen e menjëhershme nga struktura në të cilën gjendet. Ekzekutimi vazhdon në deklaratën e parë
pas strukturës. Urdhëresa break përdoret për kërcimi të parakohshëm nga struktura ose ti shmanget
mbetjes së strukturës switch.
Analizë: Në programin e mësipërmë kur struktura if heton se vlera e x është 0 (rreshti 11), break
ekzekutohet dhe cikli for ndërpritet. Programi vazhdon me cout pas strukturës for në rreshti 15.
Cikli ekzekutohet vetëm një herë. Të theksojmë se në rreshtin 7, ndryshorja x është definuar jashtë
strukturës for pasi qëllimi i jonë ishte përdorimi i ndryshores x brenda dhe jashtë strukturës for
(shiko ndryshoret lokale dhe globale).
Urdhëresa continue kur ekzekutohet në ciklin while, do-while, for i kalon urdhëresat e
mbetura në trupin e strukturës në të cilën gjendet dhe vazhdon me iteracionin tjetër të ciklit. Në
strukturat while dhe do-while, testi për vazhdimin e ciklit zhvillohet menjëherë pasi të ekzekutohet
urdhëresa continue. Në strukturën for pasi të ekzekutohet shprehja për inkrementim pastaj
zhvillohet testi për vazhdimin e ciklit. Më parë kemi theksuar se struktura while mund të përdoret
për paraqitjen e strukturës for. Kjo nuk vlenë vetëm në astin kur shprehja për inkrementim në
strukturën while pasohet me urdhëresën continue. Në këtë rast inkrementimi nuk ekzekutohet para
se të testohet kushti për vazhdimin e përsëritjes she while nuk e ekzekuton në mënyrë të njejtë si
edhe for.
Prg9 e përdor urdhëresën continue në strukturën for që ta kalon urdhëresën dalëse në
strukturë dhe fillon iteracionin tjetër të ciklit.
Në këtë kapitull do të sqarojmë se për çka na nevojiten funksonet, si deklarohen ato dhe si i
thrrasim dhe kthehemi nga ato. Shumica e programeve që shërbejnë për zgjidhjen e problemeve të
caktuara janë më të mëdha se programet e paraqitura deri më tash. Problemet e ndërlikuara zgjidhen
me ndarjen e tyre në një numër më të madh të problemeve të vogla (module) të cilat mund të
menagjohen më lehtë. Në këtë mënyrë arrijmë tek kuptimi programimit modular. Modulet në C++
quhen funksione dhe klasa.
Programet e C++ zakonisht shkruhet me kombinimin e funksioneve dhe klasave të shkruara
mga vet programuesi dhe funksioneve dhe klasave që janë në dispozicion në bibliotekën standarde
të C++. Biblioteka standarde e C++ ka një koleksion të pasur të funksioneve që kryejnë tllogaritje ë
zakonshme matematike, manipulimin me stringje, manipulimin me karaktere, kërkimin e gabimeve
hyrëse/dalëse dhe shumë operacione tjera.
Programuesi mund të shkruaj funksione që të definoj detyra specifike që mund të përdoret
në shumë pika në program. Këto quhen funksione të definura nga programuesi. Urdhëresat që e
definojnë funksionin shkruhen vetëm njëherë dhe këto urdhëresa janë të fshehura për funksionet
tjera.
Funksioni është tërësi e deklarimeve të organizuara në mënyrë të caktuar. Një funksion është
pjesë pavarur e kodit të C++ i cili e ka emrin dhe kryen një detyrë të caktuar që mund të kthej një
vlerë në programin thirrës. Ti sqarojmë këto që thamë më lartë:
o Funksioni është pjesë pavarur e kodit të C++ Përkthyesi i C++ funksonin e trajton si një
tërësi të veçant programore
o Funksioni e ka emrin e vet. Çdo funksion e ka emrin e vet unikat të njejtin emër nuk guxon
ta ketë asnë funksion ose ndryshore tjetër). Me përdorimin e emrit në pjesë tjetër të
programit ekzekutohen urdhëresat të cilat i përmban funksioni. Kjo njihet si thirrrje e
funksionit. Një funksion mund të thirret nga funksioni tjetër. Për ngjitjen e emrave të
funksioneve vlejnë të njejta rregulla si emërtimet e ndryshoreve.
o Një funksion kryen një detyrë të caktuar. Detyra është një punë diskrete që duhet ta kryej
funksioni si pjesë e programit siç është psh llogaritje të ndryshme, dërgimi i një rreshti të
tekstit në shtypës, klasifikime të ndryshme etj.
o Një funksion mund të kthej një vlerë në programin thirrës. Kur programi e thirr një
funksion, urdhëresat që i përmban ai ekzekutohen. Këto urdhëresa mund ti dërgojnë
informatat prapa në programin thirrës nëse ato na nevoiten.
Një program i C++ nuk i ekzekuton urdhëresat në funksion përderisa funksioni nuk thirret
nga ndonjë pjesë tjetër e programit. Kur të thirret funksioni, programi mund ti dërgoj informata
funksionit në formë të një ose më shumë argumenteve. Një argument është një e dhënë e programit
që i duhet funksionit për të kryer një detyrë të caktuar. Urdhëresat në funksion ekzekutohen pastaj
duke e kryer qëllimin për të cilat janë shkruar. Kur kryhen urdhëresat e funksionit, ekzekutimi
kthehet prapa në të njejtin vend në program që e ka thirrë funksionin. Funksionet mund ti dërgojnë
prapa informacionet në program në formë të një vlere kthyese.
Çdo herë kur të thirret funksioni, ekzekutimi dërgohet (kalon) në atë funksion. Kur të
përfundon funksioni, ekzekutimi dërgohet prapa në vendin prej të cilot funksioni ishte thirr. Një
funksion mund të thirret aq herë sa të nevoitet.
Bazat e gjuhës programuese C++ S. Bekteshi 58
Më parë kemi theksuar se para se të përdoret ndryshorja duhet të deklarohet ose të definohet.
Edhe për funksionet vlen e njejta gjë. Funksionet duhet të deklarohen ose të definohen para se të
thirren.
Përdorimi i funksioneve në program kërkon që së pari të deklarohet e pastaj të definohet
funksioni. Deklarimi i tregon kompajllerit emrin, tipin kthyes dhe parametrat e funksionit.
Definicioni i tregon kompajllerit se si punon funksioni. Asnjë funksion nuk mund të thirret prej
funksionit tjetër nëse më parë nuk është i deklaruar. Deklarimi i funksionit quhet prototipi i tij.
Definimi i funksionit
Definimi i funksionit kërkon nga kompajlleri i C++ të rezervoj memorje për ndryshoren ose
funksionin e emruar me një identifikator. Forma e përgjithshme e definimit të funksionit është :
tipi_kthyes emri_funksion( lista e parametrave);
{
deklarata(t)
urdhëresa(i)
....................
urdhëresa_kthyese
}
Definimi i funksonit përbëhet nga :
- tipin e vlerës kthyese,
- emri i funksonit, Kreu i funksionit
- lista e parametrave dhe
- trupi i funksonit
Tri elemetet e para e formojnë kreun e funksonit. Këto elemente e përbëjnë të gjitha
informatat e nevojshme që funksioni të thirret dhe të shfrytëzohet në mënyrë të drejtë, por nuk n’a
tregojnë asgjë se si e kryen funksioni punën e vet. Kjo është detyrë e trupit të funksonit.
Funksoni nuk definohet asnjëherë brenda funksonit tjetër. Të gjitha kodet e funksoneve në
programe duhet të jenë sekuenciale, dmth njëra pas tjetrës. Kllapa që e mbyll funksonin duhet të
jetë para kodit të funksionit të ardhshëm .
Kreu i funksionit
Tipi i vlerës se kthyer mund të jetë çfardo tipi i të dhënave ose tipi i nxjerrur. Është e qartë
se tipit int, float, char e kështu me radhë, janë tipe të përshtatshme për vlerën e kthyer. E njëjta gjë
vlen edhe për void që dmth se funksioni nuk kthen kurrfarë vlere.
Bazat e gjuhës programuese C++ S. Bekteshi 59
Shembull: Nëse funksioni e llogaritë vlerën reale me precizitet të zakonshëm atëhere tipi i vlerës
kthyese është float ose nëse kemi:
int funksioni1(...) // kthen një tip int.
souble funksioni2(...) // kthen një tip double.
void funksioni3(...) // nuk krhen asgjë.
Lista e parametrave
Shumë funksione i përdorin argumentet të cilat janë vlera të dërguara në funksion kur ai
thirret. Funksioni duhet ta dij se çfarë llojit të argumenteve të pres – tipin e të dhënave për çdo
argument. Funksionit mund ti dërgohet çdo tip i të dhënave të C++. Informatat e tipit të argumentit
jipet në kreun e funksionit me listën e parametrave.
Lista e parametrave është lista e ndarë me presje që përmban deklaratat e parametrave që
pranohen nga funksioni kur ai të thirret. Për çdo argument që i dërgohet funksionit, lista e
parametrave duhet të ketë nga një vend. Ky vend përcakton tipin e të dhënave dhe emrin e
parametrit. Nëse funksioni nuk pranon asnjë vlerë, lista e parametrave është void ose rhjesht është e
zbrazët. Në listën e parametrave të funksionit duhet të shkruhet gjithsesi mënyrë eksplicite tipi për
çdo parametër.
Trupi i funksionit
Trupi i funksionit shpesh quhet bllok dhe është vendi ku kryhet puna. Ai paraqet tërësinë e
deklaratave ekzekutuese, deklaratave të zakonshme dhe të ndryshoreve që përdoren në funksion.
Deklaratat e ndryshoreve duhet të shkruhen para deklaratave ekzekutuese prg,28.
Kllapat e mëdha shënojnë fillimin dhe fundin e trupit të funksionit. Rrjedhja e ekzekutimit
kur kalon në funksionin e thirrur po kalon në urdhëresën e parë ekzekutuese në trupin e funksionit.
Ekzekutimi del nga funksioni përmes urdhërave drejtuese siç janë: return, abort dhe exit ose thjesht
duke kaluar fundin e trupit të funksionit (kllapa e madhe e djathtë). Kllapat e formojnë bllokun nga
urdhëresat të cilat i rrethojnë. Brenda bllokut funksional mund të keni blloqet e brendshme.
Shembull:
Bazat e gjuhës programuese C++ S. Bekteshi 60
Pas kreut të funksionit është definuar trupi i tij. Pasi dëshirohet të llogaritet shuma e
katrorëve prej 1 deri në n nevoiten dy ndryshore, ndryshorja i për kontrollimin e ciklit for dhe
ndryshorja shuma për agregimin e shumës së katrorëve gjatë llogaritjes. Ndryshorja i është
deklaruar e tipit int, ndërsa shuma si long int. Deklarimi dhe inicializimi i ndryshoreve është i njëjtë
si tek funksioni main.
Në këtë program funksioni main() e thirrë funksionin shuma_katror dhe si vlerë të
parametrit formal e specifikon 40. Parametri 40 është parametri i vërtetë i funksionit sepse me atë
vlerë të parametrit ekzekutohet me të vërtetë funksioni. Parametri i vërtetë duhet të jetë i tipit të
njëjtë si edhe parametri formal. Funksioni main mund ta thirrë funksionin shuma _katror edhe më
shumë herë me vlera të tjera të parametrit të vërtetë.
Deklarimi i funksionit
Prototipi i funksionit
Tek ndryshoret deklarimi i saj është i njejtë me definimin e saj, por kjo nuk vlen edhe për
funksionin. Deklarimi i funksionit është paralajmrim për një funksion i cili është definuar diku
tjetër dhe përcakton se çfarë vlere kthehet nga funksioni. Definimi i funksionit e definon se çka bën
funksioni si dhe jep numrin dhe tipin e argumenteve që barten në funksion.
Forma e përgjithshme e deklarimit (prototipit) të funksionit është:
tipi_kthyes emri_funksion(lista e parametrave);
Prototipi i funksionit ndërtohet ashtu që kreut të funksionit i shtohet një pikë-presje.
Prototipi i funksionit i tregon përkthyesit se çka të pret kur më vonë, në program, të thirret
funksioni. Prototipi e përcakton tipin e vlerës së kthyer, emrin e funksionit dhe tipet e të gjithë
argumenteve që priten. Përveç rasteve kur funksioni të cilat marrin numër të ndryshëm të
argumenteve, prototipi e përcakton gjithashtu edhe numrin e argumenteve. Të gjitha këto informata
i ndihmojnë përkthyesit që të shqyrtoj se kodi burimor i juaj a i shfrytëzon saktë dhe në mënyrë
konsistente funksionet. Në këtë mënyrë i largohemi gabimeve të mundshme.
Prototipi i funksionit dhe definicioni i funksionit duhet të pajtohen plotësisht sipas tipit
kthyes emrit dhe listës së parametrave. Në të kundërtën kompajlleri do të lajmëroj për gabim. Të
theksojmë se në listën e parametrave duhet të shënohen vetëm tipet e të dhënave të parametrave.
Për dokumentim më të mirë, në atë listë mund të vendosen edhe emrat e parametrave. Përkthyesi
ata emra nuk i merr në shqyrtim.. Yë gjitha këto që u thanë më lartë janë sqaruar në prg7
Analizë: Çdo program që e kemi paraqitë deri tash e ka pasë fuksionin thirrës main() që i ka thirrë
funksionet e bibliotekës standarde të kryejnë detyra të caktuara. Funksioni katrori është thirrë në
main() me:
katrori (x)
funksioni katrori pranon një kopje të vlerës x në parametrin y. Pastaj katrori e llogaritë y*y rezultati
kthehet prapa në pikën në main ku katroti është thirrë dhe rezultati paraqitet. Të theksojmë se vlera
e x nuk ndryshon me thirrjen e funksionit. Ky proces përsëritet dhjetë herë duke e përdore
strukturën përsëritëse for. Definicioni i katrorit tregon se katrori e pret një parameter të tipit int.
Fjala e rezervuar int para katrori tregon se katrori e kthen rezultatin e tipit int. Urdhëresa return në
funksonin katrori e dërgon rezultatin e llogaritur prapa në funksionin thirrës.
Në rreshtin 5, int katrori (int); është prototip i funksonit. Tipi i të dhënave int brenda
kllapave e informon kompajllerin se funksioni katrori pret një vlerë integer nga funksioni thirrës. int
para emrit katrori e informon kompajllerin se katrori e kthen rezultatin të tipit int në funksionin në
funksionin thirrës. Kompajlleri i referohet prototipit të funksionit të hulumtoj se thirrja e katrori
përmban tip korrekt kthyes, numër korrekt i argumenteve, tipe korrekte të argumenteve dhe se
argumentet janë në radhë korrekte.
Fajllat header
Shembull: a) Fajlli header katrori.h mund të përfshihet nëse në krye të programit shkruajmë:
#include<katrori.h>
Shembull: b) Unë e kam përdor funksionin cout pothuajse në çdo program. Çdo herë më është
dashtë ta përfshij fajllin header iostream.h. sepse fajlli header përmban deklaratën e cout e cila e
sinjalizon kompajllerin për tipin kthyes dhe prototipin e funksionit. Definicioni i cout gjendet në një
vend tjetër.
Të gjitha funksionet në bibliotekën math i kthejnë të dhënat të tipit double. Nëse dëshirojmë
ti përdorim funksionet e bibliotekës math duhet të përfshihet (duhet të shkruhet) fajlli header
math,h. (ky fajll header në bibliotekën e re standarde të C++ quhet cmath.h). Disa funksione
matematike janë paraqitur në tabelën.8
Parametrat dhe argumentet janë dy emra të ndryshëm për të njëjtën gjë, të shiquar nga
aspekte të ndryshme. Nga aspekti i definimit të funksionit vlerat në listë nën kllapa pas funksionit
quhen parametra formal kurse nga aspekti i funksionit i cili i thirrë vlerat e dhëna funksionit të
thirrur quhen argumente të vërtetë. Të dhënat që dërgohen quhen parametra ndërsa të dhënat që
pranohen quhen argumente të funksionit.
Bazat e gjuhës programuese C++ S. Bekteshi 64
Një argument është vlera që i dërgohet funksionit nga programi thirrës. Çdo herë kur të
thirret funksioni atij mund ti dërgohen argumente të ndryshme. Në C++, një funksioni duhet ti
dërgohen numri dhe tipi i njejtë i argumenteve për çdo herë që thirret, por vlerat e argumentiti mund
të jenë të ndryshme. Në funksion, argumentit i çasemi duke e përdorë emrin përkatës të parametrit.
Parametri është ndryshorja e cila krijohet në stekun e programit në momentin e thirrjes së
funksionit. Kjo ndryshore përdoret që t’i ruhet vendi dhe nëpërmjet emrit të tij merren të dhënat që i
jipen.
Deri më tani shpesh jemi takuar me shprehjet „thirrja e funksionit“ dhe „kontrolla kthyese“.
T’i sqarojmë këto shprehje më detalisht.
Thënë në përgjithësi, funksioni që kontrollon thirrjet e funksionit dhe shkallën e tyre quhet
funksion thirrës. Funksioni që kontrollohet prej funksionit thirrës quhet funksion i thirrur. Që të
thirret një funksion, thjesht shkruhet emri i funksionit (duke përfshirë kllapat dhe në fund
pikëpresje).
Shembull: a) Një funksion thirret A function is invoked (dmth është ndërtuar që të kryej detyrën e
destinuar) nga funksioni thirrës. Funksioni thirrës specifikohet me emrin e funksionit dhe jep
informata (si argumente) që funksioni i thirrur duhet të kryej punën e tij. Një analogji me këtë është
hierarkia e menagjimit. Shefi (në rastin tonë funksioni thirrës) kërkon nga punëtori1 (funksioni i
thirrur) të kryej detyrën dhe të kthej (return) (të jap përsëri raport) për rezultatet e punës së kryer.
Shefi (funksioni thirrës) nuk e din se si punëtori1 (funksioni i thirrur) e kryen punën e destinuar.
Punëtori1 mund të thirrë punëtorë tjerë (punëtori2, punëtori3 etj) dhe shefi të mos jetë i njohtuar për
këtë. Në këtë rast punëtori1 (funksioni i thirrur) është shef (funksion thirrës) për punëtori2,
punëtori3 etj. Kjo procedurë mund të vazhdoj edhe mëtutje sipas nevojës.
//Prg.25
#include <iostream.h>
#include <conio.h>
int Funks1(),Funks2();
main() /*Funksioni main ekzekutohet i pari*/
{
cout<<"\n Funksioni i parë quhet main \n";
Funks1();
Funks2();
Funks2()
{
cout<<"Brenda Funks2\n";
return 0;
}
Dalja:
Funksioni i parë quhet main
Brenda Funks1
Brenda Funks2
Funksioni main është kompletuar
Kur funksioni duhet të punoj me vlera, funksionin thirrës i dërgon vlerat brenda kllapave.
Kodi i funksionit pranues ka grupin e ngjashëm të kllapave me ndryshore brenda tyre që ti pranoj të
dhënat. Të dhënat që dërgohen quhen parametra ndërsa të dhënat që pranohen quhen argumente të
funksionit. Zakonisht një funksion nuk ka qasje në të dhënat lokale të tjetrit. Megjithate nëse
funksioni i dërgon një ose më shumë vlerat e të dhënave të veta si argumente, funksioni tjetër mund
ti pranoj ato të dhëna dhe të punoj si të kishte qasje gjithëmonë.
Shembull: b) main() i dërgon dy vlera integer, v1 dhe v2, funksionit Merrvlera(), main() mund ti
dërgon vlerat si vijon:
Merrvlera(v1, v2); // E thirr funksionin Merrvlera() dhe i jep dy vlera
Dy rreshtat e parë të Merrvlera(v1, v2) mund të duken si vijon:
void Merrvlera(int v1, int v2);
{
Bazat e gjuhës programuese C++ S. Bekteshi 66
Ekzistojnë tri mënyra për dërgimin e të dhënave nga njëri funksion në funksionin tjetër.
Përmes vlerës
Përmes adresës
Përmes referencës
Se cilën metodë do të përdoret varet nga ajo se funksioni pranues a duhet me qenë në gjendje
me i ndërrue ndryshoret e funksionit thirrës. Tash do të sqarohet dërgimi përmes vlerës ndërsa më
vonë përmes adresës dhe references.
Dërgimi përmes vlerës nganjëherë quhet edhe dërgim përmes kopijimit. Kur të dërgohet një
argument nga një funksion në funksionin tjetër, vlera e argumentit i dërgohet funksionit pranues,
ndërkaq vet ndryshorja nuk i dërgohet. Dërgimi sipas vlerës dmth se se funksioni pranues nuk mund
ta ndryshoj ndryshoren e funksionit dërgues në asnjë mënyrë. Pra dërgohet - vetëm vlera e
ndryshores së funksionit dërgues – por jo edhe vet vlera. Kur vlera arrin në funksionin pranues,
funksioni pranues e pranon atë vlerë në parametrin e vet të ndryshores lokale dhe punon me
ndryshoren e vet që përmban vlerën e dërguar. Megjithate, funksioni pranues asgjë nuk do të
ndryshoj në funksionin dërgues prg.26.
Kur funksioni pranon më shumë se një parametër, tipit e të dhënave të pranuara poashtu
ndahen me presje.
Shembull: Nëse main() e dërgon një integer të emruar me i, një karakter të emruar me c, dhe një
vlerë me presje dhjetore të emruar me x në funksionin Merr_vlera (), rreshti në main() mund të
duket si vijon:
Merr_vlera (i, c, x); // Dërgon tri vlera
Definicioni i Merr_vlera () mund të duket si vijon:
void Merr_vlera (int i, char c, float x) // rreshti i definimit
Siç theksuam edhe më parë, Merr_vlera () mund ti riemroj vlerat e argumenteve dhe ti
përdor emrat e rij si parametra të tij por Merr_vlera () kurrë nuk mund ti ndryshoj kopjet e main()
për asnjë ndryshore.
1.: // Prg.26 Dërgon një argument prej main() në funksionin tjetër përmes vlerës
2.:
3.:
Bazat e gjuhës programuese C++ S. Bekteshi 67
Analizë: Nga dalja shihet se Merrvlera () mund ta ndryshoj i vetëm brenda Merrvlera (). Pas
Merrvlera () e kthen kontrollën në main(), Shihet gjithashtu se i e main() ka mbet e njejtë me vlerën
e tij origjinale. Ndryshorja i e funksionit main() dhe ndryshorja i e funskionit Merrvlera () janë
plotësisht dy ndryshore të ndryshme. Njëra është ndryshore lokale e main() ndërsa tjetra është
ndryshore lokale e Merrvlera ().
main() nuk i ka në list tipin e të dhënave të i në kllapat e rreshtit 16 sepse main() e din tipi e
të dhënave të i. Vetëm funksionit pranues, i cili nuk din asgjë për argumentet para se ti dërgohen
duhet ti tregohet tipi i të dhënave të vlerave që i dërgohen.
Pikëpresja nuk qitet në fund të rreshtit të definicionit të funksionit psh rreshti 24 nuk duhet
kurrë të ketë pikëpresje në fund të tij. Në pikën ku thirret funksioni duhet të qitet pikëpresja si në
rreshtin 16.
Shigjeta tregon se si main() e dërgon vlerën e ndryshores e jo vet ndryshoren në Merrvlera (). Në
këtë rast se shfrytëzuesi ka shtypur 3 siç është tregue edhe në dalje.
Bazat e gjuhës programuese C++ S. Bekteshi 68
Nëse nga main() dërgohet më shumë se një vlerë në Merrvlera (), të gjitha vlerat do të
dërgohen por funksioni pranues nuk mund ti ndryshoj kopjet e main() të ndryshoreve. Kur dërgohen
më shumë se një ndryshore, ndryshoret ndahen me presje
Vlera kthyese e një funksioni mund të përdoret si një argument për funksionin tjetër
Nga një funksion mund të kthehet më së shumti një vlerë. Një funksioni mund ti dërgohen
disa parametra por kthehet vetëm një. Nëse një funksion e kthen një vlerë, funksioni thirrës nuk
është e thënë ta merr atë vlerë. Megjithate, edhepse funksioni thirrës mund të injoroj vlerën e
kthyer, vlera që kthehet duhet gjithëmonë të ekzistoj. Nëse një funksion kthen një vlerë atëhere
duhet të theksohet tipi i vlerës që funksioni e kthen. Në këtë rast duhet që tipi i të dhënave i vlerës
kthyese të shënohet para emrit të funksionit.
Shembull: b) Tipi i të dhënave i vlerës kthyese të shënohet para emrit të funksionit. Prandaj nga
definicioni i funksionit, pa e shiquar urdhëresën return, dihet saktë se çfarë tipi të të dhënave kthen
funksioni.
double Funksion1(int i, float j)
ky funksion kthen një vlerë double. Tipi i të dhënave që kthehet mund të theksohet gjithashtu edhe
në prototipin e funksionit:
double Funksion1 (int i, float j);
Nëse nuk është deklaruar tipi i vlerës kthyese atëhere përkthyesi i C++ sipas definicionit e
kthen vlerën int në programin thirrës. Praktikë e mirë programuese, në mënyrë që ti shmangemi
gabimeve të mundshme, është që gjithmonë në deklarimin e funksionit të shënohet edhe tipi i vlerës
kthyese. .
Nëse funksioni nuk kthen një vlerë atëhere shënohet void para emrit të funksionit. Void
është një sinjal për kompajllerin se asnjë vlerë nuk do të kthehet.
Shembull: d) Nëse funksioni nuk kthen një vlerë atëhere shënohet void para emrit të funksionit.
Bazat e gjuhës programuese C++ S. Bekteshi 69
Urdhëresa return mund të përmbaj shprehje e cila duhet të mbyllet në kllapa. Kur urdhëresa
return përmban shprehje atëherë vlera e shprehjes kthehet në funksionin thirrës. prg.27
return (shprehja);
nën supozimin se shprehja jep një vlerë. shembulli a nën 2 dhe 3.
Bazat e gjuhës programuese C++ S. Bekteshi 70
Ndryshorja globale - është nëse dhe vetëm nëse definohet jashtë funksionit.
Ndryshorja globale vlen prej vendit të definimit r teposhtë kodit burimor,pa marrë parasysh
se sa funksione apo rreshta përmban programi. Deklaratat që janë para ndryshoreve globale nuk
mund t’i përdorin ato ndryshore. Më poshtë po japim shembuj të definimit të ndryshoreve globale
dhe lokale .(pjesa më e errët paraqet fushëveprimin e tyre).
Përkundrazi ndryshoret lokale vlejnë deri në fund të bllokut të funksionit. Dmth pasi të
kryhet funksioni këto ndryshore shkatrrohen. Dy ndryshore mund të kenë të njejtin emër nëse ato
janë ndryshore lokale në dy funksione të ndryshme. Ato janë ndryshore të ndryshme edhe pse e
kanë të njejtin emër.
Ndryshoret automatike-Sipas definicionit të gjitha ndryshoret lokale janë automatike që dmth se
shkatrrohen kur funksioni i tyre mbaron. Që të definohet një ndryshore si automatike duhet ti
Bazat e gjuhës programuese C++ S. Bekteshi 71
shtohet parashtesa auto e cila është opcionale (nuk është e domosdoshme sepse ato janë edhe ashtu
automatike)
Ndryshoret statike-Përkundër ndryshoreve automatike kemi ato statike. Sipas definicionit të gjitha
ndryshoret globale janë statike, dmth i ruajnë vlerat e tyre., Nëse një ndryshore lokale është statike
atëherë ajo e ruan vlerën e saj kur përfundon funksioni; në rast se ky funksion thirret për herë të
dytë. që të definohet një ndryshore si statike duhet ti shtohet parashtesa static.
x
4
Llogaritja e vlerës së integralit:: 2
1 dx me metodën numerike të Trapezit.
1
for (i=1;i<=n-1;i++)
s=s+f(a+i*h); s2=0
T=h*((f(a)+f(b))/2+s);
cout << "Vlera e integralit T="<< T<< "\n";
return 0; s=s+f(a+ih)
}
i=i+1
// Nënprogrami
double f(double x)
Po
{ i≤n-1
return x*x+1; Jo
}
f (a ) f (b)
T h s
Dalja: 2
Fundi
Bazat e gjuhës programuese C++ S. Bekteshi 73
x
4
Llogaritja e vlerës së integralit:: 2
1 dx me metodën numerike të Simpsonit.
1
// Programi Prg11_2
#include <iostream>
int main()
{ f(x)=x2+1
const int n=10;
const double a=1,b=4; n,a,b
int i;
double S,s1,s2,h;
h=(b-a)/(2*n); ba
h
s1=0; 2n
s2=0;
s1=0
for (i=1;i<=n-1;i++)
{
s1=s1+f(a+(2*i-1)*h); s2=0
s2=s2+f(a+2*i*h);
}
s1=s1+f(a+(2*n-1)*h);
S=h/3*(f(a)+f(b)+4*s1+2*s2); s1=s1+f[a+(2i-1)h]
cout << "Vlera e integralit S="<< S<< "\n";
return 0;
} s2=s2+f[a+2ih]
// Nënprogrami
double f(double x) i=i+1
{
return x*x+1; Po
} i≤n-1
Jo
Dalja:
S
h
f (a) f (b) 4s1 2s2
Vlera e integralit S=24 3
s1=s1+f[a+(2n-1)h]
Fundi
Bazat e gjuhës programuese C++ S. Bekteshi 74
24
1
Llogaritja e vlerës së integralit të dyfishtë: dxdy me metodën numerike të Trapezit.
12 x y 2
// Programi Prg11_3
#include <iostream>
#include <cmath>
for (i=1;i<=n-1;i++) d c
{ g
m
xi=a+i*h;
s1=s1+f(xi,c)+f(xi,d);
}
s2=0;
r
1
f (a, c) f (a, d ) f (b, c) f (b, d )
4
for (j=1;j<=m-1;j++)
{ s1=0
yj=c+j*g;
s2=s2+f(a,yj)+f(b,yj);
} i=1
s3=0;
for (i=1;i<=n-1;i++)
{ xi=a+ih
xi=a+i*h;
Dalja:
Jo
S
h
f (a) f (b) 4s1 2s2
3
s1=s1+f[a+(2n-1)h]
Fundi
Bazat e gjuhës programuese C++ S. Bekteshi 76
7. Matricat
Matricat njëdimensionale
Matrica është një grup i lokacioneve të memorjes të njëpasnjëshme çdonjëra prej tyre
përmbanë të dhëna të të njejtit tip dhe të njejtit emër. Çdo lokaciom i memorjes quhet element i
matricës. Çdo lokacioni të posaqëm të memorjes respektivisht çdo elementi të matricës i çasemi me
emrin e matricës të shoqëruar me numrin e pozitës të elementit të caktuar në kllapat e mesme ( [] )
Shembull: Në fig është është paraqitur matrica me emrin c. Kjo matricë i ka 12 elemente. Çdo
elementi mund ti drejtohemi me emrin e matricës së shoqëruar me numrin e pozitës të elementit të
caktuar në kllapat e mesme ([ ]). Numrimi i elementeve të matricës fillon nga zero kështuqë
elementi i parë në çdo matricë është elementi zero. Në rastin tonë elementi i parë është c[0]
elementi i dytë është elementi c[1] e kështu me radhë. Elementi i njëmbëdhjetë është c[10] dhe
elementi i dymbëdhjetë është c[11].
Numrimi i elementeve të matricës fillon nga zero kështu që elementi i parë në çdo matricë
është elementi zero [0]. Elementi i n-të i matricës është [n-1]. Për emra të matricave vlejnë të
njejtat konventa si edhe për ndryshoret tjera.
Numri i pozitës i cili gjendet brenda kllapave të mesme quhet edhe indeks. Indeksi pra është
numri i elementeve të matricës i futur brenda kllapave të mesme Indeksi duhet të jetë një numër i
plotë ose një shprehje që jep numër të plotë. Nëse programi e përdorë një shprehje si indeks atëhere
shprehja zhvillohet në përcaktimin e indeksit.
Kllapat e mesme që përdoren për kufizimin e indeksave të një matrice në të vërtetë janë
operatorë në C++. Prioriteti i kllapave të mesme është i njejtë si edhe i kllapave të vogla (tabela)
Deklarimi i matricës
Matricat zejnë vend në memorje. Deklarimi i një matrice bëhet duke e shkruar tipin, emrin e
matricës dhe indeksin.
tipi emri_vargut[indeksi];
Shembull: Kompajllerit i themi ti rezervoj 12 elemente për matricën me emër matrica1 të tipit long
int me deklaratën:
long matrica1[12];
Bazat e gjuhës programuese C++ S. Bekteshi 77
Pasi që çdo long int kërkon 4 bajt atëhere kompajlleri rezervon gjithsejt 48 bajt të
njëpasnjëshëm të memorjes. Në një deklaratë memorja mund të rezervohet edhe për disa matrica:
int matrica1[12], matrica2[22] matrica3[112];
Inicializimi i matricës
Inicializimi i matricës mund të bëhet me rastin e deklarimit të saj pas emrit të matricës
shkruhet shenja e barazimit (=) dhe brenda kllapave të mesme shënohen vlerat me radhë të ndara
me presje.
Nuk lejohet asesi që të inicializohen më shumë elemente se sa janë deklaruar ndërsa lejohet
që numri i elementeve të deklaruar të jetë më i madh se numri i vlerave të inicializuara Nëse
nevojitet kompajlleri mund të llogarit madhësinë e një matrice (Prg10)
Shembull: Nuk lejohet asesi që të inicializohen më shumë elemente se sa janë deklaruar si psh:
int Matrica1[5] = { 10, 20, 30, 40, 50, 60 };
Në këtë rast kompajlleri do të tregoj për gabim sepse në Matrica1 janë deklaruar 5 elemente
ndërsa janë inicializuar 6 vlera. Lejohet që numri i elementeve të deklaruar të jetë më i madh se
numri i vlerave të inicializuara psh:
int Matrica1[10] = { 10, 20, 30, 40, 50 };
sepse elementet që nuk inicializohen i marrin vlerën 0.
Plotësisht matricë e njejtë krijohet edhe nëse nuk shënohet numri i elementeve brenda
kllapave të mesme:
int Matrica1[] = { 10, 20, 30, 40, 50 };
12: }
13: for (i = 0; i<5; i++)
14: cout << i << ": " << Matrica1[i] << "\n";
15: return 0;
16: }
Dalja: Vlera per Matrica1[0]: 3
Vlera per Matrica1[1]: 6
Vlera per Matrica1[2]: 9
Vlera per Matrica1[3]: 12
Vlera per Matrica1[4]: 15
0: 3
1: 6
2: 9
3: 12
4: 15
Klasifikimi i matricave
Klasifikimi i të dhënave ( dmth vendosja e të dhënave sipas rregullave të caktuara siç është
zmadhimi ose zvoglimi) është njëra nga zbatimet më të rëndësishme të llogaritjes. Shqyrtjmë rastin
e klasifikimit të vlerave të matricës në formën e zmadhimit (prg13).
Teknika e klasifikimit të fluskave ose klasifikimit të fundosjes sepse vlerat e vogla
gradualisht „si fluska“ ngjiten lartë deri në maje të matricës ashtu si ngriten lartë fluskat në ujë
ndërsa përderisa vlerat e mëdha bijnë në fund të matricës kjo teknikë duhet të kaloj disa herë nëpër
matricë. Gjatë çdo kalimi krahasohen çiftet suksesive të elementeve. Nëse çifti është në formën e
rritjes (ose vlerat janë identike) vlerat lihen ashtu siç janë. Nëse çifti është në formë të zvoglimit ato
shkëmbehen (i ndërrojnë vendet ndërmjet veti).
Së pari krahasohet elementi i parë i matricës me elementin e dytë të matricës pastaj
elementii dytë me elementin e tretë, elementi i tretë me të katërtin e kështu me radhë deri sa të
kompletohet kalimi me krahasimin e e elementit të parafundit me elementin e fundit të matricës.
Nëse janë n elemente të matricës atëhere kryhen vetëm n -1 krahasime. Pasi bëhet krahasimi në
mënyrë suksesive, vlera e madhe nënjë kalim për disa pozita zbret poshtë përderisa vlera e vogël
mund të ngritet lartë vetëm për një pozitë. Në kalimin e parë me siguri vlera më e madhe do të zbres
në elementin e fundit të matricës. Në kalimin e dytë, vlera e dytë për nga madhësia zbret në
elementin n-1. Në kalimin e n-1, vlera e n-1 për nga madhësia me siguri zbret në elementin e dytë.
Vlera më e vogël mbetet në elementin e parë kështu që për n elemente nevoiten n-1 kalime.
E metë e kësaj teknike është sepse ekzekutohet shumë ngadal e kjo vjen në shprehje
posaqërisht tek matricat e mëdha. Natyrisht ekzistojnë edhe teknika tjera të klasifikimit.
Bartja e një argumenti të matricës në funksion bëhet duke e shkruar emrin e matricës pa
kllapa.
Matricat shumëdimensionale
Matricat mund të kenë më shumë se një dimension. Çdo dimension paraqitet me një indeks
në matricë. Pra matrica dydimensionale i ka dy indekse, matrica tredimesnionale i ka tre indekse e
kështu me radhë.
dalja:
matrica[0][0]: 0
matrica[0][1]: 0
matrica[1][0]: 1
matrica[1][1]: 2
matrica[2][0]: 2
matrica[2][1]: 4
matrica[3][0]: 3
Bazat e gjuhës programuese C++ S. Bekteshi 81
matrica[3][1]: 6
matrica[4][0]: 4
matrica[4][1]: 8
Analizë: Rreshti 4 e deklaron matrica një matricë dydimensionale. Dimensioni i parë i ka pesë
numra të plotë ndërsa dimensioni i dytë nga dy numra të plotë. Kjo formon matricën 5x2. Vlerat
inicializohen në çifte. Në rreshtat 5 dhe 6 formohet cikli for. Cikli i jashtëm for kalon nëpër secilin
anëtar të dimensionit të parë. Për çdo anëtarë të atij dimensioni cikli i brendshëm for kalon nëpër
çdo anëtarë të dimensionit të dytë. Kjo është në përputhje me daljen matrica[0][0] shoqërohet nga
matrica[0][1]. Dimensioni i parë inkrementohet vetëm pasi dimensioni i dytë është inkrementuar
me 1. Pasta dimensioni i dytë fillon përsëri.
Çdo vlerë duhet të ndahet me presje pa marrë parasysh kllapat. Në fund vendoset pikëpresje
(prg12).
36
37 // Gjen noten minimale
38 int minimum( int notat[][ testimet ], int nxenesit, int testimet )
39 {
40 int Notavogel = 100;
41
42 for ( int i = 0; i < nxenesit; i++ )
43
44 for ( int j = 0; j < testimet; j++ )
45
46 if ( notat[ i ][ j ] < Notavogel )
47 Notavogel = notat[ i ][ j ];
48
49 return Notavogel;
50 }
51
52 // Gjen noten maksimale
53 int maximum( int notat[][ testimet ], int nxenesit, int testimet )
54 {
55 int Notamadhe = 0;
56
57 for ( int i = 0; i < nxenesit; i++ )
58
59 for ( int j = 0; j < testimet; j++ )
60
61 if ( notat[ i ][ j ] > Notamadhe )
62 Notamadhe = notat[ i ][ j ];
63
64 return Notamadhe;
65 }
66
67 // Percakton noten mesatare per secilin student
68 float mesatare( int setOfNotat[], int testimet )
69 {
70 int totali = 0;
71
72 for ( int i = 0; i < testimet; i++ )
73 total += setOfNotat[ i ];
74
75 return ( float ) totali / testimet;
76 }
77
78 // Shtyp matricën
79 void rezultati( int notat[][ testimet ], int nxenesit, int testimet )
80 {
81 cout << " [0] [1] [2] [3]";
82
83 for ( int i = 0; i < nxenesit; i++ ) {
84 cout << "\nNotatStudent[" << i << "] ";
85
Bazat e gjuhës programuese C++ S. Bekteshi 83
Shembull: Struktura vijuese for i jep vlera 0 çdo elementi të rreshtit të tretë të matrica1:
for (kolona=0; kolona<4; kolona++)
matrica1[2][kolona]=0;
Ne përcaktuam rreshtin e tretë sepse ne e dijmë se indeksi i parë është gjithëmonë 2 (0 është
indeksi i parë i rreshtit ndërsa 1 është indeksi i dytë i rreshtit). Cikli for e ndryshon vetëm indeksin e
dytë ( pra indeksin e kolomës). Struktura e mëparshme është ekuivalente me:
matrica1[2][0]=0;
matrica1[2][1]=0;
matrica1[2][2]=0;
matrica1[2][3]=0;
ose
Shembull: Struktura e përfshirë vijuese e përcakton totalin e të gjitha elementeve në matricën
matrica1:
Totali=0;
for (rreshti=0; rreshti<3; rreshti++)
for (kolona=0; kolona<4; kolona++)
Totali+= matrica1[rreshti][kolona];
Struktura for i mbledh elementet e matricës për secilën herë nga një rresht. Struktura e
jashtme for fillon me dhënjen e vlerave rreshti (pra indeksit të rreshtit) nga 0 ashtu që
elemetet e rreshtit të parë të mund të totaled nga struktura e brendshme for. Struktura e jashtme
for pastaj e inkrementon rreshti në 1 ashtu që rreshti i dytë të mund të mblidhet. Pastaj
struktura e jashtme for e inkrementon rreshti në 2 ashtu që rreshti i tretë të mund të
mblidhet. Rezultati shtypet kur përfundon struktura for.
Bazat e gjuhës programuese C++ S. Bekteshi 84
8. Treguesit
Në këtë kapitull shqyrtohen treguesit (ang. pointers) në gjuhën C++. Yreguesi është njëra
prej mjeteve më të fuqishme që është në dispozicion të programeve C++ me të cilën manipulohet në
mënyrë të drejtëpërdrejtë memorja e kompjuterit. Për të kuptuar më mirë treguesit në Shtesën1.
është sqaruar edhe pak memorja RAM.
Çdo ndryshore e ka adresën e vet. Adresat mund të ruhen në tregues. Treguesit janë
ndryshore. Për ta vlejnë të gjitha rregullat kryesore si edhe për ndryshoret tjera. Pra edhe ndryshoret
e tipit tregues duhet të deklarohen para se të përdoren. Dallimi i vetëm qëndron në të dhënat të cilat
ata i mbajnë. Treguesit nuk përmbajnë të dhëna në kuptimin e zakonshëm të fjalës. Ata përmbajnë
adresat e të dhënave. Në gjuhën C++ kemi dy operatorë treguesit.
& operatori ”adresa e “
* operatori i indireksionit
Operatorët * dhe & janë inverz njëri ndaj tjetrit.
Treguesit janë njëri nga tipet e rrjedhura të gjuhës C++. Edhe pse shumë programe në
njëfarë mënyre i implementojnë treguesit, kjo në gjuhën C++ është më elegante dhe më e fuqishme
Deklarimi i treguesve
Treguesi është ndryshore që e ruan adresën e memorjes si vlerë të tij. Natyrisht vdryshoret
drejtëpërsëdrejti përmbajnë vlera të caktuara Treguesi në anën tjetër përmbam një adresë të një
ndryshoreje që përmban një vlerë të caktuar. Në këtë mënyrë ndyshorja drejtëpërsëdrejti i referohet
një vlere ndërsa treguesi në mënyrë të tërthortë i referohet një vlere fig. Referimi i një vlere
nëpërmes treguesit quhet indireksion. Deklarimi i treguesve përfshinë element të ri – operatorin e
indireksionit *. Ja forma e përgjithshme :
tipi * emri _treg
komponenta tip e specifikon tipin e të dhënave në të cilat tregohet ndërsa emri_treg është
identifikatori më të cilin emrohet treguesi. Deklaratën mund t’a lexoni lehtë nëse shkoni në kahje të
kundërt - ‘emri_treg është tregues në objektin e tipit int”.Treguesit mund të deklarohen ashtu që të
tregojnë në objektet e çfardo tipi të të dhënave. Treguesi duhet gjithësesi të inicializohet. Nëse nuk
dini se me çka t’a inicializoni treguesin atëhere jepni vlerën zero. Kjo që thamë më lartë më mirë
kuptohet në bazë të progarmit Prg.33.
1. //prg.33
2. #include <iostream.h>
3. #include <conio.h>
4.
5. main ()
6. {
7. int ndrysh=100 ;
8. int*tndrysh;
Bazat e gjuhës programuese C++ S. Bekteshi 85
9.
10. cout<<"Numri eshte:"<< ndrysh ;
11. cout<<"\n Adresa e ndryshores ndrysh eshte: "<<&ndrysh;
12.
13. tndrysh=&ndrysh;
14. cout<<"\n *tndrysh eshte: "<<*tndrysh;
15. cout<<"\n Lokacioni i tndrysh eshte: "<< tndrysh;
16. getch();
17. return 0;
18. }
Dalja: Numri eshte: 100
Adresa e ndryshores ndrysh eshte: 0x0012ff88
*tndrysh eshte: 100
Lokacioni i tndrysh eshte: 0x0012ff88
Analizë: Të marrim një shembull të treguesit në ndryshore të tipit int që në mënyrë më detale të
shqyrtojmë deklarimin e treguesve
int ndrysh =100 ;
Të supozohet se dëshironi të deklaroni një ndryshore të tipit tregues. Kjo ndryshore e tipit tregues
nuk do mbaj vlerën e ndryshores ndrysh por do t’ju tregon (drejton) në ndryshoren ndrysh. siç është
ilustruar në fig.12 Fakti se përkthyesi i C++ e ka ruajtur ndryshoren ndrysh të themi në adresën
0x0012ff88. Që të deklaroni ndryshoren e tipit Adresat Memorja
tregues tndrysh veprohet:
int *tndrysh: ndrysh në
e cila mundson që në mënyrë indirekte t’i 0x0012ff88 100 tndrysh dërgon
afrohemi vlerës së ndryshores ndrysh. Karakteri në ndrysh
tndrysh në
yll * e deklaron ndryshoren tndrysh si tregues 0x0012ff88
0x0012ff88
ndërsa tipi int që ndryshorja tndrysh është
tregues në ndryshoren më numër të plotë. Dmth
kombinimi int* e deklaron ndryshoren tndrysh
Fig.12 Paraqitja skematike e memorjes
të tipit “tregues në tipin int” dhe tregon se në
program do të shfrytëzohet për afrimin në mënyrë indirekte të ndryshores së numrit të plotë .
Nëse x është ndryshore e çfardo tipi atëhere vlera e shprehjes &x është adresa x. Vlera e
shprehjes &x mund t’i jipet ndryshores e cila është e deklaruar si tregues në tip të njejtë siç është x.
Përndryshe edhe tndrysh mund të shkruhet urdhëresa:
int *tndrysh=&ndrysh;
e cila ndryshores tndrysh i jipet adresa e ndryshores ndrysh .
Pra, ndryshorja ndrysh është deklaruar si ndryshore e tipit int dhe është inicializuar me
vlerën 100, tndrysh është deklaruar si tregues në vlerën e tipit int – është inicializuar me adresën e
ndryshores ndrysh; tndrysh është tregues. Adresa të cilën tndrysh e ruan është adresa e ndryshores
ndrysh. vlera në adresën të cilën tndrysh e ruan është 100.
Vërejmë se adresa e ndrysh është e njejtë me vlerën e tndrysh në dalje që vërteton se adresa
e ndrysh me të vërtetë i është dhënë ndryshores të tipit tregues tndrysh.
Operatori i adresës
Operatori & - quhet operatori i adresës është një operator unar i cili kthen adresën e
operandit të tij.
Bazat e gjuhës programuese C++ S. Bekteshi 86
Fig treguesin në memorje duke supozuar se ndryshorja e tipit int është ruajtur në lokacionin
0x0012ff88 ndërsa ndryshorja e tipit tregues tndrysh është ruajtur në lakozcionin e memorjes
0x0012ff88. operandi i operatorit të adresës duhet me qenë një tndrysh (diçka në të cilën vlera
mund ti jipet siç është emri i ndryshores). Operatori i adresës nuk mund të zbatohet në konstante, në
shprehje të cilat nuk rezultojnë me references ose ndryshoret që deklarohen me klasën register.
Operatori i indireksionit
Shembull: nt x; , x = y:
Shembull: Që t’ia jepni vlerën nga matja1 ndryshores së re në matja2 duke shfrytëzuar treguesin
tmatja duhet që
:int matja1;
int matja;
matja = *tmatja;
Operatori i indireksionit (*) para ndryshores tmatja dmth “ mirre vlerën e cila ruhet në
adresën e ndryshores tmatja dhe jipja ndryshores matja”.
Shtrohet pyetja se operatorët a mund të kenë tregues si operandë dhe nëse po si përdoren
ata. Treguesit janë operand valid në shprehjet aritmetikore, shprehjet për dhënjen e vlerave dhe
shprehjet krahasuese; Megjithate të gjithë operatorët që përdoren në këto shprehje natyrisht se nuk
janë të xalid me ndryshoret e tipit tregues.
Një grup i vogël i operacioneve aritmetike mund të kryhen në tregues. Treguesi mund të
inkrementohet (++) dhe të dekrementohet (- -), një integer mund ti shtohet treguesit (+ ose +=), një
integer mund të zbritet nga treguesi (- ose -=) ose një tregues mund të zbritet nga treguesi tjetër.
Sqarim: Në matematikën e zakonshme 3000 + 2 = 3002. një gjë e tillë nuk vlen në matematikën e
treguesve. Kur një integer i shtohet ose i zbritet një treguesi atëhere treguesi nuk rritet ose
zvoglohet për atë integer por me integer herë madhësia e objektit të cilit i referohet treguesi. Numri
i bajtëve varet nga tipi i të dhënave të objektit. Psh urdhëresa :
tvlera +=2;
Bazat e gjuhës programuese C++ S. Bekteshi 87
do të jep 3008 (3000+2*4) nëse një integer është ruatur në 4 bajt të memorjes.
Nëse treguesi rritet për një atëhere operatori i inkrementimit (++) dhe dekrementimit (- -)
mund të përdoren. Urdhëresat tvlera++; si edhe ++tvlera; e rritin treguesn që tregon në lokacionin e
ardhshëm të matricës. Urdhëresat tvlera- -; si edhe - -tvlera; e zvoglojnë treguesin që tregon në
lokacionin e mëparshëm të matricës.
Ndryshoret e tipit tregues mund të zbriten njëra nga tjetra. Psh nëse tvlera1 e përmban
lokacionin 3000 ndërsa tvlera2 e përmban vlerën 3008 atëhere urdhëresa:
x=tvlera1 – tvlera2:
x do ti jep vlerën 2.
Nëse matrica është deklaruar me të dhëna të tipeve të ndryshme, urdhëresa që vjen do ta rrit
treguesin për dyfishin e numrit të bajtëve që nevoiten për ruajtjen e një objekti të atij tipi të të
dhënave. Kur e kryejmë matematikën me tregues në vargun e karaktereve rezultatet do të jenë
konsistente me matematikën e zakonshme sepse madhësia e karaktereve është 1 bajt.
Aritmetika me trergues është e pakuptimtë përveç në rastin kur kryhet me një matricë. Ne
nuk mund të supozojmë se dy ndryshore të të njejtit tipi ruhen në mënyrë kontinuale (afër njëri
tjetri) në memorje përveç rastit kur ata janë elemente fqinj (afër njëri tjetrit) të një matrice.
Një treguesi mund ti jipet vlera e treguesit tjetër nëse ata të dytë janë të të njejtit tip. Në
rastet tjera duhet të përdoret operatori cast për të kthyer vlerat e treguesit në të djadhtë të operatorit
për dhënjen e vlerave në treguesin e tipit majtas operatorit për dhënjen e vlerave. Përjashtim nga kjo
rregullë është treguesi në void (pra void*) që është një tregues gjenerues që mund të paraqes çfardo
tipi të treguesve. Çfardo tipi i treguesve mund të jetë oid pa e përdor operatorin cast.
Treguesi void* nuk mund të dereferencohet sepse kompajlleri duhet të dij tipin e të dhënave
që të përcaktoj numrin e bajtëve që duhet dereferencuar për secilin tregues. Në rastin e treguesit në
void numri i bajtëve nuk mund të përcaktohet nga tipi i të dhënave.
Treguesit mund të krahasohen duke i përdor operatorët për krahasim dhe operatorin e
barazimit. Krahasimet e tila janë të pakuptimta përveç për treguesit që tregojnë në anëtarët e të të
njejtës matrica sepse kemi të bëjmë me krahasimin e adresave që ruhen në tregues.
Treguesit dhe matricat kanë lidhje të ngushtë në C++. Emri i një matrice mund të mendohet
si një tregues konstant. Treguesit mund të përdoren për kryerjen e çfardo operacioni duke përfshi
edhe indeksimin.
Shembull: Të supozojmë se matrica e tipit int b[5] dhe ndryshorja integer e tipit tregues tb janë
deklaruar më parë. Pasi emri i matricës (pa indeks) është tregues në elementin e parë të matricës ne
mund të vendosim tb në adresën e elementit të parë të matricës b me urdhëresën:
tb = b;
kjo është ekuivalente me marrjen e adresës së elementit të parë si vijon:
tb = &b[0];
Elementit të matricës b[3] mund ti çasemi me shprehjen treguesore:
*(tb+3);
në shprehjen e mësipërme 3 është offset në tregues. Kur treguesi tregon në fillimin e një matrice
offset tregon se cilit element të matricës i çasemi dhe se vlera offset është identike me indeksin. Ku
notacion quhet notacioni treguesoffset. Kllapat janë të domosdoshme për shkak të prioriteti i
operatorit * është më i madh se i +.
Treguesit mund të indeksohen si edhe matricat. Për shembull shprehja:
tb[1];
Bazat e gjuhës programuese C++ S. Bekteshi 88
Treguesit në funksione
9. Stringjet
Karakteret janë elementet themelore të ndërtimit të programit burimor të C++. Çdo program
është i kompozuar si sekuencë e karaktereve – të cilat janë kuptimplote si tërësi – që interpretohen
nga kompjuteri si vargje të instruksionve që përdoren për kryerjen e ndonjë detyre. Një program
mund të përmbaj konstante të karaktereve. Konstanta e karakterit është një vlerë integer që paraqitet
si karakter në thojza të njëfishta. Vlera e karakterit konstant është vlera integer e karakterit në
grupin e karaktereve të makinës. Psh „x“ paraqet vlerën integer të x (122 në grupin e karaktereve
ASCII).
Stringu është varg i karaktereve i cili trajtohet si një njësi e vetme. Një string mund të
përmbaj shkronja, numra dhe karaktere speciale. Konstantet string në C++ shkruhen në thojza të
dyfishta.
Një string në C++ është një varg i karaktereve që mbaron me karakterin null (\0). Një
stringu i çasemi nëpërmes treguesit në karakterin e parë të stringut. Vlera e një stringu është adresa
(konstantë) e karakterit të tij të parë. Kështu në C++ është më e saktë të thuhet se stringu është një
tregues konstantë – në fakt tregues në karakterin e parë të stringut. Në këtë mënyrë stringjet janë të
ngjashme me matricat sepse emri i matricës është gjithashtu tregues (konstant) në elementin e tij të
parë.
Stringu mund të inicializohet në një deklaratë ose në matricë të karaktereve ose në
ndryshore të tipit char*.
Nganjëherë është e nevojshme që të futet i tërë rreshti në matricë. Për këtë qëllim në C++
kemi funksionin cin.getline. Funksioni cin.getline i ka tri argumente - vargu i karaktereve në të cilin
ruhet rreshti i tekstit, gjatësia dhe karakteri përkufizues.
Bazat e gjuhës programuese C++ S. Bekteshi 90
10. Klasa
Tipi i ri bëhet me deklarimin e klasës. Klasa është një grup i ndryshoreve, shpesh të tipeve
të ndryshme të cilat janë të kombinuara me tërësinë e funksioneve të lidhura mes vete. Klasa mund
të përbëhet nga çfardo kombinimi i tipeve të ndryshoreve dhe tipeve të klasave tjera. Ndryshoret që
i përmban klasa paraqesin ndryshoret (të dhënat) anëtarë. Ndryshoret anëtarë janë pra pjesë e
klasës. Funksionet anëtarë (metodat) në klasë zakonisht manipulojnë me ndryshoret anëtarë.
Funksionet anëtarë janë pjesë e klasës njësoj si edhe ndryshoret anëtarë. Mostra individuale e klasës
është objekti. Funksionet anëtarë përcaktojnë se çka mund të kryejnë objektet e klasës. Nga kjo që u
tha më lartë rrjedh se klasat i mundësojnë programuesit të modelojnë objektet të cilat kanë veti (që
paraqiten nëpërmes të dhënave anëtarë) dhe sjelljeve (që paraqiten nëpërmes funksioneve anëtarë).
Deklarimi i klasës
Deklarimi i klasës bëhet duke përdor fjalën e rezervuar class e shoqëruar me emrin e klasës
çiftit të klapave të mëdha {} brenda të cilave gjenden të dhënat anëtarë dhe funksionet anëtarë të
klasës. Deklarimi i klasës përfundon me pikëpresje. Sintaksa për klasën është si vijon:
class emri_klases
{
// këtu vijnë fjalët e rezervuara për kontrollin e çasjes
// këtu vijnë ndryshoret e deklaruara dhe metodat e deklaruara të klasës
};
Deklarimi gjithashtu vetëm i paraqet përkthyesit se çka është klasa, cilat të dhëna i përmban
(NumStudent, Viti) dhe çka mund të bëjë deklarimi mesatarja().
Në këtë rast nëse vlera e plotë (int) ka dy bajt, Klasa i ka 4 bajt (të dy ndryshoret nga dy).
mesatarja() nuk zen hapësirë sepse kurrfarë hapësire depozituese nuk rezervohet për funksionet
(metodat) anëtarë prg14.
Bazat e gjuhës programuese C++ S. Bekteshi 92
Analizë: Deklarimi i klasës bëhet duke përdor fjalën e rezervuar class (rreshti 6)e shoqëruar me
emrin e klasës (Grupi) çiftit të kllapave të mëdha {}(reshti 7 dhe 11) brenda të cilave gjenden të
dhënat anëtarë Numstudent (rreshti 9) dhe Viti (rreshti 10). Deklarimi i klasës përfundon me
pikëpresje (rreshti11).
Në rreshtin 14 fillon funksioni main. Fizika është deklaruar si objekt i klasës Grupi në
rreshtin 16. Numri i studentëve të Fizikës është dhënë me 15 në rreshtin 17. Në rrshtat 18 dhe 19
ndryshorja Numstudent është pëdor për të shtypur njoftiin për Fizikën.
Rreshti 8 përmban fjalën e rezervuar public, e cila tregon se çdo gjë që pason është publike deri
te fjala e rezervuar private ose mbarimi i deklaratës së klasës.
Emri i klasës bëhet përcaktues i tipit të ri. Mund të kemi disa objekte në klasë ashtu si mund
të kemi disa ndryshore psh të tipit int. Programuesi mund të krijoj tipe të reja të klasës sipas
nevojës. Kjo është arsyeja pse thuhet se C++ është një gjuhë e cila mund të zgjërohet
Definimi i objektit
Definimi i objakteve bëhet që të bëhet dallimi ndërmjet klasës si ide dhe klasës së caktuar që
ne n’a intereson (Fizika). D.m.th. objekti është mostër individuale e klasës. Një klasë (psh Grupi)
mund të ketë një ose më shumë objekte (Fizika, Kimia,…)
Bazat e gjuhës programuese C++ S. Bekteshi 93
Pasi të definohet objekti (p.sh. Fizika) me anë të operatorit pikë (.) bëhet çasja në anëtarët e
atij objekti, prg14).
Kur shfrytëzohen metodat e klasës ato thirren. Në këtë rast është thirrë funksioni
mesatarja() për objektin Fizika.
Duhet theksuar se vlerat iu jipen objekteve e jo klasave ashtu si iu jipen vlerat ndryshoreve e
jo tipeve.
Shembull:
Nuk iu jipen vlera tipit të të dhënave:
int=5; //gabim Grupi NumStudent=15; //gabim
por ndryshoreve
int x; //mirë Grupi Fizika; //mirë
x=5; //mirë Fizika. NumStudent=15; //mirë
Zakonisht programuesit e rinj gabojnë kur thirrin funksionet të cilat nuk janë deklaruar në
klasë, p.sh.
class. Grupi; class. Grupi;
Grupi Fizika; gabim mesatarja (); mirë
Fizika. mesatarja (); Grupi Fizika;
mesatarja ();
Specifikuesit për çasje të anëtarëve (public oe private) mbarojnë me dy pika (:) dhe mund të
paraqiten në definicionin e klasës shumë herë dhe në çfardo renditje.Të gjithë anëtarët e klasës, të
dhënat dhe metodat të cilat nuk deklarohen (si public) nënkupton se janë private. Anëtarëve private
mund t’i çasemi vetëm brenda metodave (funksioneve) të së njejtës klasë. Anëtarëve public mund
t’i çasemi nëpërmjet të çdo objekti të klasës.
Shembull:
class Grupi class Grupi
{ { public
unsigned int NumStudent; unsigned int NumStudent;
unsigned int Viti; unsigned int Viti;
mesatarja (); mesatarja ();
}; gabim }; mirë
Grupi Fizika; Grupi. Fizika;
Fizika. NumStudent=15; Fizika. NumStudent=15;
Fizika. Viti=4; Fizika. Viti=4;
Fizika. mesatarja(); Fizika. mesatarja()
Bazat e gjuhës programuese C++ S. Bekteshi 94
Duhet theksuar se është gabim pasi Fizika nuk ka çasje në ndryshoret NumStudent, Viti dhe
mesatarja() edhepse Fizika është objekt i klasës Grupi. Më parë kemi theksuar se të dhënat
konsiderohen private përveç nëse deklarohen si public. Nëse dëshirojë që Fizika të ketë çasje në
ndryshoret NumStudent, Viti dhe Mesatarja() atëhere duhet të përdoret fjala e rezervuar public
(si në rastin mirë).
Të dhënat anëtarë natyrisht vargisen në pjesën private të klasës dhe funksionet anëtarë
natyrisht vargisen në pjesën public të klasës. E lumdërta është e pazakonshme dhe konsiderohet si
praktikë e dobët programuese
Theksuam se si rregullë e përgjithshme është që të dhënat anëtarë të ruhen si private. Për
këtë arsye duhet të formohen funksione public të njohura si funksione çasëse për vendosjen dhe
marrjen e ndryshoreve private. Këto funksione çasëse janë funksionet anëtarë të cilat thirren nga
pjesët tjera të programit me qëllim që t’I fitojnë dhe vendosin ndryshoret private prg15 .
Analizë: Kjo klasë ka 5 metoda public. Rreshtat 9 dhe 10 përmbajnë funksionet çasëse për Viti.
Rreshtat 13 she 14 përmbajnë metodat çasëse për Drejtimi. Këto funksione çasëse i vendosin (i
japin) ndryshoret anëtarë dhe i kthejnë vlerat e tyre. Funksioni anëtar public mesatarja() është
deklaruar në rreshtin 16. mesatarja() nuk është funksion çasës. Ai as nuk merr e as nuk jep
ndryshore anëtarë, ai kryen shërbime tjera për klasën por psh e shtyp fjalën mesatarja. Të dhënat
anëtarë hanë deklaruar në rreshtat 20 dhe 21. Që të vendosni vitin e Fizikës duhet ta jipni vlerën
metodës PerVite() si vijon:
Grupi Fizika;
Fizika.PerVite(2); // E ven vitin e Fizikës duke përdor funksionin çasës public
Bazat e gjuhës programuese C++ S. Bekteshi 95
Theksuam më parë se funksioni çasës siguron interfejs public për të dhënat anëtarë private
të klasës. Implementim quhet definimi i funksionit. Definimi i funksionit anëtarë fillon me emrin e
klasës pas së cilës vjen dy pika të dyfishta, emri i funksionit dhe parametrat e tij. (prg16)
45: {
46: Grupi Fizika;
47: Fizika.VenViti(2);
48: Fizika.mesatarja();
49: cout << "Grupi i Fizikës per vitin e - " ;
50: cout << Fizika.MerrViti() << " ka 15 studente \n";
51: Fizika.mesatarja();
52; return 0;
53: }
Dalja: mesatarja.
Grupi i Fizikës per vitin e – 2 ka 15 studente
mesatarja.
Analizë: Definicioni i klassës Grupi bëhet në rreshtat 6-14 contain the definition of the Cat class.
Rreshti 8 përmbanë public, i cili i tregon kompajllerit se në vazhdi ka të bëjë me anëtarë publik.
Në rreshtin 9 deklarohet funksion çasës MerrViti().MerrViti () mundëson çasjen në
ndryshoren anëtar privat VitiI, i cili është deklaruar në rreshtin 13.
Rreshti 10 ka funksionin çasës publik VenViti().VenViti() pranon një integer si një
argument dhe ven VitiI në vlerën e atij argumenti.
Në rreshtin 11 deklarohet metoda e klasës mesatarja().mesatarja () inuk është funksion
çasës. Këtu ai është një metodë e përgjiyhshme që shtyp fjalën mesatarja në ekran.
Rreshti 12 fillon pjesa private, e cila përfshin vetëm deklaratën në rreshtin e 13 të ndryshores
anëtar privat VitiI. Deklarimi i klasës përfundon me mbylljen e kllapës dhe pikëpresje në rreshtin
14.
Rreshtat 18-21 përmbajnë defiimin e funksionit anëtar MerrViti(). Kjo metodë nuk pranon
parametar, ajo kthen një integer. Të theksojë se metodat e klasës përmbajnë emrin e klasës të
shoqëruar me dy parë dypika. Dhe emri i funksionit (rreshti 18). Kjo sintaksë i tregon kompallerit
se funksioni MerrViti() function që definohet këtu është njëri që është deklaruar në klasën
Grupi. Me përjashtimin e këtij rreshti kryesues funksioni NerrViti() krijohet si çdo funksion
tjetër.
Funksioni NerrViti() i necoitet vetëm një rresht; ai kthen vlerën në VitiI. Të theksojmë se
funksioni main() nuk mund ti çaset VitiI sepse VitiI është privat në klasën Grupi.
Funksioni main main() ka çasje në metodën publike NerrViti() sepse NerrViti() ëdhtë
funksion anëtar i klasës Grupi, ai ka çasje të plotë në ndryshoren VitiI. Kjo çashe i mundëson
NerrViti () të kthej vlerën e VitiI në main().
Rreshti 26 përmban definimin e funksionit anëtar VenViti(). Ai pranon një parametrë integer
dhe e ven vlerën e VitiI në vlerën e atij parametri në rreshtin 30 sepse ai është anëtar i klasës
Grupi. VenViti()ka çasje direkte në ndryshoren anëtar VitiI.
Në rreshtin 37 fillon definimi ose implementimi i metodës mesatarja() të klasës Grupi. Ai
është funksion i një rreshti që shtyp fjalën mesatarja në ekran. Të përkujtojmë se karakteri \n
shtyp rreshtin e ri në ekran.
Në rreshtin 44 fillon trupi i programitme funksionin e njohur main() Në këtë rast ai nuk ka
argumente dhe kthen void. Në rreshtin 46, main() deklaron një Grupi që quhet Fizika. Në
rrestin 47, vlera 5 i jipet ndryshores anëtar VitiI me metodën çasëse VenViti(). Të
theksojmë se metoda thirret duke e përdor emrin e klasës (Fizika) i shoqëeuar nga operatori
anëtar (.) dhe emri i metodës (VenViti()). Në të njejtën mënyrë mund të thirrençdo metodë
tjetër në klasë.
Bazat e gjuhës programuese C++ S. Bekteshi 97
Në rreshtin 48 thirret funksioni anëtar mesatarja() dhe rreshti 49 shtyp njoftiminduke e përdor
funksionin çasës MerrViti() . Rreshti 51 e thirr përsëri mesataraja().
Nëse në program nuk është deklaruar konstruktori ose destruktori, kompajlleri do ta formoj
një në vend të juaj. Konstruktori dhe destruktori default nuk pranojnë argumente dhe nuk bëjnë
asgjë. çfarë të mire kemi nga konstruktori i cili nuk bën asgjë? Pjesërisht kjo është çështje e formës.
Të gjitha objektet duhet të konstruktohen dhe destruktohen dhe këto funksione që nuk bëjnë asgjë
thirren në kohën e duhur.
Kur të definohet një objekt i klasës thirret konstruktori. Konstruktori mund të mos ketë
parametra, ta ketë një ose më shumë parametra.
Shembull: Nëse konstruktori Grupi ka dy parametra ju mund të definoni objektin e Grupi si vijon:
Grupi Fizika (5,7);
Nëse konstruktori pranon një parametër:
Grupi Fizika (5);
Në rastin kur konstruktori nuk pranon parametra atëhere e lini pa kllapa:
Grupi Fizika ;
Bazat e gjuhës programuese C++ S. Bekteshi 98
Në rastin kur konstruktori nuk pranon parametra atëhere duhet të lihet pa kllapa. Ky është
një përjashtim nga rregulla e cila thotë se të gjitha funksionet duhet të kenë kllapa bile edhe nëse
nuk kanë parametra.
34:
35: // Definimi i VenViti, funksion çasës public
37:
38: void Grupi::VenViti(int Viti)
39: {
40: // Even ndryshoren anëtar VitiI në vlerën e
41: // e vendosur nga parametri Viti
42: VitiI = Viti;
43: }
44:
45: // Definimi i metodës mesatarja
46: // kthen void
47: // parameterat: Ska
48: // veprimi: Shtyp mesatarja në ekran
49: void Grupi::mesatarja()
50: {
51: cout << "mesatarja.\n";
52: }
54: // Formon grupi, e ven VitiI, ka mesatarja
55 // na tregon VitiI përsëri e tregon mesatarja.
56: int main()
57: {
58: Grupi Fizika(5);
59: Fizika.mesatarja();
60: cout << ""Grupi i Fizikës per vitin e - " ;
61: cout << Fizika.MerrViti() << " ka 15 studente \n";
62: Fizika.mesatarja();
63: Fizika.VenViti(7);
64: cout << " Fizika në vitin- - " ;
65: cout << Fizika.MerrViti() << " ka 14 studentë.\n";
66; return 0;
67: }
Dalja: mesatarja.
Grupi i Fizikës per vitin e - 5 ka 15 studente
mesatarja.
Fizika në vitin- 7 ka 14 studentë.
Analizë: Programi Prg17 është i njejtë me programin Prg16 përveçse në rreshtin 9 ia shton
konstruktorin i cili pranon një integer.
Rreshti 10 deklaron destruktorin, i cili ska parametra. Destruktorët kurrë nuk kanë
argumente, dhe kurrë as konstruktori e as destruktori nuk kthejnë vlera – nuk kthejnë as void.
Rreshtat 19-22 paraqesin implementimin e konstruktorit. Është e ngjashme me
implementimin e funksionit çasës VenViti(). Këtu nuk kemi vlerë kthyese value.
Rreshtat 24-26 paraqesin implementimin e destruktorit ~Grupi(). Ky funksion nuk kryen
asgjë,por duhet të përfshihet definimii funksionit nëse është deklaruar në deklarimin e klasës.
Rreshti 58 përmban definimin e objektit Fizika. të Grupi Vlera 5 është bartur në
konstruktorin Fizika. Nuk ka nevoj të thorretl VenViti(), sepse Fizika ishte krijuar me vlerën
5 në ndryshoren e tij VitiI, siç është paraqitur në rreshtin 61.
Në rreshtin 63, VitiI i Fizikës iu është ridhënë vlera tani në 7.
Rreshti 65 shtyp vlerën e re.
Bazat e gjuhës programuese C++ S. Bekteshi 100
Klasat e thjeshtojnë programimin sepse klientët (klientët janë pjesë të programit të cilat
krijojnë dhe i përdorin objektet e klasës) duhet të mirren vetëm me operacionet që gjenden në
objekt. Operacionet e tilla janë të dizajnuara që më shumë të jenë të orientuara kah klienti se sa të
orientuara kah implementimi. Klienti nuk duhet të ketë lidhje me implementimin e klasës (edhepse
klienti natyrisht dëshiron implementim korrekt dhe efikas). Interfejsi ndryshohet por shumë më
rrallë se sa implementimi. Kur një implementim ndryshohet në pajtueshmëri me atë duhet të
ndryshohet edhe kodi i varur nga implementimi. Me fshehjen e implementimit ne e eliminojmë
mundësinë që pjesët tjera të programit të bëhen të varura nga detalet e implementimit të klasës.
Njëra prej parimeve themelore të ingjinieringut të mirë softuerik ëahtë ndarja e interfejsit
nga implementimi. Kjo e bën më të lehtë modifikimin e programit.
Në të vërtetë fajllat header duhet të përmbajnë disa pjesë të implementimit dhe
paralajmërime për disa pjesë tjera të implementimit.
Përfundim:
Fjala e rezervuar class përdoret për të deklaruar tipe të reja. Klasa është koleksion i të
dhënave të cilët mund të jenë të tipeve të ndryshme duke përfshirë edhe klasa të tjera. Klasa
gjithashtu përmban funksionet e klasës ose metodat – ato janë funksione të cilat shfrytëzohen për
manipulimin me të dhënat në klasë dhe për kryerjen e shërbimeve tjera për klasën.
Objektet definohen si të tipit të ri në të njejtën mënyrë si definohen ndryshoret. Duhet të
theksohet tipi (klasa) e pastaj emri i ndryshores (objekti). Anëtarët dhe funksionet e klasës I çasemi
me operatorin pikë (*).
Fjalët e rezervuara për kontrollën e çasjes shfrytëzohen për deklarimin e seksionit të klasës
si është private. Secila fjalë e rezervuar e ndryshon kontrollën e çasjes nga ajo pikë (ku deklarohet)
deri në fund të klasës ose deri të fjala tjetër e rezervuar për kontroll të çasjes. Deklarimi i klasës
mbaron me mbylljen e kllapës së madhe dhe shenjën pikëpresje.
Metoda public e çasjes është funksioni anëtar i klasës i cili shfrytëzohet për ruajtjen e vlerës
së ndryshores private ose vendosjen e vlerës së saj.
Bazat e gjuhës programuese C++ S. Bekteshi 101
Emri i klasës bëhet përcaktues i tipit të ri. Nund të kemi disa objekte në klasë ashtu si mund
të kemi disa ndryshore psh të tipit int. Programuesi mund të krijoj tipe të reja të klasës sipas
nevojës. Kjo është arsyeja pse thuhet se C++ është një gjuhë e cila mund të zgjërohet.
(Shembulli11)
Të theksojmë se të dhënat anëtarë nuk mund të inicializohen kur gjenden në trupin e klasës.
Këto të dhënat anëtarë duhet të inicializohen nga konstruktori i klasës ose mund ti jepen vlera me
funksionin “vendose”.
Funksioni me të njejtin emër si edhe klasa të cilit i paraprin karakteri tildë (~) quhet
destruktor i asaj klase (ky shembull nuk e përmbanë në mënyrë eksplicite destruktorin). Destruktori
nuk ka argimente prandaj edhe nuk mund të përgjithsohet.
Funksionet public i implementojnë sjelljet ose shërbimet që klasa iu jep klientëve të saj – të
cilave iu referohemi si interfejsi i klasës ose interfejsi public).
Definicioni i klasës përmbanë deklaratat e të dhënave anëtarë të klasës dhe funksioneve
anëtarë të klasës. Deklarata e të dhënave anëtarë të klasës janë prototipet e funksioneve. Funksionet
anëtarë mund të definohen brenda klasës por praktikë e mirë programuese është që të definohen
jasht klasës.
Të theksojmë se operatori binar i rezulucionti të fushëveprimit (::) binary scope resolution
operator. Në shembullin e mësipërmë çdo definicion i funksionit anëtarë është i përcjellur nga
definicioni i klasës. Posa të definohet klasa dhe të deklarohen funksonet anëtarë të saj funksionet
anëtarë duhet të definohen. Çdo funksion anëtarë i klasës mund të definohet drejpërsëdrejti në
trupin e klasës (më mirë se sa të përfshiihen nprototipet e funksionit në klasë) ose funksionet
anëtarë mund të definohen jashtë trupit të klasës. Kur të definohet funksioni anëtarë pas definimit të
klasës përkatëse emrit të funksionit i paraprin emri i klasës dhe operatori (::). Pasi klasat e
ndryshme mund të kenë të njejtat emra anëtarë operatori :: i lidhë emrat anëtarë me emrin e klasës
në mënyrë të njëvlershme të identifikoj funksionet anëtarë të klasës së veqantë. Bile edhe nëse
funksioni anëtarë i deklaruar në definicionin e klasës mund të definohet jashtë definicionit të klasës.
Funksioni i tillë është akoma brenda fushëveprimit të klasës dmth emri i tij njihet vetëm nga
anëtarët tjerë të klasës përveç nëse i referohemi drejt një objekti të klasës, referencës në një objekt
të klasës ose treguesit në një objekt të klasës.
Të sqarojmë shkurtimisht mbi fushëveprimin e klasës. Nëse funksioni anëtarë është i
definuar në definicionin e klasës funksioni anëtarë automatikisht është në formën inline. Mbani
mend se kompajlleri mban të drejtën që të mos inline asnjë funksion.
Është interesant se funksionet anëtarë shtypUshtarake dhe shtypStandarde nuk kanë
argumente. Kjo është për arsye se funksionet anëtarë në mënyrë implicite e dijnë se duhet ti shtypin
të dhënat anëtarë të objektit Koha të veqant. Kjo i bën funksionet anëtarë thirrës më konciz se sa
funksionet thirrëse të zakoshme në programimin procedural.
Klasat e thjeshtojnë programimin sepse klientët (shfrytëzuesit e objektit të klasës) duhet të
mirren vetëm me operacionet që gjenden në objekt. Operacionet e tilla janë të dizajnuara që më
shumë të jenë të orientuara kah klienti se sa të orientuara kah implementimi. Klienti nuk duhet të
ketë lidhje me implementimin e klasës (edhepse klienti natyrisht dëshiron implementim korrekt dhe
efikas). Interfejsi ndryshohet por shumë më rrallë se sa implementimi. Kur një implementim
ndryshohet në pajtueshmëri me atë duhet të ndryshohet edhe kodi i varur nga implementimi. Me
fshehjen e implementimit ne e eliminojmë mundësinë që pjesët tjera të programit të bëhen të varura
nga detalet e implementimit të klasës.
Shpesh klasë nuk duhet krijuar “prej rastit”. Ato mund të fitohen prej klasëve tjera që japin
atribute dhe sjellje që klasa e re mund ti përdor. Ose klasat mund të përmbajnë objekte të klasave
tjera si anëtarë të tyre. Një softuer i tillë e rrit produktivitetin e programuesit. Krijimi i klasave të
reja nga klasat ekzistuese quhet trashëgimi. Përfshiraja e objekteve të klasës si anëtarë të klasëve
tjera quhet kompozim. Për trashëgiminë dhe kompozimin do të diskutojmë edhe më vonë.
Bazat e gjuhës programuese C++ S. Bekteshi 104
Shtesa.1
Lokacionet e memorjes
Memorja e kompjuterit mund të paramendohet si një varg i kubëzave. Çdo kubëz – lokacion
i memorjes – është një nga shumë e shumë kubëza të vargisur dhe që janë të numruar në mënyrë
sekuenciale (njëri pas tjetrit). Këta numra njihen si adresa të memorjes. Çdo kubëz është i madh një
bajt. Një ndryshore rezervon një ose më shumë kubëza (pra një ose më shumë bajt) ku mund të
ruhet vlera.
Emri i ndryshores është një emërtim i njërit prej këtyre
kubëzave që dhërben për gjetjen e tij pa e dijtur fare adresën e tij
(Fig. 13).
Figura.13
1. // Prg.18 Programi për mbledhjen e dy numrave të plotë
2. #include <iostream.h>
3.
4. int main()
5. {
6. int int1, int2, shuma; // deklarimi
7. cout << "Shtype numrin e pare \n"; // kërkon
8. cin >> int1; // lexon një integer
9. cout << "Shtype numrin e dyte\n"; // kërkon
10. cin >> int2; // lexon një integer
11. shuma = int1 + int2; // shuma
12. cout << "Shuma eshte " << shuma << endl; //shtyp shumën
13.
14. return 0; // tregon se programi ka përfunduar me sukses
15. }
Dalja: Shtype numrin e pare 2
Shtype numrin e dyte 2
Shuma eshte 4
she nëse shfrytëzuesi e shtyp numrin 72 si vlerë për int2. kjo vlerë vendoset në lokacionin e
memorjes int2 dhe memorja duket si në fig.14b. Kur programi i ka fituar vlerat për int1 dhe
int2 ai i mbledh këto vlera dhe i vendos në ndryshoren shuma. Urdhëresa:
shuma=int1+int2;
që kryen mbledhjen gjithashtu e shkatrron vlerën. Kjo ndodh kur shuma e llogaritur e int1 dhe
int2 vendoset në lokacionin shuma (pa marrë parasysh se çfarë vlere ka pasë shuma ajo vlerë
shkatrrohet). Pasi që është llogaritur shuma, memorja duket si në fig.14c). Të theksojmë se vlerat e
int1 dhe int2 janë plotësisht të njejta me ato para se të përdoreshin për llogaritjen e shumës.
Këto vlera janë përdorë por nuk janë shkatërruar kur kompjuteri i ka krye llogaritjen. Kështu, kur
vlera lexohet nga lokacioni i memorjes, ky proces është joshkatërrues
Bazat e gjuhës programuese C++ S. Bekteshi 107
Shtesa.2
Qarqet logjike
Operacionet logjike
Operacionet elementare
Operacioni OSE
Më parë theksuam se operacioni i mbledhjes i Bulit kryhet me ndihmën e qarkut logjik OSE ka
shumë hyrje A,B,C…N e vetëm në dalje Y. Logjika e qarkut të tillë A
qëndron në atë që ekzistenca e daljes Y është e kushtëzuar me B Y=A+B
ekzistencën e cilësdo hyrje A ose B ose C ose…N ose shumë hyrje së Qarku OSE
bashku. Thënë në mënyrë më precize kjo dmth se në daljen e qarkut OSE
vendoset gjendja e njëshit logjik në rastin kur në njërin apo më shumë A B Y
hyrje veprojnë sinjalet, vlerat e të cilave iu përgjigjen gjithashtu njëshit
logjik. Operacioni i tillë OSE nganjëherë quhet edhe disnjuksion (ndarje) 0 0 0
që shënohet me “ v ” (nga latinishtja ”vel” që dmth ”njëri ose tjetëri ose të 1 0 1
dy bashkë”). 0 1 1
Në fig. Është paraqit grafikisht qarku OSE me dy hyrje me të cilat 1 1 1
sillen sinjalet të paraqitur me A dhe B. Sipas logjikës së dhënë për
operacionin OSE, funksioni i Bulit për këtë qark e ka formën: Tabela funksionale
Mbledhja logjike
Y=A+B (“A ose B”)
Nëse në funksionin e dhënë zëvendësohen të gjitha vlerat e mundshme të ndryshoreve A dhe
B dhe për to përcaktohet vlera përkatëse për Y fitohet tabela e kombinimeve për qarkun OSE e
paraqitur më lartë në figurë.
Operacioni EDHE
Operacioni i shumëzimit i Bulit kryhet me ndihmën e qarkut EDHE. Në fig është paraqitur
simboli grafik i tij me dy hyrje. Logjika e qarkut të tillë qëndron në atë
që dalja Y ekziston vetëm nëse ekzistojnë të gjitha daljet A dhe B dhe C A Y=A· B
dhe ,,,N njëkohësisht. B
Operacioni EDHE respektivisht shumëzimi logjik ose Qarku EDHE
konjuksioni (lidhje) siç quhet edhe ndryshe – shënohet me simbolin ” * ”
ose ” ^ ” i cili shprehet si “edhe” prandaj logjika e paraqitur e qarkut A B Y
paraqitet me funksionin:
0 0 0
Y=A^B=A·B (“A edhe B”) 1 0 0
0 1 0
Me zëvendësimin e të gjithave vlerave të mundshme të
1 1 1
ndryshoreve A dhe B në këtë funksion fitohet tabela e kombinimeve për
qarkun EDHE (Fig.).
Tabela funksionale
Shumëzimi logjik
Bazat e gjuhës programuese C++ S. Bekteshi 109
Operacioni JO
Operacioni i komplementimit i Bulit kryhet me ndihmën e qarkut logjik JO. Në fig. është
paraqiur simboli grafik i qarkut të tillë. Për dallim nga qarqet e
mëparshme, ky ka vetëm një hyrje dhe natyrisht, vetëm një dalje. A ◦ Y=A
Logjika e qarkut JO qëndron në atë që sinjali në hyrje nuk mund
Qarku JO
të ketë vlerë të njejtë si sinjali në dalje. Me fjalë tjera kjo dmth se
në dalje të qarkut vendoset gjendja e njëshit logjik kur në hyrje
◦
është sinjali me vlerë logjike zero dhe anasjelltas. Për këtë arsye Qarku JO paraqitet me rrethin
operacioni i komplementimit quhet edhe negacion kurse qarku në përbërje të qarqeve tjera
JO – negator ose inventor. Prandaj funksioni i qarkut JO në fig.
është dhënë me shprehjen: A Y
Y A 0 1
dhe shprehet si “komplement A ose ”jo A”. Tabela e 1 0
kombinimeve të
Tabela funksionale
qarkut JO është mjaft e thjeshtë dhe është dhënë në fig. Komplementimi logjik
Qarqet elementare logjike OSE, EDHE dhe JO zbatohen për kryerjen e operacioneve logjike
të mbledhjes, të shumëzimit dhe të komplementimit dhe për këte arsye, siç kemi treguar edhe me
parë, këto operacione quhen edhe OSE, EDHE dhe JO. Qarqet e dhëna janë plotësisht të
mjaftueshme për interpretimin fizik të çfardo funksioni në algjebrën ndërperëse dhe për këtë arsye
këto qarqe i takojnë të njejtës bazë. Më bazë nënkuptohet tërësia e qarqeve logjike me të cilët mund
të realizohen të gjitha funksionet ndëreprerëse. A Y=A· B
Gjatë projektimit të rrjetave ndërprerëse zakonisht vihet edhe B
kushti që ato duhet të ndërtohen duke shfrytëzuar bazën e cila përmban Qarku JOOSE
një numër sa ma të vogël të qarqeve logjike themelore. Kështu psh
ekziston edhe baza të cilën e formon vetëm një qark logjik siç është A B Y
JOEDHE dhe JOOSE kurse rrjetat nërprerëse të realizuara duke
0 0 1
shfrytëzuar bazën e tillë quhen homogjene. Qarqet e theksuara 1 0 0
JOEDHE dhe JOOSE realizohen me ndihmën e qarqeve elementare 0 1 0
logjike. Me lidhjen e invertorit në daljen e qarkut elementar OSE 1 1 0
fitohet qarku JOEDHE fig. Ky qark përmban operacionet logjike JO-
OSE kështu që funksioni i Bulit për këtë qark shprehet me Tabela funksionale
komplementin e funksionit e qarkut elementar OSE . Operacioni logjik JOOSE
Y A B
Ky funksion tregon se në rastin e ekzistencës së sinjalit në cilëndo hyrje gjendja e fituar
në dalje nuk do t’i përgjigjet njëshit logjik por zeros logjike. Tabela e kombinimeve e qarkut fig.
paraqet edhe atë se njëshi logjik në dalje kushtëzon praninë koncidente të zerove logjike në të
gjitha daljet. Duhet të theksojmë se ky fakt është plotësisht i kundërt me atë i cili është konstatuar
në qarkun elementar EDHE.
Bazat e gjuhës programuese C++ S. Bekteshi 110
Tabela funksionale
Operacioni logjik EX-OSE Operacioni logjik JOEDHE
Logjika e qarkut elementar OSE, siç kemi theksuar më parë, e siguron gjendjen e njëshit
logjik në dalje, kur ekziston sinjali në cilëndo hyrje ose në shumë hyrje njëkohësisht. Mirëpo
logjika e qarkut ekskluziv EX-OSE kushtëzon formimin e gjendjes A
logjike të njëshit në dalje gjatë ekzistencës së sinjalit ngacmues. B ◦ Y=A· B
Logjika e tillë e qarkut në hyrjet A dhe B, fig, mund të shprehet me
Qarku EX-OSE
funksionin: (ose ekskluzive)
Y AB AB A B A B Y
Gjendja e njëshit logjik në dalje të qarkut elementar EDHE sigurohet me veprim koincident
të sinjaleve ngacmuese në të gjitha hyrjet. Mirëpo operacioni logjik A
◦ Y=A· B
“inkluziv edhe” kushtëzon formimin e gjendjes së njëshit logjik në B
dalje jo vetëm në ekzistencën koincidente por edhe gjatë Qarku EX-JOOSE
mosekzekutimit koincident të sinjalit në të gjitha hyrjet e qarkut. Me (inkluzive EDHE)
fjalë tjera, dalja te ky qark ekziston nëse ekzistojnë njëkohësisht të A B Y
gjitha ose nëse njëkohësisht nuk ekziston asnjë hyrje.
Qarku inkluziv EDHE i njohur edhe si qarku koincident 0 0 1
është paraqitur në fig. Funksioni logjik i këtij qarku tregon pra se të 1 0 0
dy hyrjet janë të barabarta dhe shkruhet në formën: 0 1 0
_ _ 1 1 1
Y A B AB A B Tabela funksionale
Simboli” ” paraqet operacionin “inkluziv edhe” kështu që funksioni Operacioni EX-JOOSE
i dhënë shprehet si ”inkluzive A dhe B” edhe ky funksion përmban (inkluzive EDHE)
Bazat e gjuhës programuese C++ S. Bekteshi 111
të gjitha operacionet logjike elementare. Të theksojmë edhe këtu se logjika e qarkut inkluzive
EDHE mund të realizohet edhe me kombinime tjera të qarqeve elementare logjike.
Duke i krahasuar tabelat funksionale respektivisht kombinatorike të qarqeve inkluzive
EDHE dhe inkluzive EDHE në fig. shihet se funksionet logjike të këtyre qarqeve janë
komplementare. Pëe arsye operacioni “inkluziv EDHE” zakonisht kryhet me qarkun logjik EX-OSE
me negacionin shtesë. Prej këtu rrjedh se edhe shprehja logjike e dhënë për këtë funksion me
relacionin 0 mund të shkruhet në formë:
Y A B AB A B