You are on page 1of 43

Prof. Dr. Agni Dika Material punues. Nuk sht pr shumzim!

02
Direktivat paraprocesorike

2 Programimi i avancuar n C++

Njohuri t prgjithshme
Kompjutert jan paisje elektronike digjitale t cilat i kuptojn nj numr t caktuar komandash, si jan komandat pr marrje t t dhnave prmes njsive hyrse, ato pr kryerje t operacioneve t ndryshme aritmetikore dhe logjike mbi t dhnat (prmes njsis aritmetiko-logjike t procesorit), komandat pr ruajtje t t dhnave n memorien periferike dhe pr paraqitje t rezultateve n njsit dalse. Grumbulli i komandave t cilat i ipen kompjuterit me qllim t zgjidhjes s nj problemi duke u mbshtetur n nj algoritm t caktuar quhet program (ang. program), kurse vet procesi i shkruarjes s programit njihet si programim (ang. programming). Puna e kompjuterit mbshtetet n shfrytzimin e sinjaleve digjitale (ang. digital signals), prmes t cilve paraqiten dy shifrat binare (ang. binary digit) 0 dhe 1 , zakonisht si dy nivele t ndryshme tensionesh. Pr kt arsye, komandat t cilat i ipen kompjuterit, si dhe t dhnat q prpunohen brenda tij, paraqiten si vargje t shifrave binare . Kurse gjuha prmes s cils komunikohet me kompjuterin njihet si gjuh e makins (ang. machine language). Shkruarja e programeve n gjuhn e makins sht nj pun e rnd, sepse duhet t mbahen n mend vargje t shifrave binare pr komandat e veanta si dhe t konvertohen t dhnat e zakonshme n nj kod binar (ang. binary code). Me qllim t lehtsimit t programimit n gjuhn e makins mund t shfrytzohet gjuha asembler (ang. assembly language), te e cila komandat paraqesin shkurtesa ose kode mnemonike (ang. mnemonic code), kurse vlerat q shfrytzohen gjat llogaritjeve ipen direkt si numra heksadecimal, ose indirekt prmes emrave t variablave prkatse. Kshtu, p.sh. komandat pr mbledhje, zbritje dhe shumzim kompjuterit i jepen prmes shkurtesave ADD , SUB dhe MULT . Gjat ksaj, kto komanda dhe vlerat numerike prcjellse kompjuteri nuk i kupton direkt sepse nuk jan t shkruara n form binare. Pr kt qllim ato duhet t prkthehen n gjuh t makins duke e shfrytzuar programin i cili quhet Asembler (ang. assembler). Gjuha e makins dhe gjuha asembler, meq jan t afrta me logjikn e puns s kompjuterit, njihen si gjuh t ulta programuese (ang. low-level languages). Por, me qllim t lehtsimit t procesit t programimit, shfrytzohen gjuh t larta programuese (ang. high-level languages), t cilat jan t afrta me logjikn e puns s njeriut. T tilla jan, p.sh. gjuht FORTRAN , BASIC , COBOL , C , PASCAL , C++ , JAVA , C# etj., ose versionet e ndryshme t tyre. Nnkuptohet se programet e shkruara n gjuht e larta programuese nuk kuptohen direkt nga kompjuteri. Prandaj ato duhet t prkthehen n gjuhn e makins duke e shfrytzuar programin i cili njihet si kompilues (ang. compiler). Pr programin e prkthyer n gjuhn e makins thuhet se paraqet nj program objektiv (ang. object program), ose nj kod objektiv (ang. object code).

Direktivat paraprocesorike 3 Programi i shkruar n gjuhn programuese C++ paraqet program burimor dhe si i till ruhet n nj fajll burimor . Me Editor procesin e kompilimit, kontrollohet saktsia e komandave t shkruara dhe, Programi burimor nse nuk ka gabime, programi burimor prkthehet n program objektiv , gj q Compiler shihet edhe n paraqitjen skematike e cila sht dhn n Fig.1.1 . Programi objektiv Fig.1.1 Procesi i krijimit t programit ekzekutiv nga programi burimor
Fajlla t tjer objektiv Linker Programi ekzekutiv

N fund, pr ta fituar programin ekzekutiv , prmes linkuesit (ang. linker) fajllit objektiv i shtohen edhe fajlla t tjer objektiv, t marra nga biblioteka standarde ose edhe prej bibliotekave tjera me fajlla. Programi ekzekutiv i cili fitohet si rezultat gjat procesit n fjal, ruhet n nj fajll ekzekutiv . Programet burimore n gjuhn C++ plotsohen edhe me funksione t domosdoshme q merren nga bibliotekat e shumta t ksaj gjuhe. Pr kt qllim, n fillim t programeve vendosen t ashtuquajturit fajlla t ballins , si direktiva paraprocesorike (ang. preprocessor directive), t cilat fillojn me simbolin # . Inkorporimi i tyre n programet Editor burimore, para kompilimit, bhet prmes programit i cili quhet paraprocesor (ang. Programi burimor preprocessor). Paraqitja skematike e Fajlla t ballins dhe Preprocessor procesit t krijimit t programit direktiva paraprocesorike ekzekutiv, n kt rast duket ashtu si sht dhn n Fig.1.2 . Compiler
Programi objektiv

Fig.1.2 Fajlla t tjer objektiv Linker Versioni i plotsuar i procesit t krijimit t programit ekzekutiv Programi ekzekutiv Direktivat paraprocesorike, pr dallim nga komandat tjera q paraqiten n program fillojn me simbolin # . Para kompilimit, prmes paraprocesorit kto direktiva insertohen brenda programit n pozitn prkatse. N gjuhn programuese C++ , fajllat burimor zakonisht e kan prapashtesn .cpp , fajllat e ballins - prapashtesn .h , ose jan pa prapashtes, fajllat objektiv - prapashtesn .obj , kurse fajllat ekzekutiv dallohen me prapashtesn .exe .

