SlideShare a Scribd company logo
1 of 71
Hyrje në Algoritmikë
Kur blejmë një kompjuter, ne nuk do të mundnim të komunikonim me të në se kompjuteri nuk
do të ishte paisur me një bashkësi programesh që quhet sistemi operativ i kompjuterit. Një nga
më të njohurit është sistemi Windows, që është sistemi që ne njohim në kompjuterat tanë
personalë dhe në ata që kemi në shkollat tona.
Kompjuteri përbëhet atëhere nga pjesa fizike e tij që quhet harware-i i kompjuterit, si dhe nga
bashkësia e programeve që përbën software-in e tij.
Që të kuptojmë si funksionon një program në kompjuter duhet të kemi një ide mbi hardware-in e
kompjuterit dhe pikërisht figura 1. 1 na jep një pamje të përgjithëshme të tij. Kompjuteri ka
pjesën qëndrore që përbëhet nga procesori dhe kujtesa (qëndrore dhe sekondare), ka paisjet
hyrëse të tij siç janë tastjera, USB, hard disku, si dhe pjesët dalëse siç janë monitori dhe mund të
jenë përsëri USB, hard disku ose printeri.
Figura 1. 1 Pjesët kryesore të kompjuterit
Kur kompjuteri ekzekuton një program, të gjithë pjesët hardware-ike të tij vihen në punë.
Programi dhe të dhënat futen nga paisjet hyrëse dhe vendosen në kujtesë, procesori proceson
instruksionet e programit. Po përveҫ programeve që kompjuteri ka kur blihet, ne mund të
hartojmë programet tona duke e pasuruar kështu pjesën softwarike të kompjuterit.
Ç ’është një program dhe si duhet të mendojmë para se të shkruajmë një program? Materiali i
këtij teksti është një ndërthurje e këtyre dy apekteve, pra si mendojmë ne për të zgjidhur një
problem në kompjuter dhe si e realizojmë atë me një program në gjuhën e programimit C++.
Kur fillojmë të mësojmë një gjuhë programimi, mund të na duket se pjesa më e vështirë e
zgjidhjes së një problemi në kompjuter është të shprehurit e ideve tona në gjuhën e programimit.
Në fakt, pjesa më e rëndësishme në procesin e zgjidhjes së një problemi është gjetja e metodës së
zgjidhjes së problemit. Në këtë fazë të punës ne nuk kemi pse të mendojmë fare për gjuhën me të
cilën do të punojmë në kompjuter, por ne duhet të jemi në gjëndje të shprehim me fjalët tona
rradhën e hapave që duhet të ndjekim për të zgjidhur një problem të caktuar. Këto hapa do ti
mendonim si instruksione që mund tja jepnim një personi se sa një kompjuteri. Dhe pikërisht kjo
rradhë instruksionesh që do të realizonin zgjidhjen e një problemi quhet algoritëm dhe mënyra e
të shprehurit të tij me fjalët tona quhet pseudokod.
Algoritmi shpreh mënyrën si ne e konceptojmë zgjidhjen e një problemi. Ne mund ta paraqesim
atë në mënyra të ndryshme, me fjalët tona (pseudokodi), ose me simbole (bllokskema).
Gjuha e programimit na ndihmon që pseudokodin ose bllokskemën tja shprehim kompjuterit në
një mënyrë të kuptueshme për të, ose në formën e kodit burim të një programi.
Po ç’është instruksioni për kompjuterin?
Një instruksion është një komandë bazike për të cilën ekziston një mekanizëm hardware-i që e
ekzekuton atë.
Kompjuteri është një makinë programuese e dezinjuar të ekzekutojë instruksione. Programi
përbëhet nga instruksione, dhe kur themi programi ekzekutohet, këto instruksione janë në
kujtesë dhe ekzekutohen. Në fakt kur ne shkruajmë atë që quajmë kod burim të një programi ne
nuk shkruajmë instruksione, por një bashkësi të tërë instruksionesh njëherësh, si një rresht të
kodit burim që e quajmë statement. Këtë lehtësi na e japin gjuhët e programimit të nivelit të
lartë siç është dhe gjuha C++.
Kompjuteri ekzekuton vetëm instruksionet në formën binare të tyre (me zero dhe njësha), ose
themi instruksionet të shprehura në gjuhën makinë si për shembull:
1011010000000101
Gjuha makinë ose gjuhë të afërta me të quhen gjuhë të nivelit të ulët. Eshtë vështirë të shkruajmë
kodin burim të një programi në gjuhë të nivelit të ulët, mbasi gjuhë të tilla përshkruajnë në detaje
çdo komandë që kompjuterit i duhet të ekzekutojë për të zgjidhur një problem. Në vend që të
shkruhen programe në gjuhën makinë, përdoren gjuhët e programimit të nivelit të lartë dhe janë
kompilatorët ata që e kthejnë kodin burim në gjuhën makinë, që dhe ata vetë janë programe të
kompjuterit.
Ka disa gjuhë programimi të nivelit të lartë si C, C++, Java, C#, Python etj. Në këtë tekst ne do
të punojmë në gjuhën e programimit C++, që mund të konsiderohet si një gjuhë që ka edhe
elementë të një gjuhe të nivelit të ulët dhe njëkohësisht është gjuhë e nivelit të lartë.
Siç shihet dhe nga Figura 1. 1 hyrja në kompjuter mund të mendohet nga dy pjesë, një program
dhe të dhënat. Kompjuteri ndjek instruksionet e programit të cilat përdorin dhe disa të dhëna
hyrëse të nevojshme që programi të realizojë veprimet e tij. Për shembull një program mbledh dy
numra, atëhere këta dy numra janë të dhënat.
Figura 1. 2 Pamje e thjeshtë e ekzekutimit të programit
Me fjalë të tjera të dhënat janë të dhënat hyrëse për programin, dhe programi bashkë me të
dhënat, janë hyrja për kompjuterin dhe themi kompjuteri ekzekuton programin mbi të dhënat.
Kompilatori
Thamë që kompilatorët janë programe që përkthejnë kodin burim në gjuhë makine. Pra hyrja në
një kompilator është një program dhe dalja është përsëri një program por në një formë tjetër.
Programin hyrës ne zakonisht e quajmë programi burim ose kodi burim dhe daljen e quajmë
programin objekt ose kodi objekt. Kodi objekt përbëhet nga instruksione që makina mund ti
ekzekutojë. Figura 1. 2 paraqet procesin e përkthimit të kodit burim të një programi:
Figura 1. 3 Kompilimi dhe Ekzekutimi i programit C++
Linker-i
Duhet të dimë që para se programi të ekzekutohet, programit objekt që kompilatori prodhon nga
program burim, I shtohen dhe pjesë të tjera të cilat na ofrohen nga ata që e kanë krijuar gjuhën
C++ duke e lehtësuar kështu punën tonë. Lidhja e programit të shkruar nga ne dhe atyre pjesëve
të cilat na jepen të gatëshme realizohet me një tjetër program që quhet linker. Atëhere një skemë
e përgjithëshme e ndërveprimit të kompilatorit dhe linkerit do të jepej nga figura 1. 3
Figura 1. 4 Pergatitja e një programi C++ për tu ekzekutuar
Është sistemi operativ që bën të mundur komunikimin tonë me të gjitha paisjet hyrëse dhe dalëse
të kompjuterit. Një nga detyrat e sistemit operativ është dhe ekzekutimi i programeve që ne vetë
krijojmë.
2. Pseudokodi,bllokskemat dhe simbolikae tyre
Programimi i një “Kompjuteri Njeri (Roboti)”
Për të krijuar idenë e një algoritmi, të pseudokodit me të cilin algoritmi shprehet, si dhe të
kthimit të tij në një program i cili është i kuptueshëm nga kompilatori marrim si shembull një
problem praktik që e shtrojmë për zgjidhje: ndërrimin e rrotës së makinës. Supozojmë se qëllimi
ynë do të ishte krijimi i një mekanizmi “njeriu robot” që do të realizonte veprimet e kërkuara për
ndërrimin e një rrote makine.
Algoritmi
Instruksionet për ndërrimin e rrotës të shprehura në gjuhën e zakonshme janë si vijojnë:
1. Ngrihet makina.
2. Hiqen vidat qe fiksojnë rrotën difektoze të makinës.
3. Hiqet rrota.
4. Montohet rrota e re.
5. Vendosen vidat.
6. Zbritet makina.
Ky është një algoritëm i paraqitur me një pseudokod. Para se të shkruajmë një program, na duhet
një gjuhë të cilën do të biem dakort të përdorim dhe që kuptohet nga roboti.. Në këtë tekst ne do
të përdorim gjuhën C++ por për shembullin e mësipërm do përdorim një gjuhë të krijuar
apostafat për këtë problem, gjuha e ndërimit të rrotave, dhe që shkurtimisht po e quajmë GNR.
GNR përfshin disa emra të përgjithshëm të përdorur në fjalorin e ndërrimit të rrotave.
makinë
rrotë
vidë
krik
kuti e veglave
rrotë rezerve
xhiro-makine, kryq
GNR gjithashtu përfshin dhe foljet që vijojnë:
merr
vendos
lësho
rrotullo
Së fundi procesori që do të ekzekutojë GNR duhet të ketë aftësinë të numërojë dhe të marrë
vendime të thjeshta.
Kjo është gjithshka që një robot i ndrërrimit të rrotave kupton. Çdo gjë tjetër është e
pakuptueshme nga roboti i ndërrimit të rrotave.
Programi
Tani është momenti të konvertojmë algoritmin në gjuhën e kuptueshme nga roboti. Duke
analizuar rresht për rresht algoritmin, shohim që fraza “Hiqen vidat” ka mbetur e papërcaktuar,
mbasi folja “heq” nuk është në fjalorin e procesorit.
Hapat që vijojnë shprehin frazën “hiqen vidat” duke përdorur vetëm emrat që përmbahen në
gjuhën e kuptueshme nga roboti:
1. merr xhiro-makinën
2. vendos xhiro-makinën te vidat
3. rrotulloj xhiro-makinën pesë herë.
4. vendos xhiro-makinën te kutia e veglave.
5. lësho xhiro-makinen
Ketu nuk po marrim parasysh detajet e sintaksës së gjuhës, d.m.th rasat e ndryshme të emrave
dhe kohët e foljeve si dhe nyjet e ndryshme që mund të përdoren. Por kur do të përdorim C++ do
të kemi rregulla plotësisht të përcaktuara të saj.
Programi fillon në Hapin 1 dhe vazhdon me hapat e tjera derisa të arrijë në Hapin 5. Në
terminologjinë e programit ne themi, program ecën nga Hapi 1 deri në hapin 5. Çdo hap
përfaqësohet në një gjuhë programimi me një statement.
Natyrisht probleme të tjera mund të ngrihen: çfarë do të ndodhë në se nuk ka vida? Në këtë rast
ne na nevojitet një statement “nëse” si vijon:
1. merr xhiro-makinën
2. nese vida është present
3. {
4. vendos xhiro-makinën te vida.
5. rrotullo xhiro-makinën pesë herë në të kundërt të akrepit të orës.
6. }
7. vendos xhiro-makinën në kutinë e veglave.
Programi fillon në hapin e parë si dhe më parë. Në hapin e dytë para se të vendosë xhiro-
makinën sigurohet në se vidat janë present, në se kjo është e vërtetë, vazhdojnë Hapat
3, 4, dhe 5 si dhe më parë. Në se jo, program i kapërcen këta hapa dhe shkon drejt Hapit 7 duke
kthyer xhiro-makinën në kutinë e veglave. Këtu ne kemi të bëjmë me një shprehje logjike “vida
është present?” Kjo shprehje kthen ose një të vërtetë (true) (po vida është present) ose një jo
të vërtetë (false) (jo, nuk ka vidë).
Një shprehje është një tip statement-i që prodhon një vlerë, siç është shprehja 1 + 2. Një shprehje
logjike kthen një vlerë true ose false.
Kllapat ne GNR janë të nevojshme për t’i treguar programit cilat hapa duhen kapërcyer në se
kondita nuk është true. Hapat 4 dhe 5 ekzekutohen vetëm në se kondita është true.
Ky program i përmirësuar ka akoma një problem: si do të kuptohet që duhet të bëhen 5
rrotullime të xhiro-makinës për të hequr vidën? Si mund të realizojë programi më pak ose më
shumë rrotullime sipas rastit?
Një mënyrë është të shtojmë një tip statement-i i formës “përderisa nuk është plotësuar diçka”,
vazhdo të testosh” në GNR.
1. merr xhiro-makinën
2. nese vida është present
3. {
4. vendos xhiro-makinen te vida.
5. perderisa (vida është në makinë)
6. {
7 rrotullo xhiro-makinën pesë herë në të kundërt të akrepit të orës.
8. }
9. }
10.vendos xhiro-makinën në kutinë e veglave.
11.lësho xhiro-makinën.
Hapat 1 deri në 4 janë si më parë. Në Hapin 5, procesori duhet të marrë një vendim: vazhdon
vida të jetë në makinë? Në hapin e parë duke supozuar që vida është në makinë, procesori do
kalojë në hapin 7. Pas tij, programi kthehet në hapin 5 dhe përsërit testimin. Në se vida hiqet nga
makina, kondita në Hapin 5 do të na kthejë një false. Ne këtë moment program do kalojë në
hapin 9, dhe do të vazhdojë si më parë.
Bllokskemat
Janë bërë të zakonshme dy mënyra për të dokumentuar logjikën e një programi që është
algoritmi. Këto janë bllokskema dhe pseudokodi. Ne do ti përdorim të dyja metodat në vijim.
Zakonisht, bllokskema punon mirë për probleme të vogla dhe pseudokodi për probleme më
komplekse. Disa nga simbolet përdorur në bllokskema janë paraqitur më poshtë:
Fillimi ose mbarimi i programit, simboli terminal
Hapat ku kryen llogaritje
Veprimi i hyrjes ose daljes
Marrja e vendimit dhe degëzimi
Lidhësi i dy pjesëve të një programi
Shirit manjetik
Disk manjetik
Lidhje me faqen tjejtër
Vija të rrjedhës së algoritmit
shenime
afishim
Figura 2. 1 Një listë simbolesh që përdoren në një bllokskemë
Përdorimi i simbolit Terminal
Ky simbol tregon një pikë fillimi dhe mbarimi të logjikës së një procesi.
Fillo një process
me simbolin
Mbaro një process
me simbolin
fillim
fund
Figura 2. 2 Simbolet e fillimit dhe mbarimit të një procesi
Një bllokskemë duhet të ketë vetëm një simbol fillimi dhe një simbol mbarimi të një procesi.
Shohim më poshtë një shembull përdorimi korrekt të simbolit terminal dhe një shembull jo
korrekt të përdorimit të tij.
Fillimi dhe mbarimi në një kod C++ do të paraqitej si më poshtë:
int main () // fillimi i programit
{
return 0; //fundi i programit
}
Figura 2.4 Fillimi dhe mbarimi në një kod programi në C++
Kjo është dhe struktura e një programi në C++. Kur një program C++ ekzekutohet, kontrolli
fillon pikërisht nga rreshti:
int main ()
dhe mbaron kur takon statementin
return 0;
Ne do ta quajmë main() një funksion dhe gjithshka brenda {} përbën trupin e funksionit ku
vendosen statementet. Me return 0; do të kuptojmë se në mbarim të ekzekutimit të rregullt
programi i kthen vlerën 0 sistemit operativ që është përgjegjës per ekzekutimin e programit dhe
me që 0 është një vlerë e plotë përdoret int që shpreh faktin që kjo vlerë që kthehet është e
plotë. Megjithatë, funksionet nuk janë objekt i këtij teksti.
Përdorimi i vijës së rrjedhës së llogjikës dhe simbolit lidhës
Qëllimi i vijës është të lidhë hapa të ndryshme në procesin logjik të një bllokskeme, ndërsa
simboli i lidhësit përdoret për të lidhur dy ose më shumë vija për të ndjekur të njëjtën rrugë
logjike.
Vija e rrjedhës së logjikës paraqitet me një shigjetë me një kahe, ndërkohë që lidhësi paraqitet
me një rreth. Figura e mëposhtme ilustron ç’ka thamë:
Përdorim korrekt i
simbolit terminal
Përdorim jo
korrekt I simbolit
terminal
fillim
fund fund
fillim
fund
fillim
mbarim
Figura 2. 3 Përdorimi korrekt dhe jo korrekt i simbolit terminal
Figura 2. 5 Vija dhe lidhësi
Më poshtë kemi disa përdorime jo të rregullta të vijave të rrjedhës së logjikës dhe të lidhësit ose
mungesa të përdorimit të tyre:
Figura 2. 6 Shembuj vijash dhe lidhësish
Simbolet e Hyrje/Daljeve (input/output)
Simbolet e tilla si
dhe
janë simbolet e leximit dhe shkrimit nga dhe në paisje të ndryshme p.sh. lexim nga një file, ose
nga tasjera dhe shkrim p.sh. në monitorin e një kompjuteri. Një simbol hyrje
përdoret për leximin e informacionit nga paisje të ndryshme. Veprimi specifik zakonisht
përshkruhet si një veprim leximi duke hapur nje file ose nga tastjera. Është e rëndësishme të
kuptohet që në se një veprim leximi kërkon informacionin që duhet të përdoret, bllokskema
fillim
fund
Simboli i vijes lidh
simbolet jo vija të rrjedhës
së logjikës së një processi
Simboli i lidhesit lidh dy
ose më shumë vija të
rrjedhës së logjikës.
Jo korrekt mbasi
nuk ka lidhës
Perdorim korrekt i
lidhesit
fillim
fund
Një proces
Një vije jo
korrekte për
arsye të dy
drejtimeve
duhet së pari të paraqesë një futje të dhënash (hyrje) që merr informacion për proceset e
mëtejshëm. Disa paisje të përshkruara më poshtë mund të përdoren për veprimet hyrëse:
• Një paisje rezervimi që përdoret si kujtesë sekondare. Shembuj paisjesh rezervimi janë hard-
disqet, paisjet USB, disqet kompakte, ose disqet digitalë video.
• Një tastjerë
• Një monitor elektronik – kjo nuk është një paisje të zakonshme. Shpesh herë ai referohet si
ekran i prekshëm
Shembujt e mësipërm nuk janë të vetmet tipe të paisjeve hyrëse ose burimeve të të dhënave
hyrëse. Më poshtë janë dy shembuj hyrës: një nga një përdorues dhe një nga një file. Nuk është e
nevojshme të specifikohet burimi ose paisja. Megjithatë, për qartësi nganjëherë ata mund të
specifikohen.
Figura 2. 7 Leximi i informacionit
Një simbol dalje përdoret për shkrim në paisje të ndryshme. Tipet specifikë të
veprimeve përshkruhen si një veprim shkrimi, si shkrimi në një printer ose shkrim në file dhe
mbyllje të tij. Eshtë e rëndësishme të vemë në dukje që disa paisje mund të jenë paisje hyrje dhe
dalje.
Për shembull, një ekran elektronik ose një paisje rezervimi mund të jenë edhe paisje hyrje edhe
dalje. Ndërkohë ka disa paisje të ndryshme që mund të përdoren si paisje dalje:
• Një paisje rezervimi të përshkruar më lart.
• Një monitor elektronik.
• Një printer.
Shembull 1 Shembull 2
Fillim procesi
Fund procesi
Fillim procesi
Fund procesi
Lexohet emri
nga tastjera Hapet file
emri.dat
tastjeara
Lexohet emri
nga tastjera
Hapet file
emri.dat
Shembull 1 Shembull 2
Fillim procesi
Fund procesi
Fillim procesi
Fund procesi
Shkruhet një
raport në printer
mbyllet file
emri.dat
tastjeara
Shkruhet një
raport në printer
mbyllet file
emri.dat
Figura 2. 8 Shkrimi i informacionit
3. Shprehjae algoritmeve nëpërmjet bllokskemave
Le të shprehim nëpërmjet bllokskemave disa algoritme të thjeshtë.
3.1 Llogaritja e sipërfaqes së një ambienti në formë drejtkëndëshi me dimensione të
përcaktuara
Të shkruhet një algoritëm dhe të vizatohet një bllok-skemë që llogarit sipërfaqen e një ambienti
me gjerësi 3.5 metra dhe gjatësi 5.7 metra.
Pseudokodi:
 Vendosen në kompjuter të dhënat hyrëse, që janë
gjerësia dhe gjatësia e ambientit
 llogaritet siperfaqja duke shumëzuar gjerësinë dhe
gjatesinë
 afishohet sipërfaqja
Blloksema:
Figura 3.1 Pseudokodi, bllokskema në llogaritjen e sipërfaqes se një ambienti.
Siҫ e vemë re dhe nga pseudokodi dhe bllokskema, për zgjidhjen e një problemi, e para gjë që
mendojmë janë të dhënat që do të duheshin për t’i dhënë problemit zgjidhje, pra veprimi i parë
që bëjmë është vendosja e të dhënave në kujtesë.
Duke patur të dhënat, realizojmë me to veprimin që duam të kryejmë dhe që në këtë rast është
shumëzimi i të dhënave dhe rezultatin e kalojmë përsëri në një vend në kujtesë, që të jemi në
gjendje më pas ta përdorim këte rezultat, dhe minimumi që mund të bëjmë është afishimi i tij në
ekran.
Duhet të jemi të ndërgjegjshëm që emrat që ne përdorim si gjeresi, gjatesi, siperfaqe, nuk
janë gjë tjetër, por emërtime të vendeve të caktuara të kujtesës qëndrore të kompjuterit ku
vendosen vlerat hyrëse ose rezultati.
gjeresia=3.5
gjatesia=5.7
siperfaqja= gjeresia * gjatesia
siperfaqja
fund
fillim
3.2 Llogaritja e sipërfaqes së një ambienti në formë drejtkëndëshi me dimensione të
papërcaktuara
Supozojmë se do të realizojmë një program që llogarit sipërfaqen e ҫdo ambienti në formë
drejtkëndëshi. Në këtë rast gjatësia dhe gjerësia e ambientit nuk janë të paracaktuara, por ato
kërkohen nga kompjuteri në momentin që programi ekzekutohet, pra ky fakt duhet shprehur në
pseudokod ose në bllokskemë si më poshtë:
Pseudokodi:
 Afishohet një mesazh në ekran : “Sa është gjerësia? ”
 Kompjuteri duhet të jetë në një gjendje pritjeje që ne të
fusim gjerësinë.
 Shkruajmë numrin, dhe ai vendoset në kujtesë.
 Afishohet një mesazh në ekran : “Sa është gjatësia? ”
 Kompjuteri duhet të jetë në një gjendje pritjeje që ne të
fusim numrin përkatës.
 Shkruajmë numrin, dhe ai vendoset në kujtesë.
 Shumëzohen gjerësia dhe gjatësia të regjistruara tashmë
në kujtesë.
 Rezultati afishohet në ekran.
Blloksema:
Figura 3. 2 Pseudokodi, bllokskema në llogaritjen e sipërfaqes se një ambienti.
Siҫ mund ta kuptojmë problemi i dytë është më i përgjithshëm se i pari, dhe zgjidhja e dhënë me
algoritmin e mësipërm u jep përgjigje gjithë rasteve pavarësisht nga dimensionet konkrete.
Futet gjatesia
siperfaqja= gjeresia * gjatesia
siperfaqja
fund
fillim
Sa është gjerësia?
Futet gjeresia
Sa është gjatesia?
3.3 Llogaritja e sipërfaqes së një ambienti në formë drejtkëndëshi me dimensione që
plotësojnë kushtet gjeresia ndodhet ne intervalin [2,3] dhe gjatesia ne intervalin [3,4]
Pseudokodi:
 Afishohet një mesazh në ekran : “Sa është gjerësia? ”
 Kompjuteri duhet të jetë në një gjendje pritjeje që ne të
fusim gjerësinë.
 Shkruajmë numrin, dhe ai vendoset në kujtesë
 Ne se gjerësia ndodhet jashte [2,3] afishojmë një
mesazh “gjeresi jashte intervalit”dhe mbyllim
programin.
 Afishohet një mesazh në ekran : “Sa është gjatësia? ”
 Kompjuteri duhet të jetë në një gjendje pritjeje që ne të
fusim numrin përkatës.
 Shkruajmë numrin dhe numri vendoset në kujtesë
 Ne se gjatësia ndodhet jashte [2,3] afishojmë një
mesazh “gjatesi jashte intervalit”dhe mbyllim
programin.
 Përndryshe shumëzohen gjerësia dhe gjatësia të
regjistruara tashmë në kujtesë.
 Rezultati afishohet në ekran.
Blloksema:
Figura 3. 3 Pseudokodi, bllokskema në llogaritjen e sipërfaqes se një ambienti.
Siҫ e shohim dhe nga bllokskema, dallimi me shembulin e mëparshëm fig.3.2, qëndron në faktin
se këtu kemi vendosur një konditë për të dhënat, gjë që e kemi shprehur me simbolet:
Futet gjatesia
siperfaqja= gjeresia * gjatesia
siperfaqja
fund
fillim
Sa është gjerësia?
Futet gjeresia
Sa është gjatesia?
gjeresia< 2 ose
gjerseia > 3
gjatesia< 3 ose
gjateeia > 4
gjatesia< 3 ose
gjateeia > 4
gjeresia< 2 ose
gjerseia > 3
po
po
jo
jo
3.4 Llogaritja e veprimeve me dy numra
Supozojmë se do të realizojmë një program që kryen veprimet midis dy numrave dhe afishon
rezultatin. Se pari komjuteri duhet të dijë numrat me të cilët ne do të veprojmë dhe së dyti do të
dijë cilin veprim ne do të donim të kryenim me këta numra:
Pseudokodi:
 Afishohet një mesazh në ekran : “Numri i parë? ”
 Kompjuteri duhet të jetë në një gjendje pritjeje që ne të
fusim numrin.
 Shkruajmë numrin, dhe ai vendoset në kujtesë.
 Afishohet një mesazh në ekran : “Numri i dytë? ”
 Kompjuteri duhet të jetë në një gjendje pritjeje që ne të
fusim numrin përkatës.
 Shkruajmë numrin, dhe ai vendoset në kujtesë.
 Afishohet një mesazh në ekran : “Veprimi uaj? ”
 Kompjuteri duhet të jetë në një gjendje pritjeje që ne të
fusim simbolin që tregon veprimin: ‘+’, ’-‘, ’*’, ’/’.
(do te shohim me pas se keto siombole perfaqësojnë
veprimet arithmetike:mbledhje, zbritje, shumëzim,
pjestim)
 Shkruajmë simbolin e veprimit, dhe ai vendoset në
kujtesë.
 Në varësi të simbolit të veprimit, kryhet veprimi
përkatës;kurveprimi është pjestimi (‘/’) duhet të
sigurohemi që emëruesi është i ndryshëm nga zero.
 Ne se emeruesi është zero mbyllim programin
 Rezultati afishohet në ekran.
Blloksema:
Figura 3. 4 Pseudokodi, bllokskema në llogaritjen e veprimeve me dy numra.
Futet numri i dytë
rezultati = n1 / n2
rezultati
fund
fillim
Numri i parë n1?
Futet numri i pare
Numri i dytë n2?
Veprimi që kryhet?
Veprimi=’+’
rezultati= n1+ n2
po
jo
Veprimi=’-’
rezultati= n1- n2
po
jo
Veprimi=’*’
rezultati= n1* n2
po
jo
Veprimi=’/’
jo
n2 = 0?
po
4. Algoritme me te avancuar me bllokskemat (ciklet)
Shpesh zgjidhja e një problemi lidhet me përsëritjen e një hapi ose të disa hapave. Në këtë rast në
programim përdoren ciklet për të cilët gjuhët e programimit, pra dhe gjuha C++, ka disa rregulla
shkrimi. Të shohim si mund ti paraqesim ciklet në një pseudokod apo bllokskemë. Shohim disa
shembuj.
4.1 Llogaritja e sipërfaqes së disa ambienteve:
Në shembullin 3.2 të paragrafit të mësipërm supozojmë se duam të llogarisim sipërfaqen e
secilit nga ambientet e një shtëpie, që ka dy dhoma, një kuzhinë dhe një koridor, dhe një
banjë, pra gjithësej 5 ambiente. Pra llogaritja e sipërfaqes që ne bëmë në këtë shembull do të
përsëritej 5 herë. Kemi në këtë rast një cikël me 5 hapa, ku në ҫdo hap të tij do të kryeshin të
gjitha hapat e llogaritjes së sipërfaqes së një ambienti. Me një pseudokod dhe bllokskemë do
të kemi këtë parasitke
Pseudokodi:
 Përsëriten hapat e mëposhtëm 5 herë:
 Afishohet një mesazh në ekran : “Sa është gjerësia?
”
 Kompjuteri duhet të jetë në një gjendje pritjeje që
ne të fusim gjerësinë.
 Shkruajmë numrin, dhe ai vendoset në kujtesë.
 Afishohet një mesazh në ekran : “Sa është gjatësia?
”
 Kompjuteri duhet të jetë në një gjendje pritjeje që
