Documente Academic
Documente Profesional
Documente Cultură
Fiiere antet 3. Variabile externe 4. Variabile i funcii statice 5. Tipuri de date abstracte
Compilarea independent
Principii
Codul surs al unui program nu este ntotdeauna coninut n acelai fiier. De exemplu, definiiile funciilor standard, care sunt apelate din majoritatea programelor, nu sunt scrise n fiierele din care se realizeaz apelul. Se vor prezenta modalitile n care se poate face mprirea codului surs al unui program n mai multe fiiere, n special pentru a obine o mai bun organizare a programului. Se vor discuta mecanismele prin care se poate realiza acest lucru, crearea unei aplicaii executabile din mai multe fiiere surs, precum i principiile de proiectare care trebuie avute n vedere la mprirea unei aplicaii complexe n module diferite.
Compilarea independent
Exemplu de program
#include <stdio.h> int calcul(int a, int b) { return a + b; } void main(void) { int x=3, y=4, z; z=calcul( x, y ); printf("rezultatul calculelor este %d \n", z); }
Compilarea independent
Exemplu de program
Programul realizeaz un set bine definit de calcule sau prelucrri asupra unor date particulare. Algoritmul de calcul (funcia calcul) poate fi definit i implementat independent de aplicaie pentru a fi incorporat n mai multe aplicaii diferite. Aplicaia n ansamblu se poate implementa prin dou module (fiiere) diferite: un fiier calc.c care s conin implementarea funciei calcul i un fiier prog.c care s implementeze funcia main.
Compilarea independent
Fiier executabil din mai multe fiiere surs
Problemele care apar n cazul unui program mprit n mai multe fiiere surs sunt: cum se asigur faptul c o variabil global (extern) definit ntr-un fiier poate fi cunoscut, la compilare, n alte fiiere ? cum se asigur faptul c acestei variabile i este asociat aceeai zon unic de memorie ? cum se asigur faptul c o funcie definit ntr-un fiier poate fi apelat n alte fiiere ? Aceste probleme sunt rezolvate n diferite faze ale procesrii codului: preprocesarea, compilarea i editarea de legturi.
Compilarea independent
Fiier executabil din mai multe fiiere surs
Preprocesarea are rolul de a completa codul surs, n special prin includerea altor fiiere. Compilarea se face la nivel de fiier: este verificat corectitudinea sintactic a codului dintr-un fiier i faptul c toi identificatorii (nume de funcii i de variabile) care apar n acel fiier sunt cunoscui (vizibili). Un identificator se consider cunoscut n aceast faz dac a fost declarat sau definit.
Compilarea independent
Fiier executabil din mai multe fiiere surs
n urma compilrii unui fiier surs rezult un fiier obiect. Fiierul obiect are de obicei acelai nume ca i fiierul surs, dar primete extensia .o sau .obj (n funcie de sistemul sub care se lucreaz). Editarea legturilor (linkeditarea) realizeaz legarea tuturor apelurilor de funcii de codul efectiv apelat. Aceast faz necesit deci accesul la definiiile tuturor funciilor, din toate fiierele obiect care vor fi parte a aplicaiei. n urm operaiei de editare a legturilor rezult fiierul executabil. n sistemele Windows aceste fiiere au extensia .exe. n Linux nu au, de obicei, aceast extensie.
Compilarea independent
Fiier executabil din mai multe fiiere surs
Pentru a putea compila independent fiierul prog.c se asigur faptul c funcia calcul va fi cunoscut n acest fiier prin completarea lui cu o declaraie a funciei: int calcul(int a, int b); Pentru faza de editare a legturilor trebuie specificate toate fiierele care sunt implicate n obinerea executabilului. Modalitile practice de compilare i linkeditare a unui program C compus din mai multe fiiere surs depind de sistemul utilizat. n medii ca TurboC sau VisualC se creaz un proiect la care se adaug toate fiierele surs ale aplicaiei. Acestea vor fi n mod automat linkeditate mpreun.
Compilarea independent
Fiier executabil din mai multe fiiere surs
n mediul gcc se pot parcurge toi sau numai o parte din paii descrii. De exemplu, pentru cele dou fiiere ale aplicaiei precedente, vom avea: PREPROCESAREA I COMPILAREA gcc c calc.c =>se genereaz pe disc fiierul obiect calc.o gcc c prog.c =>se genereaz pe disc fiierul obiect prog.o EDITAREA LEGTURILOR gcc o prog calc.o prog.o => se genereaz pe disc fiierul executabil prog Acelai efect se poate obine i printr-o singur rulare a lui gcc: gcc o prog calc.c prog.c
Compilarea independent
Fiier executabil din mai multe fiiere surs
Aplicaie format din mai multe module: calc.c
prog.c calc.o prog prog.o
calc.h
Preprocesare
Compilare
Linkeditare
Compilarea independent
Lucrul n modul project
n mediul Borland C, compilarea i linkeditarea mpreun a mai multor fiiere se face n modul project. Pentru aceasta, trebuie executai urmtorii pai: Selectarea opiunii Project, apoi Open project. Stabilirea numelui fiierului project (extensia .prj). Marcarea cu INS a fiierelor care trebuie compilate i apoi linkeditate. Fiierele antet nu se includ n project (Cu DEL se elimin un fiier selectat greit). Selectarea opiunii pentru construirea programului executabil (meniul Compile, opiunea Build all). Selectarea opiunii Project i apoi Close project pentru ncheierea lucrului n modul project.
Compilarea independent
Fiiere antet
Pe lng modulele program, care conin definiiile funciilor, se pot defini module antet (header) asociate modulelor program. Modulele antet au rol declarativ. Un modul antet asociat unui modul program conine toate informaiile necesare pentru a verifica corectitudinea utilizrii funciilor sau altor entiti definite n modulul program asociat, atunci cnd acestea sunt utilizate n alte module. Se obisnuiete ca numele fiierului antet asociat unui modul x sa fie x.h iar numele modulului program x.c. De exemplu, modulului calc.c i se poate ataa modulul antet calc.h, cu urmtorul coninut:
Compilarea independent
Fiiere antet
Un program care utilizeaz funcia calcul nu mai trebuie s scrie declaraia ei, ci doar s specifice includerea fiierului antet n care aceasta este declarat. Programul prog.c se rescrie astfel: Fiierul prog.c:
#include <stdio.h> #include "calc.h" void main(void) { int x=3, y=4, z; z=calcul(x,y); printf("rezultatul calculelor este %d \n", z); }
O directiv #include este nlocuit n timpul preprocesrii cu coninutul integral al fiierului specificat.
Compilarea independent
Fiiere antet
Forma directivei #include poate fi: #include "nume_de_fisier" #include <nume_de_fisier> Cum se face cutarea ? Dac numele fiierului de inclus este dat ntre ghilimele, preprocesorul caut fiierul pornind de la directorul curent, cel n care se afl programul. Dac fiierul nu e gsit, sau dac numele este dat ntre paranteze unghiulare, cutarea fiierului se face n continuare dup reguli definite de implementarea compilatorului de C utilizat: se pot specifica directoarele n care s se efectueze cutarea (prin opiuni de configurare).
Compilarea independent
Fiiere antet
Directiva #include ofer o modalitate de a utiliza aceleai declaraii n cazul programelor care sunt mprite pe mai multe fiiere. Dac se modific un fiier inclus, trebuie recompilate toate fiierele care l includ pe acesta direct sau indirect. Un fiier antet bine construit s poate conin: Definiii de tipuri Declaraii de funcii Declaraii de variabile Definiii de constante Macrodefiniii Directive de includere
Compilarea independent
Fiiere antet
Un fiier antet bine proiectat nu trebuie s conin definiii de funcii i definiii de date! n principiu, un fiier antet poate fi inclus de ctre mai multe module diferite ale aceleiai aplicaii. n cazul n care acest modul antet conine o definiie de funcie sau o definiie de variabil global, prin includerea multipl se realizeaz definirea multipl a acestor entiti, fapt care constituie o eroare.
Compilarea independent
Variabile externe
Variabilele globale (externe) exist i i pstreaz valorile de-a lungul execuiei ntregului program. Ele pot fi folosite pentru comunicarea ntre funcii. n cazul n care aceste funcii fac parte din fiiere diferite, se pune problema definirii variabilelor externe astfel nct s fie cunoscute tuturor modulelor, dar fr a genera erori din cauza definirii lor multiple. Dac se include definiia unei variabile globale ntr-un modul antet, i acest modul antet este inclus de mai multe ori n fiiere ale aceluiai proiect, se va obine o eroare de programare, din cauza variabilei definite de mai multe ori.
Compilarea independent
Variabile externe
Soluia este declararea de variabile globale, utiliznd cuvntul cheie extern. O declaraie precizeaz doar natura variabilei, dar fr s i rezerve spaiu de memorie. Prin opoziie, o definiie creaz variabila, i rezerv spaiu de memorie. O anumit variabil poate avea oricte declaraii, dar poate fi definit o singur dat. Pentru identificatorii din clasa extern, trebuie s existe o definiie ntr-unul din fiiere; n celelalte fiiere apare doar declaraia acestora, precedat de specificatorul extern.
Compilarea independent
Variabile externe-exemplu de utilizare
Exemplul urmtor([19], pag. 231) prezint funciile calculeaza(), prel() i main() aflate n fiiere diferite i compilate separat, care folosesc n comun o variabil extern: valoare_importanta. Memoria corespunztoare lui valoare_importanta este alocat prin definiia din fiierul calcule.c. Declaraia variabilei valoare_importanta din fiierul antet calcule.h precizeaz (prin modificatorul extern) c memoria pentru valoare_importanta este alocat n alt parte. Acest fiier antet este inclus n prelucrari.c i prog.c. Fiierul calcule.h: extern int valoare_importanta; void calculeaza(void);
Compilarea independent
Variabile externe-exemplu de utilizare
Fiierul calcule.c: int valoare_importanta=1; void calculeaza(void) { valoare_importanta = 3; } Fiierul prelucrari.h: void prel (void); Fiierul prelucrari.c: #include "calcule.h" void prel (void) { valoare_importanta=4; }
Compilarea independent
Variabile externe-exemplu de utilizare
Fiierul prog.c: #include "calcule.h" #include "prelucrari.h" void main(void) { valoare_importanta=5; calculeaza(); prel(); }
Compilarea independent
Variabile externe-concluzii
n general, dac o funcie se refer la un nume declarat extern, atunci trebuie s existe o definiie a acelui identificator ntr-unul din fiierele sau bibliotecile programului. Toate funciile unui program care se refer la acelai nume extern indic aceeai entitate. Entitilor declarate cu extern nu li se mai aloc memorie la compilare, dar n faza de linkeditare sunt asociate cu definiiile lor.
Compilarea independent
Variabile externe-concluzii
Tipul specificat n declaraiile externe trebuie s fie acelai ca i tipul din definiie. ntr-un program compus din mai multe fiiere, o definiie de dat extern, fr specificatorul extern, are voie s apar o singur dat, ntr-un singur fiier. Orice alt fiier care mai declar acel identificator trebuie s foloseasc cuvntul cheie extern n declaraie (omiterea va fi semnalat ca eroare la faza de editare a legturilor ).
Compilarea independent
Variabile i funcii statice
Anumite variabile i funcii definite i utilizate ntr-un modul pot s aib un rol limitat la realizarea unor operaii ajuttoare, subordonate operaiilor exportate de modul. Asemenea variabile i funcii nu trebuie s fie direct accesate din afara modulului. Declararea ca static a unei variabile globale sau funcii, i limiteaz vizibilitatea la fiierul curent. O asemenea variabil sau funcie nu poate fi apelat din alt fiier surs. O variabil sau o funcie static nu este vizibil din alte fiiere. Declaraia de clas static se aplic i variabilelor interne (locale unei funcii), cu alt semnificaie(opus lui automatic). O asemenea variabil va exista n permanen, n loc s fie creat i s dispar la fiecare apel al funciei.