4 Programimi i avancuar n C++ Pasi t prfundoj procesi i krijimit t programit ekzekutiv, prmes programit Loader (shih Fig.1.3 ) ai vendoset n memorien kryesore t kompjuterit. N fund, si rezultat i Editor puns s hardverit (ang. hardware) prkats, programi ekzekutohet dhe i Programi burimor jep rezultatet e krkuara.
Fajlla t ballins dhe komanda paraprocesorike Preprocessor Compiler Programi objektiv Fajlla t tjer objektiv Linker Programi ekzekutiv

Fig.1.3 Versioni komplet prej shkruarjes deri te ekzekutimi i nj programi n kompjuter

Loader Programi ekzekutiv n memorie Hardware Rezultatet e programit

Paraprocesori
Rreshtat e programit t cilt fillojn me simbolin # (ang. number sign, shqip thurje) prmbajn direktiva paraprocesorike (ang. preprocessor directive), t cilat thjesht njihen edhe si komanda paraprocesorike . Kto direktiva prpunohen para kompilimit, prmes programit q quhet paraprocesor (ang. preprocessor), i cili sht pjes e kompilerit . Si rezultat, programi burimor modifikohet para se ai t kompilohet n kod objektiv . Kto direktiva nuk jan komanda t gjuhs programuese C++ dhe prandaj n fund t tyre nuk shnohet pikpresja ( ; ). Paraprocesori sht n gjendje t'i njohi direktivat praparocesorike t cilat jan prfshir n tabeln e dhn n Fig.1.4 . #include #ifdef #endif #define #ifndef #line #undef #elif #pragma #if #else #error

Fig.1.4 Direktivat paraprocesorike

Direktivat paraprocesorike 5 N pjesn vijuese, prmes shembujve t programeve elementare do t tregohet shfrytzimi i ktyre direktiva paraprocesorike.

Direktiva #include
Prmes direktivs paraprocesorike #include n programin burimor insertohet kopja e fajllit, i cili sht shkruar paraprakisht dhe ruhet n disk. Zakonisht insertohen fajlla standard t cilt gjenden n prbrje t pakos s gjuhs programuese C++, por insertohen edhe fajlla jostandard t shkruar prej programerit.

Insertimi i fajllave standard


Direktiva paraprocesorike e cila shfrytzohet pr insertimin e fajllave standrad shkruhet n formn: #include <f> Prmes ksaj komande n programin burimor insertohet kopja e fajllit me emr f , i cili sht shnuar brenda kllapave kndore (ang. angle brackets), duke filluar prej rreshtit ku sht vendosur kjo direktiv. E till p.sh. sht direktiva:
#include <iostream>

e cila prdoret pothuajse n do program. Prmes saj n programin burimor insertohet fajlli iostream i klass n t cilin mes tjerash prfshihen definicionet e komandave pr lexim t vlerave hyrse dhe shtypje t rezultateve. Fajllat e till quhen edhe fajlla t ballins (ang. header file), ose fajlla insertues (ang. include file). Forma e dhn e ksaj direktive shfrytzohet pr fajllat q prfshihen n bibliotekn standarde t fajllave t ballins (ang. standard library header files) dhe zakonisht vendosen n fillim t programit.

Insertimi i fajllave jostandard


N programin burimor mund t insertohen edhe fajlla jostandard , t cilt shkruhen nga programeri. Pr insertimin e fajllave t till shfrytzohet direktiva paraprocesorike te e cila emri f i fajllit q insertohet shkruhet nn thonjza: #include "f" N kt rast, emri i fajllit duhet t shoqrohet edhe me shtegun ku ai sht vendosur n disk.

6 Programimi i avancuar n C++ Fajlli q insertohet paraprakisht duhet t jet shkruar prmes nj tekstprocesori. Gjat ruajtjes s tij n disk, prve emrit fajlli mund t ket edhe prapashtes, p.sh. t forms .txt . Shembull Programi prmes s cilit tregohet shfrytzimi i direktivs paraprocesorike #include , pr insertimin e fajllit struct.txt .

// Program include1 #include <iostream> using namespace std; #include "C:\Alfa\struct.txt" int main() { koha dita; dita.a=5; dita.b=dita.a+15; cout << "a=" << dita.a << " b=" << dita.b << endl; return 0; }

Ktu, fajlli struct.txt sht shkruar duke e shfrytzuar programin Microsoft Notepad dhe ruhet n shtegun C:\Alfa . Prmbajtja e ktij fajlli sht: struct koha { int a; double b; }; Si rezultat i insertimit, para kompilimit pjesa e programit burimor duket kshtu:
.....................

struct koha { int a; double b; };


int main() {

Direktivat paraprocesorike 7
koha dita; dita.a=5; dita.b=dita.a+15; cout << dita.a << " " << dita.b << endl; return 0; }

Pr ta par prmbajtjen e pjess fillestare t programit t dhn m sipr, pas insertimeve prmes direktivs paraprocesorike standarde #include <iostream>, duhet t shfrytzohet doracaku i kompilerit prkats. Emri i fajllit mund t shnohet edhe nn kllapa kndore, kshtu:
#include <C:\Test.txt>

N kt rast kompjuteri e krkon fajllin n grupin e fajllave standard dhe pasi nuk e gjen, vazhdon me krkimin e tij n direktoriumin punues aktual, ose n direktoriumin q gjendet n shtegun e shkruar para fajllit (nse ai sht shnuar). Shembull Programi prmes s cilit n programin include2a insertohet fajlli alfa.txt i cili n veti e prmban definimin e funkcionit jeta pr shtypje t nj teksti.

// Programi include2a #include <iostream> using namespace std; #include "C:\Alfa\dita.txt" int main() { jeta(1,10); return 0; }

Pjesa e programit q ruhet n fajllin dita.txt sht:


void jeta(int m,int n) { int i; for (i=m;i<=n;i++) cout << "Koha e bukur\n"; return; }

8 Programimi i avancuar n C++ Si rezultat, programi burimor pas insertimit t fajllit n fjal duket kshtu:
....................... void jeta(int m,int n) { int i; for (i=m;i<=n;i++) cout << "Koha e bukur\n"; return; } int main() { jeta(1,10); return 0; }