ne të fusim numrin përkatës.
 Shkruajmë numrin, dhe ai vendoset në kujtesë.
 Shumëzohen gjerësia dhe gjatësia të regjistruara
tashmë në kujtesë.
 Rezultati afishohet në ekran.
Blloksema:
Figura 4. 1 Pseudokodi, bllokskema në llogaritjen e sipërfaqes se 5 ambienteve.
Një element të rëndësishëm që vemë re në këtë shembull është akumulimi i një vlere te një vend
në kujtesë dhe pikërisht te vendi i kujtesës i quajtur numrator. Fillimisht ai duhet të marrë një
vlerë 0, dhe më pas kësaj vlere i shtohet 1 për ҫdo hap të ciklit. Kjo gjë do të siguronte që në një
moment kjo vlerë të bëhet 5 dhe kjo gjë do ti jepte fund ciklit, ose përsëritjes së llogaritjeve.
Përndryshe cikli nuk do të mbaronte së vepruari.
Futet gjatesia
siperfaqja= gjeresia *
gjatesia
siperfaqja
fund
fillim
Sa është gjerësia?
Futet gjeresia
Sa është gjatesia?
Fillojmë të numërojmë sa llogaritje
kemi bere:
numrator = 0
numratori = numratori + 1
nunratori < 5
po
po
4.2 Llogaritja e shumës së sipërfaqeve të disa ambienteve:
Pseudokodi:
 I jepet totalit te siperfaqeve vlera 0
 Përsëriten hapat e mëposhtëm 5 herë:
 Afishohet një mesazh në ekran : “Sa është gjerësia?
”
 Kompjuteri duhet të jetë në një gjendje pritjeje që
ne të fusim gjerësinë.
 Shkruajmë numrin, dhe ai vendoset në kujtesë.
 Afishohet një mesazh në ekran : “Sa është gjatësia?
”
 Kompjuteri duhet të jetë në një gjendje pritjeje që
ne të fusim numrin përkatës.
 Shkruajmë numrin, dhe ai vendoset në kujtesë.
 Shumëzohen gjerësia dhe gjatësia të regjistruara
tashmë në kujtesë.
 Shtohet siperfaqja e gjetur në totalin e sipërfaqeve
 Rezultati afishohet në ekran.
 Afishohet totali i sipërfaqeve
Blloksema:
Figura 4. 2 Pseudokodi, bllokskema në llogaritjen e sipërfaqes se 5 ambienteve duke gjetur dhe shumën e
sipërfaqeve.
4.2 Përsëritja e futjes së të dhënave kur ato janë jo korrekte
Llogaritja e sipërfaqes
Në 3.3 dhe 3.4 pamë se kur të dhënat nuk ishin korrekte, ose nuk plotësonin kushtet tona, ne e
mbyllnim programin. Në fakt është mirë të mos e mbyllim programin por ti japim mundësi atij
që e përdor atë, ti fusë përsëri të dhënat në mënyrë korrekte. Atëhere figurat 3.3 dhe 3.4 do të
kishin ndryshime si në pseudokod ashtu dhe në bllokskemë:
Futet gjatesia
siperfaqja= gjeresia *
gjatesia
siperfaqja
fund
fillim
Sa është gjerësia?
Futet gjeresia
Sa është gjatesia?
Fillojmë të numërojmë sa llogaritje
kemi bere:
numrator = 0
totali = 0
numratori = numratori + 1
Totali= totali + siperfaqja
nunratori < 5
po
po
Siperfaqja totali
Pseudokodi:
Cikël :përderisa gjerësia të jetë një vlerë brenda [2,3]
 Afishohet një mesazh në ekran : “Sa është gjerësia?
”
 Kompjuteri duhet të jetë në një gjendje pritjeje që
ne të fusim gjerësinë.
 Shkruajmë numrin, dhe ai vendoset në kujtesë
Cikël :përderisa gjatësia të jetë një vlerë brenda [3,4]
 Afishohet një mesazh në ekran : “Sa është gjatësia?
”
 Kompjuteri duhet të jetë në një gjendje pritjeje që
ne të fusim numrin përkatës.
 Shkruajmë numrin dhe numri vendoset në kujtesë
 Shumëzohen gjerësia dhe gjatësia të regjistruara tashmë
në kujtesë.
 Rezultati afishohet në ekran.
Blloksema:
Figura 4. 2 Pseudokodi, bllokskema në llogaritjen e sipërfaqes se një ambienti.
Futet gjatesia
siperfaqja= gjeresia * gjatesia
siperfaqja
fund
fillim
Sa është gjerësia?
Futet gjeresia
Sa është gjatesia?
gjeresia< 2 ose
gjerseia > 3
gjatesia< 3 ose
gjateeia > 4
jo
jo
po
po
Veprimet me dy numra
Pseudokodi:
 Afishohet një mesazh në ekran : “Numri i parë? ”
 Kompjuteri duhet të jetë në një gjendje pritjeje që ne të
fusim numrin.
 Shkruajmë numrin, dhe ai vendoset në kujtesë.
 Afishohet një mesazh në ekran : “Numri i dytë? ”
 Kompjuteri duhet të jetë në një gjendje pritjeje që ne të
fusim numrin përkatës.
 Shkruajmë numrin, dhe ai vendoset në kujtesë.
 Afishohet një mesazh në ekran : “Veprimi uaj? ”
 Kompjuteri duhet të jetë në një gjendje pritjeje që ne të
fusim simbolin që tregon veprimin: ‘+’, ’-‘, ’*’, ’/’.
(do te shohim me pas se keto siombole perfaqësojnë
veprimet arithmetike:mbledhje, zbritje, shumëzim,
pjestim)
 Shkruajmë simbolin e veprimit, dhe ai vendoset në
kujtesë.
 Në varësi të simbolit të veprimit, kryhet veprimi
përkatës;kurveprimi është pjestimi (‘/’) duhet të
sigurohemi që emëruesi është i ndryshëm nga zero.
Ne se veprimi ëthë pjesetim kryejmë një cikël:
cikëli:
 Përderisa emeruesi është zero përsrëritim futjen e
tij.
 Rezultati afishohet në ekran.
Blloksema:
Figura 4. 3 Pseudokodi, bllokskema në llogaritjen e veprimeve me dy numra.
Futet numri i dytë
rezultati = n1 / n2
rezultati
fund
fillim
Numri i parë n1?
Futet numri i pare
Numri i dytë n2?
Veprimi që kryhet?
Veprimi=’+’
rezultati= n1+ n2
po
jo
Veprimi=’-’
rezultati= n1- n2
po
jo
Veprimi=’*’
rezultati= n1* n2
po
jo
Veprimi=’/’
po
n2 = 0?
Futet
numri
i dytë
jopo
1. Paraqitjae algoritmeve mbi vargjet numerike me bllokskeme
Shpesh të dhënat hyrëse në një program janë vargje numrash për të cilët mund të përcaktohet një
rregull në përcaktimin e secilit prej tyre duke ditur numrat paraardhës. Përdorimi i të dhënave të
tilla në një program e lehtëson programin në kuptimin e shmangjes së futjes së të dhënave një
nga një, mbasi ato mund të krijohen në bazë të një formule. Le të shohim disa shembuj nëpërmjet
pseudokodeve dhe bllokskemave.
5.1 Të gjendet shuma e 100 numrave të parë natyralë, pra shtrohet për zgjidhje gjetja e
shumës 1 + 2 + 3 + . . . + 100;
Siҫ shohim të dhënat që përdoren janë 1, 2, 3, . . ., 100; karakteristikë e të dhënave në këtë rast,
është që ekziston një lidhje e tillë midis dy elementëve të njëpasnjëshëm:
numri = numri paraardhës + 1
Kjo cilësi bën të mundur që ne t’i bëjmë të ditur programit vetëm numrin e parë në këtë varg
numrash dhe sa të tillë janë. Veprimi i mësipërm përsëritet 100 herë, pra duhet të interesohemi ti
numërojmë hapat derisa ato të arrijnë vlerën 100. Për këte na duhet një numrator, i cili fillimisht
merr vlerën zero. Gjithë puna do të bëhet në një cikël, brenda të cilit me ndihmën e formulës së
mësipërme krijohen një pas një gjithë numrat e vargut. Pseudokodi dhe bllokskema e mëposhtme
e realizojnë këtë proces:
Pseudokodi:
 Vendosim në një vend në kujtese me emrin numratori qe
i japim vleren 0. Këtu do shtohen hapat qe ne kryejmë
 Vendosim në një vend në kujtesë me emrin shuma
vlerën 0; këtu do të shtohen numrat e vargut.
 Vendosim në një vend të kujtesës me emrin numri, vlerën
e numrit të parë ne varg dhe pikërisht vlerën 1.
 Cikël: përsëriten hapat e mëposhtëm 100 herë:
 Shtojmë te shuma numrin
 E rrisim numrin me 1 duke zbatuar formulën që lidh
dy elementë të njëpasnjëshëm të vargut
 Rezultati afishohet në ekran.
Blloksema:
Figura 5. 1 Pseudokodi, bllokskema në llogaritjen e shumës së 100 numrave të parë natyralë
shuma = shuma + numri
numri = numri + 1;
fund
fillim
numrator= 0
numri = 1
shuma = 0
numratori = numratori + 1
nunratori < 100
po
jo
shuma
5.2 Të gjendet shuma e disa numrave të parë natyralë, pra shtrohet për zgjidhje gjetja e
shumës 1 + 2 + 3 + . . . ku numri i numrave nuk është i paracaktuar;
Pak ndryshim ka ky problem nga problemi në 5.1. Ndryshimi i vetëm është që duhet ti bëjmë të
ditur programit sa numra do të mbledhim.
Pseudokodi:
 Sa numra natyralë do të mblidhen?
 Numri i numrave, nr, vendoset në kujtesë
 Vendosim në një vend në kujtese me emrin numratori qe
i japim vleren 0. Këtu do shtohen hapat qe ne kryejmë
 Vendosim në një vend në kujtesëme emrin shuma vlerën
0; këtu do të shtohen numrat e vargut.
 Vendosim në një vend të kujtesës me emrin numri, vlerën
e numrit të parë ne varg dhe pikërisht vlerën 1.
 Cikël: përsëriten hapat e mëposhtëm sa është vlera e nr:
 Shtojmë te shuma numrin
 E rrisim numrin me 1 duke zbatuar formulën që lidh
dy elementë të njëpasnjëshëm të vargut
 Rezultati afishohet në ekran.
Blloksema:
Figura 5. 2 Pseudokodi, bllokskema në llogaritjen e shumës së një numri të ҫfarëdoshëm numrash të parë
natyralë
Në probleme të tjerë formula lidhëse midis dy elementëve të njëpasnjëshëm të një vargu numrash
mund të jetë më e komplikuar dhe fundi i hapave të ciklit të lidhet me një konditë të caktuar. Për
shembull:
5.2 Të gjendet shuma e thyesave
𝟏
𝟐
+
𝟏
𝟑
+
𝟏
𝟒
+ … përderisa thyesa të jetë më e madhe se
𝟏
𝟏𝟎𝟎𝟎
Në këtë problem përsëri ekziston një lidhje e emëruesit të një elementi me emëruesin e elementit
paraardhës:
shuma = shuma + numri
numri = numri + 1;
fund
fillim
numratori =0; numri = 1
shuma = 0
numratori = numratori + 1
nunratori < nr
jo
shuma
Futet nr
Sa numrajanë?
po
emëruesi = emëruesi i elementit parardhës + 1
, ndërkohë që numuruesi është gjithmonë 1.
Përsëri do të kemi një cikël ku elementi në ҫdo hap krijohet nga një formulë, por cikli në këtë
rast mbaron kur plotësohet kondita që elemeti i rradhës <= 1/1000. Pseudokodi dhe bllokskema
janë:
Pseudokodi:
 Vendosim në një vend në kujtesëme emrin shuma vlerën
0; këtu do të shtohen numrat e vargut.
 Vendosim në një vend të kujtesës me emrin numri, vlerën
eemëruesit tëthyesës së parë ne varg dhe pikërisht
vlerën 2.
 Cikël: përsëriten hapat e mëposhtëm përderisa thyesa të
jetë më e madhe se 1/1000:
 Shtojmë te shuma thyesën
 E rrisim emëruesin me 1 duke zbatuar formulën që
lidh dy elementë të njëpasnjëshëm të vargut
 Rezultati afishohet në ekran.
Blloksema:
Figura 5. 3 Pseudokodi, bllokskema në llogaritjen e shumës së një numri thyesash
𝟏
𝟐
+
𝟏
𝟑
+
𝟏
𝟒
+ … përderisa
thyesa të jetë më e madhe se 1/1000
2. Programet ngakrijimi ne ekzekutim (roli i kompilatorit)
Programi më i thjeshtë në C++, thjesht afishon një mesazh në ekran, dhe është programi që i
korrespondon bllokskemës fare të thjeshtë të figures 6.1:
Shembull 1: Të krijohet një program i tillë që gjatë ekzekutimit të tij të afishojë në ekran
shprehjen “Programi im i pare ne C++”:
shuma = shuma + 1/emeruesi
emeruesi = emeruesi + 1;
fund
fillim
emeruesi = 2
shuma = 0
1
𝑒𝑚𝑒𝑟𝑢𝑒𝑠𝑖
>
1
1000
jo
shuma
po
Blloksema:
Kodi burim Rezultati gjatë ekzekutimit
// program im i pare ne C++
#include <iostream>
using namespace std;
int main ()
{
cout<<"Programi im i pare ne C++n";
return 0;
}
Programi im i pare ne C++
Figura 6.1 Bllokskema dhe kodi burim i një programi që afishon një mesazh në ekran
Para se të analizojmë programin e mësipërm rresht të rresht duhet të kemi të qartë hapat që
kalohen nga momenti që ne e shkruajmë programin në një gjuhë të nivelit të lartë, në rastin tonë
me gjuhën C++, deri në momentin që ai ekzekutohet në kompjuter duke na dhënë rezultatin në
paisjet dalëse të tij. Janë këta hapa ku një program kalon:
a) Shkruhet programi burim në një editor si një sekuencë statementesh dhe regjistrohet me një
prapashtesë që njihet nga kompilatori që disponojmë, p.sh. .cpp ose .cc. Ky është file-i
kodit burim. Në këtë mënyrë do të shkruanim programin e figurës 6.1.
b) Shpesh një program burim përmban të ashtuquajturat direktiva dhe janë ato që paraprihen
nga simboli #. Rreshta të tilla përfaqësojnë pjesë kodi që për lehtësi ofrohen nga C++ duke
shkruar nga ana jonë një rresht të vetëm.
Në rastin e kodit burim në fig. 6.1 një direktivë paraqet nga rreshti:
#include <iostream>
c) Ekzekutohet kompilatori (përkthyesi) për të konvertuar programin makinë në instruksione
makine. Një statement zbërthehet në disa instruksione në gjuhën makinë.
Kompilatori gjithashtu na ve në dukje gabimet që ne bëjmë gjatë shkrimit të programit,
gabime që nuk respektojnë rregullat e shkrimit të një programi në C++. Ne i korigjojmë
këto gabime dhe përsëri e përkthejmë programin me ndihmën e kompilatorit.
d) Ekzekutohet program linker për të lidhur së bashku pjesë të ndryshme të një programi siҫ
janë kodi i mësiperm i shkruar nga ne dhe kodi që rreshti
#include <iostream>
fillim
fund
Programi im i pare
ne C++
përfaqëson duke prodhuar kështu një file të ekzekutueshëm.
Hapat b–d shpesh realizohen me një komandë të vetme ose klikim butoni në varësi të ambientit
të punës ku ne zhvillojmë një program.
Gabimet që mund të dallohen në një hap të çfarëdoshëm do të pengonin ekzekutimin e hapave
pasues. Diagrama ne fig.6.2 paraqet këtë rradhë hapash:
Figura 6.2 Programi nga krijimi në ekzekutim
Ushtrim:
Krijoni një ambient pune për shkruar një program në C++. Mund të përdoren ambiente të
ndryshme pune si Code Block, Visual C++, NetBeans etj.
Të gjithë këto ambiente pune na japin mundësi të shkruajme në program dhe me një buton të
përkthejmë(kompilatori), lidhim (linkeri) dhe të ekzekutojmë programin tonë.
Kjo punë duhet të bëhet në bashkëpunim me instruktorin tuaj në laborator.
Kodi Burim
Paraprocesori
Kodi Burim i
Modifikuar
Kompilatori
Kodi Objekt
Linkeri
Kodi i Ekzekutueshëm
3. Prezantim me gjuhën C++
I rikthehemi programit të parë në gjuhën C++, figura 6.1 dhe e analizojmë atë rresht për rresht
Kodi burim
// program im i pare ne C++
#include <iostream>
using namespace std;
int main ()
{
cout<<"Programi im i pare ne C++n";
return 0;
}
Figura 7.1 Kodi burim i një programi që afishon një mesazh në ekran
int main ()
Ky rresht i korrespondon fillimit të funksionit main(). Funksioni përfshin zakonisht një pjesë
kodi që realizon diçka. Funksioni ka një sintaksë të përcaktuar. Funksioni main() është pika e
programit ku fillon ekzekutimi i tij. Pavarësisht ku ndodhet ky funksion në kodin burim. Pra ky
funksion është i domosdoshëm në çdo program të C. Formati e plotë e funksionit main() është:
int main(){
. . .
return 0;
}
Fjala main ndiqet nga çifti i parantesave (()). Ky çift kllapash dallon një funksion nga shprehje te
tjera. Opsionalisht, këto paranthesa mund të përfshijnë një listë elementësh të quajtur parametra
brenda tyre.
Mbas këtyre parantesave ne gjejmë trupin e funksionit të përfshirë në kllapat ({}). Ajo që
ndodhet në këto kllapa është çfarë funksioni bën kur ai ekzekutohet.
cout<<"Programi im i pare ne C++n";
Ky rresht është një statement C++. Një statement është një shprehje e thjeshtë ose e përbërë që
aktualisht ka një efekt. Në fakt, ky statement realizon të vetmin veprim që është afishimi i
mesazhit "Programi im i pare ne C++" në ekran. "n" siguron kalimin e kursorit në
rreshtin që vijon në ekran, poshtë mesazhit që çfaqet në të. Kjo gjë sigurohet edhe në një mënyrë
tjetër. Provoni statementin
cout<<"Programi im i pare ne C++"<<endl; endl siguron të njëjtën gjë, pra kalimin e
kursorit në rreshtin që vijon.
cout është formati që lejon afishimin e një vargu karakteresh (në këtë rast vargu i karaktereve
Programi im i pare ne C++) në ekran.
Përdorimi i cout bëhet i mundur duke shtuar në krye të kodit rreshtat:
#include <iostream>
using namespace std;
Shënojmë që statementi mbaron gjithmonë me një pikëpresje (;). Ky karakter përdoret për të
shënuar fundin e statementit në një program C++ (një nga gabimet sintaksore më të zakonshme
që bëhet në fakt është të harruarit e pikëpresjes në fund të një statementi).
return 0;
këtu kemi kthimin e numrit 0 nga funksioni main(). Ç’ka kthehet nga ky funksion merret
parasysh nga sistemi operativ, Windows; në këtë rast vlera zero tregon një mbarim normal të
programit për këtë sistem.
Programi strukturohet në rreshta të ndryshëm që të jetë më i lexueshëm gjë që është e
këshillueshme. Por mund të shkruhej dhe në një rresht. Kështu kodi burim i fig. 1.8 është njëlloj
si
// program im i pare në C++
#include <iostream>
using namespace std;
int main (){ cout<<"Programi im i pare ne C++n"; return 0;}
Figura 7.2 Në C++, ndarja midis statementeve bëhet me (;) në fund të secilitprej tyre.
4. Variablat dhe Konstantet
Rimarrim në shqyrtim shembullin e llogaritjes së sipërfaqes së një ambienti në formë
drejtkëndëshi të fig 3.1, ku vlerat e dimensioneve i kemi numra të plotë.
Pseudokodi:
 Vendosen në kompjuter të dhënat hyrëse, që janë
gjerësia dhe gjatësia e ambientit
 llogaritet siperfaqja duke shumëzuar gjerësinë dhe
gjatesinë
 afishohet sipërfaqja
