Sunteți pe pagina 1din 8

Compilare independenta...................................................................................................................1 Avantajele structurarii programelor C pe mai multe fisiere.........................................................1 Recomandari de structurare pe mai multe fisiere.........................................................................

1 Compilare independenta in GCC.................................................................................................3 Tipul de date abstracte stiva.............................................................................................................4 Implementarea stivei folosind un tablou......................................................................................4 Implementarea stivei folosind liste simplu inlantuite...................................................................6 Teme................................................................................................................................................. Tema 1.......................................................................................................................................... Tema ! ........................................................................................................................................."

Compilare independenta
Avantajele structurarii programelor C pe mai multe fisiere
* n cazul programelor mari, daca tot programul ar fi scris ntr-un singur fisier, programul ar fi foarte greu de urmarit si timpul de compilare ar fi foarte mare, nefiind folosita facilitatea de compilare independenta. Acest aspect este foarte util n faza de corectare a erorilor sintactice si semantice, cnd doar fisierul eronat trebuie recompilat, pentru restul fisierelor trebuind doar linkeditate fisierele obiect. Daca ntregul program este plasat ntrun singur fisier atunci orice modificare sau corectie impune recompilarea ntregului program. * Structurarea programelor pe mai multe fisiere permite simularea mecanismului de ncapsulare a datelor. Variabilele si functiile avnd clasa de memorare static pot fi accesate doar n cadrul fisierului n care ele au fost definite. Variabilele si functiile declarate cu clasa de memorare extern sunt definite ntr-un alt fisier dect cel curent, dar ele pot fi accesate n fisierul curent. Astfel fisierele apar n C ca un mecanism de control al vizibilitatii obiectelor.

Recomandari de structurare pe mai multe fisiere


n general, se alege un fisier care va fi fisierul principal, n acest fisier fiind implementata functia main(); n celelalte fisiere nu va mai fi implementata aceasta functie. n fisierul antet se vor trece definitia tipurilor de date folosite si declaratiile (prototipurile) functiilor. Nu se vor trece n fisierul antet declaratii de variabile si implementari de functii (este perfect "legal" sa apara declaratii de variabile si implementari de functii, fisierul antet fiind tratat ca orice fisier C, dar aceasta maniera de programare distruge conceptul de modularizare a programelor si de ncapsulare a datelor). n fisierul auxiliar antetului (cu acelasi nume si extensia .c) se va trece implementarea functiilor definite n fisierul antet. n acest fisier nu se va implementa functia main(). Att fisierul principal ct si cel auxiliar vor include fisirul antet. Astfel se realizeaza ncapsularea tipurilor de date si a functiilor n fisiere separate. Aceasta maniera de structurare a programelor este folosita n scrierea unor biblioteci de functii. Programatorul care doreste sa furnizeze o biblioteca de functii va scrie fisierul antet si fisierul auxiliar antetului, care va include fisierul antet. n fisierul antet vor fi trecute functiile si tipurile de date oferite de biblioteca, iar n fisierul auxiliar vor fi implementate aceste functii. Aceste fisiere se compileaza mpreuna, rezultnd un fisier obiect (nu executabil), iar biblioteca va oferi acces la aceste functii prin includerea n orice program a fisierului antet si prin linkeditarea cu fisierul obiect. Programatorul acestei biblioteci nu va

oferi spre utilizare dect fisierul antet si fisierul obiect, astfel maniera de implementare a functiilor oferite de biblioteca ramne invizibila pentru utilizatorul bibliotecii. Pentru a exemplifica aceste reguli, consideram un program pentru calculul sumei a doua numere complexe. Pentru aceasta, se va defini o functie suma. De asemenea, vor fi definite si doua functii pentru citirea, respectiv afisarea numerelor complexe. Programul va fi structurat pe trei fisiere: calcul.c - care contine functia main, operatii.h fisierul antet unde sunt declarate principalele tipuri de date si functii si operatii.c implementarea functiilor.
//== calcul.c == #include <stdio.h> #include "operatii.h" int main(void) { complex x,y; print ("introduceti primul numar!n"); x=citire(); print ("introduceti al "#lea numar!n"); y=citire(); print ("!nsuma$ "); a isare(suma(x,y)); print ("!n"); return %;

&

//== operatii.h == /' de inire tip de date complex '/ typede struct nr(complex { dou)le p(real; dou)le p(ima*; & complex; /' prototipuri unctii exportate '/ complex citire(void); void a isare(complex); complex suma(complex,complex); //== operatii.c == #include <stdio.h> #include "operatii.h" /' implementare unctii exportate '/ complex citire(void) { complex nr; print ("+artea reala$ "); scan (",l ",-nr.p(real); print ("+artea ima*inara$ "); scan (",l ",-nr.p(ima*); & return nr;

