1.12.2. Substituiri de succesiuni de caractere la preprocesare
2018/12/27 in Programare in C
Constructia #define se poate folosi la substitutii de succesiuni de caractere. In acest scop se utilizeaza formatul:
#define nume "succesiune_de_caractere"
unde:
nume | Este precedat si urmat de cel putin un spatiu. |
Folosind aceasta constructie, preprocesarea substituie nume cu succesiune_de_caractere peste tot in textul sursa care urmeaza constructiei #define respective, exceptand cazul in care nume apare intr-un sir de caractere sau un comentariu.
Numele definit printr-o constructie #define substituindu-se prin secventa de caractere corespunzatoare nu mai este prezent la compilare.
De obicei, un astfel de nume se scrie cu litere mari, pentru a scoate in evidenta faptul ca el este definit cu printr-o constructie #define.
Succesiune_de_caractere incepe cu primul caracter care nu este alb. Ea poate fi continuata pe mai multe linii terminand randul cu care dorim sa se continue cu backslash.
#define este folosita frecvent pentru a defini constante. De aceea, uneori un nume definit printr-o constructie #define se spune ca este o constanta simbolica.
O constructie #define autorizeaza substitutia pe care o defineste din punctul in care ea este scrisa si pana la sfarsitul fisierului in care ea este scrisa sau pana la intalnirea unei constructii #undef care o anuleaza. Aceasta are formatul:
#undef nume
Succesiunea de caractere dintr-o constructie #define poate contine nume care au fost definite in prealabil prin alte constructii #define.
Exemple:
1.
...
#define A 100
/*A se substituie prin 100 incepand din acest punct al fisierului sursa*/
...
#define FACT 20
#define DIMMAX (A*FACT)
...
char tab[DIMMAX];
...
double mat[A][FACT];
...
Dupa preprocesare se obtin declaratiile:
...
char tab[(100*20)];
...
double mat[100][20];
...
DIMMAX s-a substituit prin (100*20) si nu prin valoarea 2000 a produsului deoarece preprocesorul nu face calcule ci numai substitutii. Din aceasta cauza se recomanda ca expresiile utilizate in constructiile #define sa fie incluse in paranteze rotunde.
2.
#define A 123
#define B A+120
...
x=3*B; // se substituie prin x=3*123+120;
...
3.
#define A 123
#define B (A+120)
...
x=3*B; // se substituie prin x=3*(123+120);
...
4.
#define A 100
...
int x[A+1]; // declaratia devine int x[100+1];
...
#undef A
#define A 3.5
...
double y;
...
y=A; // instructiunea devine y=3.5;
...
In exemplele de mai sus A este o constanta simbolica. Ea este un nume atribuit unei constante, nume care insa nu mai este prezent in faza de compilare.
B defineste o expresie constanta, care este evaluata de compilator la intalnirea ei.
Constantele simbolice se utilizeaza frecvent in locul constantelor obisnuite deoarece ele prezinta urmatoarele avantaje:
- permite sa se atribuie nume sugestive unor constante. Este mul mai sugestiv sa folosim constanta simbolica PI definita prin
#define PI 3.14159
decat valoarea ei. - permite realizarea de prescurtari. De exemplu, daca valoarea 3.14159 se foloseste de mai multe ori in program, atunci este mai simplu sa folosim numele PI atribuit ei.
- permite inlocuirea simpla a unei constante printr-o alta. Daca o constanta se foloseste de mai multe ori in program si ulterior se constata ca valoarea ei trebuie schimbata (de exemplu este o constanta flotanta careia trebuie sa ii schimbam precizia), atunci este mult mai simplu sa-i schimbam valoarea o singura data in constructia #define decat sa o cautam peste tot in program si sa-i schimbam valoarea in mod corespunzator.