Blloksema:
8.1 Llogaritja e sipërfaqes, ku gjerësia dhe gjatësia janë numra të plotë
Për të paraqitur këtë bllokskemë në një kod burim të një programi në C++ na duhet të
familjarizohemi me konceptet e variablave dhe tipet e tyre në C++.
8.1 Identifikimi i Variablave
Në shembullin e mësipërm të llogaritjes së sipërfaqes, na duhet një vend në kujtesë ku të
vendosim gjatësinë dhe një vend ku të vendosim gjerësinë. Na duhet një vend gjithashtu për të
vendosur rezultatin e llogaritjes së sipërfaqes.
Kjo gjë bëhet e mundur në C++ (si dhe në gjuhët e tjera të programimit) duke përdorur të
ashtuquajturat variabla të cilat emërtojnë pikërisht vende në kujtesë.
Atëhere procesin e mësipërm do ta paraqesim si më poshtë:
gjeresia = 3 gjatesia = 5
siperfaqja = gjeresia * gjatesia;
Eshtë e qartë që ky është një shëmbull shumë i thjeshtë mbasi kemi vetëm dy vlera të plota të
vogla me të cilat mund të kishim vepruar direkt 3 * 5, por imagjinoni të kishim miljona numra të
tillë dhe shumë veprime matematikore me ta.
Për këtë arsye, ne përcaktojmë një variabël si porcion të kujtesës për të rezervuar një vlerë të
përcaktuar. Çdo variabël kërkon një identifikues që e dallon atë nga të tjerët. Për shembull, në
kodin e mësipërm identifikuesit e variablave janë gjeresia, gjatesia, dhe siperfaqja
por ne mund të përdornim çdo lloj emri të pranueshëm (do të shohim më poshte disa rregulla për
emrat e variablave).
Identifikuesit
Një identifikues i pranueshëm është një sekuencë e një ose më shumë gërmave, shifrave, ose
gjeresia = 3
gjatesia = 5
siperfaqja= gjeresia * gjatesia
siperfaqja
fund
fillim
karakterit (_) (underscore). As hapësira e as shenjat e pikësimit nuk mund të jenë pjesë e një
identifikuesi. Përveç kësaj një identifikues nuk mund të fillojë me një shifër. Ai fillon me një
gërmë ose me (_ ).
Një tjetër rregull që duhet të marrim parasysh për identifikuesit është që nuk mund të përdorim
për ta fjalët e vet gjuhës C++ që ne i quajmë fjalë të rezervuara. Fjalë të tilla të rezervuara në
C++ janë:
bool, case, char, class, const, const_cast, continue, default, delete, do,
double, dynamic_cast, else, enum, explicit, export, extern, false, float,
for, friend, goto, if, inline, int, long, mutable, namespace, new, operator,
private, protected, public, register, reinterpret_cast, return, short,
signed, sizeof, static, static_cast, struct, switch, template, this, throw,
true, try, typedef, typeid, typename, union, unsigned, using, virtual, void,
volatile, wchar_t, while
Vërejtje1: Gjuha C++ është një gjuhë "case sensitive" pra gërmat e vogla konsiderohen ndryshe
nga të mëdhatë. Kjo do të thotë që një identifikues i shkruar me gërma të mëdha konsiderohet
ndryshe nga një i shkruar me gërma të vogla. Kështu për shembull variabli Siperfaqja nuk
është i njëjtë me siperfaqja. Në shembullin e mësipërm kemi tre identifikues të ndryshëm
variablash.
Vërejtje2: Rekomandohet që si identifikues variablash të përdoren fjalë që shprehin
domethënien e këtyre variablave, pra qëllimin për të cilin ata përdoren. Të tillë identifikues
u përdorën në shembullin e mësipërm: gjeresia, gjatesia, dhe siperfaqja.
Konstantet
Në shembullin e mësipërm, figura 8.1 vlerat 3, 5 quhen konstante, dhe ashtu si variablat edhe
ato zenë një vend në kujtesë. Dallojmë konstante të ndryshme të tipeve të ndryshme. 3, dhe 5
janë konstante numerike kurse një shprehje e përbërë nga karaktere (gërma, shifra, e karaktere
të tjerë) quhet konstante string. E tillë është për shembull shprehja "Programi im i pare ne
C++". Vemë në dukje që konstantet stringje vendosen në thonjëza dyfishe " gjatë përdorimit të
tyre në një program.
5. Tipet themelore të të dhënave
Kur programohet, ne vendosim ose themi rezervojmë variablat në kujtesën e kompjuterit, por
kompjuteri duhet të dijë çfarë lloj të dhënash ne do të vendosim atje, mbasi nuk i jepet e njëjta
hapësirë kujtese një numri të plotë, ose një numri dhjetor, ose një karakteri.
Kujtesa e kompjuterit organizohet në byte. Një byte është minimumi i sasisë së kujtesës që C++
mund të menaxhojë. Një byte lejon rezervimin e një sasie të vogël të dhënash: një karakter të
vetëm, ose një numur të plotë të vogël (në përgjithësi një të plotë midis 0 dhe 255). Përveç kësaj,
kompjuteri mund të manipulojë të dhëna më komplekse që kërkojnë disa byte për ti rezervuar, të
tilla si numrat e gjatë ose numrat jo të plotë. Në shembullin e mësipërm të llogaritjes së
sipërfaqes ne do të mjaftoheshim me numrat e plotë dhe në këtë rat do të duhej që para
përdorimit të variablave, ti deklaronim ata, pra të përcaktonim tipet e tyre si numra te plotë:
int gjeresia; //deklarimi i variablit gjeresia
int gjatesia; //deklarimi i variablit gjatesia
int siperfaqja; //deklarimi i variablit siperfaqja
gjeresia = 3;
gjatesia = 5;
siperfaqja = gjeresia * gjatesia;
ose
int gjeresia, gjatesia, siperfaqja; // deklarimi i tre variablave
gjeresia = 3;
gjatesia = 5;
siperfaqja = gjeresia * gjatesia;
Atëhere kodi burim që i përgjigjet bllokskemës në fig. 8.1, ku vlerat e variablave jepen si të
dhëna brenda programit do të jetë:
Kodi burim Rezultati gjatë ekzekutimit
// llogaritja e siperfaqes
#include <iostream>
using namespace std;
int main ()
{
int gjeresia, gjatesia, siperfaqja;
gjeresia = 3;
gjatesia = 5;
siperfaqja = gjeresia * gjatesia;
cout<<"Siperfaqja:"<< siperfaqja <<endl;
return 0;
}
Siperfaqja:15
Figura 9.1 . Kodi burim që i korrespondon bllokskemës në fig. 8.1
Në se do të përdornim vlera dhjetore për gjeresia gjatesia dhe siperfaqja do të kishim
kodin e mëposhtëm:
// llogaritja e siperfaqes
#include <iostream>
using namespace std;
int main ()
{
double gjeresia, gjatesia, siperfaqja;
gjeresia = 3.4;
gjatesia = 5.2;
siperfaqja = gjeresia * gjatesia;
cout<<"Siperfaqja:"<< siperfaqja <<endl;
return 0;
}
Siperfaqja:17.28
Figura 9.2 . Variabla të tipit double
Në vijim është një përmbledhje e tipeve të ndryshëm të të dhenave në C++, si dhe intervali i
vlerave që mund të përdoret për secilën prej tyre. Këta tipe quhen dhe tipe primitivë:
Emri Përshkrimi Madhësia* Intervali*
Char Karakter ose i plotë i vogël 1 byte
Me shenjë: -128 to 127
Pa shenjë: 0 to 255
short int
(short)
i plotë short. 2 byte
Me shenjë: -32768 to 32767
Pa shenjë: 0 to 65535
Int i plotë. 4 byte
Me shenjë: -2147483648 to 2147483647
Pa shenjë: 0 to 4294967295
long int
(long) i plotë long. 4 byte
Me shenjë: -2147483648 to 2147483647
Pa shenjë: 0 to 4294967295
Bool
Vlerë buleane. Merr nje nga vlerat: true ose
false.
1 byte true ose false
Float Numur me pike notuese. 4 byte +/- 3.4e +/- 38 (~7 shifra)
Double
Numur me pike notuese me precision të
dyfishtë.
8 byte +/- 1.7e +/- 308 (~15 shifra)
long
double
Numur me pike notuese me precision të
dyfishtë long.
8 byte +/- 1.7e +/- 308 (~15 shifra)
wchar_t Karakter i gjërë. 2 ose 4 bytes 1 karakter i gjerë
Figura 9.3 Tipet primitive në C++
6. Operatoret
Pasi u njohëm me nevojën e përdorimit të variablave dhe konstanteve, jemi gati të operojmë me
to. Për këtë qëllim C++ përdor operatorët.
Dhenja e Vlerës(Assignment) (=)
Operatori i dhënjes së vlerës i jep një vlerë një variabli.
a = 5;
Rregulli më i rëndësishëm kur japim një vlerë është rregulli nga e djathta-në të majtë: operatori i
dhënjes së vlerës ka vend nga e djathta në të majtë, dhe kurrë në drejtim të kundërt:
a = b;
Ky statement i jep variablit a vlerën që ndodhet në variablin b. Vlera që ndodhej deri tani në a
humbet.
a merr vlerën e b, por në se b ndryshon më vonë, kjo nuk do të sjellë një ndryshim te a.
Për shembull, le të marrim parasysh kodin që vijon –
// operatori i dhenjes se vleres
#include <iostream>
using namespace std;
int main ()
{
int a, b; // a:?, b:?
a = 10; // a:10, b:?
b = 4; // a:10, b:4
a = b; // a:4, b:4
b = 7; // a:4, b:7
cout << "a:";
cout << a;
cout << " b:";
cout << b;
return 0;
}
a:4 b:7
Figura 10.1 Operatori i dhënjes së vlerës
Ky kod do rezulton në atë që vlera që përmbahet në a është 4 dhe ajo që përmbahet në b është 7.
Shënojmë se a nuk preket nga modifikimi i fundit i b megjithëse kemi shkruar a = b më parë
(kjo për arsye të rregullit nga e djathta në të majtë).
Shprehja e mëposhtme është gjithashtu e vlefshme në C++:
a = b = c = 5;
Këtu jepet vlera 5 te të tre variablat: a, b dhe c.
7. Operatorët Arithmetikë ( +, -, *, /, % )
Pesë veprimet arithmetikë që mbështeten nga gjuha C++ janë:
+ Mbledhja
- Zbritja
* Shumëzimi
/ Pjestimi
% mbetja e pjestimit (modulo)
Figura 11.1 Operatorët arithmetikë
Veprimet si mbledhja, zbritja, shemëzimi, pjestimi i korrespondojnë veprimeve korresponduese
arithmetike. I vetmi që mund të mos jetë familjar për ju është veprimi modulo; operatori i tij
është shenja e përqindjes (%). Modulo është veprimi që jep mbetjen e pjestimit të dy vlerave të
plota, pra ky veprim përdoret vetëm midis dy numrave të plotë. Për shembull:
a = 11 % 3;
variabli a do të mbajë vlerën 2, mbasi 2 është mbetja e pjestimit midis 11 dhe 3.
Operatorët e përbërë të dhënjes së vlerës (+=, -=, *=, /=, %=, >>=, <<=, &=, ^=, |=)
Kur duam të modifikojmë vlerën e një variabli duke kryer një veprim në vlerën aktualisht të
rezervuar në këtë variabël, ne mund të perdorim operatorët e përbërë të dhënjes së vlerës:
Shprehja është ekuivalente me
vlera += rritja; vlera = vlera + rritja;
a -= 5; a = a - 5;
a /= b; a = a / b;
cmimi *= njesite + 1; cmimi = cmimi * (njesite + 1);
Figura 11.2 Operatorë të përbërë të dhënjes së vlerës
dhe e njëjta gjë për gjithë operatorët e tjerë. Për shembull:
// operatoret e perbere te dhenjes se
vleres
#include <iostream>
using namespace std;
int main ()
{
int a, b=3;
a = b;
a += 2; // equivalent me a = a+2
cout << a;
return 0;
}
5
Figura 11.3 Shembull i përdorimit të operatorëve të përberë
Shtimi dhe Zbritja (++, --)
Duke i shkurtuar më tepër disa shprehje, operatori i shtesës (++) dhe i zbritjes (--) rrit ose
zvogëlon vlerën e rezervuar në një variabël me 1. Ata janë ekuivalent me +=1 dhe -=1,
respektivisht. Kështu:
c++;
c+=1;
c=c+1;
Janë të gjithë ekuivalentë në funksionin e tyre: të tre ata rritin me një vlerën e c.
Një karakteristikë e këtij operatori është që mund të përdoret para (++a) ose pas (a++)
identifikuesit të variablit (pa hapësirë midis tyre). Megjithëse në shembujt e thjeshtë si a++ ose
++a të dyja shprehjet kanë të njëjtin kuptim, në shprehje të tjera ato mund të kenë një ndryshim
të rëndësishëm: në rastin e (++a) vlera rritet para se rezultati i shprehjes të vlerësohet dhe për
këtë arsye është vlera e rritur që konsiderohet në vlerësimin e një shprehje të jashtme; në rastin e
(a++) vlera e rezervuar në a rritet pas vlerësimit, prandaj është vlera e rezervuar fillimisht te a që
merret parasysh në vlerësimin e një shprehje të jashtme. Vemë re diferencën:
Shembull 1 Shembull 2
B=3;
A=++B;
// A eshte 4, B eshte 4
B=3;
A=B++;
// A eshte 3, B eshte 4
Figura 11.4 Shembuj të përdorimit të operatorëve ++ majtas dhe djathtas një variabli
Në shembullin 1, B rritet para se vlera e tij të kopjohet në A. Ndërsa në shëmbullin 2, vlera e B
kopjohet në A dhe pastaj B rritet.
Ka një prioritet ndërmjet operatorëve arithmetikë dhe pikërisht rradha e veprimit të tyre shprehet
si më poshtë:
Niveli Operatori Përshkrimi Grupimi
1 * / % shumezim Nga e majta në të djathtë
2 + - mbledhje Nga e majta në të djathtë
Pra në se nuk kemi kllapa, veprimet e shumëzimit dhe pjestimit bëhen para atyre të mbjedhjes
dhe zbritjes. Vetëm vendosja e kllapave mund ta ndryshojë këtë rradhë.
8. Operatorët e Krahasimit ( ==, !=, >, <, >=, <= )
Me qëllim që të vlerësojmë krahasimin midis dy shprehjeve ne mund të përdorim operatorët
relacionalë dhe të barazisë. Rezultati i një operatori relacional është një vlerë boolean-e që mund
të jetë true ose false, në përputhje me rezultatin e tij boolean.
Ne mund të duam të krahasojmë dy shprehje, për shembull, për të evidentuar në se ato janë të
barabarta ose njëra është më e madhe se tjetra.
Këtu është një listë operatorësh relacionale dhe të barazimit që mund të përdoren në C++:
== I barabartë me
!= Jo i barabartë me
> Më i madh se
< Më i vogël se
>= Më i madh ose i barabartë me
<= Më i vogël ose i barabartë me
Figura 12. 1 Operatorët relacionalë
Këtu kemi disa shembuj:
(7 == 5) // vleresohet si false.
(5 > 4) // vleresohet si true.
(3 != 2) // vleresohet si true.
(6 >= 6) // vleresohet si true.
(5 < 5) // vleresohet si false.
Natyrisht, në vend që të përdorim vetëm konstantet numerike, ne mund të përdorim një shprehje
të çfarëdoshme që përfshin variabla. Supozojmë që a=2, b=3 dhe c=6,
(a == 5) // vleresohet si false mbasi a nuk eshte i barabarte me 5.
(a*b >= c) // vleresohet si true mbasi (2*3 >= 6) eshte true.
(b+4 > a*c) // vleresohet si false mbasi (3+4 > 2*6) eshte false.
((b=2) == a) // vleresohet si true.
Të jeni të kujdesshëm! Operatori = (një shënjë =) nuk është i njëjti me operatorin == (dy shenja
barazimi), i pari është operatori i dhënjes së vlerës, (jepet vlera nga e djathta në të majtë) dhe
tjetri (==) është operatori i barazisë që krahason në se dy shprehje në dy anët e tij janë të
barabarta. Në këtë mënyrë, në shprehjen ((b=2) == a), së pari ne i japim vlerën 2 variablit b
dhe pastaj e krahasojmë me a, që gjithashtu rezervon vlerën, kështu që rezultati i veprimit është
true.
Ka një prioritet ndërmjet operatorëve të krahasimit dhe pikërisht rradha e veprimit të tyre
shprehet si më poshtë:
Niveli Operatori Përshkrimi Grupimi
1 < > <= >= Relacional Nga e majta në të djathtë
2 == != Barazim Nga e majta në të djathtë
Vetëm vendosja e kllapave mund ta ndryshojë këtë rradhë.
Ushtrime:
1. Si është vlera e shprehjeve që vijojnë si të plotë dhe si vlerë booleane?
a) 3
b) 5+7
c) 3+(3<4)
d) (2>1)+(3<2)
Operatorët Logjikë ( !, &&, || )
Operatori ! është operatori i C++ të realizon veprimin logjik JO, dhe ka vetëm një operand
boolean, të vendosur në të djathtë, dhe ajo që bën është gjetja e inversit të vlerës së tij, pra false
në se operandi është true dhe true në se operandi është false. Pra, ai kthen vlerën e kundërt
booleane të operandit të tij. Për shembull:
!(5 == 5) // vleresohet false mbasi shprehja ne te dhjathte(5 == 5)
// eshte true.
!(6 <= 4) // vleresohet true mbasi (6 <= 4) do te ishte false.
!true // vleresohet false
!false // vleresohet true.
Operatorët logjikë && dhe || përdoren kur vlerësohen dy shprehje për të marrë një rezultat të
vetëm relacional. Operatori && i korrespondon veprimit logjik boolean DHE. Ky veprim rezulton
true në se të dy operandët janë true, dhe false përndryshe. Operatori || i korrespondon
veprimit logjik boolean OSE. Ky veprim rezulton true në se të paktën një nga operandët është
true, dhe false kur të dy operandët janë false. Tabelat që vijonë paraqet rezultatin e
operatorit && duke vlerësuat shprehjen a && b dhe a || b :
OPERATORI && OPERATORI ||
A B a && b a B a || b
True True true true True true
True False false true false true
False True false false True true
False False false False false false
Për shembull:
( (5 == 5) && (3 > 6) ) // vleresohet si false ( true && false ).
( (5 == 5) || (3 > 6) ) // vleresohet true ( true || false ).
Kur përdoren operatorët logjikë, C++ vlerëson çfarë është e nevojshme nga e majta në të djathtë
për të ardhur në rezultatin relacional të kombinuar, duke injoruar pjesën që mbetet. Për këtë
arsye, në shembullin e fundit ((5==5)||(3>6)), C++ do të vlerësonte fillimisht në se 5==5 është
true, dhe në se kjo ka vend, nuk do të vazhdonte të kontrollonte më tej në se 3>6 është e vërtetë
ose jo. Kjo njihet si vlerësimi qark –i shkurtër, dhe punon në këtë mënyrë:
operatori Qarku i shkurtër
&&
Në se shprehja në të majtë është false, rezultati i kombinuar është false (shprehja në anën e
djathtë nuk vlerësohet).
|| Në se shprehja në të majtë është true, rezultati i kombinuar është true (shprehja në anën e djathtë
nuk vlerësohet)
Tabela 1.9 Operatorët Logjikë
Kjo është e rëndësishme kur shprehja në anën e djathtë ka efekte anësore, si ndryshim vlerash:
if ((i < 10)&&(++i < n)) { /*...*/ }
Kjo shprehje e kushtëzuar rrit i me një, por vetëm në se kondita në të majtë të && është e vërtetë,
përndryshe shprehja në të djathtë të (++i < n) asnjëherë nuk vlerësohet.
Ka një prioritet ndërmjet operatorëve të krahasimit dhe pikërisht rradha e veprimit të tyre
shprehet si më poshtë:
Niveli Operatori Përshkrimi Grupimi
1 ! JO llogjike
2 && DHE logjike
3 || OSE logjike
Vetëm vendosja e kllapave mund ta ndryshojë këtë rradhë.
9. Vleresimi i shprehjeve dhe prioriteti i operatoreve
Prioriteti i operatorëve
Më sipër përmëndëm prioritetin që kanë operatorët e ndryshëm brenda kategorisë përkatëse të
tyre. Por mund të kemi shprehje komplekse ku përfshihen veprime të ndryshme të të gjitha
kategorive: arithmetike, veprime krahasimi, veprime llogjike.
Nga prioriteti më i madh në atë më të ulët, renditja e prioriteteve për një pjesë të operatorëve,
është si më poshtë:
Niveli Operatori Përshkrimi Grupimi
1 * / % shumezim Nga e majta në të djathtë
2 + - mbledhje Nga e majta në të djathtë
3 < > <= >= relacional Nga e majta në të djathtë
4 == != barazim Nga e majta në të djathtë
5 ! JO
6 && DHE logjike
7 || OSE logjike
8 = *= /= %= += -= >>= <<= dhënje vlere Nga e djathta në të majtë
Figura 13. 1 Prioriteti i operatorëve
10. Shkrimi ne ekran dhe Leximi i te dhenave nga tastiera
14.1 Dalja Standarte (cout)
Në programet e paragrafeve të mëparshëm kemi përdorur formatin e afishimit në ekran të një
rezultati dhe për këtë na janë dashur disa rreshta kodi:
Fillimisht përfshinim në program direktivën:
#include <iostream>
Të shoqëruar me specifikimin
using namespace std;
pra:
#include <iostream>
using namespace std;
dhe më pas përdornim formatin
cout << variabel/konstante . . .
ku << quhet operator i daljes dhe (cout) na përfaqëson formatin e daljes standarte në ekran në
C++.
cout << "nje shprehje ne ekran"; // printon nje shprehje ne ekran
cout << 120; // printon numrin 120 ne ekran
cout << x; // printon permbajtjen e x ne ekran
Operatori << shton të dhënat që vijojnë pas tij në një sekuencë karakteresh që e paraprin atë. Në
shembujt e mësipërm fillimisht vendoset konstantja string
nje shprehje ne ekran,
, më pas shtohet konstantja numerike 120 dhe më pas përmbajtja e variablit x në sekuencën e
karaktereve që cout bën të mundur të afishohet. Kështu do ta imagjinojmë për momentin cout.
Shënojmë që fjalia në statementin e parë përfshihet midis thonjëzave dyfishe (") mbasi është një
konstante string karakteresh. Gjithmonë kur ne duam të përdorim një konstante string
karakteresh, ne duhet ta përfshijmë atë midis thonjëzave të dyfishta që ajo të dallohet nga një
emër variabli. Për shembull, këtu janë dy fjali që kanë rezultate shumë të ndryshme:
cout << "Pershendetje"; // printon pershendetje
cout << Pershendetje; // printon permbajtjen e variablit Pershendetje
Operatori i daljes (<<) mund të përdoret më shumë se një herë në një statement të vetëm:
cout << "Pershendetje, " << "ky eshte " << "nje statement C++";
Ky statement i fundit do të shtypë mesazhin Pershendetje, ky eshte nje statement C++
në ekran. Dobia e përsëritjes së operatorit të daljes (<<) duket kur kombinojmë shtypjen e
variablave dhe konstanteve ose të më shumë se dy variablave:
cout << "Pershendetje, une jam " << mosha << " vjet dhe adresa ime eshte " <<
adresa;
Në se supozojmë se variabli mosha ka vlerën 24 dhe adresa përmban “Rr. Deshmoret e Kombit
Nr 20” rezultati i statementit të mësipërm do të ishte:
Pershendetje, une jam 24 vjet dhe adresa ime eshte Rr. Deshmoret e Kombit Nr
20
Eshtë e rëndësishme të vemë re që cout nuk kalon në rresht tjetër pas rezultatit në se ne nuk
mendojmë vet ta bëjmë këtë gjë. Kështu statementet e mëposhtme do të shfaqin rezultatet e tyre
në një rresht:
cout << "Ky eshte nje pohim.";
cout << " Ky eshte nje pohim tjeter.";
Ky eshte nje pohim. Ky eshte nje pohim tjeter.
Për të realizuar kalimin në një rresht tjetër pas shtypit të një mesazhi specifikohet karakteri
special i rreshtit të ri n (backslash, n):
cout << "Pohimi i pare.n";
cout << " Pohimii dyte.nPohimi i trete.";
nga ku marrim këtë rezultat:
Pohimi i pare.
Pohimi i dyte.
Pohimi i trete.
Për kalimin në një rresht të ri mund të përdorim dhe sintaksën endl që quhet një manipulator.
Për shembull:
cout << "Pohimi i pare." << endl;
cout << "Pohimi i dyte." << endl;
që do të printonte:
Pohimi i pare.
Pohimi i dyte.
Manipulatori endl prodhon një karakter të kalimit në rresht të ri, ekzaktësisht çfarë bën dhe 'n'.
Mund të përdoren të dy formatet pa ndonjë ndryshim në rezultat.
14.2 Hyrja Standarte (cin)
Paisja standarte e hyrjes në kopmjuter është tastjera. Përdorimi i hyrjes standarte në C++
realizohet nëpërmjet operatorit të hyrjes (>>) i përdorur së bashku me formatin cin që e
përfytyrojmë për momentin si mbartës të një sekuencë karakteresh. Operatori duhet të ndiqet
nga variabli që rezervon të dhënat që futen si një sekuencë karakteresh. Për shembull:
int mosha;
cin >> mosha;
Statementi i parë deklaron një variabël të tipit int të quajtur mosha, dhe i dyti pret për një hyrje
nga cin (tastjera) për ta rezervuar në këtë variabël të plotë.
>> trajton hyrjen nga tastjera kur ne shtypim tastin RETURN. Për këtë arsye, edhe në se ju
kërkoni një karakter të vetëm, futja e tij nga cin nuk bëhet pa shtypur tastin RETURN pasi
karakteri të jetë shtypur.
Duhet gjithmonë të konsiderojmë tipin e variablit që jemi duke përdorur si mbartës të asaj çfarë
futet me cin. Në se kërkojmë një të plotë duhet të shtypim një të plotë, në se kërkojmë një
karakter duhet të shtypim një karakter dhe në se kërkojmë një string karakteresh, duhet të
shtypim një string karakteresh.
// shembull hyrje/daljesh
#include <iostream>
using namespace std;
int main ()
{
int i;
cout << "shtypni nje vlere te plote: ";
cin >> i;
cout << "Vlera e shtypur eshte " << i;
cout << " dhe dyfishi eshte " << i*2 << ".n";
return 0;
}
shtypni nje vlere te
plote: 702
Vlera e shtypur eshte 702
dhe dyfishi eshte 1404.
Figura 14.1 Nje shembull hyrje/daljesh
Përdoruesi i programit mund të jetë një nga faktorët që gjeneron gabime qoftë dhe në programin
më të thjeshtë që përdor cin (si në programin më sipër). Në se kerkohet një vlerë e plotë dhe
përdoruesi i programit fut një emër (një varg karakteresh), do të kemi një operim të gabuar mbasi
nuk jepet çfarë pritej. Kështu kur përdoren të dhëna hyrëse që sigurohen nga cin duhet të jemi të
sigurtë të futen të dhëna të rregullta. Më vonë do të mësojmë se ka mënyra për te zgjidhur
situatat e gabimeve që shkaktohen nga shtypja e të dhënave të përdoruesit.
Mund të përdoret cin për të kërkuar më shumë se një e dhënë hyrëse nga përdoruesi:
cin >> a >> b;
gjë që është ekuivalente me
cin >> a;
cin >> b;
në të dy rastet përdoruesi duhet të japë dy të dhëna, një për variablin a dhe një tjetër për variablin
b që mund të ndahen me një ndarës: një hapësirë, një karakter tab ose me një karakter që
gjeneron një rresht të ri.
14.3 cin dhe stringjet
Ne mund të përdorim cin për të futur stringje nëpërmjet variablave të tipit string me operatorin
(>>) siç do të bënim me variablat e tipeve të tjerë themelore. Variabla të tipit string do të ishin
variablat që kanë si vlera të tyre stringje.
cin >> njestring;
Megjithatë, cin gjatë futjes së të dhënës ndalon së vepruari sapo gjen një karakter hapësirë,
kështu në këtë rast do të marrë fjalën e parë të një fjalie. Kjo sjellje mund ose jo të jetë ajo që ne
duam; për shembull në se ne duam të marrim një fjali nga përdoruesi, kjo procedurë hyrje nuk
është e dobishme.
Me qëllim futje të një rreshti të plotë, ne mund të përdorim funksionin getline, që është më i
rekomanduar për të marrë çfarë përdoruesi fut si të dhënë në cin:
// cin me stringje
#include <iostream>
#include <string>
using namespace std;
int main ()
{
string njestr;
cout << "Emri juaj? ";
getline (cin, njestr);
cout << "Pershendetje " << njestr << ".n";
cout << "Dega juaj? ";
getline (cin, njestr);
cout << "Me pelqen " << njestr
Emri juaj? Arjan Bregu
Pershendetje Arjan Bregu.
Dega juaj? Informatike
Ekonomike
Me pelqen Informatike
Ekonomike shume!
<< " shume!n";
return 0;
}
Figura 14. 2 Përdorim i getline per stringjet që përmbajnë hapësira
15. Strukturat e Kontrollit
Le të diskutojmë një problem praktik që do ta zgjidhim me një program. Do të përcaktohet
në se nxënësi është kalues në bazë të pikëve që ka marrë në provimet e matures. Janë tre lëndë
pikët e të cilave mbidhen. Në se shuma e pikëve e kalon 50 nxënësi konsiderohet kalues,
përndryshe jo.
Bllokskema e algoritmit të këtij problemi do të paraqitej në një nga bllokskemat e mëposhtme:
Figura 15.1 Bllokskema e problemit të vlerësimit të nxënësve
Bllokskema e parë jep një përgjigje vetëm për nxënësin kalues, e dyta jep përgjigje për të dy
rastet.
Një program zakonisht nuk kufizohet me një sekuencë instruksionesh që ekzekutohen njëri pas
tjetrit. Gjatë ekzekutimit të tij, mund të kemi degëzime, si në fig. 15.1, ose marrje vendimesh.
Për këtë arsye, C++ siguron strukturat e kontrollit që shërbejnë për të specifikuar çfarë duhet
bërë nga programi ynë, kur dhe në çfarë rrethanash.
Me strukturat e kontrollit ne do të prezantojmë një koncept të ri: statementin e përbërë ose
bllokun. Një bllok është një grup satementesh që ndahen me pikëpresje (;) si gjithë statementet e
C++, por të grupuara së bashku në kllapa gjarpërushe{ }:
{ statement1; statement2; statement3; }
Një statement mund të jetë ose një statement i thjeshtë (një instruksion që mbaron me një
pikëpresje) ose një statement i përbërë (shumë instruksione të grupuara në një bllok), si ai që
sapo paraqitëm. Në rastin kur duam që statementi të jetë i thjeshtë, nuk është e nevojshme ta
përfshijmë atë midis kllapave ({}). Por në rastin kur duam që një statement të jetë i përbërë, ai
Fillim
Fusni pikët e provimeve
test1, test2, test3
Shuma > 50
fund
Nxenes kalues
po jo
Fillim
Fusni pikët e provimeve
test1, test2, test3
Shuma > 50
fund
Nxenes
kalues
po jo
Nxenes jo
kalues
duhet të përfshihet midis kllapave ({}), duke formuar një bllok.
Struktura e një kondite: if dhe else
if. . është një nga strukturat e kontrollit. Në se përdoret fjala-çelës if për të ekzekutuar një
statement ose bllok, ai ekzekutohet vetëm në se një konditë plotësohet. Forma më e thjeshtë e
kësaj strukture kontrolli është:
if (konditë)
statement
ku konditë është një shprehje logjike që do të vlerësohet pra një shprehje që mund të ketë dy
vlera e vërtetë (true) ose jo e vërtetë (false). Në se kjo konditë është true, statementi
ekzekutohet. Në se ajo është false, statement injorohet (nuk ekzekutohet) dhe programi
vazhdon menjëherë pas strukturës së konditës.
Në se mund të specifikojmë çfarë duam të ndodhë në se kondita nuk plotësohet përdorim fjalën-
çelës else. Forma e saj së bashku me if është:
if (kondite)
statement1
else
statement2
Me një bllokskemë një strukture kontrolli do të paraqitej si më poshtë
Figura 15.2 Bllokskema e një structure kontrolli if…else. .
në rastin e problemit të marrë me sipër do të kishim kodin e mëposhtëm për bllokskemën e parë:
// vleresimi i nxenesve
#include <iostream>
using namespace std;
int main ()
{
int test1, test2, test3, shuma = 0;
cout << "Fusni piket e tre testeven";
cin >> test1 >> test2 >> test3;
shuma = test1 + test2 + test3;
if(shuma > 50)
cout << "nxenesi eshte kaluesn";
return 0;
}
Fusni piket e tre testeve
15
16
17
Nxenesi eshte kalues
Figura 15.3 Kodi i problemit të vlerësimit të nxënësve, një alterantivë diskutohet
dhe në përgjigje të bllokskemës së dytë do të kishim kodin
// vleresimi i nxenesve
#include <iostream>
using namespace std;
int main ()
{
int test1, test2, test3, shuma = 0;
cout << "Fusni piket e tre testeven";
cin >> test1 >> test2 >> test3;
shuma = test1 + test2 + test3;
if(shuma > 50)
cout << "nxenesi eshte kaluesn";
else
cout << "nxenesi eshte jo kaluesn";
return 0;
}
Fusni piket e tre testeve
5
10
5
Nxenesi eshte jo kalues
Figura 15.4 Kodi i problemit të vlerësimit të nxënësve, dy alternativa
Në rastin kur ka më shumë statemente që kryen kur kondita plotësohet ose jo, përdoren kllapat
gjarpëruese si në kodin e mëposhtëm:
// vleresimi i nxenesve
#include <iostream>
using namespace std;
Fusni piket e tre testeve
45
30
int main ()
{
int test1, test2, test3;
int shuma = 0, diferenca = 0;
cout << "Fusni piket e tre testeven";
cin >> test1 >> test2 >> test3;
shuma = test1 + test2 + test3;
if(shuma > 50){
diferenca = 100 - shuma;
cout << "nxenesi eshte kalues,n";
cout << " per " << diferenca
<< " pike plotesohen 100n";
}
else{
diferenca = 51 - shuma;
cout << "nxenesi eshte jo kaluesn";
cout << "duhen dhe " << diferenca
<< " pike per te kaluarn";
}
return 0;
}
20
Nxenesi eshte kalues, per 5
pike plotesohen 100
Figura 15.5 Kodi i problemit të vlerësimit të nxënësve, më shumë se një statement në çdo alternativë
Strukturat if + else mund të bashkohen në se duam të verifikojmë më shumë se dy
alternativa. Le të shohim shembullin e mëposhtëm:
// vleresimi i nxenesve
#include <iostream>
using namespace std;
int main ()
{
int test1, test2, test3, shuma = 0,
diferenca = 0;
cout << "Fusni piket e tre testeven";
cin >> test1 >> test2 >> test3;
shuma = test1 + test2 + test3;
if(shuma > 50)
cout << "nxenesi eshte kaluesn";
else if(shuma > 0 && shuma <= 50)
cout << "nxenesi eshte jo kaluesn";
else
cout << "nxenesi mungoi ne provimn";
return 0;
}
Fusni piket e tre testeve
0
0
0
nxenesi mungoi ne provim
Figura 15.6 Kodi i problemit të vlerësimit të nxënësve, më shumë se dy alternativa
Venë re këtu shprehjen logjike
(shuma > 0 && shuma <= 50)
Kuptimi i së cilës është shuma është > 0 dhe shuma është <= 50, që është një shprehje e
kompozuar nga dy shprehje (shuma > 0) krahasimi dhe (shuma <= 50)
16. Strukturat Iterative (Ciklet)
Probleme të ndryshme praktike kërkojnë përsëritjen e një serie hapash disa herë. Le të marrim
një shembull: Do të llogaritim shumën e 10 numrave të parë natyralë: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10.
Mbledhja e 10 numrave realizohet duke përsëritur 10 herë shtimin e një numri në një vend në
kujtesë. Në çdo hap pasardhës numri rritet me një derisa të arrijmë në numrin 10. Në këtë rast
numri i herëve që bëhen të njëjtat veprime (shtohet numri në vendin e kujtesës, rritet numri me
një) përputhet me numrin më të madh pra do të realizohen 10 cikle me të njëjtat veprime. Duhet
të kemi parasysh se fillimisht vendi në kujtesë duhet të ketë vlerën zero, mbasi duhet të
sigurohemi që vlera fillestare në këtë vend të kujtesës nuk duhet të ketë efekt në rezultatin
përfundimtar.
Algoritmi i këtij problem do të paraqitej me bllokskemën:
Figura 16. 1 Bllokskema e llogaritjes së shumës së 10 numrave te pare natyralë
Nga këndvështrimi i programit, ciklet kanë si qëllim përsëritjen e një ose disa statementeve një
numur herësh, në se një konditë plotësohet. Në C++ ka disa formate që realizojnë një cikël.
Cikli while
Formati i tij është:
while (shprehje) statement
dhe funksionaliteti i tij është thjesht të përsërisë statement përderisa kondita (shprehje)
mbetet e vërtetë.
Për shembull, ne do të bëjmë një program për të numuruar në mënyrë zbritëse. Para se të
shkruajmë kodin le ta paraqesim këtë rast me një bllokskemë e më pas shkruajmë kodin duke
përdorur një cikël while:
Figura 16. 2 Bllokskema e numurimit zbritës të n numrave
// numurim zbrites duke perdorur while
#include <iostream>
using namespace std;
int main ()
{
int n;
cout << "Filloni me numrin > ";
cin >> n;
while (n>0) {
cout << n << ", ";
--n;
}
cout << "Nisu!n";
return 0;
}
Filloni me numrin > 8
8, 7, 6, 5, 4, 3, 2, 1, Nisu!
Figura 16. 3 Një shembull i përdorimt të ciklitwhile
Kur programi fillon, përdoruesit i kërkohet të fusë një numur fillestar për numurimin zbritës.
Atëhere cikli fillon; në se vlera e futur e plotëson konditën n > 0 (n të jetë më e madhe se zero),
blloku që vijon konditën do të ekzekutohet dhe përsëritet përderisa kondita (n > 0) mbetet e
vërtetë.
I gjithë procesi i programit të mëparshëm mund të interpretohet në përputhje me skriptin që vijon
(që fillon në main):
fillimLexo numrin n
n>0? Afisho n
n=n-1
pojo
fund
1. Përdoruesi i jep një vlerë n-së
2. Kontrollohet kondita while(n > 0). Në këtë pikë ka dy mundësi:
* kondita është e vërtetë: statement ekzekutohet (hapi 3)
* kondita nuk është e vërtetë: injorohet statement dhe vazhdohet pas tij (hapi 5)
3. Ekzekutohet statementi:
cout << n << ", ";
--n;
(afishohet vlera n në ekran dhe zvogëlohet n me 1)
4. Fundi i bllokut. Kthimi automatik në hapin 2
5. Vazhdon program menjëherë pas bllokut: afishohet Nisu! Dhe programi mbaron.
Kur krijojmë një cikël while, ne duhet gjithmonë të konsiderojmë që ai duhet të mbarojë në një
moment, prandaj ne duhet të sigurojmë në bllok mënyrën që ta detyrojnë konditën të bëhet false,
Përndryshe cikli do të vazhdojë pafundësisht. Në rastin tonë ne kemi veprimin --n; që pakëson
vlerën e variablit që vlerësohet në konditë (n) me një – kjo gjë eventualisht do ta bëjë konditën
(n > 0) false pas një numri hapash të ciklit; për të qënë më specifik, kur n bëhet 0, d.m.th. kur
ciklit while i numurimit zbritës mbaron.
Cikli do-while
Formati i tij është:
do statement while (kondita);
Funksionaliteti i tij është ekzaktësisht i njëjtë si cikli while, më përjashtimin që kondita në ciklin
do-while vlerësohet pas ekzekutimit të statementit në vend të vlerësimit para tij, duke garantuar
kështu të paktën një ekzekutim edhe në rastin kur kondita nuk plotësohet asnjëherë. Për shembull
duam të realizojmë një program që kërkon një numur nga ne dhe ky process vazhdon përderisa
nuk kemi futur numrin zero. Ky është një rast që justifikon përdorimin e një sintakse do . .
.while të ciklit gjë që shihet dhe nga bllokskema dhe programi që vijojnë:
fillim
Lexo numrin
n
n!=0?
Figura 16. 4 Bllokskema e futjes së një numri përderisa ai nuk është zero
// kerkimi i nje numri
#include <iostream>
using namespace std;
int main ()
{
unsigned long n;
do {
cout << "Futni nje numur(0-fund): ";
cin >> n;
cout << "Ju futet numrin: " << n << "n";
} while (n != 0);
return 0;
}
Futni nje numur(0-fund):
12345
Ju futet numrin: 12345
Futni nje numur(0-fund):
160277
Ju futet numrin: 160277
Futni nje numur(0-fund): 0
Ju futet numrin: 0
Figura 16. 5 Një shembull i përdorimit të ciklitdo..while
Cikli do-while zakonisht përdoret kur variablat që përbëjnë konditën përcaktohen fillimisht në
trupin e ciklit, si në rastin e mëparshëm, ku n e merr vlerën brenda në bllok dhe do jetë ajo që do
të përcaktojë fundin e ciklit. Në se nuk fusim vlerën 0, shohim që cikli përsëritet më shumë herë.
Cikli for
Formati i tij është:
for (inicializimi; kondita; modifikim) statement;
dhe funksioni i tij kryesor është të përsërisë statement derisa kondita të mbetet e
vërtetë, si dhe në ciklin while. Por përveç kësaj, cikli for siguron një vend për statemente
inicializimi dhe një për statemente modifikimi. Kështu ky cikël është specifikisht i dezinjuar
për të realizuar veprime përsëritëse me një numrator i cili inicializohet dhe rritet në çdo hap të
ciklit (hap).
Ai punon në mënyrën që vijon:
pojo
fund
1. Inicializimi ekzekutohet. Në përgjithësi variablit numrator i jepet një vlerë
fillestare. Kjo pjesë ekzekutohet vetëm një herë.
2. Kondita kontrollohet. Në se është e vërtetë cikli vazhdon, përndryshe cikli
mbaron dhe statement kapërcehet (nuk ekzekutohet).
3. statement ekzekutohet. Si zakonisht, ai mund të jetë ose një statement i vetëm ose një
bllok statemetesh të përfshira në kllapat { }.
4. Së fundi, çfarëdo që të jetë specifikuar në fushën e shtimit, kjo ekzekutohet dhe cikli
kthehet prapa në hapin 2.
Këtu është një shembull i numurimit zbritës duke filluar nga numri 10 duke përdorur ciklin for:
Figura 16. 6 Bllokskema e numurimit zbritës të numrave duke filluar nga 10
fillim
n>0?
Afisho n
n=n-1
pojo
fund
n=10
// numurimit zbritës duke përdorur ciklin
for #include <iostream>
using namespace std;
int main ()
{
for (int n=10; n>0; n--) {
cout << n << ", ";
}
cout << "Nisu!n";
return 0;
}
10, 9, 8, 7, 6, 5, 4, 3, 2, 1,
Nisu!
Figura 16. 7 Një shembull i përdorimit të ciklitfor..
Pjesët e inicializimit dhe të shtimit në formatin for (inicializimi; kondita; modifikim)
statement . . . janë jo të detyrueshme. Ato mund të mbeten bosh, por në çdo rast shënja e
pikëpresjes midis tyre duhet të shkruhet. Për shembull ne mund të shkruajmë:
for (;n < 10;) në se ne do të donim të mos bënim inicializim dhe modifikim; ose for (;n <
10;n++) në se ne duam të përfshijmë një fushë modifikimi por jo inicializim (ndoshta sepse
variabli është inicializuar përpara).
Statementi break
Duke përdorur statementin break ne mund ta ndërpresim ciklin edhe në se kondita për mbarimin
e tij nuk plotësohet. Ky statement mund të përdoret për të ndërprerë një cikël të pafundëm ose
forcërisht ta ndërpresim atë para mbylljes natyrale të tij. Për shembull duam ta ndërpresim
numurimin zbritës para mbylljes natyrale të tij:
Figura 16. 8 Bllokskema e numurimit zbritës të n numrave që mbaron para
mbylljes natyrale të tij
// shembull i break ne nje cikel
10, 9, 8, 7, 6, 5, 4, 3, numurimi
perfundon!
fillim
n>0?
Afisho n n=n-1
pojo
fund
n=10
n==3?
po jo
#include <iostream>
using namespace std;
int main ()
{
int n;
for (n=10; n>0; n--)
{
cout << n << ", ";
if (n==3)
{
cout << "numurimi perfundon!";
break;
}
}
return 0;
}
Figura 16. 9 Përdorimi në kod i statementit break
Statementi continue
Statementi continue shkakton kapërcimin e mbetjes së ciklit në hapin korrent duke shkuar në
fund të bllokut të statementeve, duke shkaktuar kapërcimin në hapin që vijon të ciklit. Për
shembull, ne kapërcejmë numrin 5 në këtë numurim zbritës:
Figura 16. 10 Bllokskema e numurimit zbritës të n numrave që kapërcen numrin 5
// shembull i continue ne nje cikel
#include <iostream>
using namespace std;
int main ()
{
for (int n=10; n>0; n--) {
if (n==5) continue;
cout << n << ", ";
}
cout << "Nisu!n";
return 0;
}
10, 9, 8, 7, 6, 4, 3, 2, 1, Nisu!
Figura 16. 11 Shembull i përdorimit të statementit continue
fillim
n>0?
Afisho n
n=n-1
pojo
fund
n=10
n==5?
po
jo
17. Funksionet
Shembuj Funksionesh
Përdorimi i funksioneve mundëson strukturimin e programeve tona në një formë modulare duke
bërë të mundur atë çka quhet programimin i strukturuar, që na ofrohet në C++.
Le të shohim shembullin e një programi në C++ që llogarit shumën e dy numrave të plotë:
Kodi burim Rezultati gjatë ekzekutimit
//ky program gjen shumen e dy numrave
#include <iostream>
using namespace std;
int main ()
{
int a=1, b=2, rezultat;
rezultat = a+b;
cout<< "shuma e a, b: " << rezultat << endl;
return 0;
}
shuma e a, b: 3
Figura 17. 1 Llogaritja e shumës së dy numrave të plotë
Të njëjtën gjë mund ta realizojmë ndryshe në C++, duke përdorur një funksion, funksionin
shuma ne këtë shembull:
Kodi burim Rezultati gjatë ekzekutimit
//ky program gjen shumen e dy numrave
//duke përdorur një thirrje funksioni,
//shih përcaktimin e funksionit shuma
#include <iostream>
using namespace std;
//percaktimi i funksionit shuma()
int shuma(int a, int b)
{
int s;
s=a+b;
return (s);
}
int main ()
{
int a=1, b=2, rezultat;
rezultat= shuma(a,b);
cout<< "shuma e a, b: " << rezultat << endl;
return 0;
shuma e a, b: 3
}
Figura 17. 2 Llogaritja e shumës së dy numrave të plotë duke përdorur një funksion
Ose një formë tjetër e pranueshme nga C++ do të ishte:
Kodi burim Rezultati gjatë ekzekutimit
//ky program gjen shumen e dy numrave duke thirrur
një
//funksion, shih deklarimin dhe percaktimin e
funksionit
#include <iostream>
using namespace std;
//deklarimi i funksionit prototip shuma()
int shuma(int, int);
int main ()
{
int a=1, b=2,rezultat;
rezultat= shuma(a,b);
cout<< "shuma e a, b: " << rezultat << endl;
return 0;
}
//percaktimi i funksionit shuma()
int shuma(int a, int b)
{
int s;
s=a+b;
return (s);
}
shuma e a, b: 3
Figura 17. 3 Llogaritja e shumës së dy numrave të plotë duke përdorur një funksion
Në shembujt e mësipërm realizohet e njëjta gjë por fillimisht gjithshka realizohet në funksionin
main të programit dhe në rastin e dytë dhe të tretë veprimi që do të kryejmë dhe që është
llogaritja e shumës së dy numrave, realizohet në funksionin shume. Brenda këtij funksioni kryhet
produkti i dy numrave dhe rezultati kthehet nga funksioni me statmentin return. Ky funksion
thirret në main dhe me që ai kthen një vlerë, kjo e fundit vendoset në një statement afishimi që
është cout. Siç e shohim më sipër, funksioni mund të përcaktohet para se ai thirret (si në
rastin e dytë, ku është përcaktuar mbi main fig 17. 2), ose vetëm deklarohet para se të thirret
dhe përcaktohet poshtë funksionit main siç është vepruar në rastin e tretë, fig 17. 3.
Pra, një funksion është një grup statementesh që ekzekutohet kur thirret në një pikë të programit.
Formati i një funksioni është si më poshtë:
tipi emri( parameter1, parameter2, ...) { statemente }
ku:
 tipi është specifikuesi i tipit të asaj ç’ka funksioni kthen. Në shembullin e mësipërm është
int.
 emri është identifikuesi me të cilin thirret një funksion. Në shembullin e mësipërm është
shuma.
 parametrat (aq sa nevojiten): çdo parametër shoqërohet me tipin e tij i ndjekur nga një
identifikues, si në një deklarim të thjeshtë variabli (për shembull: int x) dhe që vepron në
një funksion si një variabël i rregullt lokal. Nëpërmjet parametrave kalohen vlerat e
argumentave. Pra termi argument përdoret në thirrjen e funksionit dhe termi parametër në
përcaktimin e funksionit. Parametrat ndahen me presje. Kështu në shembujt e mësipërm kemi
argumentat a dhe b në thirrjen
shuma(a, b)
të funksionit shuma() në rreshtin
cout<< "shuma e a, b: " << rezultat << endl;
dhe kemi parametrat o dhe po në përcaktimin e tij:
int shuma(int a, int b)
{
int s;
s = a + b;
return s;
}
Pra kemi një korrespondencë të tilllë midis argumenteve dhe parametrave:
Në funksionin main, ne thirrëm funksionin shuma duke kaluar në të dy vlera: a dhe b, që u
korrespondojnë parametrave int a dhe int b të deklaruara në funksionin shuma. Parametrat
mund të shënohen me çfarëdo lloj emrash, ndaj dhe quhen shpesh parametra formalë. Per
shembull mund të shkruanim:
int shuma(int x, int y)
{
int s;
s = x + y;
return s;
}
në vend të
int shuma(int a, int b)
{
int s;
s = a + b;
return s;
}
do të ishte e njëjta gjë dhe do të kishim korrespondencën:
 statementet përbëjnë trupin e funksionit. Trupi i funksionit është një bllok statementesh të
futur në kllapat { }. Në shembullin e mësipërm ky bllok statementesh është:
{
int s;
s = a + b;
return s;
}
Tani mund të kuptojmë më mirë strukturën main që kemi përmëndur dhe më parë. main vetë
nuk është gjë tjetër veçse një funksion që kthen një vlerë int.
Duhet të kujtojmë që një program në C++ gjithmonë fillon me ekzekutimin e funksionit main.
Në pikën ku funksioni shuma thirret në main, kontrolli kalon nga main në funksionin shuma.
Vlerat e dy argumenteve që kalojnë në thirrjen e funksionit si (a dhe b) kopjohen në variablat a
dhe b që kuptohen si variabla lokale për funksionin shuma.
Rreshti
cout<< "shuma e a, b: " << rezultat << endl;
afishon rezultatin e veprimit.
Shembull i një funksioni pa parametra
Shembullin e mësipërm mund ta trajtonim dhe me një funksion pa parametra, si më poshtë:
Kodi burim Rezultati gjatë ekzekutimit
//ky program gjen shumen e dy numrave
//duke përdorur një thirrje funksioni,
//shih përcaktimin e funksionit shuma
#include <iostream>
using namespace std;
//percaktimi i funksionit shuma()
int shuma()
{
int a, b, s;
cout << "Futni vlerat e a, dhe b n";
cin >> a >> b;
s=a+b;
return (s);
}
int main ()
{
Futni vlerat e a, dhe b
1
2
shuma e a, b: 3
int rezultat;
rezultat= shuma();
cout<< "shuma e a, b: " << rezultat << endl;
return 0;
}
Figura 17. 4 Llogaritja e shumës së dy numrave të plotë duke përdorur një funksion pa parametra
Fusha e Veprimit të Variablave
Fusha e veprimit të variablave të deklaruar në funksion ashtu si dhe në një bllok tjetër të
brendshëm {} është vet ky funksion ose bllok dhe ato nuk mund të përdoren jashtë tyre. Në
shembullin e mësipërm, fig 17. 4, do të ishte i pamundur përdorimi i variablave a, b në
funksionin main mbasi ata janë variabla lokalë për funksionin shuma, dhe nuk ekzistojnë jashtë
tij. Figura 17. 5 bën një përmbledhje të rasteve të ndryshme të fushës së veprimit të variablave në
varësi të faktit se ku ata deklarohen në një program.
Le të ilustrojmë me disa shembuj fushën e veprimit të variablave në raste të ndryshme:
Një variabël lokal: nuk ekziston më jashte bllokut ku është deklaruar Ekzekutimi
# #include <iostream>
using namespace std;
int ShtoDhePrinto()
{
int vlera = 1; // variabel lokal
++vlera;
return vlera;
} // vlera nuk ekziston me
int main()
{
int rezultat;
rezultat = ShtoDhePrinto();
cout << "vlera= " << rezultat << endl;
rezultat = ShtoDhePrinto();
cout << "vlera= " << rezultat << endl;
return 0;
}
2
2
Një variabël global: është i vlefshëm kudo në program Ekzekutimi
#include <iostream>
using namespace std;
int vlera = 1; // variabel global
int ShtoDhePrinto()
{
++vlera;
return vlera;
} // vlera nuk ekziston me
2
3
int main()
{
int rezultat;
rezultat = ShtoDhePrinto();
cout << "vlera= " << rezultat << endl;
rezultat = ShtoDhePrinto();
cout << "vlera= " << rezultat << endl;
return 0;
}
Figura 17.5 Fusha e veprimit të variablave
Duhet të dimë se, fusha e veprimit të variablave lokalë kufizohet brenda bllokut ku ata
deklarohen. Megjithatë, ne e kemi mundësinë e deklarimit të variablave globalë; ata janë të
aksesueshëm nga çdo pikë e kodit brenda dhe jashtë funksioneve. Që të përdorim një variabël
global, duhet ta deklarojmë atë jashtë çdo funksioni ose blloku, fig 17. 5, shembulli i dytë.
Ribëjmë shembullin në fig 17.4 duke shtuar atje një variabël global që përdoret sa herë llogaritet
shuma e dy numrave.
Kodi burim Rezultati gjatë ekzekutimit
//ky program gjen shumen e dy numrave
//duke përdorur një thirrje funksioni,
//ky veprim përsëritet 5 herë
#include <iostream>
using namespace std;
int numerator = 0;
//percaktimi i funksionit shuma()
int shuma()
{
int a, b, s;
cout << "Futni vlerat e a, dhe b n";
cin >> a >> b;
s=a+b;
numerator++; //shtohet me nje numroatori
return (s);
}
int main ()
{
int rezultat;
while(numerator < 5){
rezultat= shuma();
cout<< "shuma e a, b: " << rezultat << endl;
}
Futni vlerat e a, dhe b
1
2
shuma e a, b: 3
Futni vlerat e a, dhe b
10
25
shuma e a, b: 35
Futni vlerat e a, dhe b
15
17
shuma e a, b: 32
Futni vlerat e a, dhe b
11
22
shuma e a, b: 33
Futni vlerat e a, dhe b
32
43
shuma e a, b: 75
return 0;
}
Figura 17.6 Shembull përdorimi i variablave lokale dhe globalë
Shohim në fig 17.6 përdorimin e variablit global numrator, që është deklaruar jashtë çdo
funksioni dhe është inicializuar me vlerën 0. Vemë re se ky variabël njihet nga të dy funksionet
që janë në këtë program, funksioni main dhe shuma.
Ushtrim:
1. Realizoni një program që afishon vlerën e produkteve të një magazine sipas modelit të
shembullit të mësipërm. Përdorni një variabël global që tregon numrin e produktit të afishuar.
Funksionet pa tip. Përdorimi i void.
Siç dhe e pamë më sipër sintaksa e deklarimit të një funksioni
tipi emri( parameter1, parameter2, ...) { statemente }
fillon me një tip, që është tipi i vet funksionit (d.m.th tipi i të dhënës që kthehet nga funksioni me
statementin return). Po çfarë ndodh kur ne nuk duam të kthejmë një vlerë?
Së pari kur mund të paraqitet një rast i tillë, pra kur duam një funksion i cili të mos na kthejë
asnjë vlerë ? Një rast i tillë do të ishte kur ne i japim funksionit si detyrë, për shembull, të bëjë
afishime. Kur funksioni nuk kthen vlerë, tipi i kthimit për funksionin duhet të jetë void, për
shembull:
Kodi burim
Rezultati gjatë ekzekutimit
// shembull i nje funksioni void
#include <iostream>
using namespace std;
void printim_mesazhi ()
{
cout << "Nje funksion void!";
}
int main ()
{
printim_mesazhi();
return 0;
}
Nje funksion void!
Figura 17. 7 Një funksion që nuk kthen vlerë, tipi i kthimit është void
Le të ribëjmë ndryshe shembullin e mësipërm fig 17.6 duke synuar që për afishimin e rezultatit
të përdorim një tjetër funksion të cilin po e quajmë afishim.
Kodi burim Rezultati gjatë
Ekzekutimit
//ky program gjen shumen e dy numrave
//duke përdorur një thirrje funksioni,
//ky veprim përsëritet 5 herë
#include <iostream>
using namespace std;
int numerator = 0;
//percaktimi i funksionit shuma()
int shuma()
{
int a, b, s;
cout << "Futni vlerat e a, dhe b n";
cin >> a >> b;
s=a+b;
numerator++; //shtohet me nje numroatori
return (s);
}
void afishim (int r){
cout<< "shuma e a, b: " << r << endl;
}
int main ()
{
int rezultat;
while(numerator < 5){
rezultat= shuma();
afishim(rezultat);
}
return 0;
}
Futni vlerat e a, dhe b
1
2
shuma e a, b: 3
Futni vlerat e a, dhe b
10
25
shuma e a, b: 35
Futni vlerat e a, dhe b
15
17
shuma e a, b: 32
Futni vlerat e a, dhe b
11
22
shuma e a, b: 33
Futni vlerat e a, dhe b
32
43
shuma e a, b: 75
Figura 17. 8 Afishimi i rezultatit i organizuar në një funksion void
Në fig 17.8 afishimi i rezultatit të programit 17.6 është vendosur në funksionin afishim me tip
kthimi void.
void afishim (int r){
cout<< "shuma e a, b: " << r << endl;
}
Vemë re se një funksion me tip kthimi void nuk mund të kombinohet me statementin cout,
mbasi një funksion i tillë nuk kthen vlerë, si rrjedhim ai thjesht thirret si në fig. 17.8
Çfarë duhet gjithmonë të kujtojmë është se formati i thirrjes së një funksioni përfshin emrin e tij
dhe parametrat brenda parantezave. Kur nuk kemi parametra, parantezat do të shkruhen, por në
këtë rast pa parametra brenda tyre, për shembull:
shuma(a,b) // kodi ne Fig. 17.3
afishim(); // kodi ne Fig 17.8
parantezat tregojnë që kemi të bëjmë me një thirrje funksioni dhe jo me emrin e një variabli në
Rekursiviteti
Është një mënyrë zgjidhje problemi që e kalon atë në një version më të thjeshtë të problemit
origjinal dhe kjo gjë vazhdon në disa hapa. Kur themi version më të thjeshtë, kuptohet një vlerë
më e vogël parametri deri në një vlerë që provokon dhe fundin e këtij procesi rekursiv. Marrim si
shembull llogaritjen e faktorialit e një numri (n!). Formula matematike është:
n! = n * (n-1) * (n-2) * (n-3) ... * 1
më konkretisht, 5! (faktoriali i 5) do të ishte:
5! = 5 * 4 * 3 * 2 * 1 = 120
Vemë re se mund të shkruajmë :
n! = n * (n – 1)! , duke e shënuar n! me f(n), mund të shkruajmë:
f(n) = n * f(n-1)
Pra f(n-1) nuk është gjë tjetër vetëm një version më i thjeshtuar i f(n), nga pikëpamja e vlerës së
parametrit të tij.
Kjo është dhe esenca e mënyrës rekursive të një problem.
Më poshtë jepet kodi i dy mënyrave të ndryshme që mund të përdorim për zgjidhjen e n!. Një
mënyrë është ajo që ne kemi përdorur deri tani për zgjidhjen e një problem të tillë dhe që e
quajmë iterative dhe një mënyrë është mënyra rekursive.
Mënyra iterative Mënyra rekursive
// Programi llogarit n!
#include <iostream>
using namespace std;
long faktorial(int n)
{
int k;
long rezultat = 1;
for (k = 2; k <= n; k++)
rezultat = rezultat * k;
return rezultat;
}
int main ()
{
int n;
cout << "fusni nje vleren";
cin >> n;
// Programi llogarit n!
#include <iostream>
using namespace std;
long faktorial(int n)
{
if (n==1)
return 1;
else
return n * faktorial(n-1);
}
int main ()
{
int n;
cout << "fusni nje vlere:n";
cin >> n;
cout << " n!: "
cout << " n!: " << faktorial(n)
<<endl;
return 0;
}
fusni nje vlere: 5
n!: 120
<< faktorial(n) <<endl;
return 0;
}
fusni nje vlere: 5
n!: 120
Figura 17. 9 Një zgjidhje iterative(majtas) dhe një zgjidhje rekursive (djathtas) e faktorialit
Vemë re se në funksionin faktorial (në rastin rekursiv) është përfshirë një thirrje e atij vetë,
por vetëm në se argumenti që kalon është më i madh se 1, përndryshe funksioni ndalon.
Përcaktimi i një alternative ndalimi të vlerës së argumentit është esencial për rekusivitetin,
përndryshe do të krijonim një process pa fund.
Ky funksion ka një kufizim për arsye të tipit të të dhënave të përdorura në dezinjimin e tij (long)
për më thjeshtësi. Rezultati i marrë nuk do të jetë i vlefshëm për vlerat shumë më të mëdha se
10! ose 15!, në varësi të sistemit ku ne e kompilojmë atë.
Si realizohet procesi i rekursivitetit:
Figura 17. 10 Zgjidhja rekursive e 5!
Deklarimi i funksioneve
Deri tani kemi parë raste kur përcaktimi i funksionit bëhet para funksionit main ose para
funksionit ku ai thirret, ose funksioni mund të deklarohet si prototip para funksionit ku ai thirret
dhe përcaktohet pas funksionit main duke e lënë këtë të fundit si funksion të parë në kodin
burim. Të dy variantet janë të mundshëm. Ajo që duhet të kemi parasysh është që një funksion
nuk mund të thirret në se nuk është përcaktuar ose deklaruar më parë.
Më shpesh ne përdorim mënyrën e dytë d.m.th. deklarohet prototipi i funksionit para thirrjes së
tij dhe poshtë funksionit ku ai thirret bëhet përcaktimi i tij.
Forma e deklarimit të një funksioni është:
tipi emri ( tipi_argumentit1, tipi_argumentit2, ...);
Gjuha c++

More Related Content

What's hot

Sistemi Kompjuterik
Sistemi KompjuterikSistemi Kompjuterik
Sistemi KompjuterikMagribe
 
Borxhi publik dhe deficiti buxhetor ne Shqiperi
Borxhi publik dhe deficiti buxhetor ne ShqiperiBorxhi publik dhe deficiti buxhetor ne Shqiperi
Borxhi publik dhe deficiti buxhetor ne ShqiperiDarla Evangjeli
 
Segmentimi i tregut dhe pozicionimi
Segmentimi i tregut dhe pozicionimiSegmentimi i tregut dhe pozicionimi
Segmentimi i tregut dhe pozicionimiHekuran Zogaj
 
Pyetje me pergjigje nga informatika
Pyetje me  pergjigje nga  informatikaPyetje me  pergjigje nga  informatika
Pyetje me pergjigje nga informatikaDritan Halimi
 
Tema d iplomes nehat duraku
Tema d iplomes nehat durakuTema d iplomes nehat duraku
Tema d iplomes nehat durakuNehat Duraku
 
Kompjuteri, Historiku i tij dhe pjeset harduerike te tij ( CPU - Mikroproces...
Kompjuteri,  Historiku i tij dhe pjeset harduerike te tij ( CPU - Mikroproces...Kompjuteri,  Historiku i tij dhe pjeset harduerike te tij ( CPU - Mikroproces...
Kompjuteri, Historiku i tij dhe pjeset harduerike te tij ( CPU - Mikroproces...Lirim Jahiu
 
Makroekonomia - BPV- Bruto Produkti Vendor
Makroekonomia - BPV- Bruto Produkti Vendor Makroekonomia - BPV- Bruto Produkti Vendor
Makroekonomia - BPV- Bruto Produkti Vendor Menaxherat
 
Njesite hyrse dhe dalese te Kompjuterit ©
Njesite hyrse dhe dalese te Kompjuterit ©Njesite hyrse dhe dalese te Kompjuterit ©
Njesite hyrse dhe dalese te Kompjuterit ©Lirim Jahiu
 
Ndërtimi i bazës së të dhënave në programin Access
Ndërtimi i bazës së të dhënave në programin AccessNdërtimi i bazës së të dhënave në programin Access
Ndërtimi i bazës së të dhënave në programin AccessRexhino Kovaci
 
Programi festa e abetares. agime komplet
Programi festa e abetares. agime kompletProgrami festa e abetares. agime komplet
Programi festa e abetares. agime kompletAberi Kajo
 

What's hot (20)

Plan biznesi
Plan biznesi Plan biznesi
Plan biznesi
 
Bazat e programimit ne C++ (agni dika)
Bazat e programimit ne C++  (agni dika)Bazat e programimit ne C++  (agni dika)
Bazat e programimit ne C++ (agni dika)
 
Makroekonomia slides
Makroekonomia slidesMakroekonomia slides
Makroekonomia slides
 
Inflacioni ne shqiperi
Inflacioni ne shqiperi Inflacioni ne shqiperi
Inflacioni ne shqiperi
 
Sistemi Kompjuterik
Sistemi KompjuterikSistemi Kompjuterik
Sistemi Kompjuterik
 
Borxhi publik dhe deficiti buxhetor ne Shqiperi
Borxhi publik dhe deficiti buxhetor ne ShqiperiBorxhi publik dhe deficiti buxhetor ne Shqiperi
Borxhi publik dhe deficiti buxhetor ne Shqiperi
 
Segmentimi i tregut dhe pozicionimi
Segmentimi i tregut dhe pozicionimiSegmentimi i tregut dhe pozicionimi
Segmentimi i tregut dhe pozicionimi
 
Pyetje me pergjigje nga informatika
Pyetje me  pergjigje nga  informatikaPyetje me  pergjigje nga  informatika
Pyetje me pergjigje nga informatika
 
Tema d iplomes nehat duraku
Tema d iplomes nehat durakuTema d iplomes nehat duraku
Tema d iplomes nehat duraku
 
Kompjuteri, Historiku i tij dhe pjeset harduerike te tij ( CPU - Mikroproces...
Kompjuteri,  Historiku i tij dhe pjeset harduerike te tij ( CPU - Mikroproces...Kompjuteri,  Historiku i tij dhe pjeset harduerike te tij ( CPU - Mikroproces...
Kompjuteri, Historiku i tij dhe pjeset harduerike te tij ( CPU - Mikroproces...
 
Plan biznesi
Plan biznesiPlan biznesi
Plan biznesi
 
Figurat letrare
Figurat letrareFigurat letrare
Figurat letrare
 
Makroekonomia - BPV- Bruto Produkti Vendor
Makroekonomia - BPV- Bruto Produkti Vendor Makroekonomia - BPV- Bruto Produkti Vendor
Makroekonomia - BPV- Bruto Produkti Vendor
 
PROJEKT-Ndotja e Mjedisit
PROJEKT-Ndotja e MjedisitPROJEKT-Ndotja e Mjedisit
PROJEKT-Ndotja e Mjedisit
 
Njesite hyrse dhe dalese te Kompjuterit ©
Njesite hyrse dhe dalese te Kompjuterit ©Njesite hyrse dhe dalese te Kompjuterit ©
Njesite hyrse dhe dalese te Kompjuterit ©
 
Ndërtimi i bazës së të dhënave në programin Access
Ndërtimi i bazës së të dhënave në programin AccessNdërtimi i bazës së të dhënave në programin Access
Ndërtimi i bazës së të dhënave në programin Access
 
Plan biznesi
Plan biznesiPlan biznesi
Plan biznesi
 
Memoria RAM-ROM
Memoria RAM-ROMMemoria RAM-ROM
Memoria RAM-ROM
 
Programi festa e abetares. agime komplet
Programi festa e abetares. agime kompletProgrami festa e abetares. agime komplet
Programi festa e abetares. agime komplet
 
Cikli i Krebsit
Cikli i KrebsitCikli i Krebsit
Cikli i Krebsit
 

Similar to Gjuha c++

C++ Workshop Presentation
C++ Workshop PresentationC++ Workshop Presentation
C++ Workshop PresentationOrven Bregu
 
Visual basic leksionet e mia
Visual basic leksionet e miaVisual basic leksionet e mia
Visual basic leksionet e miaMarkelian Laho
 
teknologjia informative / Ligjerata 5
teknologjia informative / Ligjerata 5teknologjia informative / Ligjerata 5
teknologjia informative / Ligjerata 5ilir 1122
 
PHP Day at UNICEF Lab of Kosova
PHP Day at UNICEF Lab of KosovaPHP Day at UNICEF Lab of Kosova
PHP Day at UNICEF Lab of KosovaFlamur Mavraj
 
Bazat e programimit ne c++
Bazat e programimit ne c++Bazat e programimit ne c++
Bazat e programimit ne c++Xhelal Bislimi
 
Deyrat e portofolit te Tik me Zgjedhje 12 Semestri i 1
Deyrat e portofolit te Tik me Zgjedhje 12 Semestri i 1Deyrat e portofolit te Tik me Zgjedhje 12 Semestri i 1
Deyrat e portofolit te Tik me Zgjedhje 12 Semestri i 1Rexhino Kovaci
 
Deyrat e portofolit te Tik me Zgjedhje
Deyrat e portofolit te Tik me Zgjedhje Deyrat e portofolit te Tik me Zgjedhje
Deyrat e portofolit te Tik me Zgjedhje Rexhino Kovaci
 
Programimi 1
Programimi 1Programimi 1
Programimi 1tushi8
 
Softveri sistemor informatike biznesore
Softveri sistemor informatike biznesoreSoftveri sistemor informatike biznesore
Softveri sistemor informatike biznesoreValdet Shala
 
software hardware
software hardwaresoftware hardware
software hardwareFred Kapo
 

Similar to Gjuha c++ (20)

Leksion_C.ppt
Leksion_C.pptLeksion_C.ppt
Leksion_C.ppt
 
C++ Workshop Presentation
C++ Workshop PresentationC++ Workshop Presentation
C++ Workshop Presentation
 
Visual basic leksionet e mia
Visual basic leksionet e miaVisual basic leksionet e mia
Visual basic leksionet e mia
 
teknologjia informative / Ligjerata 5
teknologjia informative / Ligjerata 5teknologjia informative / Ligjerata 5
teknologjia informative / Ligjerata 5
 
ligjerata.ppt
ligjerata.pptligjerata.ppt
ligjerata.ppt
 
ligjerata.ppt
ligjerata.pptligjerata.ppt
ligjerata.ppt
 
PHP Day at UNICEF Lab of Kosova
PHP Day at UNICEF Lab of KosovaPHP Day at UNICEF Lab of Kosova
PHP Day at UNICEF Lab of Kosova
 
Hyrje_Leksion_PDF-1.pdf
Hyrje_Leksion_PDF-1.pdfHyrje_Leksion_PDF-1.pdf
Hyrje_Leksion_PDF-1.pdf
 
Bazat e programimit ne c++
Bazat e programimit ne c++Bazat e programimit ne c++
Bazat e programimit ne c++
 
Ligjerata 5
Ligjerata 5Ligjerata 5
Ligjerata 5
 
Programim - Shqip
Programim - ShqipProgramim - Shqip
Programim - Shqip
 
Softwaret
SoftwaretSoftwaret
Softwaret
 
Deyrat e portofolit te Tik me Zgjedhje 12 Semestri i 1
Deyrat e portofolit te Tik me Zgjedhje 12 Semestri i 1Deyrat e portofolit te Tik me Zgjedhje 12 Semestri i 1
Deyrat e portofolit te Tik me Zgjedhje 12 Semestri i 1
 
Deyrat e portofolit te Tik me Zgjedhje
Deyrat e portofolit te Tik me Zgjedhje Deyrat e portofolit te Tik me Zgjedhje
Deyrat e portofolit te Tik me Zgjedhje
 
Softveri sistemor
Softveri sistemorSoftveri sistemor
Softveri sistemor
 
Programimi 1
Programimi 1Programimi 1
Programimi 1
 
Softveri sistemor informatike biznesore
Softveri sistemor informatike biznesoreSoftveri sistemor informatike biznesore
Softveri sistemor informatike biznesore
 
geogebra.pptx
geogebra.pptxgeogebra.pptx
geogebra.pptx
 
geogebra
 geogebra geogebra
geogebra
 
software hardware
software hardwaresoftware hardware
software hardware
 

Gjuha c++

  • 1. Hyrje në Algoritmikë Kur blejmë një kompjuter, ne nuk do të mundnim të komunikonim me të në se kompjuteri nuk do të ishte paisur me një bashkësi programesh që quhet sistemi operativ i kompjuterit. Një nga më të njohurit është sistemi Windows, që është sistemi që ne njohim në kompjuterat tanë personalë dhe në ata që kemi në shkollat tona. Kompjuteri përbëhet atëhere nga pjesa fizike e tij që quhet harware-i i kompjuterit, si dhe nga bashkësia e programeve që përbën software-in e tij. Që të kuptojmë si funksionon një program në kompjuter duhet të kemi një ide mbi hardware-in e kompjuterit dhe pikërisht figura 1. 1 na jep një pamje të përgjithëshme të tij. Kompjuteri ka pjesën qëndrore që përbëhet nga procesori dhe kujtesa (qëndrore dhe sekondare), ka paisjet hyrëse të tij siç janë tastjera, USB, hard disku, si dhe pjesët dalëse siç janë monitori dhe mund të jenë përsëri USB, hard disku ose printeri. Figura 1. 1 Pjesët kryesore të kompjuterit Kur kompjuteri ekzekuton një program, të gjithë pjesët hardware-ike të tij vihen në punë. Programi dhe të dhënat futen nga paisjet hyrëse dhe vendosen në kujtesë, procesori proceson instruksionet e programit. Po përveҫ programeve që kompjuteri ka kur blihet, ne mund të hartojmë programet tona duke e pasuruar kështu pjesën softwarike të kompjuterit. Ç ’është një program dhe si duhet të mendojmë para se të shkruajmë një program? Materiali i këtij teksti është një ndërthurje e këtyre dy apekteve, pra si mendojmë ne për të zgjidhur një problem në kompjuter dhe si e realizojmë atë me një program në gjuhën e programimit C++. Kur fillojmë të mësojmë një gjuhë programimi, mund të na duket se pjesa më e vështirë e zgjidhjes së një problemi në kompjuter është të shprehurit e ideve tona në gjuhën e programimit.
  • 2. Në fakt, pjesa më e rëndësishme në procesin e zgjidhjes së një problemi është gjetja e metodës së zgjidhjes së problemit. Në këtë fazë të punës ne nuk kemi pse të mendojmë fare për gjuhën me të cilën do të punojmë në kompjuter, por ne duhet të jemi në gjëndje të shprehim me fjalët tona rradhën e hapave që duhet të ndjekim për të zgjidhur një problem të caktuar. Këto hapa do ti mendonim si instruksione që mund tja jepnim një personi se sa një kompjuteri. Dhe pikërisht kjo rradhë instruksionesh që do të realizonin zgjidhjen e një problemi quhet algoritëm dhe mënyra e të shprehurit të tij me fjalët tona quhet pseudokod. Algoritmi shpreh mënyrën si ne e konceptojmë zgjidhjen e një problemi. Ne mund ta paraqesim atë në mënyra të ndryshme, me fjalët tona (pseudokodi), ose me simbole (bllokskema). Gjuha e programimit na ndihmon që pseudokodin ose bllokskemën tja shprehim kompjuterit në një mënyrë të kuptueshme për të, ose në formën e kodit burim të një programi. Po ç’është instruksioni për kompjuterin? Një instruksion është një komandë bazike për të cilën ekziston një mekanizëm hardware-i që e ekzekuton atë. Kompjuteri është një makinë programuese e dezinjuar të ekzekutojë instruksione. Programi përbëhet nga instruksione, dhe kur themi programi ekzekutohet, këto instruksione janë në kujtesë dhe ekzekutohen. Në fakt kur ne shkruajmë atë që quajmë kod burim të një programi ne nuk shkruajmë instruksione, por një bashkësi të tërë instruksionesh njëherësh, si një rresht të kodit burim që e quajmë statement. Këtë lehtësi na e japin gjuhët e programimit të nivelit të lartë siç është dhe gjuha C++. Kompjuteri ekzekuton vetëm instruksionet në formën binare të tyre (me zero dhe njësha), ose themi instruksionet të shprehura në gjuhën makinë si për shembull: 1011010000000101 Gjuha makinë ose gjuhë të afërta me të quhen gjuhë të nivelit të ulët. Eshtë vështirë të shkruajmë kodin burim të një programi në gjuhë të nivelit të ulët, mbasi gjuhë të tilla përshkruajnë në detaje çdo komandë që kompjuterit i duhet të ekzekutojë për të zgjidhur një problem. Në vend që të shkruhen programe në gjuhën makinë, përdoren gjuhët e programimit të nivelit të lartë dhe janë kompilatorët ata që e kthejnë kodin burim në gjuhën makinë, që dhe ata vetë janë programe të kompjuterit. Ka disa gjuhë programimi të nivelit të lartë si C, C++, Java, C#, Python etj. Në këtë tekst ne do të punojmë në gjuhën e programimit C++, që mund të konsiderohet si një gjuhë që ka edhe elementë të një gjuhe të nivelit të ulët dhe njëkohësisht është gjuhë e nivelit të lartë. Siç shihet dhe nga Figura 1. 1 hyrja në kompjuter mund të mendohet nga dy pjesë, një program dhe të dhënat. Kompjuteri ndjek instruksionet e programit të cilat përdorin dhe disa të dhëna hyrëse të nevojshme që programi të realizojë veprimet e tij. Për shembull një program mbledh dy numra, atëhere këta dy numra janë të dhënat.
  • 3. Figura 1. 2 Pamje e thjeshtë e ekzekutimit të programit Me fjalë të tjera të dhënat janë të dhënat hyrëse për programin, dhe programi bashkë me të dhënat, janë hyrja për kompjuterin dhe themi kompjuteri ekzekuton programin mbi të dhënat. Kompilatori Thamë që kompilatorët janë programe që përkthejnë kodin burim në gjuhë makine. Pra hyrja në një kompilator është një program dhe dalja është përsëri një program por në një formë tjetër. Programin hyrës ne zakonisht e quajmë programi burim ose kodi burim dhe daljen e quajmë programin objekt ose kodi objekt. Kodi objekt përbëhet nga instruksione që makina mund ti ekzekutojë. Figura 1. 2 paraqet procesin e përkthimit të kodit burim të një programi: Figura 1. 3 Kompilimi dhe Ekzekutimi i programit C++
  • 4. Linker-i Duhet të dimë që para se programi të ekzekutohet, programit objekt që kompilatori prodhon nga program burim, I shtohen dhe pjesë të tjera të cilat na ofrohen nga ata që e kanë krijuar gjuhën C++ duke e lehtësuar kështu punën tonë. Lidhja e programit të shkruar nga ne dhe atyre pjesëve të cilat na jepen të gatëshme realizohet me një tjetër program që quhet linker. Atëhere një skemë e përgjithëshme e ndërveprimit të kompilatorit dhe linkerit do të jepej nga figura 1. 3 Figura 1. 4 Pergatitja e një programi C++ për tu ekzekutuar Është sistemi operativ që bën të mundur komunikimin tonë me të gjitha paisjet hyrëse dhe dalëse të kompjuterit. Një nga detyrat e sistemit operativ është dhe ekzekutimi i programeve që ne vetë krijojmë. 2. Pseudokodi,bllokskemat dhe simbolikae tyre Programimi i një “Kompjuteri Njeri (Roboti)” Për të krijuar idenë e një algoritmi, të pseudokodit me të cilin algoritmi shprehet, si dhe të kthimit të tij në një program i cili është i kuptueshëm nga kompilatori marrim si shembull një problem praktik që e shtrojmë për zgjidhje: ndërrimin e rrotës së makinës. Supozojmë se qëllimi ynë do të ishte krijimi i një mekanizmi “njeriu robot” që do të realizonte veprimet e kërkuara për ndërrimin e një rrote makine. Algoritmi
  • 5. Instruksionet për ndërrimin e rrotës të shprehura në gjuhën e zakonshme janë si vijojnë: 1. Ngrihet makina. 2. Hiqen vidat qe fiksojnë rrotën difektoze të makinës. 3. Hiqet rrota. 4. Montohet rrota e re. 5. Vendosen vidat. 6. Zbritet makina. Ky është një algoritëm i paraqitur me një pseudokod. Para se të shkruajmë një program, na duhet një gjuhë të cilën do të biem dakort të përdorim dhe që kuptohet nga roboti.. Në këtë tekst ne do të përdorim gjuhën C++ por për shembullin e mësipërm do përdorim një gjuhë të krijuar apostafat për këtë problem, gjuha e ndërimit të rrotave, dhe që shkurtimisht po e quajmë GNR. GNR përfshin disa emra të përgjithshëm të përdorur në fjalorin e ndërrimit të rrotave. makinë rrotë vidë krik kuti e veglave rrotë rezerve xhiro-makine, kryq GNR gjithashtu përfshin dhe foljet që vijojnë: merr vendos lësho rrotullo Së fundi procesori që do të ekzekutojë GNR duhet të ketë aftësinë të numërojë dhe të marrë vendime të thjeshta. Kjo është gjithshka që një robot i ndrërrimit të rrotave kupton. Çdo gjë tjetër është e pakuptueshme nga roboti i ndërrimit të rrotave. Programi Tani është momenti të konvertojmë algoritmin në gjuhën e kuptueshme nga roboti. Duke analizuar rresht për rresht algoritmin, shohim që fraza “Hiqen vidat” ka mbetur e papërcaktuar, mbasi folja “heq” nuk është në fjalorin e procesorit. Hapat që vijojnë shprehin frazën “hiqen vidat” duke përdorur vetëm emrat që përmbahen në gjuhën e kuptueshme nga roboti: 1. merr xhiro-makinën 2. vendos xhiro-makinën te vidat 3. rrotulloj xhiro-makinën pesë herë. 4. vendos xhiro-makinën te kutia e veglave. 5. lësho xhiro-makinen
  • 6. Ketu nuk po marrim parasysh detajet e sintaksës së gjuhës, d.m.th rasat e ndryshme të emrave dhe kohët e foljeve si dhe nyjet e ndryshme që mund të përdoren. Por kur do të përdorim C++ do të kemi rregulla plotësisht të përcaktuara të saj. Programi fillon në Hapin 1 dhe vazhdon me hapat e tjera derisa të arrijë në Hapin 5. Në terminologjinë e programit ne themi, program ecën nga Hapi 1 deri në hapin 5. Çdo hap përfaqësohet në një gjuhë programimi me një statement. Natyrisht probleme të tjera mund të ngrihen: çfarë do të ndodhë në se nuk ka vida? Në këtë rast ne na nevojitet një statement “nëse” si vijon: 1. merr xhiro-makinën 2. nese vida është present 3. { 4. vendos xhiro-makinën te vida. 5. rrotullo xhiro-makinën pesë herë në të kundërt të akrepit të orës. 6. } 7. vendos xhiro-makinën në kutinë e veglave. Programi fillon në hapin e parë si dhe më parë. Në hapin e dytë para se të vendosë xhiro- makinën sigurohet në se vidat janë present, në se kjo është e vërtetë, vazhdojnë Hapat 3, 4, dhe 5 si dhe më parë. Në se jo, program i kapërcen këta hapa dhe shkon drejt Hapit 7 duke kthyer xhiro-makinën në kutinë e veglave. Këtu ne kemi të bëjmë me një shprehje logjike “vida është present?” Kjo shprehje kthen ose një të vërtetë (true) (po vida është present) ose një jo të vërtetë (false) (jo, nuk ka vidë). Një shprehje është një tip statement-i që prodhon një vlerë, siç është shprehja 1 + 2. Një shprehje logjike kthen një vlerë true ose false. Kllapat ne GNR janë të nevojshme për t’i treguar programit cilat hapa duhen kapërcyer në se kondita nuk është true. Hapat 4 dhe 5 ekzekutohen vetëm në se kondita është true. Ky program i përmirësuar ka akoma një problem: si do të kuptohet që duhet të bëhen 5 rrotullime të xhiro-makinës për të hequr vidën? Si mund të realizojë programi më pak ose më shumë rrotullime sipas rastit? Një mënyrë është të shtojmë një tip statement-i i formës “përderisa nuk është plotësuar diçka”, vazhdo të testosh” në GNR. 1. merr xhiro-makinën 2. nese vida është present 3. { 4. vendos xhiro-makinen te vida. 5. perderisa (vida është në makinë) 6. { 7 rrotullo xhiro-makinën pesë herë në të kundërt të akrepit të orës. 8. } 9. } 10.vendos xhiro-makinën në kutinë e veglave. 11.lësho xhiro-makinën.
  • 7. Hapat 1 deri në 4 janë si më parë. Në Hapin 5, procesori duhet të marrë një vendim: vazhdon vida të jetë në makinë? Në hapin e parë duke supozuar që vida është në makinë, procesori do kalojë në hapin 7. Pas tij, programi kthehet në hapin 5 dhe përsërit testimin. Në se vida hiqet nga makina, kondita në Hapin 5 do të na kthejë një false. Ne këtë moment program do kalojë në hapin 9, dhe do të vazhdojë si më parë. Bllokskemat Janë bërë të zakonshme dy mënyra për të dokumentuar logjikën e një programi që është algoritmi. Këto janë bllokskema dhe pseudokodi. Ne do ti përdorim të dyja metodat në vijim. Zakonisht, bllokskema punon mirë për probleme të vogla dhe pseudokodi për probleme më komplekse. Disa nga simbolet përdorur në bllokskema janë paraqitur më poshtë: Fillimi ose mbarimi i programit, simboli terminal Hapat ku kryen llogaritje Veprimi i hyrjes ose daljes Marrja e vendimit dhe degëzimi Lidhësi i dy pjesëve të një programi Shirit manjetik Disk manjetik Lidhje me faqen tjejtër Vija të rrjedhës së algoritmit shenime afishim Figura 2. 1 Një listë simbolesh që përdoren në një bllokskemë Përdorimi i simbolit Terminal Ky simbol tregon një pikë fillimi dhe mbarimi të logjikës së një procesi. Fillo një process me simbolin Mbaro një process me simbolin fillim fund Figura 2. 2 Simbolet e fillimit dhe mbarimit të një procesi
  • 8. Një bllokskemë duhet të ketë vetëm një simbol fillimi dhe një simbol mbarimi të një procesi. Shohim më poshtë një shembull përdorimi korrekt të simbolit terminal dhe një shembull jo korrekt të përdorimit të tij.
  • 9. Fillimi dhe mbarimi në një kod C++ do të paraqitej si më poshtë: int main () // fillimi i programit { return 0; //fundi i programit } Figura 2.4 Fillimi dhe mbarimi në një kod programi në C++ Kjo është dhe struktura e një programi në C++. Kur një program C++ ekzekutohet, kontrolli fillon pikërisht nga rreshti: int main () dhe mbaron kur takon statementin return 0; Ne do ta quajmë main() një funksion dhe gjithshka brenda {} përbën trupin e funksionit ku vendosen statementet. Me return 0; do të kuptojmë se në mbarim të ekzekutimit të rregullt programi i kthen vlerën 0 sistemit operativ që është përgjegjës per ekzekutimin e programit dhe me që 0 është një vlerë e plotë përdoret int që shpreh faktin që kjo vlerë që kthehet është e plotë. Megjithatë, funksionet nuk janë objekt i këtij teksti. Përdorimi i vijës së rrjedhës së llogjikës dhe simbolit lidhës Qëllimi i vijës është të lidhë hapa të ndryshme në procesin logjik të një bllokskeme, ndërsa simboli i lidhësit përdoret për të lidhur dy ose më shumë vija për të ndjekur të njëjtën rrugë logjike. Vija e rrjedhës së logjikës paraqitet me një shigjetë me një kahe, ndërkohë që lidhësi paraqitet me një rreth. Figura e mëposhtme ilustron ç’ka thamë: Përdorim korrekt i simbolit terminal Përdorim jo korrekt I simbolit terminal fillim fund fund fillim fund fillim mbarim Figura 2. 3 Përdorimi korrekt dhe jo korrekt i simbolit terminal
  • 10. Figura 2. 5 Vija dhe lidhësi Më poshtë kemi disa përdorime jo të rregullta të vijave të rrjedhës së logjikës dhe të lidhësit ose mungesa të përdorimit të tyre: Figura 2. 6 Shembuj vijash dhe lidhësish Simbolet e Hyrje/Daljeve (input/output) Simbolet e tilla si dhe janë simbolet e leximit dhe shkrimit nga dhe në paisje të ndryshme p.sh. lexim nga një file, ose nga tasjera dhe shkrim p.sh. në monitorin e një kompjuteri. Një simbol hyrje përdoret për leximin e informacionit nga paisje të ndryshme. Veprimi specifik zakonisht përshkruhet si një veprim leximi duke hapur nje file ose nga tastjera. Është e rëndësishme të kuptohet që në se një veprim leximi kërkon informacionin që duhet të përdoret, bllokskema fillim fund Simboli i vijes lidh simbolet jo vija të rrjedhës së logjikës së një processi Simboli i lidhesit lidh dy ose më shumë vija të rrjedhës së logjikës. Jo korrekt mbasi nuk ka lidhës Perdorim korrekt i lidhesit fillim fund Një proces Një vije jo korrekte për arsye të dy drejtimeve
  • 11. duhet së pari të paraqesë një futje të dhënash (hyrje) që merr informacion për proceset e mëtejshëm. Disa paisje të përshkruara më poshtë mund të përdoren për veprimet hyrëse: • Një paisje rezervimi që përdoret si kujtesë sekondare. Shembuj paisjesh rezervimi janë hard- disqet, paisjet USB, disqet kompakte, ose disqet digitalë video. • Një tastjerë • Një monitor elektronik – kjo nuk është një paisje të zakonshme. Shpesh herë ai referohet si ekran i prekshëm Shembujt e mësipërm nuk janë të vetmet tipe të paisjeve hyrëse ose burimeve të të dhënave hyrëse. Më poshtë janë dy shembuj hyrës: një nga një përdorues dhe një nga një file. Nuk është e nevojshme të specifikohet burimi ose paisja. Megjithatë, për qartësi nganjëherë ata mund të specifikohen. Figura 2. 7 Leximi i informacionit Një simbol dalje përdoret për shkrim në paisje të ndryshme. Tipet specifikë të veprimeve përshkruhen si një veprim shkrimi, si shkrimi në një printer ose shkrim në file dhe mbyllje të tij. Eshtë e rëndësishme të vemë në dukje që disa paisje mund të jenë paisje hyrje dhe dalje. Për shembull, një ekran elektronik ose një paisje rezervimi mund të jenë edhe paisje hyrje edhe dalje. Ndërkohë ka disa paisje të ndryshme që mund të përdoren si paisje dalje: • Një paisje rezervimi të përshkruar më lart. • Një monitor elektronik. • Një printer. Shembull 1 Shembull 2 Fillim procesi Fund procesi Fillim procesi Fund procesi Lexohet emri nga tastjera Hapet file emri.dat tastjeara Lexohet emri nga tastjera Hapet file emri.dat Shembull 1 Shembull 2 Fillim procesi Fund procesi Fillim procesi Fund procesi Shkruhet një raport në printer mbyllet file emri.dat tastjeara Shkruhet një raport në printer mbyllet file emri.dat
  • 12. Figura 2. 8 Shkrimi i informacionit 3. Shprehjae algoritmeve nëpërmjet bllokskemave Le të shprehim nëpërmjet bllokskemave disa algoritme të thjeshtë. 3.1 Llogaritja e sipërfaqes së një ambienti në formë drejtkëndëshi me dimensione të përcaktuara Të shkruhet një algoritëm dhe të vizatohet një bllok-skemë që llogarit sipërfaqen e një ambienti me gjerësi 3.5 metra dhe gjatësi 5.7 metra. Pseudokodi:  Vendosen në kompjuter të dhënat hyrëse, që janë gjerësia dhe gjatësia e ambientit  llogaritet siperfaqja duke shumëzuar gjerësinë dhe gjatesinë  afishohet sipërfaqja Blloksema: Figura 3.1 Pseudokodi, bllokskema në llogaritjen e sipërfaqes se një ambienti. Siҫ e vemë re dhe nga pseudokodi dhe bllokskema, për zgjidhjen e një problemi, e para gjë që mendojmë janë të dhënat që do të duheshin për t’i dhënë problemit zgjidhje, pra veprimi i parë që bëjmë është vendosja e të dhënave në kujtesë. Duke patur të dhënat, realizojmë me to veprimin që duam të kryejmë dhe që në këtë rast është shumëzimi i të dhënave dhe rezultatin e kalojmë përsëri në një vend në kujtesë, që të jemi në gjendje më pas ta përdorim këte rezultat, dhe minimumi që mund të bëjmë është afishimi i tij në ekran. Duhet të jemi të ndërgjegjshëm që emrat që ne përdorim si gjeresi, gjatesi, siperfaqe, nuk janë gjë tjetër, por emërtime të vendeve të caktuara të kujtesës qëndrore të kompjuterit ku vendosen vlerat hyrëse ose rezultati. gjeresia=3.5 gjatesia=5.7 siperfaqja= gjeresia * gjatesia siperfaqja fund fillim
  • 13. 3.2 Llogaritja e sipërfaqes së një ambienti në formë drejtkëndëshi me dimensione të papërcaktuara Supozojmë se do të realizojmë një program që llogarit sipërfaqen e ҫdo ambienti në formë drejtkëndëshi. Në këtë rast gjatësia dhe gjerësia e ambientit nuk janë të paracaktuara, por ato kërkohen nga kompjuteri në momentin që programi ekzekutohet, pra ky fakt duhet shprehur në pseudokod ose në bllokskemë si më poshtë: Pseudokodi:  Afishohet një mesazh në ekran : “Sa është gjerësia? ”  Kompjuteri duhet të jetë në një gjendje pritjeje që ne të fusim gjerësinë.  Shkruajmë numrin, dhe ai vendoset në kujtesë.  Afishohet një mesazh në ekran : “Sa është gjatësia? ”  Kompjuteri duhet të jetë në një gjendje pritjeje që ne të fusim numrin përkatës.  Shkruajmë numrin, dhe ai vendoset në kujtesë.  Shumëzohen gjerësia dhe gjatësia të regjistruara tashmë në kujtesë.  Rezultati afishohet në ekran. Blloksema: Figura 3. 2 Pseudokodi, bllokskema në llogaritjen e sipërfaqes se një ambienti. Siҫ mund ta kuptojmë problemi i dytë është më i përgjithshëm se i pari, dhe zgjidhja e dhënë me algoritmin e mësipërm u jep përgjigje gjithë rasteve pavarësisht nga dimensionet konkrete. Futet gjatesia siperfaqja= gjeresia * gjatesia siperfaqja fund fillim Sa është gjerësia? Futet gjeresia Sa është gjatesia?
  • 14. 3.3 Llogaritja e sipërfaqes së një ambienti në formë drejtkëndëshi me dimensione që plotësojnë kushtet gjeresia ndodhet ne intervalin [2,3] dhe gjatesia ne intervalin [3,4] Pseudokodi:  Afishohet një mesazh në ekran : “Sa është gjerësia? ”  Kompjuteri duhet të jetë në një gjendje pritjeje që ne të fusim gjerësinë.  Shkruajmë numrin, dhe ai vendoset në kujtesë  Ne se gjerësia ndodhet jashte [2,3] afishojmë një mesazh “gjeresi jashte intervalit”dhe mbyllim programin.  Afishohet një mesazh në ekran : “Sa është gjatësia? ”  Kompjuteri duhet të jetë në një gjendje pritjeje që ne të fusim numrin përkatës.  Shkruajmë numrin dhe numri vendoset në kujtesë  Ne se gjatësia ndodhet jashte [2,3] afishojmë një mesazh “gjatesi jashte intervalit”dhe mbyllim programin.  Përndryshe shumëzohen gjerësia dhe gjatësia të regjistruara tashmë në kujtesë.  Rezultati afishohet në ekran. Blloksema: Figura 3. 3 Pseudokodi, bllokskema në llogaritjen e sipërfaqes se një ambienti. Siҫ e shohim dhe nga bllokskema, dallimi me shembulin e mëparshëm fig.3.2, qëndron në faktin se këtu kemi vendosur një konditë për të dhënat, gjë që e kemi shprehur me simbolet: Futet gjatesia siperfaqja= gjeresia * gjatesia siperfaqja fund fillim Sa është gjerësia? Futet gjeresia Sa është gjatesia? gjeresia< 2 ose gjerseia > 3 gjatesia< 3 ose gjateeia > 4 gjatesia< 3 ose gjateeia > 4 gjeresia< 2 ose gjerseia > 3 po po jo jo
  • 15. 3.4 Llogaritja e veprimeve me dy numra Supozojmë se do të realizojmë një program që kryen veprimet midis dy numrave dhe afishon rezultatin. Se pari komjuteri duhet të dijë numrat me të cilët ne do të veprojmë dhe së dyti do të dijë cilin veprim ne do të donim të kryenim me këta numra:
  • 16. Pseudokodi:  Afishohet një mesazh në ekran : “Numri i parë? ”  Kompjuteri duhet të jetë në një gjendje pritjeje që ne të fusim numrin.  Shkruajmë numrin, dhe ai vendoset në kujtesë.  Afishohet një mesazh në ekran : “Numri i dytë? ”  Kompjuteri duhet të jetë në një gjendje pritjeje që ne të fusim numrin përkatës.  Shkruajmë numrin, dhe ai vendoset në kujtesë.  Afishohet një mesazh në ekran : “Veprimi uaj? ”  Kompjuteri duhet të jetë në një gjendje pritjeje që ne të fusim simbolin që tregon veprimin: ‘+’, ’-‘, ’*’, ’/’. (do te shohim me pas se keto siombole perfaqësojnë veprimet arithmetike:mbledhje, zbritje, shumëzim, pjestim)  Shkruajmë simbolin e veprimit, dhe ai vendoset në kujtesë.  Në varësi të simbolit të veprimit, kryhet veprimi përkatës;kurveprimi është pjestimi (‘/’) duhet të sigurohemi që emëruesi është i ndryshëm nga zero.  Ne se emeruesi është zero mbyllim programin  Rezultati afishohet në ekran. Blloksema: Figura 3. 4 Pseudokodi, bllokskema në llogaritjen e veprimeve me dy numra. Futet numri i dytë rezultati = n1 / n2 rezultati fund fillim Numri i parë n1? Futet numri i pare Numri i dytë n2? Veprimi që kryhet? Veprimi=’+’ rezultati= n1+ n2 po jo Veprimi=’-’ rezultati= n1- n2 po jo Veprimi=’*’ rezultati= n1* n2 po jo Veprimi=’/’ jo n2 = 0? po
  • 17.
  • 18. 4. Algoritme me te avancuar me bllokskemat (ciklet) Shpesh zgjidhja e një problemi lidhet me përsëritjen e një hapi ose të disa hapave. Në këtë rast në programim përdoren ciklet për të cilët gjuhët e programimit, pra dhe gjuha C++, ka disa rregulla shkrimi. Të shohim si mund ti paraqesim ciklet në një pseudokod apo bllokskemë. Shohim disa shembuj. 4.1 Llogaritja e sipërfaqes së disa ambienteve: Në shembullin 3.2 të paragrafit të mësipërm supozojmë se duam të llogarisim sipërfaqen e secilit nga ambientet e një shtëpie, që ka dy dhoma, një kuzhinë dhe një koridor, dhe një banjë, pra gjithësej 5 ambiente. Pra llogaritja e sipërfaqes që ne bëmë në këtë shembull do të përsëritej 5 herë. Kemi në këtë rast një cikël me 5 hapa, ku në ҫdo hap të tij do të kryeshin të gjitha hapat e llogaritjes së sipërfaqes së një ambienti. Me një pseudokod dhe bllokskemë do të kemi këtë parasitke Pseudokodi:  Përsëriten hapat e mëposhtëm 5 herë:  Afishohet një mesazh në ekran : “Sa është gjerësia? ”  Kompjuteri duhet të jetë në një gjendje pritjeje që ne të fusim gjerësinë.  Shkruajmë numrin, dhe ai vendoset në kujtesë.  Afishohet një mesazh në ekran : “Sa është gjatësia? ”  Kompjuteri duhet të jetë në një gjendje pritjeje që ne të fusim numrin përkatës.  Shkruajmë numrin, dhe ai vendoset në kujtesë.  Shumëzohen gjerësia dhe gjatësia të regjistruara tashmë në kujtesë.  Rezultati afishohet në ekran. Blloksema: Figura 4. 1 Pseudokodi, bllokskema në llogaritjen e sipërfaqes se 5 ambienteve. Një element të rëndësishëm që vemë re në këtë shembull është akumulimi i një vlere te një vend në kujtesë dhe pikërisht te vendi i kujtesës i quajtur numrator. Fillimisht ai duhet të marrë një vlerë 0, dhe më pas kësaj vlere i shtohet 1 për ҫdo hap të ciklit. Kjo gjë do të siguronte që në një moment kjo vlerë të bëhet 5 dhe kjo gjë do ti jepte fund ciklit, ose përsëritjes së llogaritjeve. Përndryshe cikli nuk do të mbaronte së vepruari. Futet gjatesia siperfaqja= gjeresia * gjatesia siperfaqja fund fillim Sa është gjerësia? Futet gjeresia Sa është gjatesia? Fillojmë të numërojmë sa llogaritje kemi bere: numrator = 0 numratori = numratori + 1 nunratori < 5 po po
  • 19. 4.2 Llogaritja e shumës së sipërfaqeve të disa ambienteve: Pseudokodi:  I jepet totalit te siperfaqeve vlera 0  Përsëriten hapat e mëposhtëm 5 herë:  Afishohet një mesazh në ekran : “Sa është gjerësia? ”  Kompjuteri duhet të jetë në një gjendje pritjeje që ne të fusim gjerësinë.  Shkruajmë numrin, dhe ai vendoset në kujtesë.  Afishohet një mesazh në ekran : “Sa është gjatësia? ”  Kompjuteri duhet të jetë në një gjendje pritjeje që ne të fusim numrin përkatës.  Shkruajmë numrin, dhe ai vendoset në kujtesë.  Shumëzohen gjerësia dhe gjatësia të regjistruara tashmë në kujtesë.  Shtohet siperfaqja e gjetur në totalin e sipërfaqeve  Rezultati afishohet në ekran.  Afishohet totali i sipërfaqeve Blloksema: Figura 4. 2 Pseudokodi, bllokskema në llogaritjen e sipërfaqes se 5 ambienteve duke gjetur dhe shumën e sipërfaqeve. 4.2 Përsëritja e futjes së të dhënave kur ato janë jo korrekte Llogaritja e sipërfaqes Në 3.3 dhe 3.4 pamë se kur të dhënat nuk ishin korrekte, ose nuk plotësonin kushtet tona, ne e mbyllnim programin. Në fakt është mirë të mos e mbyllim programin por ti japim mundësi atij që e përdor atë, ti fusë përsëri të dhënat në mënyrë korrekte. Atëhere figurat 3.3 dhe 3.4 do të kishin ndryshime si në pseudokod ashtu dhe në bllokskemë: Futet gjatesia siperfaqja= gjeresia * gjatesia siperfaqja fund fillim Sa është gjerësia? Futet gjeresia Sa është gjatesia? Fillojmë të numërojmë sa llogaritje kemi bere: numrator = 0 totali = 0 numratori = numratori + 1 Totali= totali + siperfaqja nunratori < 5 po po Siperfaqja totali
  • 20. Pseudokodi: Cikël :përderisa gjerësia të jetë një vlerë brenda [2,3]  Afishohet një mesazh në ekran : “Sa është gjerësia? ”  Kompjuteri duhet të jetë në një gjendje pritjeje që ne të fusim gjerësinë.  Shkruajmë numrin, dhe ai vendoset në kujtesë Cikël :përderisa gjatësia të jetë një vlerë brenda [3,4]  Afishohet një mesazh në ekran : “Sa është gjatësia? ”  Kompjuteri duhet të jetë në një gjendje pritjeje që ne të fusim numrin përkatës.  Shkruajmë numrin dhe numri vendoset në kujtesë  Shumëzohen gjerësia dhe gjatësia të regjistruara tashmë në kujtesë.  Rezultati afishohet në ekran. Blloksema: Figura 4. 2 Pseudokodi, bllokskema në llogaritjen e sipërfaqes se një ambienti. Futet gjatesia siperfaqja= gjeresia * gjatesia siperfaqja fund fillim Sa është gjerësia? Futet gjeresia Sa është gjatesia? gjeresia< 2 ose gjerseia > 3 gjatesia< 3 ose gjateeia > 4 jo jo po po
  • 21. Veprimet me dy numra Pseudokodi:  Afishohet një mesazh në ekran : “Numri i parë? ”  Kompjuteri duhet të jetë në një gjendje pritjeje që ne të fusim numrin.  Shkruajmë numrin, dhe ai vendoset në kujtesë.  Afishohet një mesazh në ekran : “Numri i dytë? ”  Kompjuteri duhet të jetë në një gjendje pritjeje që ne të fusim numrin përkatës.  Shkruajmë numrin, dhe ai vendoset në kujtesë.  Afishohet një mesazh në ekran : “Veprimi uaj? ”  Kompjuteri duhet të jetë në një gjendje pritjeje që ne të fusim simbolin që tregon veprimin: ‘+’, ’-‘, ’*’, ’/’. (do te shohim me pas se keto siombole perfaqësojnë veprimet arithmetike:mbledhje, zbritje, shumëzim, pjestim)  Shkruajmë simbolin e veprimit, dhe ai vendoset në kujtesë.  Në varësi të simbolit të veprimit, kryhet veprimi përkatës;kurveprimi është pjestimi (‘/’) duhet të sigurohemi që emëruesi është i ndryshëm nga zero. Ne se veprimi ëthë pjesetim kryejmë një cikël: cikëli:  Përderisa emeruesi është zero përsrëritim futjen e tij.  Rezultati afishohet në ekran. Blloksema: Figura 4. 3 Pseudokodi, bllokskema në llogaritjen e veprimeve me dy numra. Futet numri i dytë rezultati = n1 / n2 rezultati fund fillim Numri i parë n1? Futet numri i pare Numri i dytë n2? Veprimi që kryhet? Veprimi=’+’ rezultati= n1+ n2 po jo Veprimi=’-’ rezultati= n1- n2 po jo Veprimi=’*’ rezultati= n1* n2 po jo Veprimi=’/’ po n2 = 0? Futet numri i dytë jopo
  • 22.
  • 23. 1. Paraqitjae algoritmeve mbi vargjet numerike me bllokskeme Shpesh të dhënat hyrëse në një program janë vargje numrash për të cilët mund të përcaktohet një rregull në përcaktimin e secilit prej tyre duke ditur numrat paraardhës. Përdorimi i të dhënave të tilla në një program e lehtëson programin në kuptimin e shmangjes së futjes së të dhënave një nga një, mbasi ato mund të krijohen në bazë të një formule. Le të shohim disa shembuj nëpërmjet pseudokodeve dhe bllokskemave. 5.1 Të gjendet shuma e 100 numrave të parë natyralë, pra shtrohet për zgjidhje gjetja e shumës 1 + 2 + 3 + . . . + 100; Siҫ shohim të dhënat që përdoren janë 1, 2, 3, . . ., 100; karakteristikë e të dhënave në këtë rast, është që ekziston një lidhje e tillë midis dy elementëve të njëpasnjëshëm: numri = numri paraardhës + 1 Kjo cilësi bën të mundur që ne t’i bëjmë të ditur programit vetëm numrin e parë në këtë varg numrash dhe sa të tillë janë. Veprimi i mësipërm përsëritet 100 herë, pra duhet të interesohemi ti numërojmë hapat derisa ato të arrijnë vlerën 100. Për këte na duhet një numrator, i cili fillimisht merr vlerën zero. Gjithë puna do të bëhet në një cikël, brenda të cilit me ndihmën e formulës së mësipërme krijohen një pas një gjithë numrat e vargut. Pseudokodi dhe bllokskema e mëposhtme e realizojnë këtë proces: Pseudokodi:  Vendosim në një vend në kujtese me emrin numratori qe i japim vleren 0. Këtu do shtohen hapat qe ne kryejmë  Vendosim në një vend në kujtesë me emrin shuma vlerën 0; këtu do të shtohen numrat e vargut.  Vendosim në një vend të kujtesës me emrin numri, vlerën e numrit të parë ne varg dhe pikërisht vlerën 1.  Cikël: përsëriten hapat e mëposhtëm 100 herë:  Shtojmë te shuma numrin  E rrisim numrin me 1 duke zbatuar formulën që lidh dy elementë të njëpasnjëshëm të vargut  Rezultati afishohet në ekran. Blloksema: Figura 5. 1 Pseudokodi, bllokskema në llogaritjen e shumës së 100 numrave të parë natyralë shuma = shuma + numri numri = numri + 1; fund fillim numrator= 0 numri = 1 shuma = 0 numratori = numratori + 1 nunratori < 100 po jo shuma
  • 24. 5.2 Të gjendet shuma e disa numrave të parë natyralë, pra shtrohet për zgjidhje gjetja e shumës 1 + 2 + 3 + . . . ku numri i numrave nuk është i paracaktuar; Pak ndryshim ka ky problem nga problemi në 5.1. Ndryshimi i vetëm është që duhet ti bëjmë të ditur programit sa numra do të mbledhim. Pseudokodi:  Sa numra natyralë do të mblidhen?  Numri i numrave, nr, vendoset në kujtesë  Vendosim në një vend në kujtese me emrin numratori qe i japim vleren 0. Këtu do shtohen hapat qe ne kryejmë  Vendosim në një vend në kujtesëme emrin shuma vlerën 0; këtu do të shtohen numrat e vargut.  Vendosim në një vend të kujtesës me emrin numri, vlerën e numrit të parë ne varg dhe pikërisht vlerën 1.  Cikël: përsëriten hapat e mëposhtëm sa është vlera e nr:  Shtojmë te shuma numrin  E rrisim numrin me 1 duke zbatuar formulën që lidh dy elementë të njëpasnjëshëm të vargut  Rezultati afishohet në ekran. Blloksema: Figura 5. 2 Pseudokodi, bllokskema në llogaritjen e shumës së një numri të ҫfarëdoshëm numrash të parë natyralë Në probleme të tjerë formula lidhëse midis dy elementëve të njëpasnjëshëm të një vargu numrash mund të jetë më e komplikuar dhe fundi i hapave të ciklit të lidhet me një konditë të caktuar. Për shembull: 5.2 Të gjendet shuma e thyesave 𝟏 𝟐 + 𝟏 𝟑 + 𝟏 𝟒 + … përderisa thyesa të jetë më e madhe se 𝟏 𝟏𝟎𝟎𝟎 Në këtë problem përsëri ekziston një lidhje e emëruesit të një elementi me emëruesin e elementit paraardhës: shuma = shuma + numri numri = numri + 1; fund fillim numratori =0; numri = 1 shuma = 0 numratori = numratori + 1 nunratori < nr jo shuma Futet nr Sa numrajanë? po
  • 25. emëruesi = emëruesi i elementit parardhës + 1 , ndërkohë që numuruesi është gjithmonë 1. Përsëri do të kemi një cikël ku elementi në ҫdo hap krijohet nga një formulë, por cikli në këtë rast mbaron kur plotësohet kondita që elemeti i rradhës <= 1/1000. Pseudokodi dhe bllokskema janë: Pseudokodi:  Vendosim në një vend në kujtesëme emrin shuma vlerën 0; këtu do të shtohen numrat e vargut.  Vendosim në një vend të kujtesës me emrin numri, vlerën eemëruesit tëthyesës së parë ne varg dhe pikërisht vlerën 2.  Cikël: përsëriten hapat e mëposhtëm përderisa thyesa të jetë më e madhe se 1/1000:  Shtojmë te shuma thyesën  E rrisim emëruesin me 1 duke zbatuar formulën që lidh dy elementë të njëpasnjëshëm të vargut  Rezultati afishohet në ekran. Blloksema: Figura 5. 3 Pseudokodi, bllokskema në llogaritjen e shumës së një numri thyesash 𝟏 𝟐 + 𝟏 𝟑 + 𝟏 𝟒 + … përderisa thyesa të jetë më e madhe se 1/1000 2. Programet ngakrijimi ne ekzekutim (roli i kompilatorit) Programi më i thjeshtë në C++, thjesht afishon një mesazh në ekran, dhe është programi që i korrespondon bllokskemës fare të thjeshtë të figures 6.1: Shembull 1: Të krijohet një program i tillë që gjatë ekzekutimit të tij të afishojë në ekran shprehjen “Programi im i pare ne C++”: shuma = shuma + 1/emeruesi emeruesi = emeruesi + 1; fund fillim emeruesi = 2 shuma = 0 1 𝑒𝑚𝑒𝑟𝑢𝑒𝑠𝑖 > 1 1000 jo shuma po
  • 26. Blloksema: Kodi burim Rezultati gjatë ekzekutimit // program im i pare ne C++ #include <iostream> using namespace std; int main () { cout<<"Programi im i pare ne C++n"; return 0; } Programi im i pare ne C++ Figura 6.1 Bllokskema dhe kodi burim i një programi që afishon një mesazh në ekran Para se të analizojmë programin e mësipërm rresht të rresht duhet të kemi të qartë hapat që kalohen nga momenti që ne e shkruajmë programin në një gjuhë të nivelit të lartë, në rastin tonë me gjuhën C++, deri në momentin që ai ekzekutohet në kompjuter duke na dhënë rezultatin në paisjet dalëse të tij. Janë këta hapa ku një program kalon: a) Shkruhet programi burim në një editor si një sekuencë statementesh dhe regjistrohet me një prapashtesë që njihet nga kompilatori që disponojmë, p.sh. .cpp ose .cc. Ky është file-i kodit burim. Në këtë mënyrë do të shkruanim programin e figurës 6.1. b) Shpesh një program burim përmban të ashtuquajturat direktiva dhe janë ato që paraprihen nga simboli #. Rreshta të tilla përfaqësojnë pjesë kodi që për lehtësi ofrohen nga C++ duke shkruar nga ana jonë një rresht të vetëm. Në rastin e kodit burim në fig. 6.1 një direktivë paraqet nga rreshti: #include <iostream> c) Ekzekutohet kompilatori (përkthyesi) për të konvertuar programin makinë në instruksione makine. Një statement zbërthehet në disa instruksione në gjuhën makinë. Kompilatori gjithashtu na ve në dukje gabimet që ne bëjmë gjatë shkrimit të programit, gabime që nuk respektojnë rregullat e shkrimit të një programi në C++. Ne i korigjojmë këto gabime dhe përsëri e përkthejmë programin me ndihmën e kompilatorit. d) Ekzekutohet program linker për të lidhur së bashku pjesë të ndryshme të një programi siҫ janë kodi i mësiperm i shkruar nga ne dhe kodi që rreshti #include <iostream> fillim fund Programi im i pare ne C++
  • 27. përfaqëson duke prodhuar kështu një file të ekzekutueshëm. Hapat b–d shpesh realizohen me një komandë të vetme ose klikim butoni në varësi të ambientit të punës ku ne zhvillojmë një program. Gabimet që mund të dallohen në një hap të çfarëdoshëm do të pengonin ekzekutimin e hapave pasues. Diagrama ne fig.6.2 paraqet këtë rradhë hapash: Figura 6.2 Programi nga krijimi në ekzekutim Ushtrim: Krijoni një ambient pune për shkruar një program në C++. Mund të përdoren ambiente të ndryshme pune si Code Block, Visual C++, NetBeans etj. Të gjithë këto ambiente pune na japin mundësi të shkruajme në program dhe me një buton të përkthejmë(kompilatori), lidhim (linkeri) dhe të ekzekutojmë programin tonë. Kjo punë duhet të bëhet në bashkëpunim me instruktorin tuaj në laborator. Kodi Burim Paraprocesori Kodi Burim i Modifikuar Kompilatori Kodi Objekt Linkeri Kodi i Ekzekutueshëm
  • 28. 3. Prezantim me gjuhën C++ I rikthehemi programit të parë në gjuhën C++, figura 6.1 dhe e analizojmë atë rresht për rresht Kodi burim // program im i pare ne C++ #include <iostream> using namespace std; int main () { cout<<"Programi im i pare ne C++n"; return 0; } Figura 7.1 Kodi burim i një programi që afishon një mesazh në ekran int main () Ky rresht i korrespondon fillimit të funksionit main(). Funksioni përfshin zakonisht një pjesë kodi që realizon diçka. Funksioni ka një sintaksë të përcaktuar. Funksioni main() është pika e programit ku fillon ekzekutimi i tij. Pavarësisht ku ndodhet ky funksion në kodin burim. Pra ky funksion është i domosdoshëm në çdo program të C. Formati e plotë e funksionit main() është: int main(){ . . . return 0; } Fjala main ndiqet nga çifti i parantesave (()). Ky çift kllapash dallon një funksion nga shprehje te tjera. Opsionalisht, këto paranthesa mund të përfshijnë një listë elementësh të quajtur parametra brenda tyre. Mbas këtyre parantesave ne gjejmë trupin e funksionit të përfshirë në kllapat ({}). Ajo që ndodhet në këto kllapa është çfarë funksioni bën kur ai ekzekutohet. cout<<"Programi im i pare ne C++n"; Ky rresht është një statement C++. Një statement është një shprehje e thjeshtë ose e përbërë që aktualisht ka një efekt. Në fakt, ky statement realizon të vetmin veprim që është afishimi i mesazhit "Programi im i pare ne C++" në ekran. "n" siguron kalimin e kursorit në rreshtin që vijon në ekran, poshtë mesazhit që çfaqet në të. Kjo gjë sigurohet edhe në një mënyrë tjetër. Provoni statementin
  • 29. cout<<"Programi im i pare ne C++"<<endl; endl siguron të njëjtën gjë, pra kalimin e kursorit në rreshtin që vijon. cout është formati që lejon afishimin e një vargu karakteresh (në këtë rast vargu i karaktereve Programi im i pare ne C++) në ekran. Përdorimi i cout bëhet i mundur duke shtuar në krye të kodit rreshtat: #include <iostream> using namespace std; Shënojmë që statementi mbaron gjithmonë me një pikëpresje (;). Ky karakter përdoret për të shënuar fundin e statementit në një program C++ (një nga gabimet sintaksore më të zakonshme që bëhet në fakt është të harruarit e pikëpresjes në fund të një statementi). return 0; këtu kemi kthimin e numrit 0 nga funksioni main(). Ç’ka kthehet nga ky funksion merret parasysh nga sistemi operativ, Windows; në këtë rast vlera zero tregon një mbarim normal të programit për këtë sistem. Programi strukturohet në rreshta të ndryshëm që të jetë më i lexueshëm gjë që është e këshillueshme. Por mund të shkruhej dhe në një rresht. Kështu kodi burim i fig. 1.8 është njëlloj si // program im i pare në C++ #include <iostream> using namespace std; int main (){ cout<<"Programi im i pare ne C++n"; return 0;} Figura 7.2 Në C++, ndarja midis statementeve bëhet me (;) në fund të secilitprej tyre. 4. Variablat dhe Konstantet Rimarrim në shqyrtim shembullin e llogaritjes së sipërfaqes së një ambienti në formë drejtkëndëshi të fig 3.1, ku vlerat e dimensioneve i kemi numra të plotë.
  • 30. Pseudokodi:  Vendosen në kompjuter të dhënat hyrëse, që janë gjerësia dhe gjatësia e ambientit  llogaritet siperfaqja duke shumëzuar gjerësinë dhe gjatesinë  afishohet sipërfaqja Blloksema: 8.1 Llogaritja e sipërfaqes, ku gjerësia dhe gjatësia janë numra të plotë Për të paraqitur këtë bllokskemë në një kod burim të një programi në C++ na duhet të familjarizohemi me konceptet e variablave dhe tipet e tyre në C++. 8.1 Identifikimi i Variablave Në shembullin e mësipërm të llogaritjes së sipërfaqes, na duhet një vend në kujtesë ku të vendosim gjatësinë dhe një vend ku të vendosim gjerësinë. Na duhet një vend gjithashtu për të vendosur rezultatin e llogaritjes së sipërfaqes. Kjo gjë bëhet e mundur në C++ (si dhe në gjuhët e tjera të programimit) duke përdorur të ashtuquajturat variabla të cilat emërtojnë pikërisht vende në kujtesë. Atëhere procesin e mësipërm do ta paraqesim si më poshtë: gjeresia = 3 gjatesia = 5 siperfaqja = gjeresia * gjatesia; Eshtë e qartë që ky është një shëmbull shumë i thjeshtë mbasi kemi vetëm dy vlera të plota të vogla me të cilat mund të kishim vepruar direkt 3 * 5, por imagjinoni të kishim miljona numra të tillë dhe shumë veprime matematikore me ta. Për këtë arsye, ne përcaktojmë një variabël si porcion të kujtesës për të rezervuar një vlerë të përcaktuar. Çdo variabël kërkon një identifikues që e dallon atë nga të tjerët. Për shembull, në kodin e mësipërm identifikuesit e variablave janë gjeresia, gjatesia, dhe siperfaqja por ne mund të përdornim çdo lloj emri të pranueshëm (do të shohim më poshte disa rregulla për emrat e variablave). Identifikuesit Një identifikues i pranueshëm është një sekuencë e një ose më shumë gërmave, shifrave, ose gjeresia = 3 gjatesia = 5 siperfaqja= gjeresia * gjatesia siperfaqja fund fillim
  • 31. karakterit (_) (underscore). As hapësira e as shenjat e pikësimit nuk mund të jenë pjesë e një identifikuesi. Përveç kësaj një identifikues nuk mund të fillojë me një shifër. Ai fillon me një gërmë ose me (_ ). Një tjetër rregull që duhet të marrim parasysh për identifikuesit është që nuk mund të përdorim për ta fjalët e vet gjuhës C++ që ne i quajmë fjalë të rezervuara. Fjalë të tilla të rezervuara në C++ janë: bool, case, char, class, const, const_cast, continue, default, delete, do, double, dynamic_cast, else, enum, explicit, export, extern, false, float, for, friend, goto, if, inline, int, long, mutable, namespace, new, operator, private, protected, public, register, reinterpret_cast, return, short, signed, sizeof, static, static_cast, struct, switch, template, this, throw, true, try, typedef, typeid, typename, union, unsigned, using, virtual, void, volatile, wchar_t, while Vërejtje1: Gjuha C++ është një gjuhë "case sensitive" pra gërmat e vogla konsiderohen ndryshe nga të mëdhatë. Kjo do të thotë që një identifikues i shkruar me gërma të mëdha konsiderohet ndryshe nga një i shkruar me gërma të vogla. Kështu për shembull variabli Siperfaqja nuk është i njëjtë me siperfaqja. Në shembullin e mësipërm kemi tre identifikues të ndryshëm variablash. Vërejtje2: Rekomandohet që si identifikues variablash të përdoren fjalë që shprehin domethënien e këtyre variablave, pra qëllimin për të cilin ata përdoren. Të tillë identifikues u përdorën në shembullin e mësipërm: gjeresia, gjatesia, dhe siperfaqja. Konstantet Në shembullin e mësipërm, figura 8.1 vlerat 3, 5 quhen konstante, dhe ashtu si variablat edhe ato zenë një vend në kujtesë. Dallojmë konstante të ndryshme të tipeve të ndryshme. 3, dhe 5 janë konstante numerike kurse një shprehje e përbërë nga karaktere (gërma, shifra, e karaktere të tjerë) quhet konstante string. E tillë është për shembull shprehja "Programi im i pare ne C++". Vemë në dukje që konstantet stringje vendosen në thonjëza dyfishe " gjatë përdorimit të tyre në një program. 5. Tipet themelore të të dhënave Kur programohet, ne vendosim ose themi rezervojmë variablat në kujtesën e kompjuterit, por kompjuteri duhet të dijë çfarë lloj të dhënash ne do të vendosim atje, mbasi nuk i jepet e njëjta hapësirë kujtese një numri të plotë, ose një numri dhjetor, ose një karakteri. Kujtesa e kompjuterit organizohet në byte. Një byte është minimumi i sasisë së kujtesës që C++ mund të menaxhojë. Një byte lejon rezervimin e një sasie të vogël të dhënash: një karakter të vetëm, ose një numur të plotë të vogël (në përgjithësi një të plotë midis 0 dhe 255). Përveç kësaj, kompjuteri mund të manipulojë të dhëna më komplekse që kërkojnë disa byte për ti rezervuar, të tilla si numrat e gjatë ose numrat jo të plotë. Në shembullin e mësipërm të llogaritjes së sipërfaqes ne do të mjaftoheshim me numrat e plotë dhe në këtë rat do të duhej që para përdorimit të variablave, ti deklaronim ata, pra të përcaktonim tipet e tyre si numra te plotë:
  • 32. int gjeresia; //deklarimi i variablit gjeresia int gjatesia; //deklarimi i variablit gjatesia int siperfaqja; //deklarimi i variablit siperfaqja gjeresia = 3; gjatesia = 5; siperfaqja = gjeresia * gjatesia; ose int gjeresia, gjatesia, siperfaqja; // deklarimi i tre variablave gjeresia = 3; gjatesia = 5; siperfaqja = gjeresia * gjatesia; Atëhere kodi burim që i përgjigjet bllokskemës në fig. 8.1, ku vlerat e variablave jepen si të dhëna brenda programit do të jetë: Kodi burim Rezultati gjatë ekzekutimit // llogaritja e siperfaqes #include <iostream> using namespace std; int main () { int gjeresia, gjatesia, siperfaqja; gjeresia = 3; gjatesia = 5; siperfaqja = gjeresia * gjatesia; cout<<"Siperfaqja:"<< siperfaqja <<endl; return 0; } Siperfaqja:15 Figura 9.1 . Kodi burim që i korrespondon bllokskemës në fig. 8.1 Në se do të përdornim vlera dhjetore për gjeresia gjatesia dhe siperfaqja do të kishim kodin e mëposhtëm:
  • 33. // llogaritja e siperfaqes #include <iostream> using namespace std; int main () { double gjeresia, gjatesia, siperfaqja; gjeresia = 3.4; gjatesia = 5.2; siperfaqja = gjeresia * gjatesia; cout<<"Siperfaqja:"<< siperfaqja <<endl; return 0; } Siperfaqja:17.28 Figura 9.2 . Variabla të tipit double Në vijim është një përmbledhje e tipeve të ndryshëm të të dhenave në C++, si dhe intervali i vlerave që mund të përdoret për secilën prej tyre. Këta tipe quhen dhe tipe primitivë: Emri Përshkrimi Madhësia* Intervali* Char Karakter ose i plotë i vogël 1 byte Me shenjë: -128 to 127 Pa shenjë: 0 to 255 short int (short) i plotë short. 2 byte Me shenjë: -32768 to 32767 Pa shenjë: 0 to 65535 Int i plotë. 4 byte Me shenjë: -2147483648 to 2147483647 Pa shenjë: 0 to 4294967295 long int (long) i plotë long. 4 byte Me shenjë: -2147483648 to 2147483647 Pa shenjë: 0 to 4294967295 Bool Vlerë buleane. Merr nje nga vlerat: true ose false. 1 byte true ose false Float Numur me pike notuese. 4 byte +/- 3.4e +/- 38 (~7 shifra) Double Numur me pike notuese me precision të dyfishtë. 8 byte +/- 1.7e +/- 308 (~15 shifra) long double Numur me pike notuese me precision të dyfishtë long. 8 byte +/- 1.7e +/- 308 (~15 shifra) wchar_t Karakter i gjërë. 2 ose 4 bytes 1 karakter i gjerë Figura 9.3 Tipet primitive në C++ 6. Operatoret Pasi u njohëm me nevojën e përdorimit të variablave dhe konstanteve, jemi gati të operojmë me to. Për këtë qëllim C++ përdor operatorët. Dhenja e Vlerës(Assignment) (=) Operatori i dhënjes së vlerës i jep një vlerë një variabli.
  • 34. a = 5; Rregulli më i rëndësishëm kur japim një vlerë është rregulli nga e djathta-në të majtë: operatori i dhënjes së vlerës ka vend nga e djathta në të majtë, dhe kurrë në drejtim të kundërt: a = b; Ky statement i jep variablit a vlerën që ndodhet në variablin b. Vlera që ndodhej deri tani në a humbet. a merr vlerën e b, por në se b ndryshon më vonë, kjo nuk do të sjellë një ndryshim te a. Për shembull, le të marrim parasysh kodin që vijon – // operatori i dhenjes se vleres #include <iostream> using namespace std; int main () { int a, b; // a:?, b:? a = 10; // a:10, b:? b = 4; // a:10, b:4 a = b; // a:4, b:4 b = 7; // a:4, b:7 cout << "a:"; cout << a; cout << " b:"; cout << b; return 0; } a:4 b:7 Figura 10.1 Operatori i dhënjes së vlerës Ky kod do rezulton në atë që vlera që përmbahet në a është 4 dhe ajo që përmbahet në b është 7. Shënojmë se a nuk preket nga modifikimi i fundit i b megjithëse kemi shkruar a = b më parë (kjo për arsye të rregullit nga e djathta në të majtë). Shprehja e mëposhtme është gjithashtu e vlefshme në C++: a = b = c = 5;
  • 35. Këtu jepet vlera 5 te të tre variablat: a, b dhe c. 7. Operatorët Arithmetikë ( +, -, *, /, % ) Pesë veprimet arithmetikë që mbështeten nga gjuha C++ janë: + Mbledhja - Zbritja * Shumëzimi / Pjestimi % mbetja e pjestimit (modulo) Figura 11.1 Operatorët arithmetikë Veprimet si mbledhja, zbritja, shemëzimi, pjestimi i korrespondojnë veprimeve korresponduese arithmetike. I vetmi që mund të mos jetë familjar për ju është veprimi modulo; operatori i tij është shenja e përqindjes (%). Modulo është veprimi që jep mbetjen e pjestimit të dy vlerave të plota, pra ky veprim përdoret vetëm midis dy numrave të plotë. Për shembull: a = 11 % 3; variabli a do të mbajë vlerën 2, mbasi 2 është mbetja e pjestimit midis 11 dhe 3. Operatorët e përbërë të dhënjes së vlerës (+=, -=, *=, /=, %=, >>=, <<=, &=, ^=, |=) Kur duam të modifikojmë vlerën e një variabli duke kryer një veprim në vlerën aktualisht të rezervuar në këtë variabël, ne mund të perdorim operatorët e përbërë të dhënjes së vlerës: Shprehja është ekuivalente me vlera += rritja; vlera = vlera + rritja; a -= 5; a = a - 5; a /= b; a = a / b; cmimi *= njesite + 1; cmimi = cmimi * (njesite + 1); Figura 11.2 Operatorë të përbërë të dhënjes së vlerës
  • 36. dhe e njëjta gjë për gjithë operatorët e tjerë. Për shembull: // operatoret e perbere te dhenjes se vleres #include <iostream> using namespace std; int main () { int a, b=3; a = b; a += 2; // equivalent me a = a+2 cout << a; return 0; } 5 Figura 11.3 Shembull i përdorimit të operatorëve të përberë Shtimi dhe Zbritja (++, --) Duke i shkurtuar më tepër disa shprehje, operatori i shtesës (++) dhe i zbritjes (--) rrit ose zvogëlon vlerën e rezervuar në një variabël me 1. Ata janë ekuivalent me +=1 dhe -=1, respektivisht. Kështu: c++; c+=1; c=c+1; Janë të gjithë ekuivalentë në funksionin e tyre: të tre ata rritin me një vlerën e c. Një karakteristikë e këtij operatori është që mund të përdoret para (++a) ose pas (a++) identifikuesit të variablit (pa hapësirë midis tyre). Megjithëse në shembujt e thjeshtë si a++ ose ++a të dyja shprehjet kanë të njëjtin kuptim, në shprehje të tjera ato mund të kenë një ndryshim të rëndësishëm: në rastin e (++a) vlera rritet para se rezultati i shprehjes të vlerësohet dhe për këtë arsye është vlera e rritur që konsiderohet në vlerësimin e një shprehje të jashtme; në rastin e (a++) vlera e rezervuar në a rritet pas vlerësimit, prandaj është vlera e rezervuar fillimisht te a që merret parasysh në vlerësimin e një shprehje të jashtme. Vemë re diferencën: Shembull 1 Shembull 2 B=3; A=++B; // A eshte 4, B eshte 4 B=3; A=B++; // A eshte 3, B eshte 4 Figura 11.4 Shembuj të përdorimit të operatorëve ++ majtas dhe djathtas një variabli
  • 37. Në shembullin 1, B rritet para se vlera e tij të kopjohet në A. Ndërsa në shëmbullin 2, vlera e B kopjohet në A dhe pastaj B rritet. Ka një prioritet ndërmjet operatorëve arithmetikë dhe pikërisht rradha e veprimit të tyre shprehet si më poshtë: Niveli Operatori Përshkrimi Grupimi 1 * / % shumezim Nga e majta në të djathtë 2 + - mbledhje Nga e majta në të djathtë Pra në se nuk kemi kllapa, veprimet e shumëzimit dhe pjestimit bëhen para atyre të mbjedhjes dhe zbritjes. Vetëm vendosja e kllapave mund ta ndryshojë këtë rradhë. 8. Operatorët e Krahasimit ( ==, !=, >, <, >=, <= ) Me qëllim që të vlerësojmë krahasimin midis dy shprehjeve ne mund të përdorim operatorët relacionalë dhe të barazisë. Rezultati i një operatori relacional është një vlerë boolean-e që mund të jetë true ose false, në përputhje me rezultatin e tij boolean. Ne mund të duam të krahasojmë dy shprehje, për shembull, për të evidentuar në se ato janë të barabarta ose njëra është më e madhe se tjetra. Këtu është një listë operatorësh relacionale dhe të barazimit që mund të përdoren në C++: == I barabartë me != Jo i barabartë me > Më i madh se < Më i vogël se >= Më i madh ose i barabartë me <= Më i vogël ose i barabartë me Figura 12. 1 Operatorët relacionalë Këtu kemi disa shembuj: (7 == 5) // vleresohet si false. (5 > 4) // vleresohet si true. (3 != 2) // vleresohet si true. (6 >= 6) // vleresohet si true.
  • 38. (5 < 5) // vleresohet si false. Natyrisht, në vend që të përdorim vetëm konstantet numerike, ne mund të përdorim një shprehje të çfarëdoshme që përfshin variabla. Supozojmë që a=2, b=3 dhe c=6, (a == 5) // vleresohet si false mbasi a nuk eshte i barabarte me 5. (a*b >= c) // vleresohet si true mbasi (2*3 >= 6) eshte true. (b+4 > a*c) // vleresohet si false mbasi (3+4 > 2*6) eshte false. ((b=2) == a) // vleresohet si true. Të jeni të kujdesshëm! Operatori = (një shënjë =) nuk është i njëjti me operatorin == (dy shenja barazimi), i pari është operatori i dhënjes së vlerës, (jepet vlera nga e djathta në të majtë) dhe tjetri (==) është operatori i barazisë që krahason në se dy shprehje në dy anët e tij janë të barabarta. Në këtë mënyrë, në shprehjen ((b=2) == a), së pari ne i japim vlerën 2 variablit b dhe pastaj e krahasojmë me a, që gjithashtu rezervon vlerën, kështu që rezultati i veprimit është true. Ka një prioritet ndërmjet operatorëve të krahasimit dhe pikërisht rradha e veprimit të tyre shprehet si më poshtë: Niveli Operatori Përshkrimi Grupimi 1 < > <= >= Relacional Nga e majta në të djathtë 2 == != Barazim Nga e majta në të djathtë Vetëm vendosja e kllapave mund ta ndryshojë këtë rradhë. Ushtrime: 1. Si është vlera e shprehjeve që vijojnë si të plotë dhe si vlerë booleane? a) 3 b) 5+7 c) 3+(3<4) d) (2>1)+(3<2) Operatorët Logjikë ( !, &&, || ) Operatori ! është operatori i C++ të realizon veprimin logjik JO, dhe ka vetëm një operand boolean, të vendosur në të djathtë, dhe ajo që bën është gjetja e inversit të vlerës së tij, pra false në se operandi është true dhe true në se operandi është false. Pra, ai kthen vlerën e kundërt booleane të operandit të tij. Për shembull: !(5 == 5) // vleresohet false mbasi shprehja ne te dhjathte(5 == 5)
  • 39. // eshte true. !(6 <= 4) // vleresohet true mbasi (6 <= 4) do te ishte false. !true // vleresohet false !false // vleresohet true. Operatorët logjikë && dhe || përdoren kur vlerësohen dy shprehje për të marrë një rezultat të vetëm relacional. Operatori && i korrespondon veprimit logjik boolean DHE. Ky veprim rezulton true në se të dy operandët janë true, dhe false përndryshe. Operatori || i korrespondon veprimit logjik boolean OSE. Ky veprim rezulton true në se të paktën një nga operandët është true, dhe false kur të dy operandët janë false. Tabelat që vijonë paraqet rezultatin e operatorit && duke vlerësuat shprehjen a && b dhe a || b : OPERATORI && OPERATORI || A B a && b a B a || b True True true true True true True False false true false true False True false false True true False False false False false false Për shembull: ( (5 == 5) && (3 > 6) ) // vleresohet si false ( true && false ). ( (5 == 5) || (3 > 6) ) // vleresohet true ( true || false ). Kur përdoren operatorët logjikë, C++ vlerëson çfarë është e nevojshme nga e majta në të djathtë për të ardhur në rezultatin relacional të kombinuar, duke injoruar pjesën që mbetet. Për këtë arsye, në shembullin e fundit ((5==5)||(3>6)), C++ do të vlerësonte fillimisht në se 5==5 është true, dhe në se kjo ka vend, nuk do të vazhdonte të kontrollonte më tej në se 3>6 është e vërtetë ose jo. Kjo njihet si vlerësimi qark –i shkurtër, dhe punon në këtë mënyrë: operatori Qarku i shkurtër && Në se shprehja në të majtë është false, rezultati i kombinuar është false (shprehja në anën e djathtë nuk vlerësohet). || Në se shprehja në të majtë është true, rezultati i kombinuar është true (shprehja në anën e djathtë nuk vlerësohet) Tabela 1.9 Operatorët Logjikë Kjo është e rëndësishme kur shprehja në anën e djathtë ka efekte anësore, si ndryshim vlerash:
  • 40. if ((i < 10)&&(++i < n)) { /*...*/ } Kjo shprehje e kushtëzuar rrit i me një, por vetëm në se kondita në të majtë të && është e vërtetë, përndryshe shprehja në të djathtë të (++i < n) asnjëherë nuk vlerësohet. Ka një prioritet ndërmjet operatorëve të krahasimit dhe pikërisht rradha e veprimit të tyre shprehet si më poshtë: Niveli Operatori Përshkrimi Grupimi 1 ! JO llogjike 2 && DHE logjike 3 || OSE logjike Vetëm vendosja e kllapave mund ta ndryshojë këtë rradhë. 9. Vleresimi i shprehjeve dhe prioriteti i operatoreve Prioriteti i operatorëve Më sipër përmëndëm prioritetin që kanë operatorët e ndryshëm brenda kategorisë përkatëse të tyre. Por mund të kemi shprehje komplekse ku përfshihen veprime të ndryshme të të gjitha kategorive: arithmetike, veprime krahasimi, veprime llogjike. Nga prioriteti më i madh në atë më të ulët, renditja e prioriteteve për një pjesë të operatorëve, është si më poshtë: Niveli Operatori Përshkrimi Grupimi 1 * / % shumezim Nga e majta në të djathtë 2 + - mbledhje Nga e majta në të djathtë 3 < > <= >= relacional Nga e majta në të djathtë 4 == != barazim Nga e majta në të djathtë 5 ! JO 6 && DHE logjike 7 || OSE logjike
  • 41. 8 = *= /= %= += -= >>= <<= dhënje vlere Nga e djathta në të majtë Figura 13. 1 Prioriteti i operatorëve 10. Shkrimi ne ekran dhe Leximi i te dhenave nga tastiera 14.1 Dalja Standarte (cout) Në programet e paragrafeve të mëparshëm kemi përdorur formatin e afishimit në ekran të një rezultati dhe për këtë na janë dashur disa rreshta kodi: Fillimisht përfshinim në program direktivën: #include <iostream> Të shoqëruar me specifikimin using namespace std; pra: #include <iostream> using namespace std; dhe më pas përdornim formatin cout << variabel/konstante . . . ku << quhet operator i daljes dhe (cout) na përfaqëson formatin e daljes standarte në ekran në C++. cout << "nje shprehje ne ekran"; // printon nje shprehje ne ekran cout << 120; // printon numrin 120 ne ekran cout << x; // printon permbajtjen e x ne ekran Operatori << shton të dhënat që vijojnë pas tij në një sekuencë karakteresh që e paraprin atë. Në shembujt e mësipërm fillimisht vendoset konstantja string nje shprehje ne ekran, , më pas shtohet konstantja numerike 120 dhe më pas përmbajtja e variablit x në sekuencën e karaktereve që cout bën të mundur të afishohet. Kështu do ta imagjinojmë për momentin cout. Shënojmë që fjalia në statementin e parë përfshihet midis thonjëzave dyfishe (") mbasi është një konstante string karakteresh. Gjithmonë kur ne duam të përdorim një konstante string karakteresh, ne duhet ta përfshijmë atë midis thonjëzave të dyfishta që ajo të dallohet nga një emër variabli. Për shembull, këtu janë dy fjali që kanë rezultate shumë të ndryshme:
  • 42. cout << "Pershendetje"; // printon pershendetje cout << Pershendetje; // printon permbajtjen e variablit Pershendetje Operatori i daljes (<<) mund të përdoret më shumë se një herë në një statement të vetëm: cout << "Pershendetje, " << "ky eshte " << "nje statement C++"; Ky statement i fundit do të shtypë mesazhin Pershendetje, ky eshte nje statement C++ në ekran. Dobia e përsëritjes së operatorit të daljes (<<) duket kur kombinojmë shtypjen e variablave dhe konstanteve ose të më shumë se dy variablave: cout << "Pershendetje, une jam " << mosha << " vjet dhe adresa ime eshte " << adresa; Në se supozojmë se variabli mosha ka vlerën 24 dhe adresa përmban “Rr. Deshmoret e Kombit Nr 20” rezultati i statementit të mësipërm do të ishte: Pershendetje, une jam 24 vjet dhe adresa ime eshte Rr. Deshmoret e Kombit Nr 20 Eshtë e rëndësishme të vemë re që cout nuk kalon në rresht tjetër pas rezultatit në se ne nuk mendojmë vet ta bëjmë këtë gjë. Kështu statementet e mëposhtme do të shfaqin rezultatet e tyre në një rresht: cout << "Ky eshte nje pohim."; cout << " Ky eshte nje pohim tjeter."; Ky eshte nje pohim. Ky eshte nje pohim tjeter. Për të realizuar kalimin në një rresht tjetër pas shtypit të një mesazhi specifikohet karakteri special i rreshtit të ri n (backslash, n): cout << "Pohimi i pare.n"; cout << " Pohimii dyte.nPohimi i trete."; nga ku marrim këtë rezultat: Pohimi i pare. Pohimi i dyte. Pohimi i trete. Për kalimin në një rresht të ri mund të përdorim dhe sintaksën endl që quhet një manipulator. Për shembull: cout << "Pohimi i pare." << endl;
  • 43. cout << "Pohimi i dyte." << endl; që do të printonte: Pohimi i pare. Pohimi i dyte. Manipulatori endl prodhon një karakter të kalimit në rresht të ri, ekzaktësisht çfarë bën dhe 'n'. Mund të përdoren të dy formatet pa ndonjë ndryshim në rezultat. 14.2 Hyrja Standarte (cin) Paisja standarte e hyrjes në kopmjuter është tastjera. Përdorimi i hyrjes standarte në C++ realizohet nëpërmjet operatorit të hyrjes (>>) i përdorur së bashku me formatin cin që e përfytyrojmë për momentin si mbartës të një sekuencë karakteresh. Operatori duhet të ndiqet nga variabli që rezervon të dhënat që futen si një sekuencë karakteresh. Për shembull: int mosha; cin >> mosha; Statementi i parë deklaron një variabël të tipit int të quajtur mosha, dhe i dyti pret për një hyrje nga cin (tastjera) për ta rezervuar në këtë variabël të plotë. >> trajton hyrjen nga tastjera kur ne shtypim tastin RETURN. Për këtë arsye, edhe në se ju kërkoni një karakter të vetëm, futja e tij nga cin nuk bëhet pa shtypur tastin RETURN pasi karakteri të jetë shtypur. Duhet gjithmonë të konsiderojmë tipin e variablit që jemi duke përdorur si mbartës të asaj çfarë futet me cin. Në se kërkojmë një të plotë duhet të shtypim një të plotë, në se kërkojmë një karakter duhet të shtypim një karakter dhe në se kërkojmë një string karakteresh, duhet të shtypim një string karakteresh. // shembull hyrje/daljesh #include <iostream> using namespace std; int main () { int i; cout << "shtypni nje vlere te plote: "; cin >> i; cout << "Vlera e shtypur eshte " << i; cout << " dhe dyfishi eshte " << i*2 << ".n"; return 0; } shtypni nje vlere te plote: 702 Vlera e shtypur eshte 702 dhe dyfishi eshte 1404. Figura 14.1 Nje shembull hyrje/daljesh Përdoruesi i programit mund të jetë një nga faktorët që gjeneron gabime qoftë dhe në programin më të thjeshtë që përdor cin (si në programin më sipër). Në se kerkohet një vlerë e plotë dhe
  • 44. përdoruesi i programit fut një emër (një varg karakteresh), do të kemi një operim të gabuar mbasi nuk jepet çfarë pritej. Kështu kur përdoren të dhëna hyrëse që sigurohen nga cin duhet të jemi të sigurtë të futen të dhëna të rregullta. Më vonë do të mësojmë se ka mënyra për te zgjidhur situatat e gabimeve që shkaktohen nga shtypja e të dhënave të përdoruesit. Mund të përdoret cin për të kërkuar më shumë se një e dhënë hyrëse nga përdoruesi: cin >> a >> b; gjë që është ekuivalente me cin >> a; cin >> b; në të dy rastet përdoruesi duhet të japë dy të dhëna, një për variablin a dhe një tjetër për variablin b që mund të ndahen me një ndarës: një hapësirë, një karakter tab ose me një karakter që gjeneron një rresht të ri. 14.3 cin dhe stringjet Ne mund të përdorim cin për të futur stringje nëpërmjet variablave të tipit string me operatorin (>>) siç do të bënim me variablat e tipeve të tjerë themelore. Variabla të tipit string do të ishin variablat që kanë si vlera të tyre stringje. cin >> njestring; Megjithatë, cin gjatë futjes së të dhënës ndalon së vepruari sapo gjen një karakter hapësirë, kështu në këtë rast do të marrë fjalën e parë të një fjalie. Kjo sjellje mund ose jo të jetë ajo që ne duam; për shembull në se ne duam të marrim një fjali nga përdoruesi, kjo procedurë hyrje nuk është e dobishme. Me qëllim futje të një rreshti të plotë, ne mund të përdorim funksionin getline, që është më i rekomanduar për të marrë çfarë përdoruesi fut si të dhënë në cin: // cin me stringje #include <iostream> #include <string> using namespace std; int main () { string njestr; cout << "Emri juaj? "; getline (cin, njestr); cout << "Pershendetje " << njestr << ".n"; cout << "Dega juaj? "; getline (cin, njestr); cout << "Me pelqen " << njestr Emri juaj? Arjan Bregu Pershendetje Arjan Bregu. Dega juaj? Informatike Ekonomike Me pelqen Informatike Ekonomike shume!
  • 45. << " shume!n"; return 0; } Figura 14. 2 Përdorim i getline per stringjet që përmbajnë hapësira
  • 46.
  • 47. 15. Strukturat e Kontrollit Le të diskutojmë një problem praktik që do ta zgjidhim me një program. Do të përcaktohet në se nxënësi është kalues në bazë të pikëve që ka marrë në provimet e matures. Janë tre lëndë pikët e të cilave mbidhen. Në se shuma e pikëve e kalon 50 nxënësi konsiderohet kalues, përndryshe jo. Bllokskema e algoritmit të këtij problemi do të paraqitej në një nga bllokskemat e mëposhtme: Figura 15.1 Bllokskema e problemit të vlerësimit të nxënësve Bllokskema e parë jep një përgjigje vetëm për nxënësin kalues, e dyta jep përgjigje për të dy rastet. Një program zakonisht nuk kufizohet me një sekuencë instruksionesh që ekzekutohen njëri pas tjetrit. Gjatë ekzekutimit të tij, mund të kemi degëzime, si në fig. 15.1, ose marrje vendimesh. Për këtë arsye, C++ siguron strukturat e kontrollit që shërbejnë për të specifikuar çfarë duhet bërë nga programi ynë, kur dhe në çfarë rrethanash. Me strukturat e kontrollit ne do të prezantojmë një koncept të ri: statementin e përbërë ose bllokun. Një bllok është një grup satementesh që ndahen me pikëpresje (;) si gjithë statementet e C++, por të grupuara së bashku në kllapa gjarpërushe{ }: { statement1; statement2; statement3; } Një statement mund të jetë ose një statement i thjeshtë (një instruksion që mbaron me një pikëpresje) ose një statement i përbërë (shumë instruksione të grupuara në një bllok), si ai që sapo paraqitëm. Në rastin kur duam që statementi të jetë i thjeshtë, nuk është e nevojshme ta përfshijmë atë midis kllapave ({}). Por në rastin kur duam që një statement të jetë i përbërë, ai Fillim Fusni pikët e provimeve test1, test2, test3 Shuma > 50 fund Nxenes kalues po jo Fillim Fusni pikët e provimeve test1, test2, test3 Shuma > 50 fund Nxenes kalues po jo Nxenes jo kalues
  • 48. duhet të përfshihet midis kllapave ({}), duke formuar një bllok. Struktura e një kondite: if dhe else if. . është një nga strukturat e kontrollit. Në se përdoret fjala-çelës if për të ekzekutuar një statement ose bllok, ai ekzekutohet vetëm në se një konditë plotësohet. Forma më e thjeshtë e kësaj strukture kontrolli është: if (konditë) statement ku konditë është një shprehje logjike që do të vlerësohet pra një shprehje që mund të ketë dy vlera e vërtetë (true) ose jo e vërtetë (false). Në se kjo konditë është true, statementi ekzekutohet. Në se ajo është false, statement injorohet (nuk ekzekutohet) dhe programi vazhdon menjëherë pas strukturës së konditës. Në se mund të specifikojmë çfarë duam të ndodhë në se kondita nuk plotësohet përdorim fjalën- çelës else. Forma e saj së bashku me if është: if (kondite) statement1 else statement2 Me një bllokskemë një strukture kontrolli do të paraqitej si më poshtë
  • 49. Figura 15.2 Bllokskema e një structure kontrolli if…else. . në rastin e problemit të marrë me sipër do të kishim kodin e mëposhtëm për bllokskemën e parë: // vleresimi i nxenesve #include <iostream> using namespace std; int main () { int test1, test2, test3, shuma = 0; cout << "Fusni piket e tre testeven"; cin >> test1 >> test2 >> test3; shuma = test1 + test2 + test3; if(shuma > 50) cout << "nxenesi eshte kaluesn"; return 0; } Fusni piket e tre testeve 15 16 17 Nxenesi eshte kalues Figura 15.3 Kodi i problemit të vlerësimit të nxënësve, një alterantivë diskutohet dhe në përgjigje të bllokskemës së dytë do të kishim kodin // vleresimi i nxenesve #include <iostream> using namespace std; int main () { int test1, test2, test3, shuma = 0; cout << "Fusni piket e tre testeven"; cin >> test1 >> test2 >> test3; shuma = test1 + test2 + test3; if(shuma > 50) cout << "nxenesi eshte kaluesn"; else cout << "nxenesi eshte jo kaluesn"; return 0; } Fusni piket e tre testeve 5 10 5 Nxenesi eshte jo kalues Figura 15.4 Kodi i problemit të vlerësimit të nxënësve, dy alternativa Në rastin kur ka më shumë statemente që kryen kur kondita plotësohet ose jo, përdoren kllapat gjarpëruese si në kodin e mëposhtëm: // vleresimi i nxenesve #include <iostream> using namespace std; Fusni piket e tre testeve 45 30
  • 50. int main () { int test1, test2, test3; int shuma = 0, diferenca = 0; cout << "Fusni piket e tre testeven"; cin >> test1 >> test2 >> test3; shuma = test1 + test2 + test3; if(shuma > 50){ diferenca = 100 - shuma; cout << "nxenesi eshte kalues,n"; cout << " per " << diferenca << " pike plotesohen 100n"; } else{ diferenca = 51 - shuma; cout << "nxenesi eshte jo kaluesn"; cout << "duhen dhe " << diferenca << " pike per te kaluarn"; } return 0; } 20 Nxenesi eshte kalues, per 5 pike plotesohen 100 Figura 15.5 Kodi i problemit të vlerësimit të nxënësve, më shumë se një statement në çdo alternativë Strukturat if + else mund të bashkohen në se duam të verifikojmë më shumë se dy alternativa. Le të shohim shembullin e mëposhtëm: // vleresimi i nxenesve #include <iostream> using namespace std; int main () { int test1, test2, test3, shuma = 0, diferenca = 0; cout << "Fusni piket e tre testeven"; cin >> test1 >> test2 >> test3; shuma = test1 + test2 + test3; if(shuma > 50) cout << "nxenesi eshte kaluesn"; else if(shuma > 0 && shuma <= 50) cout << "nxenesi eshte jo kaluesn"; else cout << "nxenesi mungoi ne provimn"; return 0; } Fusni piket e tre testeve 0 0 0 nxenesi mungoi ne provim Figura 15.6 Kodi i problemit të vlerësimit të nxënësve, më shumë se dy alternativa
  • 51. Venë re këtu shprehjen logjike (shuma > 0 && shuma <= 50) Kuptimi i së cilës është shuma është > 0 dhe shuma është <= 50, që është një shprehje e kompozuar nga dy shprehje (shuma > 0) krahasimi dhe (shuma <= 50)
  • 52. 16. Strukturat Iterative (Ciklet) Probleme të ndryshme praktike kërkojnë përsëritjen e një serie hapash disa herë. Le të marrim një shembull: Do të llogaritim shumën e 10 numrave të parë natyralë: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10. Mbledhja e 10 numrave realizohet duke përsëritur 10 herë shtimin e një numri në një vend në kujtesë. Në çdo hap pasardhës numri rritet me një derisa të arrijmë në numrin 10. Në këtë rast numri i herëve që bëhen të njëjtat veprime (shtohet numri në vendin e kujtesës, rritet numri me një) përputhet me numrin më të madh pra do të realizohen 10 cikle me të njëjtat veprime. Duhet të kemi parasysh se fillimisht vendi në kujtesë duhet të ketë vlerën zero, mbasi duhet të sigurohemi që vlera fillestare në këtë vend të kujtesës nuk duhet të ketë efekt në rezultatin përfundimtar. Algoritmi i këtij problem do të paraqitej me bllokskemën: Figura 16. 1 Bllokskema e llogaritjes së shumës së 10 numrave te pare natyralë Nga këndvështrimi i programit, ciklet kanë si qëllim përsëritjen e një ose disa statementeve një numur herësh, në se një konditë plotësohet. Në C++ ka disa formate që realizojnë një cikël. Cikli while Formati i tij është: while (shprehje) statement dhe funksionaliteti i tij është thjesht të përsërisë statement përderisa kondita (shprehje)
  • 53. mbetet e vërtetë. Për shembull, ne do të bëjmë një program për të numuruar në mënyrë zbritëse. Para se të shkruajmë kodin le ta paraqesim këtë rast me një bllokskemë e më pas shkruajmë kodin duke përdorur një cikël while: Figura 16. 2 Bllokskema e numurimit zbritës të n numrave // numurim zbrites duke perdorur while #include <iostream> using namespace std; int main () { int n; cout << "Filloni me numrin > "; cin >> n; while (n>0) { cout << n << ", "; --n; } cout << "Nisu!n"; return 0; } Filloni me numrin > 8 8, 7, 6, 5, 4, 3, 2, 1, Nisu! Figura 16. 3 Një shembull i përdorimt të ciklitwhile Kur programi fillon, përdoruesit i kërkohet të fusë një numur fillestar për numurimin zbritës. Atëhere cikli fillon; në se vlera e futur e plotëson konditën n > 0 (n të jetë më e madhe se zero), blloku që vijon konditën do të ekzekutohet dhe përsëritet përderisa kondita (n > 0) mbetet e vërtetë. I gjithë procesi i programit të mëparshëm mund të interpretohet në përputhje me skriptin që vijon (që fillon në main): fillimLexo numrin n n>0? Afisho n n=n-1 pojo fund
  • 54. 1. Përdoruesi i jep një vlerë n-së 2. Kontrollohet kondita while(n > 0). Në këtë pikë ka dy mundësi: * kondita është e vërtetë: statement ekzekutohet (hapi 3) * kondita nuk është e vërtetë: injorohet statement dhe vazhdohet pas tij (hapi 5) 3. Ekzekutohet statementi: cout << n << ", "; --n; (afishohet vlera n në ekran dhe zvogëlohet n me 1) 4. Fundi i bllokut. Kthimi automatik në hapin 2 5. Vazhdon program menjëherë pas bllokut: afishohet Nisu! Dhe programi mbaron. Kur krijojmë një cikël while, ne duhet gjithmonë të konsiderojmë që ai duhet të mbarojë në një moment, prandaj ne duhet të sigurojmë në bllok mënyrën që ta detyrojnë konditën të bëhet false, Përndryshe cikli do të vazhdojë pafundësisht. Në rastin tonë ne kemi veprimin --n; që pakëson vlerën e variablit që vlerësohet në konditë (n) me një – kjo gjë eventualisht do ta bëjë konditën (n > 0) false pas një numri hapash të ciklit; për të qënë më specifik, kur n bëhet 0, d.m.th. kur ciklit while i numurimit zbritës mbaron. Cikli do-while Formati i tij është: do statement while (kondita); Funksionaliteti i tij është ekzaktësisht i njëjtë si cikli while, më përjashtimin që kondita në ciklin do-while vlerësohet pas ekzekutimit të statementit në vend të vlerësimit para tij, duke garantuar kështu të paktën një ekzekutim edhe në rastin kur kondita nuk plotësohet asnjëherë. Për shembull duam të realizojmë një program që kërkon një numur nga ne dhe ky process vazhdon përderisa nuk kemi futur numrin zero. Ky është një rast që justifikon përdorimin e një sintakse do . . .while të ciklit gjë që shihet dhe nga bllokskema dhe programi që vijojnë: fillim Lexo numrin n n!=0?
  • 55. Figura 16. 4 Bllokskema e futjes së një numri përderisa ai nuk është zero // kerkimi i nje numri #include <iostream> using namespace std; int main () { unsigned long n; do { cout << "Futni nje numur(0-fund): "; cin >> n; cout << "Ju futet numrin: " << n << "n"; } while (n != 0); return 0; } Futni nje numur(0-fund): 12345 Ju futet numrin: 12345 Futni nje numur(0-fund): 160277 Ju futet numrin: 160277 Futni nje numur(0-fund): 0 Ju futet numrin: 0 Figura 16. 5 Një shembull i përdorimit të ciklitdo..while Cikli do-while zakonisht përdoret kur variablat që përbëjnë konditën përcaktohen fillimisht në trupin e ciklit, si në rastin e mëparshëm, ku n e merr vlerën brenda në bllok dhe do jetë ajo që do të përcaktojë fundin e ciklit. Në se nuk fusim vlerën 0, shohim që cikli përsëritet më shumë herë. Cikli for Formati i tij është: for (inicializimi; kondita; modifikim) statement; dhe funksioni i tij kryesor është të përsërisë statement derisa kondita të mbetet e vërtetë, si dhe në ciklin while. Por përveç kësaj, cikli for siguron një vend për statemente inicializimi dhe një për statemente modifikimi. Kështu ky cikël është specifikisht i dezinjuar për të realizuar veprime përsëritëse me një numrator i cili inicializohet dhe rritet në çdo hap të ciklit (hap). Ai punon në mënyrën që vijon: pojo fund
  • 56. 1. Inicializimi ekzekutohet. Në përgjithësi variablit numrator i jepet një vlerë fillestare. Kjo pjesë ekzekutohet vetëm një herë. 2. Kondita kontrollohet. Në se është e vërtetë cikli vazhdon, përndryshe cikli mbaron dhe statement kapërcehet (nuk ekzekutohet). 3. statement ekzekutohet. Si zakonisht, ai mund të jetë ose një statement i vetëm ose një bllok statemetesh të përfshira në kllapat { }. 4. Së fundi, çfarëdo që të jetë specifikuar në fushën e shtimit, kjo ekzekutohet dhe cikli kthehet prapa në hapin 2. Këtu është një shembull i numurimit zbritës duke filluar nga numri 10 duke përdorur ciklin for:
  • 57. Figura 16. 6 Bllokskema e numurimit zbritës të numrave duke filluar nga 10 fillim n>0? Afisho n n=n-1 pojo fund n=10
  • 58. // numurimit zbritës duke përdorur ciklin for #include <iostream> using namespace std; int main () { for (int n=10; n>0; n--) { cout << n << ", "; } cout << "Nisu!n"; return 0; } 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, Nisu! Figura 16. 7 Një shembull i përdorimit të ciklitfor.. Pjesët e inicializimit dhe të shtimit në formatin for (inicializimi; kondita; modifikim) statement . . . janë jo të detyrueshme. Ato mund të mbeten bosh, por në çdo rast shënja e pikëpresjes midis tyre duhet të shkruhet. Për shembull ne mund të shkruajmë: for (;n < 10;) në se ne do të donim të mos bënim inicializim dhe modifikim; ose for (;n < 10;n++) në se ne duam të përfshijmë një fushë modifikimi por jo inicializim (ndoshta sepse variabli është inicializuar përpara). Statementi break Duke përdorur statementin break ne mund ta ndërpresim ciklin edhe në se kondita për mbarimin e tij nuk plotësohet. Ky statement mund të përdoret për të ndërprerë një cikël të pafundëm ose forcërisht ta ndërpresim atë para mbylljes natyrale të tij. Për shembull duam ta ndërpresim numurimin zbritës para mbylljes natyrale të tij: Figura 16. 8 Bllokskema e numurimit zbritës të n numrave që mbaron para mbylljes natyrale të tij // shembull i break ne nje cikel 10, 9, 8, 7, 6, 5, 4, 3, numurimi perfundon! fillim n>0? Afisho n n=n-1 pojo fund n=10 n==3? po jo
  • 59. #include <iostream> using namespace std; int main () { int n; for (n=10; n>0; n--) { cout << n << ", "; if (n==3) { cout << "numurimi perfundon!"; break; } } return 0; } Figura 16. 9 Përdorimi në kod i statementit break
  • 60. Statementi continue Statementi continue shkakton kapërcimin e mbetjes së ciklit në hapin korrent duke shkuar në fund të bllokut të statementeve, duke shkaktuar kapërcimin në hapin që vijon të ciklit. Për shembull, ne kapërcejmë numrin 5 në këtë numurim zbritës: Figura 16. 10 Bllokskema e numurimit zbritës të n numrave që kapërcen numrin 5 // shembull i continue ne nje cikel #include <iostream> using namespace std; int main () { for (int n=10; n>0; n--) { if (n==5) continue; cout << n << ", "; } cout << "Nisu!n"; return 0; } 10, 9, 8, 7, 6, 4, 3, 2, 1, Nisu! Figura 16. 11 Shembull i përdorimit të statementit continue fillim n>0? Afisho n n=n-1 pojo fund n=10 n==5? po jo
  • 61. 17. Funksionet Shembuj Funksionesh Përdorimi i funksioneve mundëson strukturimin e programeve tona në një formë modulare duke bërë të mundur atë çka quhet programimin i strukturuar, që na ofrohet në C++. Le të shohim shembullin e një programi në C++ që llogarit shumën e dy numrave të plotë: Kodi burim Rezultati gjatë ekzekutimit //ky program gjen shumen e dy numrave #include <iostream> using namespace std; int main () { int a=1, b=2, rezultat; rezultat = a+b; cout<< "shuma e a, b: " << rezultat << endl; return 0; } shuma e a, b: 3 Figura 17. 1 Llogaritja e shumës së dy numrave të plotë Të njëjtën gjë mund ta realizojmë ndryshe në C++, duke përdorur një funksion, funksionin shuma ne këtë shembull: Kodi burim Rezultati gjatë ekzekutimit //ky program gjen shumen e dy numrave //duke përdorur një thirrje funksioni, //shih përcaktimin e funksionit shuma #include <iostream> using namespace std; //percaktimi i funksionit shuma() int shuma(int a, int b) { int s; s=a+b; return (s); } int main () { int a=1, b=2, rezultat; rezultat= shuma(a,b); cout<< "shuma e a, b: " << rezultat << endl; return 0; shuma e a, b: 3
  • 62. } Figura 17. 2 Llogaritja e shumës së dy numrave të plotë duke përdorur një funksion Ose një formë tjetër e pranueshme nga C++ do të ishte: Kodi burim Rezultati gjatë ekzekutimit //ky program gjen shumen e dy numrave duke thirrur një //funksion, shih deklarimin dhe percaktimin e funksionit #include <iostream> using namespace std; //deklarimi i funksionit prototip shuma() int shuma(int, int); int main () { int a=1, b=2,rezultat; rezultat= shuma(a,b); cout<< "shuma e a, b: " << rezultat << endl; return 0; } //percaktimi i funksionit shuma() int shuma(int a, int b) { int s; s=a+b; return (s); } shuma e a, b: 3 Figura 17. 3 Llogaritja e shumës së dy numrave të plotë duke përdorur një funksion Në shembujt e mësipërm realizohet e njëjta gjë por fillimisht gjithshka realizohet në funksionin main të programit dhe në rastin e dytë dhe të tretë veprimi që do të kryejmë dhe që është llogaritja e shumës së dy numrave, realizohet në funksionin shume. Brenda këtij funksioni kryhet produkti i dy numrave dhe rezultati kthehet nga funksioni me statmentin return. Ky funksion thirret në main dhe me që ai kthen një vlerë, kjo e fundit vendoset në një statement afishimi që është cout. Siç e shohim më sipër, funksioni mund të përcaktohet para se ai thirret (si në rastin e dytë, ku është përcaktuar mbi main fig 17. 2), ose vetëm deklarohet para se të thirret dhe përcaktohet poshtë funksionit main siç është vepruar në rastin e tretë, fig 17. 3. Pra, një funksion është një grup statementesh që ekzekutohet kur thirret në një pikë të programit. Formati i një funksioni është si më poshtë: tipi emri( parameter1, parameter2, ...) { statemente } ku:
  • 63.  tipi është specifikuesi i tipit të asaj ç’ka funksioni kthen. Në shembullin e mësipërm është int.  emri është identifikuesi me të cilin thirret një funksion. Në shembullin e mësipërm është shuma.  parametrat (aq sa nevojiten): çdo parametër shoqërohet me tipin e tij i ndjekur nga një identifikues, si në një deklarim të thjeshtë variabli (për shembull: int x) dhe që vepron në një funksion si një variabël i rregullt lokal. Nëpërmjet parametrave kalohen vlerat e argumentave. Pra termi argument përdoret në thirrjen e funksionit dhe termi parametër në përcaktimin e funksionit. Parametrat ndahen me presje. Kështu në shembujt e mësipërm kemi argumentat a dhe b në thirrjen shuma(a, b) të funksionit shuma() në rreshtin cout<< "shuma e a, b: " << rezultat << endl; dhe kemi parametrat o dhe po në përcaktimin e tij: int shuma(int a, int b) { int s; s = a + b; return s; } Pra kemi një korrespondencë të tilllë midis argumenteve dhe parametrave: Në funksionin main, ne thirrëm funksionin shuma duke kaluar në të dy vlera: a dhe b, që u korrespondojnë parametrave int a dhe int b të deklaruara në funksionin shuma. Parametrat mund të shënohen me çfarëdo lloj emrash, ndaj dhe quhen shpesh parametra formalë. Per shembull mund të shkruanim: int shuma(int x, int y) { int s; s = x + y; return s; } në vend të int shuma(int a, int b) { int s; s = a + b; return s; }
  • 64. do të ishte e njëjta gjë dhe do të kishim korrespondencën:  statementet përbëjnë trupin e funksionit. Trupi i funksionit është një bllok statementesh të futur në kllapat { }. Në shembullin e mësipërm ky bllok statementesh është: { int s; s = a + b; return s; } Tani mund të kuptojmë më mirë strukturën main që kemi përmëndur dhe më parë. main vetë nuk është gjë tjetër veçse një funksion që kthen një vlerë int. Duhet të kujtojmë që një program në C++ gjithmonë fillon me ekzekutimin e funksionit main. Në pikën ku funksioni shuma thirret në main, kontrolli kalon nga main në funksionin shuma. Vlerat e dy argumenteve që kalojnë në thirrjen e funksionit si (a dhe b) kopjohen në variablat a dhe b që kuptohen si variabla lokale për funksionin shuma. Rreshti cout<< "shuma e a, b: " << rezultat << endl; afishon rezultatin e veprimit. Shembull i një funksioni pa parametra Shembullin e mësipërm mund ta trajtonim dhe me një funksion pa parametra, si më poshtë: Kodi burim Rezultati gjatë ekzekutimit //ky program gjen shumen e dy numrave //duke përdorur një thirrje funksioni, //shih përcaktimin e funksionit shuma #include <iostream> using namespace std; //percaktimi i funksionit shuma() int shuma() { int a, b, s; cout << "Futni vlerat e a, dhe b n"; cin >> a >> b; s=a+b; return (s); } int main () { Futni vlerat e a, dhe b 1 2 shuma e a, b: 3
  • 65. int rezultat; rezultat= shuma(); cout<< "shuma e a, b: " << rezultat << endl; return 0; } Figura 17. 4 Llogaritja e shumës së dy numrave të plotë duke përdorur një funksion pa parametra Fusha e Veprimit të Variablave Fusha e veprimit të variablave të deklaruar në funksion ashtu si dhe në një bllok tjetër të brendshëm {} është vet ky funksion ose bllok dhe ato nuk mund të përdoren jashtë tyre. Në shembullin e mësipërm, fig 17. 4, do të ishte i pamundur përdorimi i variablave a, b në funksionin main mbasi ata janë variabla lokalë për funksionin shuma, dhe nuk ekzistojnë jashtë tij. Figura 17. 5 bën një përmbledhje të rasteve të ndryshme të fushës së veprimit të variablave në varësi të faktit se ku ata deklarohen në një program. Le të ilustrojmë me disa shembuj fushën e veprimit të variablave në raste të ndryshme: Një variabël lokal: nuk ekziston më jashte bllokut ku është deklaruar Ekzekutimi # #include <iostream> using namespace std; int ShtoDhePrinto() { int vlera = 1; // variabel lokal ++vlera; return vlera; } // vlera nuk ekziston me int main() { int rezultat; rezultat = ShtoDhePrinto(); cout << "vlera= " << rezultat << endl; rezultat = ShtoDhePrinto(); cout << "vlera= " << rezultat << endl; return 0; } 2 2 Një variabël global: është i vlefshëm kudo në program Ekzekutimi #include <iostream> using namespace std; int vlera = 1; // variabel global int ShtoDhePrinto() { ++vlera; return vlera; } // vlera nuk ekziston me 2 3
  • 66. int main() { int rezultat; rezultat = ShtoDhePrinto(); cout << "vlera= " << rezultat << endl; rezultat = ShtoDhePrinto(); cout << "vlera= " << rezultat << endl; return 0; } Figura 17.5 Fusha e veprimit të variablave Duhet të dimë se, fusha e veprimit të variablave lokalë kufizohet brenda bllokut ku ata deklarohen. Megjithatë, ne e kemi mundësinë e deklarimit të variablave globalë; ata janë të aksesueshëm nga çdo pikë e kodit brenda dhe jashtë funksioneve. Që të përdorim një variabël global, duhet ta deklarojmë atë jashtë çdo funksioni ose blloku, fig 17. 5, shembulli i dytë. Ribëjmë shembullin në fig 17.4 duke shtuar atje një variabël global që përdoret sa herë llogaritet shuma e dy numrave. Kodi burim Rezultati gjatë ekzekutimit //ky program gjen shumen e dy numrave //duke përdorur një thirrje funksioni, //ky veprim përsëritet 5 herë #include <iostream> using namespace std; int numerator = 0; //percaktimi i funksionit shuma() int shuma() { int a, b, s; cout << "Futni vlerat e a, dhe b n"; cin >> a >> b; s=a+b; numerator++; //shtohet me nje numroatori return (s); } int main () { int rezultat; while(numerator < 5){ rezultat= shuma(); cout<< "shuma e a, b: " << rezultat << endl; } Futni vlerat e a, dhe b 1 2 shuma e a, b: 3 Futni vlerat e a, dhe b 10 25 shuma e a, b: 35 Futni vlerat e a, dhe b 15 17 shuma e a, b: 32 Futni vlerat e a, dhe b 11 22 shuma e a, b: 33 Futni vlerat e a, dhe b 32 43 shuma e a, b: 75
  • 67. return 0; } Figura 17.6 Shembull përdorimi i variablave lokale dhe globalë Shohim në fig 17.6 përdorimin e variablit global numrator, që është deklaruar jashtë çdo funksioni dhe është inicializuar me vlerën 0. Vemë re se ky variabël njihet nga të dy funksionet që janë në këtë program, funksioni main dhe shuma. Ushtrim: 1. Realizoni një program që afishon vlerën e produkteve të një magazine sipas modelit të shembullit të mësipërm. Përdorni një variabël global që tregon numrin e produktit të afishuar. Funksionet pa tip. Përdorimi i void. Siç dhe e pamë më sipër sintaksa e deklarimit të një funksioni tipi emri( parameter1, parameter2, ...) { statemente } fillon me një tip, që është tipi i vet funksionit (d.m.th tipi i të dhënës që kthehet nga funksioni me statementin return). Po çfarë ndodh kur ne nuk duam të kthejmë një vlerë? Së pari kur mund të paraqitet një rast i tillë, pra kur duam një funksion i cili të mos na kthejë asnjë vlerë ? Një rast i tillë do të ishte kur ne i japim funksionit si detyrë, për shembull, të bëjë afishime. Kur funksioni nuk kthen vlerë, tipi i kthimit për funksionin duhet të jetë void, për shembull: Kodi burim Rezultati gjatë ekzekutimit // shembull i nje funksioni void #include <iostream> using namespace std; void printim_mesazhi () { cout << "Nje funksion void!"; } int main () { printim_mesazhi(); return 0; } Nje funksion void! Figura 17. 7 Një funksion që nuk kthen vlerë, tipi i kthimit është void Le të ribëjmë ndryshe shembullin e mësipërm fig 17.6 duke synuar që për afishimin e rezultatit të përdorim një tjetër funksion të cilin po e quajmë afishim. Kodi burim Rezultati gjatë Ekzekutimit
  • 68. //ky program gjen shumen e dy numrave //duke përdorur një thirrje funksioni, //ky veprim përsëritet 5 herë #include <iostream> using namespace std; int numerator = 0; //percaktimi i funksionit shuma() int shuma() { int a, b, s; cout << "Futni vlerat e a, dhe b n"; cin >> a >> b; s=a+b; numerator++; //shtohet me nje numroatori return (s); } void afishim (int r){ cout<< "shuma e a, b: " << r << endl; } int main () { int rezultat; while(numerator < 5){ rezultat= shuma(); afishim(rezultat); } return 0; } Futni vlerat e a, dhe b 1 2 shuma e a, b: 3 Futni vlerat e a, dhe b 10 25 shuma e a, b: 35 Futni vlerat e a, dhe b 15 17 shuma e a, b: 32 Futni vlerat e a, dhe b 11 22 shuma e a, b: 33 Futni vlerat e a, dhe b 32 43 shuma e a, b: 75 Figura 17. 8 Afishimi i rezultatit i organizuar në një funksion void Në fig 17.8 afishimi i rezultatit të programit 17.6 është vendosur në funksionin afishim me tip kthimi void. void afishim (int r){ cout<< "shuma e a, b: " << r << endl; } Vemë re se një funksion me tip kthimi void nuk mund të kombinohet me statementin cout, mbasi një funksion i tillë nuk kthen vlerë, si rrjedhim ai thjesht thirret si në fig. 17.8 Çfarë duhet gjithmonë të kujtojmë është se formati i thirrjes së një funksioni përfshin emrin e tij dhe parametrat brenda parantezave. Kur nuk kemi parametra, parantezat do të shkruhen, por në këtë rast pa parametra brenda tyre, për shembull:
  • 69. shuma(a,b) // kodi ne Fig. 17.3 afishim(); // kodi ne Fig 17.8 parantezat tregojnë që kemi të bëjmë me një thirrje funksioni dhe jo me emrin e një variabli në Rekursiviteti Është një mënyrë zgjidhje problemi që e kalon atë në një version më të thjeshtë të problemit origjinal dhe kjo gjë vazhdon në disa hapa. Kur themi version më të thjeshtë, kuptohet një vlerë më e vogël parametri deri në një vlerë që provokon dhe fundin e këtij procesi rekursiv. Marrim si shembull llogaritjen e faktorialit e një numri (n!). Formula matematike është: n! = n * (n-1) * (n-2) * (n-3) ... * 1 më konkretisht, 5! (faktoriali i 5) do të ishte: 5! = 5 * 4 * 3 * 2 * 1 = 120 Vemë re se mund të shkruajmë : n! = n * (n – 1)! , duke e shënuar n! me f(n), mund të shkruajmë: f(n) = n * f(n-1) Pra f(n-1) nuk është gjë tjetër vetëm një version më i thjeshtuar i f(n), nga pikëpamja e vlerës së parametrit të tij. Kjo është dhe esenca e mënyrës rekursive të një problem. Më poshtë jepet kodi i dy mënyrave të ndryshme që mund të përdorim për zgjidhjen e n!. Një mënyrë është ajo që ne kemi përdorur deri tani për zgjidhjen e një problem të tillë dhe që e quajmë iterative dhe një mënyrë është mënyra rekursive. Mënyra iterative Mënyra rekursive // Programi llogarit n! #include <iostream> using namespace std; long faktorial(int n) { int k; long rezultat = 1; for (k = 2; k <= n; k++) rezultat = rezultat * k; return rezultat; } int main () { int n; cout << "fusni nje vleren"; cin >> n; // Programi llogarit n! #include <iostream> using namespace std; long faktorial(int n) { if (n==1) return 1; else return n * faktorial(n-1); } int main () { int n; cout << "fusni nje vlere:n"; cin >> n; cout << " n!: "
  • 70. cout << " n!: " << faktorial(n) <<endl; return 0; } fusni nje vlere: 5 n!: 120 << faktorial(n) <<endl; return 0; } fusni nje vlere: 5 n!: 120 Figura 17. 9 Një zgjidhje iterative(majtas) dhe një zgjidhje rekursive (djathtas) e faktorialit Vemë re se në funksionin faktorial (në rastin rekursiv) është përfshirë një thirrje e atij vetë, por vetëm në se argumenti që kalon është më i madh se 1, përndryshe funksioni ndalon. Përcaktimi i një alternative ndalimi të vlerës së argumentit është esencial për rekusivitetin, përndryshe do të krijonim një process pa fund. Ky funksion ka një kufizim për arsye të tipit të të dhënave të përdorura në dezinjimin e tij (long) për më thjeshtësi. Rezultati i marrë nuk do të jetë i vlefshëm për vlerat shumë më të mëdha se 10! ose 15!, në varësi të sistemit ku ne e kompilojmë atë. Si realizohet procesi i rekursivitetit: Figura 17. 10 Zgjidhja rekursive e 5! Deklarimi i funksioneve Deri tani kemi parë raste kur përcaktimi i funksionit bëhet para funksionit main ose para funksionit ku ai thirret, ose funksioni mund të deklarohet si prototip para funksionit ku ai thirret dhe përcaktohet pas funksionit main duke e lënë këtë të fundit si funksion të parë në kodin burim. Të dy variantet janë të mundshëm. Ajo që duhet të kemi parasysh është që një funksion nuk mund të thirret në se nuk është përcaktuar ose deklaruar më parë. Më shpesh ne përdorim mënyrën e dytë d.m.th. deklarohet prototipi i funksionit para thirrjes së tij dhe poshtë funksionit ku ai thirret bëhet përcaktimi i tij. Forma e deklarimit të një funksioni është: tipi emri ( tipi_argumentit1, tipi_argumentit2, ...);