Sunteți pe pagina 1din 37

6/30/2014

1
Cuvinte importante:
-preprocesare: constante, macrocomenzi, directive preprocesor,
crearea propriilor macroinstructiuni cu parametrii, apelul
macroinstructiunilor cu parametrii, crearea propriilor fisiere antet;
- utilizarea unui proiect si a fisierelor antet;
- utilizarea bibliotecior-obiect de functii;
- utilitarul MAKE.
6/30/2014
2
Preprocesare
Preprocesorul este un program lansat in executie automat inainte de compilare. El
executa toate directivele preprocesor incluse in program, efectuand substitutii de
texte.
Toate directivele preprocesor incluse in program incep cu caracterul # si sunt puse
inaintea oricaror declaratii de variabile sau functii (deci, sunt plasate la inceputul
programului).
Directive preprocesor
Directiva #define permite definirea unei constante simbolice.
Sintaxa folosita este:
#define <identificator_constanta> valoare
Unde:
- <identificator_constanta> - specifica numele constantei simbolice definite; numele
constantei se scrie cu majuscule;
- <valoare> - specifica valoarea atribuita constantei; constantele pot contine valori de
diferite tipuri (int, float, char etc).
6/30/2014
3
Ca efect, preprocesorul va substitui in program orice aparitie a identificatorului de
constanta cu valoarea acesteia.
Nota: Se recomanda utilizarea constantelor simbolice atunci cand se doreste sa se
asocieze o denumire mai sugestiva la o valoare. De asemenea, prin utilizarea
constantelor simbolice programul devine mai usor de modificat.
Exemple:
1. Urmatoarea directiva creaza o constanta denumita DIM_LINIE si ii atribuie
valoarea 128:
#define DIM_LINIE 128
Cand preprocesorul de C va intalni numele constantei DIM_LINIE in program, il va
inlocui cu valoarea ei.
2. Urmatoarele directive creaza doua constante denumite TRUE si FALSE si le
atribuie valoarea 1 si respectiv 0:
#define TRUE 1
#define FALSE 0
6/30/2014
4
3. Urmatorul program (macro_define.cpp) utilizeaza doua constante predefinite cu
macroinstructiunea #define.
#include <stdio.h>
#define TITLU "Acesta este un exemplu de directiva preprocesor"
#define CAPITOL "Macroinstructiunea #define"
void main(void)
{printf("%s\n", TITLU);
printf(CAPITOL);}
Inainte de a incepe compilarea, preprocesorul va inlocui fiecare nume de constanta
cu valoarea ei, ca mai jos:
void main(void)
{printf("%s\n", "Acesta este un exemplu de directiva preprocesor");
printf("Macroinstructiunea #define");}
6/30/2014
5
Utilizarea constantei predefinite _FILE_
Constanata predefinita _FILE_ este utilizata pentru a memora numele fisierului
sursa curent.
Urmatorul program (constanta_FILE.cpp) ilustreaza modul de utilizare a constantei
_FILE_:
#include <stdio.h>
void main(void)
{printf("Programul %s este in versiunea BETA\n", __FILE__);}
Dupa executia programului pe ecran se afiseaza urmatoarele:
Programul constanta_FILE.cpp este in versiunea BETA
Utilizarea constantei predefinite _STDC_
Constanata predefinita _STDC_ este utilizata pentru a testa compatibilitatea cu
standardul ANSI C. Cu toate ca cele mai multe compilatoare de C sunt foarte
asemanatoare, fiecare ofera facilitati unice. Pentru ca programele sa poata fi mutate
cu usurinta (sa fie portabile) de la un sistem la altul ANSI (Institutul National
American pentru Standarde) a definit standarde pentru operatorii, structurile,
instructiunile si functiile pe care trebuie sa le accepte un compilator. Compilatoarele
compatibile cu aceste standarde sunt denumite compilatoare ANSI C.
6/30/2014
6
Compilatoarele ANSI C definesc constanta _STDC_ . Daca este definita aceasta
constanta, compilatorul este compatibil cu standardul ANSI. Daca nu este definita,
compilatorul nu este compatibil.
Urmatorul program (constanta_STDC.cpp) ilustreaza modul de utilizare a constantei
_STDC_ pentru verificarea compatibilitatii mediului Borland C++5.0 cu standardul
ANSI C:
#include <stdio.h>
void main(void)
{#ifdef __STDC__
printf("Compatibilitate ANSI C\n");
#else
printf("Nu este in modul ANSI C\n");
#endif}
Dupa executia programului pe ecran se afiseaza:
Nu este in modul ANSI C
Observatie: Directiva de preprocesare #ifdef testeaza daca programul a definit sau nu
un identificator sau o constanta simbolica. Asupra directivei de preprocesare #ifdef
se va reveni in acest curs.
6/30/2014
7
Nota: Cele mai multe compilatoare accepta optiuni in linia de comanda a
compilatorului sau optiuni de compilare in mediul de programare respectiv, care sa
indice utilizarea standardului ANSI.
De exemplu, urmatorul program (constanta_STDC1.cpp) a fost compilat in mediul
Borland C++ 5.0 pentru a utiliza standardul ANSI C (optiunea source setata la
ANSI pentru compilator):
#include <stdio.h>
main(void)
{#ifdef __STDC__
printf("Compatibilitate ANSI C\n");
#else
printf("Nu este in modul ANSI C\n");
#endif
return 0;}
Dupa executia programului pe ecran se afiseaza:
Compatibilitate ANSI C
In acest caz s-a setat optiunea de compilare a mediului Borland C++ 5.0 la
standardul ANSI C (optiunea source).
6/30/2014
8
Utilizarea constantei predefinite _cplusplus
Dupa cum s-a vazut pana acum, unele dintre instructiunile si comenzile prezentate
sunt valabile si in C si in C++, pe cand altele se aplica numai pentru C++. Constanta
_cplusplus este folosita pentru a testa modul de lucru al compilatorului care poate fi
C++ sau C standard. Daca se utilizeaza un compilator de C standard, constanta va fi
nedefinita.
Urmatorul program (testcpp1.cpp) ilustreaza modul de utilizare a constantei
_cplusplus pentru a determina modul de lucru curent al compilatorului:
#ifdef __cplusplus
#include <iostream.h>
#else
#include <stdio.h>
#endif
void main(void)
{#ifdef __cplusplus
cout << "Se utilizeaza C++";
#else
printf("Se utilizeaza C\n");
#endif}
Dupa executia programului pe ecran se afiseaza:
Se utilizeaza C++
6/30/2014
9
Nota: Cele mai multe compilatoare accepta optiuni in linia de comanda sau optiuni
de compilare in mediul de programare respectiv, care le indica sa compileze folosind
modul de lucru (limbajul) C++ sau modul de lucru (limbajul) C standard.
De exemplu, urmatorul program (testcpp.c) a fost compilat in mediul Borland C++
5.0 folosind limbajul C standard (optiunea source setata la ANSI pentru compilator):
#ifdef __cplusplus
#include <iostream.h>
#else
#include <stdio.h>
#endif
main(void)
{#ifdef __cplusplus
cout << "Se utilizeaza C++";
#else
printf("Se utilizeaza C\n");
#endif
return 1;}
Dupa executia programului pe ecran se afiseaza:
Se utilizeaza C
6/30/2014
10
Utilizarea directivei de preprocesare #define pentru macroinstructiuni cu
parametrii
Macroinstructiunile permit realizarea unor operatii asemanatoare functiilor care
lucreaza cu parametrii. Exista totusi cateva deosebiri.
Cand preprocesorul intalneste, intr-un program, o referire la o macroinstructiune,
aceasta este inlocuita cu instructiunile componente inainte sa inceapa compilarea.
Prin urmare, daca programul utilizeaza de 10 ori o anumita macroinstructiune, vor fi
inserate 10 copii diferite ale macroinstructiunii, printre celelalte instructiuni ale
programului. Rezulta ca dimensiunea programului executabil va creste.
Spre deosebire de macroinstructiuni, atunci cand programul utilizeaza o functie, el
contine numai o copie a codului functiei, ceea ce ii reduce dimensiunea. Cand
utilizeaza o functie, programul executa codul functiei. Totusi, functiile au
dezavantajul prelucrarilor suplimentare pe stiva pe care le implica fiecare apel. De
aceea executia functiei dureaza ceva mai mult decat cea a unei macroinstructiuni
echivalente.
De obicei, macroinstructiunile se folosesc pentru prelucrari care realizeaza un
numar redus de operatii.
6/30/2014
11
Crearea propriilor macroinstructiuni cu parametrii
Crearea unei macroinstructiuni cu parametrii se realizeaza cu ajutorul directivei
preprocesor #define.
Sintaxa definitiei unei macroinstructiuni este:
#define <nume_macro>(<lista_nume_parametrii_formali) (<corp_macro>)
unde:
- <nume_macro> - specifica numele unei macroinstructiuni cu parametrii;
- <lista_nume_parametrii_formali> - specifica o lista de identificatori delimitati prin
virgula; fiecare identificator joaca rolul unui argument formal sau inlocuitor
(placeholder) nu ca la functiile C/C++ unde parametrii formali primesc valorile
parametrilor reali din apelul functiei;
- <corp_macro> - specifica setul de instructiuni de executat.
Nota:
1. Nu se plaseaza spatiu intre numele macroinstructiunii si parametrii sai formali.
Daca se lasa spatiu atunci preprocesorul inlocuieste in program si secventa care
reprezinta lista parametrilor formali si setul de instructiuni care reprezinta corpul
macroinstructiunii.
6/30/2014
12
2. In corpul macroinstructiunii se poate folosi caracterul punct si virgula (;). Dar
acest caracter trebuie folosit cu grija pentru ca preprocesorul va plasa acest caracter
la fiecare aparitie in cadrul programului.
De exemplu, sa presupunem ca s-a plasat caracterul punct si virgula la sfarsitul
definitiei macroinstructiunii SUMA, asa cum se ilustreaza mai jos:
#define SUMA(x, y) ((x) + (y));
Daca aceasta macroinstructiune se apeleaza intr-o functie cum ar fi printf(), atunci va
rezulta eroare de compilare deoarece preprocesorul pune si punctul si virgula de
dupa macroinstructiune.
3. Daca definitia unei macroinstructiuni trebuie sa continue pe linia urmatoare, se
plaseaza un caracter backslash (\) la capatul liniei.
4. In corpul macroinstructiunii identificatorii parametrilor formali trebuie sa fie
inclusi intre paranteze pentru a accepta expresii.
5. Dupa cum se observa din definitia macroinstructiunii, aceasta nu are specificat un
tip de data pentru rezultatul pe care il returneaza, ca la functie.
6/30/2014
13
Apelul unei macroinstructiuni cu parametrii in cadrul programului se face dupa
sintaxa:
<nume_macro> (<lista_nume_parametrii_actuali>)
unde:
- <lista_nume_parametrii_actuali> - specifica o lista a parametrilor actuali (delimitati
prin virgula), care trebuie sa coincida ca numar si ordine cu fiecare dintre parametrii
formali din definitia macroinstructiunii.
Nota: La apelul macroinstructiunii se poate lasa spatiu intre numele
macroinstructiunii si lista parametrilor actuali
La intalnirea unui apel de macroinstructiune, in cadrul programului, preprocesorul
executa doua seturi de inlocuiri (substituiri):
- mai intai, numele macroinstructiunii si parametrii formali din paranteze, care sunt in
definitia macroinstructiunii, sunt inlocuiti, in program, cu setul de instructiunii din
corpul macroinstructiunii;
- apoi, orice nume de parametru formal intalnit in corpul macroinstructiunii este
inlocuit cu numele parametrului corespunzator care apare in lista parametrilor actuali.
6/30/2014
14
Urmatorul program (macro_suma.cpp) utilizeaza macroinstructiunea SUM pentru a
aduna doua valori:
#include <stdio.h>
#define SUM(x, y) ((x) + (y))
void main(void)
{printf("Aduna 3 + 5 = %d\n", SUM(3, 5));
printf("Aduna 3.4 + 3.1 = %f\n", SUM(3.4, 3.1));
printf("Aduna -100 + 1000 = %d\n", SUM(-100, 1000));}
In cadrul definitiei macroinstructiunii SUM, x si y reprezinta parametrii formali ai
macroinstructiunii.
Atunci cand preprocesorul intalneste in program un apel al macroinstruciunii cum ar
fi SUM(3, 5) se efectueaza urmatoarele substituiri:
- mai intai, SUM(x, y) cu (x) + (y) si
- apoi, x cu 3 si y cu 5.
In program substituirile vor avea ca rezultat urmatorul cod:
printf("Aduna 3 + 5 = %d\n", ((3) + (5)));
printf("Aduna 3.4 + 3.1 = %f\n",((3.4) + (3.1)) );
printf("Aduna -100 + 1000 = %d\n", ((-100) +(1000)));
6/30/2014
15
Urmatorul program (macro_minmax.cpp) foloseste macroinstructiunile MIN si
MAX pentru a calcula minimul si maximul dintre doua valori:
#include <stdio.h>
#define MIN(x, y) (((x) < (y)) ? (x): (y))
#define MAX(x, y) (((x) > (y)) ? (x): (y))
void main(void)
{printf("Maximul dintre 10.0 si 25.0 este %f\n", MAX(10.0, 25.0));
printf("Minimum dintre 3.4 si 3.1 este %f\n", MIN(3.4, 3.1));}
Substituirile preprocesorului vor avea ca rezultat urmatorul cod:
printf("Maximul dintre 10.0 si 25.0 este %f\n", (((10.0) > (25.0)) ? (10.0) : (25.0)));
printf("Minimum dintre 3.4 si 3.1 este %f\n", (((3.4) < (3.1)) ? (3.4) : (3.1)));
Directiva #include este utilizata pentru a include intr-un program un fisier antet
(header) specific unei biblioteci standard de functii C/C++ sau creat de programator.
Un fisier antet (header) contine prototipuri de functii, declaratii de constante si
definitii de macroinstructiuni. Fisierul antet are extensia .h. Fisierul antet este
specific fiecarei bibliotecii standard de functii C/C++ sau este creat de catre
programator.
6/30/2014
16
Pentru a include intr-un program un fisier antet se utilizeaza directiva
preprocesor #include. Directiva #include are doua formate de sintaxa:
a) #include <<nume_fisier_antet>.h>
b) #include < nume_fisier_antet>.h.
In varianta a) compilatorul de C/C++ va cauta respectivul fisier antet mai intai in
propriul sau director de fisiere antet. Daca il gaseste, preprocesorul il utilizeaza pe
acesta. Daca nu il gaseste, compilatorul il va cauta in directorul curent sau intr-un
director specificat de programator. De regula, compilatorul de C/C++ plaseaza
fisierele antet specifice bibliotecilor run-time in subdirectorul include a mediului de
programare respectiv.
In varianta b) compilatorul va cauta fisierul antet numai in interiorul directorului
curent.
Exemple:
1. #include <math.h> - include in program fisierul antet specific bibliotecii de functii
matematice, existent in subdirectorul include;
2. #include <iostream.h> - include in program fisierul antet specific bibliotecii
limbajului C++ cu functii de intrare/iesire, existent in subdirectorul include;
6/30/2014
17
3. #include <stdio.h> - include in program fisierul antet al bibliotecii limbajului C cu
functii de intrare/iesire, existent in subdirectorul include.
4. #include antetul_meu.h - include in program fisierul antet cu numele
antetul_meu.h creat de programator in directorul curent.
Directivele #ifdef si #ifndef
Pentru a testa daca un anumit identificator (constanta predefinita de compilator,
constante simbolice si macroinstructiuni definite de programator) a fost definit
anterior in program, preprocesorul utilizeaza directiva #ifdef.
Sintaxa directivei este:
#ifdef <nume_simbol>
<set_instructiuni>
#endif
Efectul directivei este: daca simbolul respectiv a fost definit anterior in program,
preprocesorul va efectua instructiunile din <set_instructiuni> pana la intalnirea
instructiunii #endif.
6/30/2014
18
Directiva #ifndef se foloseste atunci cand se doreste ca preprocesorul sa efectueze
anumite instructiuni daca programul nu a definit anterior un anumit simbol.
Sintaxa directivei este:
#ifndef <nume_simbol>
<set_instructiuni>
#endif
Urmatoarea instructiune utilizeaza directiva #ifndef pentru a indica preprocesorului
sa defineasca macroinstructiunea _majusc daca nu a fost definita una similara:
#ifndef _majusc
#define _majusc(c) ((((c) >= a) && ((c) <= z)) ? (c) - a + A : c)
#endif
6/30/2014
19
Directiva #ifdef-else se foloseste atunci cand se doreste ca preprocesorul sa execute un set
de instructiuni daca conditia testata cu #ifdef este adevarata si alt set de instructiuni daca
conditia este falsa.
Sintaxa directivei este:
#ifdef <nume_simbol>
<set_instructiuni_1>
#else
<set_instructiuni_2>
#endif
De exemplu, compilatoarele Microsoft Visual C++ si Borland C++ 5.0 includ constantele
predefinite care indica ce compilator se utilizeaza pentru a compila programul
(_MSC_VER pentru MS Visual C++ si __BORLANDC__ pentru Borland C++ 5.0). Cu
ajutorul acestor constante, se pot executa secvente de instructiuni specifice fiecarui
compilator. Urmatoarea secventa de cod va afisa doua mesaje in functie de utilizarea unui
compilator sau altul:
#ifdef _MSC_VER
cout << "Compilator Microsoft Visual C++";
#endif
#ifdef __BORLANDC__
cout << "Compilator BORLAND 5.0";
#endif
6/30/2014
20
Directiva #if defined
Directiva #if defined este folosita tot pentru testarea definirii unui simbol.
Sintaxa directivei este:
#if defined(<nume_simbol>)
<set_instructiuni>
#endif
Aceasta directiva are avantajul ca da posibilitatea de a combina testarile, intrucat este
compusa din directiva #if si operatorul defined.
Urmatoarea directiva #if defined testeaza daca simbolul BIBLIO_M a fost definit si
in acelasi timp daca simbolul FACT_M nu a fost definit anterior in program. Daca
aceasta conditie este adevarata atunci se include fisierul antet fis_meu.h:
#if defined(BIBLIO_M ) && !defined(FACT_M)
#include fis_meu.h
#endif
Nota: Se poate folosi #if defined pentru a construi conditii care utilizeaza operatorii
logici ai limbajului C (inclusiv &&, | | si !).
6/30/2014
21
Directiva #if defined-else se foloseste atunci cand se doreste ca preprocesorul sa
execute un set de instructiuni daca simbolul este deja definit si alt set de instructiuni
daca simbolul este nedefinit.
Sintaxa directivei este:
#if defined(<nume_simbol>)
<set_instructiuni>
#else
<set_instructiuni>
#endif
Directivele pragma
In functie de compilator, preprocesorul poate accepta diferite directive catre
compilator, denumite pragma.
Sintaxa unei directive pragma este:
#pragma <directiva_compilator>
6/30/2014
22
De exemplu, compilatorul Borland 5.0 pune la dispozitie directivele pragma startup
si exit, care permit specificarea functiilor ce vor fi executate automat atunci cand
incepe sau se termina programul:
#pragma startup <nume_functie>
#pragma exit <nume_functie>
Functia care se afla in cadrul directivei pragma startup se va executa inainte de
functia main.
Cand se utilizeaza directivele pragma startup si exit, trebuie ca functiile apelate sa
nu aiba nici un parametru si sa nu returneze nici o valoare. Deci, functia trebuie
scrisa in formatul:
void <nume_functie> (void)
6/30/2014
23
Utilizarea unui proiect si a fisierelor antet
O aplicatie C/C++ nu este alcatuita in mod obligatoriu dintr-un singur fisier sursa.
Definitiile functiilor din care este alcatuit programul se pot afla in mai multe fisiere.
Acest lucru permite elaborarea aplicatiilor in echipa, precum si reutilizarea anumitor
functii.
In final, dupa elaborarea tuturor fisierelor sursa, acestea pot fi asamblate, prin
crearea unui proiect.
In mediul de programare Borland C++ 5.0, crearea unui nou proiect se realizeaza cu
ajutorul optiunii New -> Project din meniul File al mediului de programare. Se
deschide o fereastra in care se introduc: numele fisierului proiect (.ide) si numele
fisierului executabil (.exe) care va fi creat.
6/30/2014
24
Deschiderea unui proiect existent se realizeaza cu ajutorul optiunii Open Project din
meniul Project al mediului de dezvoltare. Se alege un fisier-proiect existent si se
executa clic pe butonul OK. Pe ecran apare o fereastra care descrie continutul
fisierului proiect, ca mai jos:
Pentru adaugarea unui fisier-sursa (.C sau .C++) se selecteaza optiunea Add Node
din meniul contextual (pop-up), care apare dupa ce se executa clic cu butonul drept
pe un nod al proiectului de nivel superior.
Pentru stergerea unui fisier-sursa (.C sau .C++) se selecteaza optiunea Delete Node
din meniul contextual (pop-up), care apare dupa ce se executa clic cu butonul drept
pe un nod dorit a fi sters din proiect.
6/30/2014
25
De exemplu, sa cream un proiect simplu (proiect_exemplu1.ide), format din doua
fisiere-sursa.
Primul fisier-sursa se numeste functii_proiect.cpp si contine doua functii care
efectueaza urmatoarele: genereaza toate numerele prime mai mici decat n prin metoda
ciurul lui Eratostene si calculeaza produsul elementelor de deasupra diagonalei unei
matrice patratice cu n linii si n coloane. Al doilea fisier-sursa se numeste
proiect_exemplu1.cpp care contine functia main() in cadrul careia vom apela cele
doua functii. Tot in acest program se citeste numarul pana la care se doreste generarea
numerelor aleatoare si, de asemenea, numarul de linii ale matricei patratice.
Continutul fisierului functii_proiect.cpp este:
#include <iostream.h>
void gen_nr_prim (int ciur [], int &n)
{int i, j;
for (i=2; i<n; i++) //initial toate numerele sunt in ciur, presupuse prime
ciur [i] = 1;
for (i=2; i*i<=n; i++)
if (ciur[i]) //i este prim
for (j=2; j*i<n; j++) // se cern toti multiplii lui i
ciur[i*j] = 0;
for (i=2; i<n; i++)
if (ciur[i])
cout << "Numarul prim generat este " << i << endl;}
6/30/2014
26
double prod_sus_dig (int *a[], int &n)
{
int i, j;
double p = 1;
for (i=0; i<n-1; i++)
for (j=i+1; j<n; j++)
p = p*a[i][j];
return p;
}
Continutul fisierului proiect_exemplu1.cpp este:
#include <iostream.h>
void gen_nr_prim (int *, int &);
double prod_sus_dig (int *[], int &);
void main (void)
{int *a, nr;
int **matr; // adresa de inceput a vectorului de pointeri la linii
int lin, col, aloc = 0;
int inum = 1;
int i, j;
double produs;
cout << "Introduceti numarul n pana la care se vor genera numere prime: ";
cin >> nr;
6/30/2014
27
a = new int [nr];
if (a)
{gen_nr_prim (a, nr);
delete a;}
else
cout << "Heap-ul este plin";
cout << "Introduceti numarul de linii ale matricei patratice "; cin >> lin;
col = lin;
matr = new int *[lin]; // alocare zona de memorie pentru pointerii de linie
if (!matr)
{cout << "Heap-ul este plin\n";
aloc = 1;}
else
{for (i = 0; i < lin; i++)
{
matr[i] = new int[col]; // alocare zona de memorie pentru coloanele fiecariei linii
if (!matr[i])
{cout << "Heap-ul este plin\n";
aloc = 1;}
else
aloc = 0;}
}
6/30/2014
28
if (!aloc)
{
for (i=0; i<lin; i++)
for (j=0;j<col; j++)
matr[i][j]=inum++;
produs = prod_sus_dig (matr, lin);
cout << "Produsul elementelor de deasupra diagonalei principale este " << produs;
for (i=0; i < lin; i++)
delete[] matr [i]; //dealocarea zonei elementelor (coloanelor) matricei
delete[] matr; //dealocarea zonei pointerilor de linie
}
}
Pentru crearea proiectului, adaugarea fisierelor in proiect si transformarea proiectului
in fisier executabil, utilizand mediul de programare Borland C++ 5.0, se procedeaza
astfel:
1. Se creaza proiectul cu numele proiect_exemplu1.ide. Pe ecran apare fereastra
proiectului care contine ca prim nod numele fisierului executabil dorit a fi creat
(proiect_exemplu1.exe) si numele fisierului-sursa (proiect_exemplu1.cpp) (gol)
care are acelasi nume cu fisierul executabil.
2. Se scrie in fisierul-sursa cu numele proiect_exemplu1.cpp codul-sursa al
programului principal.
6/30/2014
29
3. Daca nu exista, se creaza, separat de proiect, fisierul functii_proiect.cpp care
contine cele doua functii si se selecteaza optiunea Add Node din meniul contextual,
care apare cand se executa clic-dreapta pe nodul proiect_exemplu1.exe. Pe ecran
apare o fereastra de dialog in cadrul careia se selecteaza fisierul functii_proiect.cpp.
4. Se selecteaza optiunea Make sau Build All din meniul Project, pentru a crea un
program executabil. Programul executabil va fi un fisier cu numele proiectului si
extensia .exe.
6/30/2014
30
Utilizarea unui fisier antet impreuna cu programele C/C++ realizate
Daca o aplicatie informatica realizata in C/C++ contine mai multe functii care se afla
in fisiere-sursa distincte sau in biblioteci rune-time distincte, este util sa se creeze un
fisier antet propriu aplicatiei (cu extensia .h). In acest fisier se pot include declaratiile
tuturor functiilor folosite de aplicatia informatica, constante predefinite sau specifice
aplicatiei si macroinstructiuni proprii aplicatiei.
De exemplu, sa recream proiectul prezentat deja, astfel incat el sa foloseasca si un
fisier antet.
Fisierul antet functii_proiect.h se creaza tot cu ajutorul mediului de programare
Borland C++ 5.0. Acest fisier contine numai declaratiile functiilor prezentate deja, ca
mai jos:
6/30/2014
31
Programul principal cu numele proiect_exemplu2.cpp face apel la fisierul antet cu
numele functii_proiect.h, ca mai jos:
#include <iostream.h>
#include "functii_proiect.h"
void main (void)
{
//instructiuni program
}
Fisierul-sursa functii_proiect.cpp ramane neschimbat.
6/30/2014
32
Utilizarea bibliotecior-obiect de functii
Crearea si utilizarea propriilor biblioteci-obiect de functii reprezinta o alta
modalitate de reutilizare a unor functii pentru aplicatii diverse.
Majoritatea compilatoarelor dispun de un program special care permite crearea de
biblioteci de functii. Mediul de programare Borland C++ 5.0 are inglobat programul
TLIB care permite crearea de fisiere biblioteci-obiect de functii (cu extensia .lib).
Crearea si gestionarea unui fisier biblioteca-obiect de functii
Majoritatea programelor care gestioneaza biblioteci-obiect de functii permit
urmatoarelor operatii:
- crearea unei biblioteci;
- adaugarea unuia sau a mai multor fisiere-obiect la biblioteca;
- inlocuirea unui fisier-obiect cu un altul;
- stergerea unuia sau mai multor fisiere obiect din biblioteca;
- listarea rutinelor (functiilor) pe care le contine biblioteca.
In functie de compilatorul de C/C++, operatiile pe care le accepta programul care
gestioneaza biblioteci-obiect pot diferi.
6/30/2014
33
Cele mai multe programe care gestiuneaza biblioteci-obiect permit adaugarea si
eliminarea fisierelor in cod obiect, utilizand simbolul plus (+) pentru a adauga un
fisier si simbolul minus (-) pentru a elimina un fisier obiect.
De exemplu, urmatoarea comanda utilizeaza programul TLIB al firmei Borland
pentru a crea o biblioteca numita functii_proiect.lib si a insera codul-obiect in
biblioteca, pentru functiile gen_nr_prim () si prod_sus_dig () continute in fisierul
functii_proiect.obj :
C:\>TLIB functii_proiect.lib + functii_proiect.obj <Enter>
Observatie: Semnul plus (+ ) din comanda inseamna inserare de fisiere-obiect in
biblioteca.
Biblioteca-obiect cu numele functii_proiect.lib creata este, apoi, inclusa in
fisierul-proiect al aplicatiei cu numele proiect_exemplu3.ide.
6/30/2014
34
Dupa includerea bibliotecii-obiect functii_proiect.lib, proiectul cu numele
proiect_exemplu3.ide arata ca mai jos:
6/30/2014
35
Simplificarea construirii aplicatiilor cu ajutorul instrumentului MAKE
MAKE este un instrument de programare care ajuta la construirea de aplicatii
complexe (ce contin fisiere cu cod-sursa, fisiere cu cod-obiect, biblioteci, alte fisiere
executabile etc dependente unele de altele) dupa ce s-au facut una sau mai multe
modificari ale fisierelor componente ale aplicatiei.
Utilitarul MAKE simplifica reconstruirea unui fisier executabil dupa ce s-au efectuat
modificari in diferitele module componente ale aplicatiei informatice complexe.
Utilitarul MAKE functioneaza impreuna cu un fisier specific aplicatiei. Acest fisier
(numit adesea fisier make) specifica diferitele fisiere pe care compilatorul le va
utiliza pentru a construi o aplicatie si listeaza pasii pe care compilatorul trebuie sa ii
parcurga atunci cand se modifica programul. Fisierul make este asemanator
programelor (adica, el contine conditii si instructiuni pe care MAKE le evalueaza si,
eventual, le executa).
Exista doua modalitati de utilizare a lui MAKE.
In prima modalitate, operatiile pe care le va executa MAKE vor fi plasate intr-un
fisier cu numele MAKEFILE. In acest caz, utilitarul MAKE se lanseaza astfel:
C:\>MAKE <Enter>
6/30/2014
36
In a doua modalitate, operatiile pe care le va executa MAKE vor fi plasate intr-un
fisier cu extensia .mak si cu un nume corespunzator aplicatiei informatice pentru care
se doreste folosirea fisierului. In acest caz, utilitarul MAKE se lanseaza astfel:
C:\>MAKE - f <nume_fisier_make>.mak <Enter>
De exemplu, pentru reconstruirea aplicatiei proiect_exemplu3.exe se poate folosi
comanda:
C:\>MAKE - f proiect_exemplu3.mak <Enter>
Mediile de programare bazate pe Windows, cum ar fi Borland C++ 5.0 sau Microsoft
Visual C++ 5.0 construiesc si gestioneaza fisierul make atunci cand se creaza fisierul
proiect al aplicatiei. De exemplu, in mediul de programare Borland C++ 5.0 fisierul
make este generat cu ajutorul optiunii Generate Makefile din meniul Project.
Fisierele make au un format specific si folosesc o sintaxa de scriere specifica pentru
prelucarile pe care le efectueaza. Liniile de comentariu sunt precedate de semnul diez
(#). Liniile cele mai importante din acest fisier sunt liniile de dependente intre
diferitele componente ale aplicatiei.
6/30/2014
37
Atunci cind se executa comanda MAKE cu fisierul make corespunzator, se va
examina mai intai linia dependentelor. Daca fisierul destinatie nu exista sau daca
fisierul destinatie este mai vechi decat oricare alt fisier de care el este dependent
(ceea ce inseamna ca s-a modificat unul dintre fisierele componente dupa ce s-a
compilat ultima data fisierul destinatie), MAKE va executa comanda care urmeaza
dupa liniile de descriere a dependentelor (de regula comanda de recompilare a
aplicatiei).
Observatie: Comanda utilitarul MAKE este destul de utilizata in sistemul de operare
Unix, mai ales la instalarea unor pachete de programe care trebuie recompilate
pentru o anumita platforama hardware.

S-ar putea să vă placă și