Capitolul 4.11. Preprocesorul C

Vezi subiectul anterior Vezi subiectul urmator In jos

Capitolul 4.11. Preprocesorul C

Mesaj  zooky la data de Mier Mar 18, 2009 12:22 pm

C admite unele extensii de limbaj cu ajutorul unui simplu macropreprocesor. Posibilitatile lui #define sint cele mai obisnuite exemple despre aceste extensii; alta este posibilitatea de a include continutul altor fisiere in timpul compilarii.

Includerea fisierelor

Pentru a usura manipularea colectii de #define si declaratii (printre altele) C admite includerea fisierelor. Orice linie de tipul

#include "filename"

este inlocuita prin continutul fisierului "filename". Adesea o linie sau doua de aceasta forma apar la inceputul fiecarui fisier sursa pentru a include declaratiile #define comune si declaratiile extern pentru variabilele globale. #include-urile pot fi grupate.
#include este calea preferata pentru a uni declaratiile impreuna pt un program mai mare. Aceasta garanteaza ca toate fisierele sursa vor fi alimentate cu aceleasi definitii si declarari de varaibile. Desigur atunci cind un fisier inclus este schimbat toate fisierele dependente trebuiesc recompilate.

Macro substituirea

O definitie de forma

#define YES 1

apeleaza o macrosubstituire de cea mai simpla forma -inlocuirea unui nume cu un sir de caractere. Numele din #define au aceasi forma ca si identificatorii din "C"; textul de inlocuire este restul liniei, o definitie lunga se poate continua prin plasarea unui \ la sfirsitul liniei de continuat. Domeniul unui nume definit prin #define este de la locul definirii pina la sfirsitul fisierului sursa. Numele pot fi redefinite si o definire poate folosi definirii precedente. Substitutiile nu se pun intre ghilimele, astfel daca YES este un nume definit, nu va avea loc nici o substituire in printf ("YES").
Deoarece implementarea lui #define nu este o parte a compilatorului propriuzis, sint foarte putine restrictii asupra a ce poate fi definit. De exemplu adeptii Algolului pot spune:

#define then
#define begin {
#define end ;}

si apoi sa scrie:

if (i > 0) then
begin
a = 1;
b = 2
end

Este de asemenea posibil de definit macrouri cu argumente, astfel ca textul de inlocuire depinde defelul in care macroul este apelat. De exemplu sa definim un macro numit max astfel:

#define max(A, B) ((A) > (B) ? (A) : (B))

Acum linia

x = max(p+q, r+s);

va fi inlocuita de linia:

x = ((p+q) > (r+s) ? (p+q) : (r+s));

Aceasta admite o functie maxima care se expadeaza intr-un cod "in-line" si nu intr-o apelare de functie. Atita vreme cit argumentele sint tratat adecvat, acest macro va servi pt orice tip de date; nu exista diferite tipuri de max pt diferite tipuri de date, asa cum se intimpla cu functiile.
Desigur, daca examinati expansiunea lui max de mai sus veti observa citeva capcane. Expresiile sint evaluate de doua ori; aceasta este rau daca sint impicate efecte colaterale ca apelari de functii si operatori de incrementare. Masuri de prevedere trebuie luate cu parantezele pentru a fi siguri ca ordinea de evaluare este respectata. (Considerati macro-ul

#define square(x) x * x

cind se apeleaza ca square(z+1).)

Exista chiar probleme lexicale; nu pot exista spatii intre numele macroului si paranteza stinga care introduce lista de argumente.

Insa fara indoiala, macro-urile sint suficient de valoroase. Un exemplu practic este biblioteca standard I/O care va fi deschisa in capitolul 7 ,in care getchar si putchar sint definite ca mcrouri, pt a evita apelarea unei functii pentru fiecare caracter procesat .
Alte posibilitati ale macropocesorului sint descrise in Apendix A.

Exercitiul 4.9. Definiti un macro swap(x,y) care schimba intre ele toate cele 2 argmente int.
avatar
zooky
Moderator
Moderator

Numarul mesajelor : 147
Data de inscriere : 15/03/2009
Varsta : 24
Localizare : Cernatesti City

Vezi profilul utilizatorului http://e-learning.forumhit.ro

Sus In jos

Vezi subiectul anterior Vezi subiectul urmator Sus


 
Permisiunile acestui forum:
Nu puteti raspunde la subiectele acestui forum