Rez. N vijim sht dhn versioni i programit paraprak te i cili fajlli dita.txt insertohet n fund t tij.
// Programi include2b #include <iostream> using namespace std; void jeta(int m,int n); int main() { jeta(1,10); return 0; } #include "C:\Alfa\dita.txt"

N kt rast, programi burimor para kompilimit do t duket kshtu:


....................... void jeta(int m,int n); int main() { jeta(1,10); return 0; } void jeta(int m,int n) { int i; for (i=m;i<=n;i++) cout << "Koha e bukur\n"; return;

Direktivat paraprocesorike 9

Direktivat paraprocesorike mund t vendosen kudo brenda programit. Gjithashtu, fajllat q insertohet nuk sht e thn q t prmbajn trsi funkcionale komplete t programeve. Shembull Versioni i programit paraprak te i cili direktiva paraprocesorike pr insertimin e fajllit delta.txt sht vendosur brenda programit.

// Programi include3 #include <iostream> using namespace std; int main() { int i; #include "C:\Alfa\delta.txt" return 0; }

Nse prmbajtja e fajllit delta.txt sht: for (i=1;i<=10;i++) cout << "Koha e bukur\n"; pas insertimit t tij, para kompilimit programi burimor duket kshtu:
................................. int main() { int i; for (i=1;i<=10;i++) cout << "Koha e bukur\n"; return 0; }

Rez. si edhe m par. Insertimi i nj funkcioni pr gjetje t vlers maksimale t dy vlerave t dhna.

Disa direktiva njkohsisht


N nj program njkohsisht mund t shfrytzohen edhe disa direktiva paraprocesorike pr insertim t fajllave jostandard.

10 Programimi i avancuar n C++

Shembull

Programi n t cilin shfrytzohen direktiva paraprocesorike pr insertim t dy fajllave jostandard InpOut.txt dhe max.txt .

// Program include2x #include <iostream> using namespace std; int max(int,int); int main() { int x,y,z; #include "C:\Alfa\InpOut.txt" z=max(x,y); cout << "Vlera maksimale: " << z << endl; return 0; } #include "C:\Alfa\max.txt"

Prmbajtjet e dy fajllave q insertohen jan: Fajlli InpOut.txt


cout << "Vlera x: "; cin >> x; cout << "Vlera y: "; cin >> y;

Fajlli max.txt

int max(int a,int b) { int y; if (a>b) y=a; else y=b; return y; } Ktu kemi t bjm me funkcionin max prmes s cilit definohet gjetja e vlers maksimale mes dy numrave t dhn a dhe b . Programi, para kompilimit, pas insertimit t fajllave duket kshtu:

Direktivat paraprocesorike 11
................................ int max(int,int); int main() { int x,y,z; cout << "Vlera x: "; cin >> x; cout << "Vlera y: "; cin >> y; z=max(7,4); cout << "Vlera maksimale: " << z << endl; return 0; } int max(int a,int b) { int y; if (a>b) y=a; else y=b; return y; }

Ktu duhet pasur kujdes gjat insertimit t pjesve t programit q variablat e pjesve q insertohen t mos vijn n kundrshtim me ato q egzistojn n pogram (p.sh. inserimi i deklarimit t variablave, ose shfr ytzimi i variablave t cilat njkohsisht paraqitne n pjesn q insertohen dhe n pjesn tjetr t programit).

Direktiva #define
Duke e shfrytzuar direktivn #define mund t definohen konstante simbolike , ose makro paraprocesorike (ang. preprocessor macro). Prmes tyre programi bhet m i lexueshm, m i thjesht dhe mund t modifikohet m leht. N form t prgjithshme kjo direktiv shkruhet kshtu: #define emri tekst Gjat prpunimit t ksaj direktive nga paraprocesori , programi burimor modifikohet para se ai t kompilohet n kod objektiv duke e zvendsuar

12 Programimi i avancuar n C++ emri -in me tekst -in, kudo q ai paraqitet n program. Ktu, emri prcaktohet si identifikator dhe e paraqet emrin e konstantes simbolike ose emrin e makros , kurse tekst -in paraprocesori e sheh vetm si tekst dhe jo si dika q sht shkruar n gjuhn C++. Gjithashtu, identifikatort e shfrytzuar jan t veant dhe paraqesin simbole paraprocesorike (ang. preprocessor symbol), sepse njihen vetm nga paraprocesori. Pavarsisht nga lloji, t gjitha njihen me nj emr makro .

Konstantet simbolike
N formn m t thjesht t saj, direktiva paraprocesorike #define shfrytzohet pr definimin e konstanteve simbolike. Shembull Programi pr llogaritje t siprfaqes dhe perimetrit t rrethit me rreze r , n t cilin prmes direktivs #define fillimisht definohet konstanta simbolike pi ku ruhet vlera e konstantes matematikore 3.1415926 .

// Programi define1 #include <iostream> using namespace std; #define pi 3.1415926 int main() { double r,s,p; cout << "Rrezja e rrethit: "; cin >> r; s=pi*r*r; cout << "\nSiprfaqja e rrethit s=" << s; p=2*pi*r; cout << "\nPerimetri i rrethit p=" << p << endl; return 0; }

Paraprocesori n programin e dhn e krkon konstanten simbolike pi dhe sa her q e gjen at e zvendson me konstanten numerike 3.1415926 . Si rezultat, kodi burimor para kompilimit duket kshtu:
........................................ int main() { double r,s,p; cout << "Rrezja e rrethit: ";

Direktivat paraprocesorike 13
cin >> r; s=3.1415926*r*r; cout << "\nSiprfaqja e rrethit s=" << s; p=2*3.1415926*r; cout << "\nPerimetri i rrethit p=" << p << endl; return 0; }

Prmes direktivs #define mund t definohen edhe konstante simbolike t cilat prmbajn tekste t fardoshme. Shembull Programi pr llogaritje t shums s numrave natyror tek, ku prfshihet definimi i konstantes simbolike alfa , n t ciln ruhet teksti i shkruar nn thonjza.

// Programi define #include <iostream> using namespace std; #define alfa "Shuma e llogaritur: " int main() { double s=0; int i,n; cout << "Vlera hyrse n: "; cin >> n; for (i=1;i<=n;i=i+2) s=s+i; cout << alfa << s << endl; return 0; }

Ktu, paraprocesori e zvendson konstanten simbolike alfa me tekstin prkats dhe si rezultat para kompilimit, komanda e fundit pr shtypje duket kshtu:
cout << "Shuma e llogaritur: " << s << endl;

14 Programimi i avancuar n C++

Makrot paraprocesorike
Prve pr definimin e konstanteve simbolike t cilat u shpjeguan m sipr, direktiva #define mund t shfrytzohen edhe pr definimin e makrove paraprocesorike .

Makrot e zakonshm
Nse direktiva #define shfrytzohet pr definimin e komandave t gjuhs programuese C++, shprehjeve aritmetikore, pjesve t ndryshme t programeve, ose edhe programeve komplete, mund t themi se kemi t bjm me makro paraprocesorike t zakonshme .
Definimi i komandave

Prmes direktivs n fjal, n program si makro mund t definohen pjes t komandave, ose edhe komanda komplete t gjuhs programuese C++. Shembull Programi pr llogaritje t shums s numrave natyror tek, ku definohet makroja shtyp me komandn pr shtypje cout.

// Programi define^ #include <iostream> #define shtyp cout using namespace std; int main() { double x,y,z; shtyp << "Vlera x="; cin >> x; shtyp << "\nVlera y="; cin >> y; z=-5; if (x<y) z=x+y; shtyp << "\nRezultati sht z=" << z << "\n"; return 0; }

Ktu, paraprocesori e zvendson emrin simbolik shtyp me komandn cout kudo q ky emr paraqitet n program. Si rezultat, pas paraprocesimit, kodi burimor duket kshtu:
...........................

Direktivat paraprocesorike 15
int main() { double x,y,z; cout << "Vlera x="; cin >> x; cout << "\nVlera y="; cin >> y; z=-5; if (x<y) z=x+y; cout << "\nRezultati sht z=" << z << "\n"; return 0; }

N makro mund t prfshihet edhe definimi i komandave me pjest prcjellse t tyre. Shembull Programi pr llogaritje t shums s numrave natyror tek , ku shfrytzohet makroja lexo pr definimin e tekstit cin >>.

// Programi define^ #include <iostream> #define lexo cin >> using namespace std; int main() { double x,y,z; cout << "Vlera x="; lexo x; cout << "\nVlera y="; lexo y; z=-5; if (x<y) z=x+y; cout << "\nRezultati sht z=" << z << "\n"; return 0; }

N kt rast, pas zvendsimit t emrit simbolik lexo nga paraprocesori, komandat prkatse n programin burimor duken kshtu:
........................... int main()

16 Programimi i avancuar n C++


{ double x,y,z; cout << "Vlera x="; cin >> x; cout << "\nVlera y="; cin >> y; ...........................

Shembull
// Shfrytezimi i #define # include <iostream> using namespace std; enum viti { pranvera, vera, vjeshta, dimri }; #define tekst "\ nStina e zgjedhur sht " #define shtyp cout << int main() { viti stina; stina=vera; shtyp tekst; switch (stina) { case pranvera: shtyp "pranvera"; break; case vera: shtyp "vera"; break; case vjeshta: shtyp "vjeshta"; break; case dimri: shtyp "dimri"; } cout << "\n\n"; return 0; }

Definimi i shprehjeve metematikore

Makrot mund t shfrytzohen edhe pr definimin e shprehjeve t ndryshme matematikore.

Direktivat paraprocesorike 17 Shembull Programi n t cilin shfrytzohet makroja delta pr definimin e shprehjes matematikore z=2*x+y, si dhe makrot shtyp e lexo n format e dhna m shembujt paraprak.

// Programi #include <iostream> using namespace std; #define delta z=2*x+y #define shtyp cout << #define lexo cin >> int main() { double x,y,z; shtyp "Vlera x="; lexo x; shtyp "\nVlera y="; lexo y; delta; shtyp "\nRezultati sht z="; shtyp z << "\n"; return 0; }

Pas zvendsimit t emrave simbolik delta , shtyp dhe lexo nga paraprocesori, programi burimor duken kshtu:
..................................... int main() { double x,y,z; cout << "Vlera x="; cin >> x; cout << "\nVlera y="; cin >> y; z=2*x+y; cout << "\nRezultati sht z="; cout << z << "\n"; return 0; }

Ktu, edhe pikpresja e shnuar n fund t shprehjes matematikore mund t prfshihet n makro, kshtu:
#define delta z=2*x+y;

18 Programimi i avancuar n C++ Pas ksaj, gjat shfrytzimit t makros n program, pikpresja nuk shnohet pas emrit delta .
Definimi i makros n disa rreshta

Nse n makro definimi krkon m shum rreshta, pr vazhdimin n rreshtin vijues shfrytzohet vija e pjerrt ( \ ), pas s cils kalohet n rresht t ri duke e shtypur pulln Enter , pa ln asnj zbrazsir. Shembull Programi n t cilin shfrytzohet makroja llogaritja pr definimin e nj vargu komandash q shkruhen n disa rreshta.

// Programi #include <iostream> using namespace std; #define llogaritja \ if (x<y) \ z=x+y; \ else \ z=2*y; int main() { double x,y,z; cout << "Vlera x="; cin >> x; cout << "\nVlera y="; cin >> y; llogaritja cout << "\nRezultati sht z="; cout << z << "\n"; return 0; }

Pasi paraprocesori ta zvendsoj emrin simbolik llogaritja me shprehjen e prfshir n makron prkatse, programi burimor para kompilimit duken kshtu:
..................................... int main() { double x,y,z; cout << "Vlera x="; cin >> x; cout << "\nVlera y="; cin >> y;

Direktivat paraprocesorike 19
if (x<y) z=x+y; else z=2*y; cout << "\nRezultati sht z="; cout << z << "\n"; return 0; }

Makrot n brendi t programit

Definimi i makrove nuk sht e thn t bhet n fillim t programit. Ato mund t definohen kudo brenda tij, por patjetr para se t shfrytzohen. Shembull Programi n t cilin makroja llogaritja nga detyra paraprake sht vendosur brenda programit.

// Programi #include <iostream> using namespace std; int main() { double x,y,z; #define llogaritja \ if (x<y) \ z=x+y; \ else \ z=2*y; cout << "Vlera x="; cin >> x; cout << "\nVlera y="; cin >> y; llogaritja cout << "\nRezultati sht z="; cout << z << "\n"; return 0; }

Edhe n kt rast efekti i veprimit t paraprocesorit sht i njjt si edhe n detyrn paraprake dhe pamja e programit burimor para kompilimit sht e njjt.

20 Programimi i avancuar n C++


Definimi i komplet programit

Prmes nj makroje mund t definohet edhe komplet programi. Shembull Shfrytzimi i makros programi prmes s cilit definohet komplet programi pr gjetjen e vlers m t madhe t dy numrave q ruhen te variablat x dhe y .

// Programi defineXXXX #include <iostream> using namespace std; #define programi int main() { double x,y,z; cout << "Vlera x="; cin >> x; cout << "\nVlera y="; cin >> y; z=(x>y) ? x : y; cout << "\nVlear maksimale: " << z << "\n"; return 0; } programi

\ \ \ \ \ \ \ \ \ \ \ \ \

N kt rast, kodi burimor para kompilimit duket:


................................. int main() { double x,y,z; cout << "Vlera x="; cin >> x; cout << "\nVlera y="; cin >> y; z=(x>y) ? x : y; cout << "\nVlear maksimale: " << z << "\n"; return 0; }

Direktivat paraprocesorike 21

Makro t paremtrizuara
Prmes direktivs #define mund t definohen edhe makro me argumente, ose si quhen ndryshe makro t parametrizuar . Meq makrot e tilla u prngjajn funkcioneve, ato njihen edhe si makro funkcione (ang. function macros). Shembull Programi n t cilin definohet makroja max prmes s cilit gjendet vlera m e madhe mes dy parametrave a dhe b t cilt jan shnuar brenda kllapave.

// Programi #include <iostream> using namespace std; #define max(a,b) ((a)>(b)) ? (a) : (b) int main() { double x,y,z; cout << "Vlera x="; cin >> x; cout << "\nVlera y="; cin >> y; z=max(x,y); cout << "Vlera maksimale: " << z << endl; return 0; }

Ktu, paraprocesori n kodin burimor e krkon sekuencn e simboleve max(x,y) dhe kur e gjen, at e zvendson me shprehjen:
(x>y) ? (x) : (y)

Si rezultat, pas paraprocesimit kodi burimor duket kshtu:


................................ int main() { double x,y,z; cout << "Vlera x="; cin >> x; cout << "\nVlera y="; cin >> y; z=(x>y) ? (x) : (y) ;

22 Programimi i avancuar n C++


cout << "Vlera maksimale: " << z << endl; return 0; }

Kjo sht e ngjashme me funkcionin e tipit inline , i cili n program mund t duket ashtu si sht dhn n vijim.
// Programi define1 #include <iostream> using namespace std; inline int max(int a,int b) { return ((a)>(b)) ? (a) : (b); } int main() { double x,y,z; cout << "Vlera x="; cin >> x; cout << "\nVlera y="; cin >> y; z=max(x,y); cout << "Vlera maksimale: " << z << endl; return 0; }

Te makrot duhet pasur kujdes q variablat q prfshihen n shprehjen e saj t shkruhen brenda kllapave, sepse rez. mund t jet i pasakt. Shembull
// Programi #include <iostream> using namespace std; #define alfa(a) a/2 int main() { int x,y; cout << "Vlera x="; cin >> x; y=alfa(x+4); cout << "Vlera e llogaritur: "

Direktivat paraprocesorike 23 Ktu, nse pas ekzekutimit t programit si vler hyrse pr variabln x e japim numrin 2, kompjuteri si rez. e jep numrin e gabuar 4 sepse llogarit me shprehjen: y= x+4 /2=2+2=4 Nse makroja shkruhet sakt (me kllapa):
#define alfa(a) (a)/2

gjat llogaritjes, pr vlern hyrse x=2 n kt rast e kemi vlern e sakt: y=( x+4 )/2=( 2+4 )/2=3 Nj makro t parametrizuar brenda programit mund t shfrytzohet edhe disa her. Shembull
// Programi #include <iostream> using namespace std; #define prod(a,b) ((a)*(b)) int main() { int x,y,z; cout << "Vlera x="; cin >> x; cout << "\nVlera y="; cin >> y; z=3*prod(x,x+2*y)+2*prod(x+1,3*x); cout << "Vlera e llogaritur: " << z << endl; return 0; }

Pas paraprocesimit, shprehja pr z sht: z=3*(x)*(x+2*y)+2*(x+1)*(3*x);

Si parametr i makros mund t merret edhe rezultati i llogaritjes s definuar.

24 Programimi i avancuar n C++ Shembull


// Programi define88 #include <iostream> #define alfa(a,b,g) \ if (a<b) \ g=a+b; \ else \ g=2*a+b; using namespace std; int main() { double x,y,z; cout << "Vlera x="; cin >> x; cout << "\nVlera y="; cin >> y; alfa(x,y,z) cout << "\nRezultati z=" << z << endl; return 0; }

Makro t ndrthurura
Gjat definimit t makrove mund t shfrytzohen variabla t makrove q jan definuar paraprakisht, pr t fituar makro t ndrthurura . Shembull
// Programi define===== #include <iostream> using namespace std; #define k x>=y #define baraz = int main() { #define alfa if (k) z baraz 2 * x + y; else z baraz x + 3 * y; double x,y,z; cout << "Vlera x="; cin >> x;

\ \ \ \

Direktivat paraprocesorike 25
cout << "\nVlera y="; cin >> y; alfa cout << "\nRezultati z=" << z << endl; return 0; }

Ktu duhet pasur kujdes q gjat shfrytzimit t identifikatorit baraz , para dhe pas tij t lihet s paku nj zbrazsir. Shembull Makroja programi q sht dhn m par gjat definimit t s cilit thirren makrot shtyp dhe lexo .

// Programi defineyyy #include <iostream> #define shtyp cout << #define lexo cin >> using namespace std; #define programi int main() { double x,y,z; shtyp "Vlera x="; lexo x; shtyp "\nVlera y="; lexo y; z=(x>y) ? x : y; shtyp "\nVlear maksimale: " << z << "\n"; return 0; } programi

\ \ \ \ \ \ \ \ \ \ \ \ \

Njlloj mund t ndrthuren makrot e zakonshme edhe me makro parametrike. Shembull Makroja programi q sht dhn m par gjat definimit t s cilit thirren makrot shtyp dhe lexo .

// Programi define=====

26 Programimi i avancuar n C++


#include <iostream> using namespace std; #define pi 3.1415926 #define siper(r) pi*r*r int main() { double r,s,p; cout << "Rrezja e rrethit: "; cin >> r; s=siper(r); cout << "\nSiprfaqja e rrethit s=" << s; p=2*pi*r; cout << "\nPerimetri i rrethit p=" << p << endl; return 0; }

Direktiva #undef
Duke e shfrytzuar direktivn #undef mund t eliminohet efekti i definimit me direktivn #define . Nj makro vlen derisa nuk eliminohet prmes direktivs #undef .
// Programi undef #include <iostream> using namespace std; #define n 3 int main() { int i,j; cout << "\ni="; for (i=1;i<=n;i++) cout << i << " "; #undef n #define n 5 cout << "\nj="; for (j=1;j<=n;j++) cout << j << " "; cout << endl; return 0; }

Direktivat paraprocesorike 27 Nse menjher pas direktivs:


#undef n

e shkruajm komandn:
cout << n;

gjat kompilimit do t paraqitet mesazhi undeclaret identifier , me t cilin na njofton se variabla n sht e padeklaruar. Shembull
// Programi undef #include <iostream> using namespace std; #define tekst "Koha e bukur" int main() { cout << "Teksti i par: " << tekst; #undef tekst #define tekst "Koha me bor" cout << "\nTeksti i dyt: " << tekst << endl; return 0; }

Pas paraprocesimit, komanda e par pr shtypje sht:


cout << "Teksti i par: " << "Koha e bukur"; kurse komanda e dyt pr shtypje duket kshtu: cout << "\nTeksti i dyt: " << "Koha me bor" << endl;

28 Programimi i avancuar n C++ Direktivat pr kompilim t kushtzuar t pjesve t programit Kto direktiva, p.sh. mund t prdoret kur ekzistohen disa versione t nj programi, gj q shfrytzohet nga shtpit softverike. N kt grup komandash bjn pjes komandat: #if #else #elif #endif Prmes ktyre komandave, kompilohen vetm pjes t caktuara t programit, t cilat e plotsojn kushtin e dhn. Shembull
// Programi if #include <iostream> using namespace std; #define n 5 int main() { int m=4; #if n>3 m=n+2; #endif cout <<"\nVlera: " << m << "\n"; return 0; }

Pas paraprocesimit, prkatsisht para kompilimit programi duket kshtu:


.................. int main() { int m=4; m=5+2; cout <<"\nVlera: " << m << "\n"; return 0; }

Shembull
// Programi if

Direktivat paraprocesorike 29
#include <iostream> using namespace std; #define n 5 int main() { int m=4; #if n>7 m=n+2; #endif cout <<"\nVlera: " << m << "\n"; return 0; }

Pas paraprocesimit, prkatsisht para kompilimit programi duket kshtu:


.................. int main() { int m=4; cout <<"\nVlera: " << m << "\n"; return 0; }

N deg mund t prfshihen edhe m shum komanda.. Shembull


// Programi if #include <iostream> using namespace std; #define n 5 int main() { int m,y; #if n>3 { m=n+2; y=3*n+m-1; cout << "\nVlera e llogaritur: " << y << "\n"; } #endif cout <<"\nVlera: " << m << "\n"; return 0; }

30 Programimi i avancuar n C++ Shembull


// Programi if-else #include <iostream> using namespace std; #define n 2 int main() { int m=4; #if (m+2)<10 // Nuk bn, n shprehje lejohen vetm konstante!!! m=n+5; #else cout << "\nTekst"; #endif cout <<"\nVlera: " << m << "\n"; return 0; }

Shembull
// Programi if #include <iostream> using namespace std; #define n 5 int main() { cout << "Fillimi\n"; #if n==5 #include "C:\alfa\KlasaKoha.txt" koha dita; cout << "\nVlera per a: "; cin >> dita.a; cout << "\nVlera per b: "; cin >> dita.b; #endif cout << "\nFundi" << "\n"; return 0; }

Ku fajlli KlasaKoha.txt gjendet n C:\alfa i shkruar n Notepad dhe prmbajtja e tij sht: class koha { public: int a;

Direktivat paraprocesorike 31 double b; }; Pas paraprocesimit, prkatsisht para kompilimit, meq plotsohet kushti te komanda #if , programi duket kshtu:
.................. int main() { cout << "Fillimi\n";

class koha { public: int a; double b; };


koha dita; cout << "\nVlera per a: "; cin >> dita.a; cout << "\nVlera per b: "; cin >> dita.b; cout << "\nFundi" << "\n"; return 0; }

Versioni kur nuk plotsohet kushti, nse p.sh. merret:


#define n 6

Pas paraprocesimit, prkatsisht para kompilimit, meq nuk plotsohet kushti te komanda #if , programi duket kshtu:
.................. int main() { cout << "Fillimi\n"; cout << "\nFundi" << "\n"; return 0; }

Nse ka m shum degzime pas komands #if , n vend t #else prdoret #elif .

Direktiva #elif

32 Programimi i avancuar n C++ Shembull


// Programi if #include <iostream> using namespace std; #define alfa 3 #define beta 5 int main() { int k; #if alfa>4 k=2*alfa+beta; #elif beta<7 k=alfa+3*beta+1; #endif cout << "Rezultati: " << k << endl; return 0; }

Pas paraprocesimit, prkatsisht para kompilimit, meq nuk plotsohet kushti te komanda e par #if por te komanda #elif , programi duket kshtu:
.................. int main() { int k; k=3+3*5+1; cout << "Rezultati: " << k << endl; return 0; }

=============================================== Prdorimi i komandave paraprocesorike sht me rndsi nse shfrytzohen para programit, ku n fakt nuk kemi mundsi t'i shfrytzojm komandat e gjuhs C++.
Shembull // Programi #if65 #include <iostream> using namespace std; #define dimensioni 25 #if dimensioni==20 #undef dimensioni #define dimensioni 40 #elif dimensioni>15

Direktivat paraprocesorike 33
#undef dimensioni #define dimensioni 10 #else #undef dimensioni #define dimensioni 30 #endif int main() { int A[dimensioni],i,s; for (i=0;i<dimensioni;i++) if (i%2==0) A[i]=2*i+1; else A[i]=7; s=0; for (i=0;i<dimensioni;i++) if (A[i]==7) s=s+A[i]; cout << "\nShuma s: " << s << "\n\n"; return 0; }

Direktivat #ifdef dhe #ifndef


Shembull
// Programi ifdef #include <iostream> using namespace std; #define x 10 int main() { int k=0; #ifdef x k=5*x+1; #endif cout << "Rezultati k=" << k << endl; return 0; }

Meq plotsohet kushti #ifdef , pas paraprocesimit, prkatsisht para kompilimit, programi duket kshtu:
.................. int main()

34 Programimi i avancuar n C++


{ int k=0; k=5*10+1; cout << "Rezultati k=" << k << endl; return 0; }

Mund ta ket edhe degn tjetr. Shembull


// Programi ifdef #include <iostream> using namespace std; #define d * int main() { int a=4,z; #ifdef d z=5 d a+1; #else z=a+3; #endif cout << "Vlera e llogaritur z=" << z << endl; return 0; }

Meq plotsohet kushti #ifdef , pas paraprocesimit, prkatsisht para kompilimit, programi duket kshtu:
.................. int main() { int a=4,z; z=5 * a+1; cout << "Vlera e llogaritur z=" << z << endl; return 0; }

Ktu t jepet shembull i forms: #ifdef m int A[m]; pjesa:

Direktivat paraprocesorike 35

int A[m]; kompilohet vetem nese sht definuar m . Vlen e kundrta:


#ifndef m #define m 10 #endif int A[m];

pjesa:

#define m 10
kompilohet vetm nse nuk sht definuar m .

Direktiva #line
Prmes ksaj direktive programuesi i prcakton numrat rendor t rreshtave n program me qllim t zbulimit t rreshtit n t cilin ka ndodhur gabim. Shembull
// Programi line #include <iostream> using namespace std; int main() { double x,y; cout << "Vlera pr x: "; #line 50 cin >> x; if (x<0) y=2*x+1; else y=x+3; cout << "Vlera e llogaritur y=" << y << endl; return 0; }

36 Programimi i avancuar n C++ Ktu, komands:


cin >> x;

i sht shoqruar numri rendor 50 . Pas ksaj, nse n rreshtat vijues ndodh ndonj gabim, n mesazhin e gabimit gjat kompilimit t tij paraqitet numri duke e marr si fillestar numrin e zgjedhur 50. P.sh. nse shprehja:
y=x+3;

gabimisht shkruhet kshtu:


y=a+3;

N mesazhin e gabimit do t shnohet se gabimi ka ndodhur n rreshtin e 54, duke i pasur parasysh numrimet vijuese:
50 51 52 53 54 cin >> x; if (x<0) y=2*x+1; else y=x+3;

Kto numra rendor shfrytzohen edhe pr vrejtjet q lidhen me rreshtat e veant t programit. Brenda programit mund t vendosen edhe disa direktiva #line dhe te secila prej tyre t vendoset nj numr rendor. Kjo mund t shfrytzohet p.sh. kur programi sht m i gjat dhe numrat rendor fillohen pr tansi t veanta t tij.

Direktiva #error
Kjo direktiv shfrytzohet pr gjenerimin e mesazhit i cili shkruhet n vazhdim t saj. N kt mnyr mundsohet ndjekja e procesit t kompilimit deri n pozitn ku sht vendosur direktiva, gj q ka rndsi kur kemi t bjm me programe m t gjata. Shembull
// Programi error #include <iostream> using namespace std; int main() {

Direktivat paraprocesorike 37
double x,y; cout << "Vlera pr x: "; #error Pozita ku kontrollohet cin >> x; if (x<0) y=2*x+1; else y=a+3; cout << "Vlera e llogaritur y=" << y << endl; return 0; }

Kur kompileri e takon direktivn n fjal, e gjeneron mesazhin Pozita ku kontrollohet n ekran dhe e ndrpret kompilimin e mtejshm. Nse shfrytzohet direktiva #line , ajo ka ndikim n numrin rendor t cilin e jep si informat t gabimit t gjeneruar edhe nga direktiva #error .

Direktiva #pragma
Kjo direktiv mundson dhnjen e instrukcioneve t ndryshme pr kompilerin. N form t prgjithshme kjo direktiv shkruhet kshtu: #pragma emri Prmes emrit t shkruar n vazhdim t direktivs prcaktohet se cilat veori (ang. features) specifike t makins ose kompilerit aktivizohen. Meq kjo direktiv lidhet me kompilerin, para shfrytzimit t saj duhet t lexo het manueli i kompilerit prkats. ---------------------------- Vazhdimi 8.12.2009 ------------------------------------------

Operatort paraprocesorik
N gjuhn C++ prdoren 3 operator paraprocesorik: defined , # dhe ## .

Operatori defined

38 Programimi i avancuar n C++ Ky operator shfrytzohet pr t testuar se a sht definuar ose jo nj identifikator. Shembull
// Programi defined1 #include <iostream> using namespace std; #define pi 3.1515926 int main() { double s,p,r=7; #if defined(pi) { s=pi*r*r; cout << "Siprfaqja e rrethit: " << s << "\n"; p=2*pi*r; cout << "Perimetri i rrethit: " << p << "\n"; } #endif cout << "Fundi" << "\n\n"; return 0; }

Rez.

Shtypen vlerat e llogaritura t siprfaqes dhe perimetrit.

Nse nuk sht definuar identifikatori pi , do t shtypet vetm fjala Fundi , kjo sepse nuk hyet n llogaritje. Degzimit mund t'i shoqrohet edhe dega #else . Shembull
// Programi definedxx2 #include <iostream> using namespace std; #define pi 3.1515926 int main() { #if defined(pi) { double s,p,r=7; s=pi*r*r;

Direktivat paraprocesorike 39
cout << "Siprfaqja e rrethit: " << s << "\n"; p=2*pi*r; cout << "Perimetri i rrethit: " << p << "\n"; } #else { cout << "Nuk sht definuar pi\n"; // Ktu mund t prfshihen shum komanda } #endif cout << "Fundi" << "\n\n"; return 0; }