void a isare(complex nr) { i (nr.p(ima*<%) print (",l ,l i!n",nr.p(real,nr.p(ima*); else print (",l .,l i!n",nr.p(real,nr.p(ima*); & complex suma(complex nr/, complex nr") { complex re0ult; re0ult.p(real=nr/.p(real . nr".p(real; re0ult.p(ima*=nr/.p(ima* . nr".p(ima*; return re0ult; &

Compilare independenta in GCC


Pasii pentru compilarea exemplului sunt urmatorii: generarea fisierelor obiect pentru fisierul operatii.c, folosind comenzile: *cc #1all #c #o operatii.o operatii.c *cc #1all #c #o calcul.o calcul.c compilarea efectiva pornind de la fisierele obiect# cu comanda$ gcc operatii.o calcul.o e%ecutabil rularea e%ecutabilului generat ./executa)il &upa cum se poate observa# fisierul operatii.' nu trece direct prin procesul compilare# ci este referit doar din codul sursa al celor doua fisiere .c. (entru programele de dimensiuni mari acest proces este autmati)at cu utilitarul make. *e creea)a un fisier de configurare numit Makefile# cu urmatorul continut$ CC=gcc CFLAGS=-Wall calcul: operatii.o calcul.o

clean: rm -f stiva teststiv.o stiva.o &in linia de comanda se apelea)a comanda ma+e# fara niciun argument pentru generarea e%ecutabilului numit calcul. Al doilea mod de utili)are este rularea comen)ii ma2e clean , avand ca re)ultat stergerea celor 3 fisiere$ cele obiect si e%ecutabilul generat.

Tipul de date abstracte stiva


Stiva este un tip special de lista n care toate insertiile si suprimarile de noduri au loc la un singur capat. Acest capat se numeste vrful stivei. Tipul abstract stiva pe care l definim contine urmatorii operatori: 1. Initializarea stivei. 2. Verificarea faptului ca stiva e plina. 3. Verificarea faptului ca stiva e goala. 4. Introducerea unui element n vrful stivei. 5. Eliminarea elementului din vrful stivei. 6. Furnizarea elementului din vrful stivei fara a-l elimina.

Implementarea stivei folosind un tablou


#include <stdio.h> #include <stdli).h> #include "stiva.h"

#de ine 345 /%%

static int stiva63457; static int var ;

/' stiva '/

/' var ul stivei '/

void init(void){ int i;

or (i = %; i < 345; i..) stiva6i7 = %; /' toate elementele devin % '/

var &

= #/; /' var ul stivei indica primul element ocupat'/

int plin(void){ return (var & /' == 345#/);

stiva este plina atunci c8nd v8r ul stivei indica spre ultimul element din stiva (cel de indice 345#/). '/

int *ol(void){ return (var & /' unctia *ol veri ica daca stiva este *oala. 98nd indicele stivei este e*al cu #/, stiva nu contine nici o valoare si *ol returnea0a /. :aca var >#/ atunci stiva contine cel putin o valoare, ast el ca *ol returnea0a %. '/ == #/);

void pune(int nr){ i (plin()){ print (";roare$ stiva este plina!n"); exit(/); & stiva6..var 7 = nr; /' noul element este introdus in var ul stivei '/ & /' unctia pune introduce <n v8r ul stivei numarul transmis prin parametrul int nr. :aca stiva este plina atunci se a isea0a un mesa= de eroare si executia este incheiata. >n ca0 contrar, se incrementea0a v8r ul stivei var , dupa care noul element este memorat <n v8r ul stivei. '/

void scoate(void){ i (*ol() ) /' daca stiva este *oala '/{ print (";roare$ stiva este *oala!n"); exit(/); & var ##; /' decrementea0a var ul stivei '/

& /' unctia scoate extra*e elementul din v8r ul stivei ara a#l returna. :aca stiva este *oala atunci scoate a isea0a un mesa= de eroare si executia pro*ramului este <ncheiata. >n ca0 contrar, v8r ul stivei este decrementat. '/

int ia(var (void){ i (*ol()){ print (";roare$ stiva este *oala!n"); exit(/); & return stiva6var 7; /' returnea0a elementul din var ul stivei '/ &

void *oleste(void){ ?hile(@*ol()){ scoate(); & &

Implementarea stivei folosind liste simplu inlantuite


Definim tipul de date abstract stiva utilizand o lista simplu inlantuita. urm indica proximul element aflat sub cel current, iar informatia utila fiind un numar real.
typede struct elementAtiva { dou)le in o; struct stiva 'urm; & stiva;

Operatiile sunt definite in fisierul "stiva.h" (comun pentru ambele implementari, evident) dupa cum urmeaza
void init(void); // initiali0ea0a var ul stivei void pune(dou)le d) // adau*a un element in stiva, modi icand si var ul curent void scoate(void); // extra*e un element din stiva, eli)erand memoria ocupata dou)le ia(var (void); // returnea0a in ormatia utila a elementului din var int *ol(void); // veri ica existenta a cel putin unui element in stiva

int plin(void); /' veri ica daca exista su icienta memorie li)era pentru adau*area unui element '/ void *oleste(void); // ster*e toate elementele din stiva

In fisierul antet stiva.h este declarat si pointerul spre varful stivei. Functiile sunt implementate in fisierul stiva.c Fisierul care foloseste aceste functii se numeste teststiv.c :
#include <stdio.h> #include "stiva.h"

int main( ){ int i, element;

init(); or(i = %; i < /%; i..){ element = (int)(random() , /%); print ("punem ,d ... ",element); pune(element); print ("6+BA7!n"); & ?hile(@*ol()){ print ( "urmea0a sa scoatem ,d ... ", ia(var ()); scoate(); print ("6A9CA7!n"); & /' echivalent cu return %; & *oleste(); '/

Teme
Tema 1
Implementati functiile descrise in fisierul antet stiva.h in fisierul stiva.c, compilati si testati folosind fisierul teststiv.c de mai sus.

Tema 2
Evaluarea unei expresii n notatie poloneza Notatia poloneza (sau postfix) este un mod de scriere a expresiilor, n care ordinea operatorilor si a operanzilor este schimbata fata de cea dintr-o expresie uzuala. n notatia uzuala (numita si infix) o expresie are forma: operand operator operand n notatia postfix (poloneza) expresia este scrisa sub forma: operand operand operator De exemplu: a + b devine n notatie poloneza a b + (a - b) * c devine a b - c * a - b * (c + d) devine a b c d + * Scrieti un program care evalueaza expresii postfix cu operanzi numere reale, expresii citite dintr-un fisier de intrare, cate una pe fiecare rand.

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