N kt rast duhet pasur kujdes q deklarimi:


double s,p,r=7;

t shnohet brenda kllapave dhe jo para komands #if , sepse nse nuk plotsohet kushti i dhn, kompjuteri do ta kompiloj vetm pjesn pas #else , duke na njoftuar njkohsisht se variablave s dhe p nuk u referohemi askund. Efektet e operatorit defined mund t mbrrihen edhe prmes komandave paraprocesorike #ifdef , ose #ifndef . Shembull
// Programi defined1 #include <iostream> using namespace std; #define pi 3.1515926 int main() { double s,p,r=7; #ifdef pi { s=pi*r*r; cout << "Siprfaqja e rrethit: " << s << "\n"; p=2*pi*r; cout << "Perimetri i rrethit: " << p << "\n";

40 Programimi i avancuar n C++


} #endif cout << "Fundi" << "\n\n"; return 0; }

Operatori #
Shembull
// Programi # #include <iostream> using namespace std; #define alfa(x) #x int main() { cout << alfa(Jeta) << "\n"; return 0; }

Rez. Jeta Sikurse: cout << "Jeta" << "\n"; Shembull


// Operatori # #include <iostream> using namespace std; #define shtypja(x) "Koha e " #x int main() { cout << shtypja(bukur); << "\n"; return 0; }

Ktu, gjat ekzekutimit t komands cout , prmes thirrjes s funkcionit shtypja(bukur) , n ekran do t shtypet teksti Koha e bukur . Kjo sht rezultat i zvendsimit t argumentit x me fjaln bukur me thonjza, prkatsisht komanda cout q ekzekutohet sht kshtu: cout << "Koha e ""bukur";

Direktivat paraprocesorike 41 ose:

cout << "Koha e bukur";

Shembull Version i shembullit paraprak.


// Programi # #include <iostream> using namespace std; #define shtypja(x) cout << "Koha e " #x << "\n" int main() { shtypja(bukur); return 0; }

Ktu kemi: cout << "Koha e " "bukur" << "\n"; ose cout << "Koha e bukur" << "\n";

Operatori ##
Ky operator prdoret pr bashkimin e dy pjesve.
// Programi ## #include <iostream> using namespace std; #define bashkimi(x,y) x ## y int main() { cout << bashkimi("Koha e ","bukur") << "\n"; return 0; }

Rez. Koha e bukur

Makro t paradefinuara
N gjuhn C++ mund t shfrytzohen 5 makro t paradefinuara.

42 Programimi i avancuar n C++

Makroja __LINE__
Prmes saj jepet nj numr i plot i cili e paraqet numrin rendor t rreshtit aktual n program. Shembull
// Programi __LINE__ #include <iostream> using namespace std; int main() { const int m=8; int i,s; int A[m]={5,-2,7,4,1,8,10,6}; s=0; for (i=0;i<m;i++) if (A[i]>3) if (A[i]<9) s=s+A[i]; cout << "Rreshti numr: " << __LINE__; cout << "\nShuma s=" << s << "\n"; return 0; }

Do t shtypet numri rendor i rreshtit ku paraqitet makroja __LINE__.

Makroja __FILE__
Prmes saj merret nj string i cili e paraqet emrin e fajllit q kompilohet. Shembull
// Programi __FILE__ #include <iostream> using namespace std; int main() { cout << "\nFajlli q kompilohet: " << __FILE__; const int m=8; int i,s; int A[m]={5,-2,7,4,1,8,10,6}; s=0; for (i=0;i<m;i++)

Direktivat paraprocesorike 43
if (A[i]>3) if (A[i]<9) s=s+A[i]; cout << "\nShuma s=" << s << "\n"; return 0; }

Makrot __DATE__ dhe __TIME__


Prmes tyre merret informata mbi datn dhe kohn kur ka filluar kompilimi i programit. Shembull
// Programi __DATE__ dhe __TIME__ #include <iostream> using namespace std; int main() { cout << "\nData e fillimit t kompilimit: " << __DATE__; cout << "\nKoha e fillimit t kompilimit: " << __TIME__; const int m=8; int i,s; int A[m]={5,-2,7,4,1,8,10,6}; s=0; for (i=0;i<m;i++) if (A[i]>3) if (A[i]<9) s=s+A[i]; cout << "\nShuma s=" << s << "\n"; return 0; }

Makroja __cplusplus
Prmes saj merret nj numr i cili e identifikon kompilerin e gjuhs C++. Nse kompileri sht i pajtueshm me standardet e gjuhs C++, ai numr do t jet m i madh ose barazi me numrin 199711 , gj q varet nga versioni i kompilerit.

You might also like