Sunteți pe pagina 1din 206

ELENA ERBAN

CLAUDIA BOTEZ

PROGRAMARE
STRUCTURAT N
LIMBAJUL C STANDARD
Ediia 2008

http://www.ace.tuiasi.ro/~eserban

Programarea calculatoarelor ____________________________________________ Curs 2008

Bibliografie recomandat
1. erban, E., Programarea calculatoarelor Note de curs, 2008.
2. Kernigham, B. W. i Ritchie, D. M., Limbajul C, Editura TEORA, Bucureti.
3. Schildt, H., C Manual complet, Editura TEORA, Bucureti.
4. Botez, C., erban, E., Maftei, L., Gospodaru, M., ova, I., Programarea calculatoarelor
n limbajul C/C++. Lucrri practice, Editura Gh. Asachi, Iai, 2002.
5. Iorga, V., Chiri, P., Stratan, C., Opincaru, C., Programare n C/C++. Culegere de
probleme. Editura Niculescu, Bucureti, 2003

1.1. LIMBAJE DE PROGRAMARE I ALGORITMI


1.1.1. Definiia i proprietile algoritmilor
Limbajele de programare sunt mijloace de comunicare ntre om i calculator. Ce
transmite un om, utilizatorul, calculatorului? n general, prelucrrile care trebuie s fie
executate de ctre calculator. Se tie c un calculator este un obiect inert atta timp
ct nu i se indic operaiile care trebuie executate. Aceste indicaii sunt exprimate sub
forma unor comenzi sau indicaii transmise spre execuie calculatorului. Descrierea de
ctre programator a succesiunii acestor operaii se numete program.
Scrierea unui program implic dou aspecte:

a) exprimarea a ceea trebuie s fac un calculator, respectiv modul n care


calculatorul

va

rezolva

problema

dat;

pentru

aceasta

utilizatorul

transmite

calculatorului un algoritm. Limbajul de programare este modul n care descriem acest


algoritm.

b) precizarea datelor care vor fi prelucrate (prelucrarea datelor nseamn


modificarea datelor de intrare astfel nct s se ajung la rezultate). Precizarea
datelor nseamn precizarea tipului datelor, organizarea lor, relaiile dintre ele.
Limbajul

de

programare

trebuie

pun

la

dispoziia

utilizatorului

faciliti

corespunztoare de descriere a datelor.


Un algoritm este o succesiune de operaii pe care le facem asupra unor date
(numite date - mrimi de intrare) pentru a obine anumite rezultate (numite i date
mrimi de ieire). Pentru a fi util un algoritm trebuie s fie precis, neambiguu i s
specifice, pentru toate cazurile posibile, o secven unic i finit de aciuni care s
conduc la un rezultat previzibil.
Operaiile unui algoritm pot fi executate fie de o persoan, fie de un calculator.
Un algoritm trebuie s aib urmtoarele proprieti:
1. Generalitate. Nu scriem un algoritm pentru rezolvarea unei probleme
particulare, ci pentru rezolvarea unei ntregi clase de probleme. De exemplu: nu
scriem un algoritm pentru rezolvarea ecuaiei

3x + 2 = 0
ci pentru rezolvarea ecuaiei de gradul I, ecuaie care are forma:

ax + b = 0
2. Claritate. Aceast proprietate se refer la construirea algoritmului. Operaiile
algoritmului i succesiunea executrii lor trebuie s fie descrise clar, precis, fr
ambiguiti astfel nct s permit execuia mecanic, automat a aciunilor
1

algoritmului. Aciunile care alctuiesc algoritmul pot fi grupate n blocuri de aciuni


pentru ca algoritmul s poat fi uor explicat, neles, testat i modificat.
Aceste grupuri de aciuni, din care este format algoritmul, trebuie s fie astfel
interconectate nct s poat fi nlocuite ntr-o versiune mbuntit a algoritmului,
fr a rescrie algoritmul n ntregime.
3. Eficien. Pentru rezolvarea unei anumite probleme pot exista mai muli
algoritmi (exist mai multe soluii). Vom alege acel algoritm care are o vitez de
execuie mai mare (numrul operaiilor care trebuie executate este mai mic) i/sau
dimensiunea sa este mai mic.
4. Un algoritm trebuie s fie complet. Pentru aceasta toate aciunile sale trebuie
s fie exact definite.
5. Neambiguitatea. Un set de instruciuni vor fi neambigue dac exist o
singur interpretare a lor.
6. Un algoritm trebuie s fie determinist. Aceasta semnific faptul c, dac
sunt urmate instruciunile din algoritm, cu siguran vom obinute ntotdeauna
rezultatul dorit.
7. Finitudinea. Acest lucru nseamn c algoritmul trebuie s se termine dup
un numr finit de pai (chiar dac acest numr este foarte mare). Aceast cerin nu
se refer numai la numrul finit de pai pe care trebui s-l execute algoritmul, dar i
la folosirea unui numr finit de variabile (date) folosite pentru atingerea rezultatului
dorit. Aceast proprietate deosebete noiunea de algoritm de cea de metod
(procedeu, regul) de calcul. Se poate spune c un algoritm este o metod de calcul
cu un numr finit de operaii. De exemplu, procedeul nvat n gimnaziu de extragere
a rdcinii ptrate dintr-un numr care nu este un ptrat perfect este o metod de
calcul, dar nu este un algoritm pentru c numrul de zecimale al rdcinii ptrate fiind
infinit, procedeul va cuprinde o infinitate de operaii. Metoda de extragere a rdcinii
ptrate poate deveni un algoritm dac limitm numrul zecimalelor rezultatului.
n afara acestor proprieti la scrierea unui algoritm trebuie bine stabilite de la
nceput datele de intrare (intrarea algoritmului datele pe care le avem la dispoziie
prin tema de proiectare enunul problemei) i datele de ieire (ieirea algoritmului
rezultatele pe care vrem s le obinem). Att pentru datele de intrare, ct i pentru
datele de ieire trebuie s stabilim:
tipul lor (date de tip ntreg, real, iruri de caractere)
domeniul n care aceste date pot lua valori. (de exemplu dac se specific n
problem: se citete un numr natural mai mic dect 20, trebuie s verificm dac
2

valoarea citit este ntr-adevr mai mic dect 20 i mai mare ca zero validarea
datelor).
Execuia

unui

algoritm

nseamn

execuia

pas

cu

pas

operaiilor

(instruciunilor) descrise de algoritm. Algoritmii se consider executai pe maini


abstracte / virtuale (ale cror caracteristici le abstractizeaz pe cele ale mainile /
sistemelor de calcul existente la un moment dat).
O astfel de main virtual este reprezentat n Figura 1:

D. I.

MEMORIE

D.E.

UNITATE ARITMETICO - LOGICA


(A.L.U)
Figura 1. Maina virtual folosit pentru execuia algoritmilor
Maina primete informaii de la dispozitivul de intrare D.I. i depune
rezultatele pe dispozitivul de ieire D.E. ALU asigur prelucrarea datelor aflate n
memorie n celule accesibile prin nume i prin adres. Celulele se pot grupa pentru a
gzdui date structurate. Prelucrrile se bazeaz pe operaii aritmetice, logice, funcii
elementare nlnuite n calcule care de obicei le exprimm prin expresii matematice.

1.1.2. Obiectele cu care lucreaz algoritmii


1.1.2.1. Constantele
Constantele sunt date ale cror valori nu se modific pe parcursul execuiei
algoritmului. Aceste constante pot fi, n funcie de limbaj, numere ntregi sau reale,
caractere i iruri de caractere, valori logice (adevrat i fals).

1.1.2.2. Variabilele
Spre deosebire de constante, variabilele conin date care se pot modifica pe
parcursul executrii algoritmului. Ele se utilizeaz pentru a pstra datele de intrare
(datele iniiale), rezultatele pariale i rezultatele finale ale algoritmului. Fiecrei
variabile i se asociaz o locaie (sau grup de locaii) de memorie unde i se pstreaz
valoarea. O variabil este, de fapt, numele simbolic (identificatorul) unei locaii din
memoria mainii virtuale.
Nu trebuie s se confunde noiunea de variabil din algoritmi cu aceea din
matematic: ntr-un algoritm, o variabil va fi ntotdeauna o valoare, pe cnd n

matematic ea reprezint o nedeterminat cu care se pot face operaii fr s-i fie


cunoscut valoarea.
Variabilele pot fi naturale, ntregi, reale, logice sau pot lua ca valori iruri de
caractere. (Tipul variabilelor difer de la un limbaj la altul). Ele se noteaz cu litere
sau cuvinte care s le sugereze semnificaia (de exemplu: a, i, index, primulElement).

1.1.2.3. Expresii
Constantele i variabilele pot s apar n expresii mpreun cu operatorii uzuali
aritmetici, relaionali sau logici.
Notaia operatorilor aritmetici este cea folosit n matematic: +, -, *, / (pentru
mprire).
Notaia operatorilor logici:
- negaia
SAU
I
Notaia operatorilor relaionali: =, , <, >, , .
Constantele i variabilele pot s apar n expresii mpreun cu operaorii i
parantezele rotunde. Nu se vor folosi paranteze ptrate.
n funcie de tipul operanzilor i cel al operatorilor, expresiile pot fi: aritmetice,
relaionale sau logice.
a) O expresie aritmetic este o expresie care cuprinde: constante, variabile sau
funcii aritmetice elementare, legate, eventual, prin operatori aritmetici.
b) O expresie relaional este format din dou expresii aritmetice legate printrun singur operator relaional (de exemplu: b>0 sau a b). Valoarea de adevr
(rezultatul) unei expresii relaionale este adevrat sau fals.

c) O expresie logic cuprinde constante, variabile sau expresii relaionale legate


prin operatori logici. Rezultatul unei astfel de expresii este adevrat sau fals. De
exemplu: (a 0) I (b 0) este o expresie logic format din dou expresii
relaionale care are valoarea adevrat numai dac att a ct i b au valori diferite de
0. Dac a = 0 sau b = 0 atunci expresia logic are valoarea fals.
n descrierea algoritmilor apar noduri de decizie, n cere trebuie s executm o
operaie sau alta n funcie de ndeplinirea sau nendeplinirea unei anumite condiii.
Aceste condiii care apar n algoritmi vor fi ntotdeauna exprimate prin expresii
relaionale sau logice.
4

1.1.2.4. Operaiile (instruciunile) de baz (elementare) care apar n algoritmi


n cele ce urmeaz vom nota cu var numele unei variabile generice din algoritm.
Instruciunile de baz pe care le poate executa maina virtual pe care sunt
executai algoritmii sunt:
citirea: se nregistreaz ntr-o anumit celul de memorie (asociat unei
variabile) o valoare citit de la un dispozitiv de intrare (de exemplu tastatura (implicit)
sau de pe disc, dintr-un fiier). n urma acestei instruciuni de iniializeaz variabila cu
numele simbolic indicat. Forma general este:
citete var
De exemplu, citirea a trei variabile pe care le numim a, b, c:
citete a, b, c

scrierea: din memorie se copie pe un dispozitiv de ieire (ecranul monitorului


(implicit) sau un

pe un disc, ntr-un fiier) valoarea variabilei al crui nume este

indicat n instruciune. n urma acestei operaii valoarea variabilei nu se terge din


memorie. Operaia de scriere are sens doar dac variabila a fost anterior definit
(exist n memorie o celul asociat variabilei var care are nscris n ea valoarea
variabilei). Forma general este:
scrie var
De exemplu:
scrie a
sau
scrie "Sistem incompatibil"

atribuirea (nlocuirea), specificat prin . Forma general este


v e;
unde v este un nume simbolic de variabil, e este o expresie (o formul, o regul de
calcul care specific un rezultat) alctuit din variabile i numere legate ntre ele prin
operatori aritmetici, logici, funcii elementare i paranteze. Se execut succesiunea
specificat de operaii asupra valorilor unor celule ale memoriei (e), iar rezultatul se
depune ntr-o celul de memorie, de asemenea specificat v.
Exemplu:
i i + 1;
5

A B;
r m % n; restul mpririi lui m la n.
O variabil se poate defini fie prin operaia de citire, fie prin operaia de atribuire;
operaiile aritmetice, logice i de scriere au sens doar pentru variabilele ce au fost
definite anterior. Cnd se construiete un algoritm, trebuie avut grij ca toate
variabilele s fie definite. Nu se vor scrie instruciuni n care figureaz variabile care
nu au fost definite anterior.

decizia. Este operaia prin care se verific o condiie a crei valoare de adevr
determin ramificarea algoritmului; n cazul n care condiia este adevrat algoritmul
se continu cu o anumit operaie (instruciune), n caz contrar cu o alta.

1.1.3. Reprezentarea algoritmilor


Exist mai multe modaliti de reprezentare a algoritmilor. Pentru fiecare
algoritm pot exista reprezentri diferite, unele mai bune dect altele. Nu exist o
reprezentare care s fie cea mai bun pentru toi algoritmii.
Modalitile de reprezentare a algoritmilor includ:
reprezentri verbale. Algoritmul este "povestit" n cuvinte
reprezentri algebrice. Algoritmul este reprezentat matematic prin formule
i simboluri.
De exemplu:
formula de transformare din grade Celsius n grade Fahrenheit (n
formul am notat cu C valoarea temperaturii n grade Celsius, iar cu F valoarea
temperaturii n grade Fahrenheit)

F =

9
C + 32
5

formula de transformare a reprezentrii unui numr din baza 2 n baza


10 (n formul am notat Bi , i = 0, n cifrele binare ale numrului)

(Bn Bn 1 K B2 B1B0 )2

= 2 n Bn + 2 n 1 Bn 1 + K + 22 B2 + 21 B1 + 20 B0

reprezentri prin scheme logice. Algoritmul este reprezentat sub forma


unei diagrame format din figuri geometrice legate prin linii care arat ordinea n care
6

sunt executate operaiile nscrise n figurile geometrice. Aceast ordine de execuie a


instruciunilor se numete structura de control.

reprezentri prin pseudocod. Algoritmul este prezentat ca un set de


instruciuni scrise utiliznd un amestec de limbaj natural i notaie matematic. Forma
instruciunilor n pseudocod este asemntoare (dar nu identic) cu cea din limbajele
de programare. Asigur o scriere compact a algoritmului, dar nu pune n eviden tot
att de sugestiv ca schemele logice succesiunea de operaii din algoritm (fluxul de
informaii).

1.1.3.1. Reprezentarea algoritmilor prin intermediul schemelor logice


Simboluri folosite
Reprezentarea grafic bidimensional a unui algoritm cu ajutorul unor simboluri
speciale se numete schem logic program sau schem logic (organigram).
Pentru reprezentarea schemelor logice au fost stabilite anumite simboluri
geometrice care sugereaz prin forma lor diferitele operaii care trebuie executate i
ordinea de execuie. Ea reprezint n acelai timp i o imagine a fluxului de informaii
care exist atunci cnd calculatorul execut programul bazat pe algoritmul descris.
Schemele logice au fost inventate de Herman Goldstine (S.U.A.) n 1946.
Alctuirea

schemei

logice

permite

ca

programatorul

neleag

logica

programului, s realizeze modularizarea programului (prin mprirea programului n


pri mai mici i mai detaliate), s verifice ndeplinirea tuturor condiiilor posibile din
program, s traduc algoritmul ntr-un limbaj de programare (de exemplu n C).
Simbolurile folosite la construirea schemelor logice se pot mpri n mai multe
categorii:
a. Simbolul linie i vrf de sgeat.

Acesta simbolizeaz direcia fluxului de informaie n calculator i succesiunea


diferitelor operaii. Liniile de flux se pot ncrucia. Liniile care se ncrucieaz nu
nseamn c sunt conectate. Dac ele sunt conectate trebuie s apar vrfuri de
sgei lng punctul de jonciune pentru a marca conexiunea. Se reprezint printr-un
7

segment de dreapt de orice lungime care trebuie s lege alte dou simboluri. Direcia
normal a fluxului este de la stnga la dreapta i de sus n jos. Cnd direcia fluxului
este de sens opus direciei normale se folosesc vrfuri de sgeat. Pentru mai mult
claritate muli programatori folosesc vrfurile de sgeat n toate cazurile.
b. Simbolul proces reprezint execuia unei operaii sau a unui grup de operaii
n urma creia se schimb valoarea, forma sau localizarea informaiei. Operaiile de
prelucrare includ operaii aritmetice, operaii logice sau mutarea datelor dintr-o zon a
memoriei n alta. Forma acestui simbol este un dreptunghi cu raportul de form 2/3.

rm%n

BA

ii+1

c. Simboluri de intrare ieire reprezint funcia general de intrare ieire,


adic de introducere a informaiei n calculator pentru prelucrare (intrare) i de
extragere a informaiei prelucrate (ieire). Arat punctele de intrare a datelor i de
ieire a rezultatelor. Mediul suport de intrare sau de ieire nu este specificat.
Citete

Scrie

list de variabile

list de expresii

De exemplu,
Citete
a, b, c

Scrie
"n nu poate fi 0"

Scrie "x=", x

Scrie x

d. Simboluri terminal care reprezint nceputul (a), sfritul (b) programului


sau a unei proceduri (funcii) sau un punct de ntrerupere sau de ntrziere ntr-un
program. Orice schem logic trebuie s nceap cu un simbol terminal START i s se
termine cu un simbol terminal STOP.
START

Funcie
STOP

Retur

(a)

nceput i sfrit program

(b) nceput i sfrit funcie

e. Simbolul conector se folosete pentru a reprezenta o linie continu cnd


folosirea liniei continue este limitat de dimensiunea hrtiei sau din considerente de
estetic ale schemei logice. Pentru a identifica conectorii de intrare i de ieire se
folosesc simboluri de identificare litere sau cifre. Astfel conectorii reprezint un
mijloc elegant de a lega dou puncte ale schemei logice fr a folosi liniile. O alt
funcie a conectorilor este aceea c permit reprezentarea unei scheme logice pe mai
multe pagini.
A
1

A
(b) Conectori pentru scheme
reprezentate pe mai multe pagini

(a) Conector pe pagin

logice

f. Simbolul proces predefinit (procedura sau funcia) se folosete pentru a


reprezenta una sau mai multe operaii specificate n detaliu n alt parte (procedur,
funcie, o alt schem logic).

Funcie

g. Simbolul decizie. Se folosete pentru a reprezenta o decizie sau o operaie de


tip comutare ce determin una sau mai multe alternative posibile. Simbolul decizie are
o intrare i dou sau mai multe ieiri. Decizia este reprezentat printr-un romb n
interiorul cruia se gsete o condiie (simpl format dintr-o expresie relaional
sau compus format dintr-o expresie logic). Valoarea de adevr a unei condiii este
fie adevrat (i algoritmul se continu pe ramura DA), fie fals (i algoritmul se
continu pe ramura NU).
NU

Condiie

DA

Exemple
P1.
S se calculeze aria unui triunghi oarecare dac se cunosc coordonatele vrfurilor
triunghiului.

Analiza problemei
Formula lui Heron reprezint o modalitate de a calcula aria unui triunghi
dac se cunosc lungimile laturilor triunghiului. Formula de calcul este:

A=

p(p a)(p b)(p c )

unde a, b, c R sunt lungimile laturilor, iar p este semiperimetrul triunghiului.


Avnd n vedere faptul c se cunosc coordonatele vrfurilor, putem calcula
lungimile laturilor triunghiului. De exemplu, latura c se calculeaz cu formula:

c =

(x A

x B ) + (y A y B )
2

Datele de intrare sunt reprezentate de coordonatele celor trei vrfuri ale


triunghiului i le corespund variabilele xa, ya, xb, yb, xc, yc. Valorile datelor de intrare
sunt de tip real i se vor citi de la tastatura calculatorului.
Data de ieire este reprezentat de aria triunghiului, este notat ca n formula lui
Heron cu A, de tip real.
Programul trebuie s citeasc cele 6 date de intrare, s calculeze aria i s
afieze valoarea ariei. n cazul n care aria este egal cu zero cele trei puncte sunt
coliniare i pe monitor se va afia un mesaj corespunztor.
Schema logic a programului este prezentat n Figura 2.
Funcia de calcul a ariei are ca date de intrare valorile coordonatelor celor trei
vrfuri ale triunghiului (disponibile de aceast dat n memorie) i ca dat de ieire
valoarea ariei. Pentru calcularea valorii ariei trebuie calculate lungimile celor trei laturi
i valoarea semiperimetrului. Datele de intrare sunt de tip real, data de ieire este de
tip real. Schema logic a funciei pentru calcularea ariei este prezentat n figura P1.2.
Funcia de calcul a lungimii unei laturi are ca date de intrare coordonatele celor
dou extremiti (disponibile n memorie) i ca dat de ieire lungimea unui segment
de dreapt. Datele de intrare sunt de tip real, data de ieire este de tip real.

10

P2.
De pe dispozitivul de intrare (tastatura) se citesc trei numere ntregi. S se
afieze valoarea celui mai mare numr dintre cele trei.
Analiza problemei
Datele de intrare sunt trei numere ntregi (pe care le notm de exemplu cu a, b
i c). Pentru aceast problem avem o singur dat de ieire: valoarea cea mai mare
dintre cele trei.
Cum determinm valoarea cea mai mare? Dac trebuie s facem acest lucru
manual (fr ajutorul calculatorului) vom compara primele dou numere i apoi
valoarea cea mai mare dintre cele dou o comparm cu valoarea celui de al treilea
numr. Schema logic care ilustreaz acest algoritm este dat n Figura 3a (cazul n
care nu folosim o subrutin funcie pentru calculul maximului) i Figura 3b (cazul n
care pentru determinarea maximului folosim o funcie).

P3.
La o firm timpul normal de lucru este de 40 ore / saptmn. Pentru fiecare or
lucrat un angajat este pltit cu un tarif exprimat n lei / or. Dac angajatul face ore
suplimentare, adic lucreaz mai mult de 40 ore / sptmn, dar mai puin de 60 de
ore / sptmn, el este pltit pentru fiecare or lucrat n plus mai mult cu 50%.
Timpul lucrat peste limita celor 60 ore / sptmn este pltit dublu fa de
timpul normal de lucru.
S se fac schema logic pentru calcularea sumei care trebuie pltite unui
anumit angajat.
Analiza problemei
Pentru fiecare angajat pentru care trebuie s calculm suma care i se cuvine ca
plat pentru timpul lucrat trebuie s cunoatem (avem nevoie de urmtoarele date de
intrare):
1. numrul de ore lucrate
2. tariful unei ore lucrate n timpul normal de lucru
Programul care va fi scris pe baza acestei scheme logice trebuie s afieze (pe
monitor) suma de plat (avem ca dat de ieire suma total de plat).
Programul trebuie s citeasc (de la tastatur) cele dou date de intrare de care
avem nevoie i pe care le notm (cu nume sugestive) nrOre i tarifOra, s calculeze
suma total de plat (sumaDePlata) i s afieze suma total de plat.
11

Schema logic a programului este dat n Figura 4a.


Calculul sumei totale de plat o realizm ntr-o subrutin (funcie) care primete
ca date de intrare numrul de ore lucrate i tariful pe or i transmite programului
principal suma calculat. Schema logic a acestei proceduri este dat n Figura 4b.

P4.
Se citesc trei numere naturale de pe dispozitivul de intrare (tastatura). S se
fac schema logic prin care se verific dac cele trei numere pot reprezenta laturile
unui triunghi. n caz afirmativ se va afia pe dispozitivul de ieire (monitorul) un
mesaj care indic tipul triunghiului (echilateral, isoscel, dreptunghic) ale crui laturi
pot avea valorile citite de la tastatur. (Nu se pune problema ca triunghiul ar putea fi
dreptunghic isoscel de ce?).
Analiza problemei
Programul trebuie s citeasc, de la tastatur, trei numere, s verifice dac
ndeplinesc anumite condiii i n funcie de condiia ndeplinit (sau nu) s afieze
mesajul corespunztor.
Datele de intrare sunt cele trei numere naturale. Date de ieire propriu zise nu
exist, programul finalizndu-se prin afiarea unui mesaj. Condiiile care trebuie
verificate sunt:
1. Cele trei numere pot fi valorile laturilor unui triunghi?
2. Triunghiul este echilateral?
3. Triunghiul este isoscel?
4. Triunghiul este dreptunghic?
Fiecare din aceste condiii va fi verificat ntr-o subrutin (funcie) care va
transmite programului principal valoarea 1 (adevrat) dac se verific condiia luat n
discuie i 0 (fals) dac nu se verific respectiva condiie.
Schema logic a programului este dat n Figura 5a, iar scheme logice ale
subrutinelor care verific condiiile cerute sunt date n Figurile 5b, 5c, 5d, 5e.

P5.
Se citesc dou numere de la tastatur. s se afieze ctul mpririi numrului
mai mare la cel mai mic.

12

Analiza problemei
Datele de intrare pentru acest algoritm sunt cele dou numere care se citesc de
la tastatur. Exist o singur dat de ieire a crei valoare este dat de ctul mpririi
a dou numere.
Algoritmul citete cele dou numere de la tastatur. Fie aceste numere notate cu
a i b. Trebuie s calculm ctul mpririi numrului mai mare la cel mai mic. Dac a
este numrul cel mai mare atunci nu avem dect s calculm a/b. Dac b este
numrul cel mai mare atunci trebuie s calculm b/a.
Pentru ca s putem scrie ntotdeauna c rezultatul este ctul mpririi lui a la b,
trebuie ca, n cazul n care b are valoare mai mare s facem interschimbarea valorilor
celor dou numere (a trebuie s ia valoarea lui b i b trebuie s ia valoarea lui a).
Cum realizm acest lucru?
S presupunem urmtoarea problem: avem un pahar i o can (de aceeai
capacitate). n pahar avem lapte i n can avem ap. Cum putem s punem laptele n
can i apa n pahar. Acest lucru nu se poate realiza direct, ci prin intermediul unui al
treilea recipient de aceeai capacitate cu paharul i cana. Punem laptele din pahar n
recipientul suplimentar, punem apa din can n pahar i apoi laptele din recipientul
suplimentar n can.
Intreschimbarea celor dou valori a i b are o rezolvarea asemntoare. Trebuie
s inem cont de faptul c a i b sunt de fapt locaii de memorii (recipiente pentru
informaii). Pentru intreschimbarea lor avem nevoie de un recipient suplimentar (alt
locaie de memorie) cu ajutorul cruia s putem facem transferul de informaii.
Schema logic pentru rezolvarea acestei probleme este dat n Figura 6.

P6.
Se citete de pe dispozitivul de intrare o valoarea natural care reprezint un an.
S se afieze un mesaj care s indice tipul anului (bisect sau nu).
Analiza problemei
Avem o singur dat de intrare i anume un numr care reprezint un an. Date
propriu-zise de ieire nu avem, algoritmul trebuind s afieze un mesaj. Schema
logic este dat n Figura 7.

13

P7.
Un punct din plan este dat prin coordonatele sale (x, y). S se stabileasc poziia
lui prin indicarea cadranului (1, 2, 3, 4) n care este plasat. Pentru un punct situat pe
una din semiaxe se vor preciza cadranele separate de semiaxa respectiv (de exemplu
2-3).

P8.
S se calculeze durata unei conexiuni Internet cunoscndu-se momentul
conectrii (dat prin or, minut i secund) i momentul deconectrii (de asemenea dat
prin or, minut i secund). Trebuie s se ia n consideraie cazul n care o conexiune
ncepe ntr-o zi i se ncheie n ziua urmtoare.

P9.
S se calculeze momentul ntreruperii unei conexiuni Internet dac se cunoate
momentul de conectare (dat prin or, minut i secund) i durata total a conexiunii
(dat prin ore, minute i secunde). Se ia n consideraie i cazul n care o conexiune
nceput ntr-o anumit i se poate ncheia n ziua urmtoare.

14

START

Calcul arie

Citeste xa, ya, xb, yb,


xc, yc

Calcul
lungime a

Calcul arie
A

Calcul
lungime b

NU

A=0

Calcul
lungime c

DA

Scrie
"Cele trei puncte
sunt coliniare"

Scrie
"Aria este " A

p (a + b + c ) / 2

p ( p a )( p b )(p c )

STOP
Retur A

Calcul
lungime

(x 1 x 2 )2 + (y1 y 2 )2

Retur d

Figura 2. Schema logic pentru calculul ariei unui triunghi

15

START

Citeste
a, b, c

DA

NU

a>b

max a

max b

DA

NU

max>c

max c

Scrie
"Maximul este ", max

STOP

Figura 3a. Schema logic pentru calculul maximului dintre 3 numere


(Varianta fr funcii)

16

Calculeaza
maximul max

START

Citeste
a, b, c

Calculeaza
maximul
max

DA

NU

a>b

max a

max b

Scrie
"Maximul este ", max
DA

max>c

NU

STOP

max c

Retur max

Figura 3b. Schema logic pentru calculul maximului dintre 3 numere


(Varianta cu funcii)

17

Calcul suma
de plata S

START

Citeste
nrOre, tarif
DA

nrOre
<= 60

NU

Calculeaza
suma de plata
S
DA
Scrie
"Suma de plata este ",
S

S nrOre tarif

nrOre
<=40

S 40 tarif + 1,5 t arif 20 +

NU

2 tarif (nrOre 60 )

S 40 tarif +

1,5 tarif (nrOre 40 )

STOP

Retur S

(a)

(b)

Figura 4. Schema logic pentru calcularea sumei de plat pentru orele lucrate la o anumit firm.

18

START

Citeste
a, b, c

NU

Scrie
"Nu este triunghi"

DA

esteTriunghi(a,b,c)

NU

DA

esteEchil(a,b,c)

DA

esteIsoscel(a,b,c)

Scrie
"Triunghi echilateral"

NU

NU

esteDr(a,b,c)

Scrie
"Triunghi oarecare"

Scrie
"Triunghic isoscel"

DA

Scrie
"Triunghi dreptunghic"

STOP

Figura 5a. Schema logic pentru verificarea proprietii de triunghi (varianta a)

19

START

Citeste
a, b, c

T esteTriung hi ( a, b , c)

NU

DA

T=1

Scrie
"Nu este triunghi"

E esteEchila teral (a, b, c )

NU

Scrie
"Triunghi echilateral"

I esteIsosce l ( a, b, c )

NU

D=1

Scrie
"Triunghi oarecare"

DA

I=1

Scrie
"Triunghic isoscel"

D esteDreptu nghic ( a, b, c )

NU

DA

E =1

DA

Scrie
"Triunghi dreptunghic"

STOP

Figura 5b. Schema logic pentru verificarea proprietii de triunghi (varianta b)

20

esteTriunghi(a,b,c)

NU

(a>0) SI
(b>0) SI
(c>0)

r 0

DA

(a+b > c) SI
(a+c > b) SI
(b+c > a)

NU

r 0

r 1

Retur r

Figura 5b. Verificarea calitii de triunghi

esteEchilateral(a,b,c,)

NU

DA

(a=b)
SI (b=c)

r 0

DA

r 1

Retur r

Figura 5c. Verificarea calitii de triunghi echilateral

21

esteIsoscel(a,b,c,)

NU

(a=b) SAU
(b=c) SAU
(c=a)

r 0

DA

r 1

Retur r

Figura 5d. Verificarea calitii de triunghi isoscel

esteDreptunghic(a,b,c,)

NU

(a2 =b2 +c2) SAU


(b2 =a2 +c2) SAU
(c2=b 2+a2)

r 0

DA

r 1

Retur r

Figura 5e. Verificarea calitii de triunghi dreptunghic

22

START

Citeste a, b

Calculeaza catul c

Scrie c

STOP

(a) Programul principal

Calculeaza catul c

DA

NU

a>b

aux a

ab

a aux

c a/b

Retur c

(b) Funcia
Figura 6. Schema logic pentru problema P5.

23

START

Citeste an

DA

NU

esteBisect

Scrie
"Anul este bisect"

Scrie
"Anul nu este bisect"

STOP

(a) Programul principal

esteBisect

an
400 = 0

NU

an
100 = 0

DA

NU

an
4 =0

DA

DA

NU

b0

b1

Retur b

(b) Funcia
Figura 7. Schema logic pentru problema P6.

x
y

( reprezint restul mpririi numrului x la y)

24

1.1.3.2. Reprezentarea algoritmilor prin pseudocod


Pseudocodul este o schi a unui program scris intr-o astfel de form nct s
poat fi convertit cu uurin ntr-un program real. Pseudocodul nu poate fi executat
sau compilat i nu exist reguli stricte de formare sau de sintax. El este doar un pas
dar un pas important n producerea formei finale a programului. Principalul
avantaj al pseudocodului este acela c permite programatorului s se concentreze
asupra algoritmului fr a lua n consideraie detaliile unui limbaj de programare
particular. De fapt, se poate scrie un algoritm n pseudocod fr a ti ce limbaj de
programare va fi folosit pentru implementarea final a algoritmului.
Limbajul pseudocod este folosit n faza de proiectare a programelor pentru
descrierea algoritmilor; el este o alternativ la schemele logice. Ca i acestea,
pseudocodul precizeaz fluxul de transmitere a informaiei n program i nu datele
implicate n algoritm. Limbajul pseudocod nu este un limbaj de programare.
Pseudocodul

are

numeroase

variante,

deosebindu-se

de

la

proiectant

la

proiectant. Toate variantele au ns ca trsturi comune utilizarea enunurilor


nestandard, precum i a operaiilor prescrise de programarea structurat.
Pentru definirea unui limbaj pseudocod (ca i pentru scheme logice) se definete
o main virtual care poate interpreta comenzile date n pseudocod (Figura 1).
Instruciunile de baz sunt aceleai ca i la schemele logice, numai c de aceast
dat nu le vom asocia simboluri grafice. n plus, n pseudocod avem i enunurile
nestandard cu forma general:
text (l_var);
unde l_var este lista variabilelor de intrare (variabile ale cror valori, calculate
anterior sunt folosite pentru prelucrarea indicat n enun).
Un algoritm n pseudocod poate fi un:
1). Modul program cu sintaxa:
program
<secven>
sf. program
2). Modul funcie cu sintaxa
funcie nume_f(lista de parametri)
<secven>;
sf. funcie
25

Exemplu:
Vom scrie n continuare pseudocodul pentru rezolvarea problemei P1.
Program
citete xa, ya, xb, yb, xc, yc
A calculArie(xa, ya, xb, yb, xc, yc)
daca A = 0
atunci
scrie "Cele trei puncte sunt coliniare"
altfel
scrie "Aria este", A
sfrit dac
sfrit program

Funcie calculArie(xa, ya, xb, yb, xc, yc)


a calculLungime(xb,yb,xc,yc)
b calculLungime(xa,ya,xc,yc)
c calculLungime(xb,yb,xa,ya)

p (a + b + c ) 2
A

p (p a) (p b ) (p c )

transmite A (sau returneaz A)


sfrit funcie

Funcie calculLungime(x1,y1,x2,y2)

(x

x 2 ) + (y 1 y 2 )
2

transmite d
sfrit funcie

26

1.1.4. Elemente de programare structurat


Instruciunile simple, de citire, scriere i de atribuire se execut n mod
secvenial, una dup alta n ordinea n care apar n program. Programele mai prezint
ns i aa numitele instruciuni de salt ce descriu o ordine de execuie diferit de
cea secvenial: n funcie de ndeplinirea sau nendeplinirea unor condiii se fac se fac
treceri n salt la instruciuni dinainte sau care urmeaz n programul scris. Cu alte
cuvinte, ordinea de execuie a instruciunilor nu coincide cu ordinea lor de scriere.
Ordinea n care se execut instruciunile unui program definete structura de
control a programului.
Instruciunile sunt paii unui program. Cele mai multe instruciuni calculeaz i
atribuie valori sau apeleaz funcii, dar exist i alte tipuri de instruciuni. Implicit
instruciunile sunt executate n secven, una dup alta. Totui, putem modifica
ordinea de execuie a instruciunilor prin utilizarea construciilor de control a
programului. Aceste construcii permit execuia unei sau mai multor instruciuni numai
dac o anumit condiie este adevrat sau fals sau permit execuia unei sau mai
multor instruciuni de mai multe ori n interiorul unei bucle. (i apelul unei funcii
poate fi privit ca o instruciune de control a fuxului programului: la apelul funciei
execuia funciei apelante se suspend pn la terminarea execuiei funciei apelate).
O instruciune este un element dintr-un program care poate fi executat conform
unei anumite ordini, ordine stabilit de structura de control a programului. Structura
de control a programului stabilete ce instruciune va fi executat la un moment dat.
Stabilirea ordinii de execuie o instruciunilor unui program este dat de aa
numitele structuri de control. exist trei structuri de control cu ajutorul crora se
poate scrie orice program.
Toate aceste instruciuni de control au o singur intrare i o singur ieire. Ele
pot fi considerate ca nite blocuri, care pot fi interpretate din nou ca simple operaii i
introduse ntr-un proces de calcul secvenial. Ca urmare, orice algoritm compus din
structurile de control prezentate poate fi transformat succesiv ntr-un bloc cu o intrare
i o ieire. Aceast secven de transformri se poate folosi pentru a-i verifica
corectitudinea.
Structurile de control sunt:
a. Secvena este o structur format din una sau mai multe instruciuni care se
execut secvenial (n ordinea n care sunt scrise n program).
Reprezentare prin schem logic (Figura 11).

27

Actiune 1

Actiune 2

Aici sche ma se
continua cat
este nevoie

Actiune n

Figura 11. Secvena


Reprezentare n pseudocod:
aciune 1;
aciune 2;
..
aciune n;
Funcia de calcul a lungimii unei laturi din P1 este un exemplu de structur
secven.

b. Selecia (decizia) este o structur care conine mai multe pri din care se
execut numai una, o singur dat, n funcie de rezultatul unui test logic. Exist mai
multe forme:
b1). Selecia cu dou alternative (structura de control fundamental)
Reprezentare prin schem logic (Figura 12):

28

Adevarat

conditie

Secventa A

Fals

Secventa B

Figura 12. Selecia cu dou alternative


Reprezentare prin pseudocod:
dac <condiie>
atunci <secven A>;
altfel <secvena B>;
sf. dac
Execuia se face astfel:
se evalueaz <condiie> (care este o expresie logic sau relaional);
dac rezultatul este adevrat atunci se executa <secven A>;
dac rezultatul este fals atunci se execut <secven B> i selecia ia sfrit.
Exemplu: problemele P1, P6.

b2). Selecia cu o alternativ vid (structura de control derivat)


Reprezentare prin schema logic (Figura 13):

Adevarat

conditie

Secventa

Figura 13. Selecia cu o alternativ

29

Reprezentare prin pseudocod


dac <condiie>
atunci <secven>;
sf. dac
Este echivalent cu c1 numai c lipsete <secvena B>. Modul de execuie:
se evalueaz <condiie>;
dac rezultatul este adevrat atunci se executa <secven>;
dac rezultatul este fals selecia ia sfrit.
Exemplu: problema P5.

b3). Selecia multipl (structur de control derivat)


Reprezentare prin schema logic (Figura 14)
Reprezentare prin pseudocod
dac <condiie 1>
atunci <secven 1>;
altfel dac <condiie 2>
atunci <secvena 2>;
.
dac <condiie n>
atunci <secvena n>
altfel <secven n+1>;
sf. dac
Modul de execuie este urmtorul:
se

verific

<condiie

1>;

dac

valoarea

este

adevrat

se

execut

<secven 1> i selecia ia sfrit; n caz contrar:


se evalueaz <condiie 2>; dac valoarea este adevrat se execut
<secven 2> i selecia ia sfrit; s.a.m.d.
Observaie: <secven n+1> este alternativa de la <condiie n>, adic se
asociaz cu ultimul dac ntlnit.

30

Adevarat

Secventa 1

conditie 1

Adevarat

Secventa 2

Fals

Fals

conditie 2

Adevarat

conditie 3

Fals
Aici schema se
continua cu cate
conditii este nevoie

Seventa 3

Adevarat

Secventa n

conditie n

Fals

Secventa
n+1

Figura 14. Selecia multipl (cazul I)


Exemplu: problema P4.

Un caz particular al seleciei multiple este acela n care trebuie s evalum o


expresie i n funcie de rezultatul expresiei trebuie s se execute o anumit secven
de instruciuni. Expresia care trebuie evaluat nu trebuie s fie o expresie logic sau
de relaie astfel nct rezultatul ei poate fi un numr oarecare (de obicei ntreg).

31

Reprezentarea prin schem logic (Figura 15).

Expresie ?

Val1

Secventa 1

Val2

Secventa 2

Val3

Secventa 3

Valn

Secventa n

Rest

Secventa
n+1

Figura 15. Selecie multipl (cazul II)


Reprezentarea prin pseudocod este.
n funcie de <Expresie> alege dintre
cazul <Val1>: <Secvena 1>;
cazul <Val2>: <Secvena 2>;
..
cazul <Valn>: <Secvena n>;
rest:

<Secvena n+1>;

sf. alege

c. Iteraia este o structur compus care conine o parte iterat care se


execut de zero sau mai multe ori n funcie de rezultatul unui test logic. Partea
iterat poate fi o instruciune simpl, o secven, o selecie sau o alt iteraie.
Acest tip de structur compus poate fi ntlnit n una din formele:

c1). Iteraie cu test iniial.


n pseudocod vom avea reprezentarea:
repet ct timp <condiie>
<secven>;
sf. repet

32

Schema logic este dat n Figura 16.

Fals

conditie

Adevarat

Secventa

Figura 16. Iteraia cu test iniial


Modul de execuie al unei iteraii este urmtorul:
se evalueaz <condiie>;
dac rezultatul este adevrat se execut <secvena>;
se calculeaz din nou valoarea <condiie>;
dac rezultatul este adevrat se execut din nou <secvena>;
procedeul se execut n acest fel pn cnd <condiie> capt valoarea fals;
atunci <secven> nu se mai execut i iteraia ia sfrit.
Pentru ca iteraia s se termine ntr-un numr finit de pai (i aa trebuie pentru
c un program are un numr finit de pai, ntotdeauna) este necesar ca partea iterat
(<secvena>) s modifice valoarea unei variabile sau a mai multor variabile ce apar i
n expresia logic reprezentnd condiia de verificat, astfel nct dup un numr de
pai aceast expresie s capete valoare fals. Condiia se verific ntotdeauna nainte
de execuia prii iterate, de aceea se numete iteraie cu test iniial. Se poate
ntmpla ca, n funcie de rezultatul evalurii condiiei, partea iterat s nu se execute
niciodat (se execut de zero ori).

c2). Iteraia cu test final.


n pseudocod are forma:
repet
<secven>;
ct timp <condiie>

33

Schema logic este dat n Figura 17.

Secventa

Fals

Adevarat

conditie

Figura 17. Iteraia cu test final


Modul de execuie este urmtorul:
se execut partea iterat <secven>;
se evalueaz <condiie>;
dac rezultatul este adevarat se execut din nou partea iterat <secven>;
se evalueaz <condiie>;
procedeul se repet pn cnd condiia devine fals; atunci partea iterat nu
se mai execut.
Trebuie s observm c iteraia cu test iniial (c1) este complet diferit de
iteraia cu test final (c2). n cel de-al doilea caz, execuia prii iterate nu este
precedat de evaluarea condiiei ca n primul caz. Datorit acestui fapt n cazul
iteraiei cu test final, partea iterat se execut ntotdeauna de cel puin o dat, n timp
ce n iteraia cu test iniial partea iterat se poate executa de zero ori.

c3). Iteraia cu contor sau ciclu.


n pseudocod reprezentarea este
repet pentru <var> = vi, vf, pas
<secven>;
sf. repet
Reprezentarea prin schema logic este dat n Figura 18a, forma general fiind
dat n Figura 18b.

34

va r vi

Fals

var vf

Adevarat

Secventa

v ar v ar + pas

Figura 18a. Iteraia cu contor

Ei

Fals

Et

Adevarat

Secventa

Em

Figura 18b. Iteraia cu contor (forma general)

35

n acest caz iteraia este controlat de variabila ntreag <var>, numit variabil
de contor a ciclului. Valorile sale succesive constituie lista ciclului. Acest tip de
structur de control se compune din:
o expresie de iniializare a variabilei de ciclu Ei: <var> vi;
testarea unei condiii pe care trebuie s o ndeplineasc variabila de ciclu prin
expresia de test Et, de exemplu: valoarea variabilei ntregi <var> trebuie s [vi, vf];
o expresie de modificare (Em) a variabilei de ciclu, care permite acestei
variabile s ia toate valorile din lista ciclului; de obicei este o instruciune de atribuire,
de exemplu n acest caz <var> <var>+pas. pas reprezint valoarea cu care se
modific variabila de ciclu i poate lua att valori pozitive ct i valori negative.
Testarea unei condiii prin evaluarea expresiei Et se face nainte de execuia
secvenei care reprezint corpul iteraiei (a prii iterate) astfel nct se poate construi
o echivalen ntre acest tip de iteraie i iteraia cu test iniial.
Acest tip de iteraie se folosete n cazurile n care cunoatem numrul de pai
care trebuie executai pentru rezolvarea problemei, avem la dispoziie o relaie de
recuren sau putem evidenia cele trei tipuri de expresii (Ei, Et, Em) referitoare la o
anumit variabil folosit n descrierea algoritmului.

36

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 2

Pentru nici una din problemele care se vor rezolva la disciplina Programarea
calculatoarelor
NU SE FOLOSESC VARIABILE GLOBALE
PREZENTAREA GENERAL A MEDIULUI DE DEZVOLTARE.
FIIERE PROIECT
Cuprins
1. Prezentarea general a mediului de dezvoltare ......................................................................2
1.1. Lansarea mediului .....................................................................................................................2
1.2. Mod de lucru...........................................................................................................................2
1.3. Setare ci pentru Borland C++ for DOS ............................................................................3
1.4. Prsirea mediului.................................................................................................................3
1.5. Linia meniu (menu bar).........................................................................................................4
2. Fiiere proiect ................................................................................................................................4
2.1. Construirea unui proiect : .....................................................................................................5
2.2. Opiunile posibile (Ctrl - O):..................................................................................................5
3. Shortcut-uri (hot keys)..................................................................................................................6
3.1. Combinaii de taste pentru execuie: ..................................................................................7
4. Utilizarea sistemului HELP ..........................................................................................................7
5. Prezentare meniuri .......................................................................................................................7
5.1. Meniul File ..............................................................................................................................7
5.2. Meniul Edit ..............................................................................................................................8
5.3. Meniul Search ........................................................................................................................8
5.4. Meniul Run..............................................................................................................................9
5.5. Meniul Compile ......................................................................................................................9
5.6. Meniul Window.......................................................................................................................9
6. Gestionarea ferestrelor ..............................................................................................................10
7. Linia de stare (status line) .........................................................................................................11
8. Rubrici de dialog (dialog boxes) ...............................................................................................12
9. Comenzi de editare ....................................................................................................................12
10. Structura unui program C ........................................................................................................14
TEMA 1 .............................................................................................................................................18
TEMA 2 .............................................................................................................................................19

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 2

1. Prezentarea general a mediului de dezvoltare


Borlandc C++, produs al firmei Borland International, este un pachet de programe
care ofer o implementare a limbajului C dup standardul ANSI i o implementare a
limbajului C++.
Extensiile implicite pentru cele doua categorii de fiiere sunt .C respectiv .CPP.
Mediul de dezvoltare integrat (IDE: Integrared Development Environment) ofer toate
facilitaile necesare pentru editarea, compilarea, linkeditarea i depanarea programelor. La
laborator vom folosi mediul integrat BorlandC++ 3.1, iar sistemul de operare este Windows
2000 Server.
1.1. Lansarea mediului
Varianta 1
Se activeaz shortcut-ul de pe desktop (BorlandC++ for Dos) prin dublu click pe
icon-ul acestuia.
Varianta 2
Din Windows Explorer sau orice alt manager de fiiere se activeaz fiierul
executabil bc.exe(varianta pentru DOS) sau bcw (varianta pentru Windows). Precizm ca
la laborator vom folosi varianta pentru DOS. Fiierele bc.exe i bcw.exe se gsesc n
C:\borlandc\bin (n cazul n care mediul este instalat n rdcina discului C). BorlandC este
directorul rdcin al mediului integrat i conine mai multe subdirectoare : BIN, BGI,
INCLUDE, LIB, CLASSLIB, TVISION, CTRL, DOC, EXAMPLES, OWL, REDIST.
1.2. Mod de lucru
Pentru a lucra organizat se va face un director numit LUCRU, n C:\TEMP sau n
C:\LABORATOR. n acest director de lucru se vor salva toate sursele (fiierele cu extensia
.C, .CPP, .PRJ, .H ), precum i celelalte fiiere rezultate n urma compilrii, linkeditrii
(extensiile .obj,.exe) i orice alt fiier personal.
Pentru ca la lansarea mediului, directorul implicit de lucru s fie cel stabilit mai sus se
face click dreapta pe icon-ul BorlandC++ for Dos, se alege Properties Program i n
csua de editare Working se completeaz calea ctre directorul de lucru dorit, n cazul
nostru c:\laborator\lucru. n acest caz la apsarea tastei F2 (pentru salvare) sau la F3
(pentru a deschide un nou fiier), directorul de lucru va fi cel stabilit mai sus i nu mai este
nevoie s schimbm directorul pentru a face salvare / deschidere fiiere. Fiierele care se
vd la un moment dat n fereastr sunt cele de pe directorul curent i au o anumita
extensie. Dac este *.cpp se vd fiierele CPP, dac este *.C se vd fiierele C, dac este
.TXT se vd cele text etc. Dac este *.* se vd toate fiierele cu toate extensiile i toate
subdirectoarele directorului curent.
2

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 2

1.3. Setare ci pentru Borland C++ for DOS


Se merge n meniu la Options Directories
include directories

c:\borlandc\include

este calea ctre fiierele header (.h) cele care se includ n programe sub forma #include
<header.h>
library directories

c:\borlandc\lib

este calea ctre bibliotecile run time (.lib) i fiierele obiect(.obj) de startup
output directories

c:\labora~1\lucru (directorul de lucru fcut anterior)

este directorul unde se vor genera fiierele .obj i .exe rezultate n urma compilrii i
linkeditrii
source directories

c:\labora~1\lucru

este directorul unde se caut sursele care nu sunt incluse n proiectul deschis
Dac nu este completat calea, aceasta se consider a fi directorul curent. Dac
sunt mai multe directoare ce trebuie incluse acestea se separa prin ;. De exemplu:
c:\borlandc\lib; c:\labora~1\lucru\mylib. Spaiile de dinainte i de dup ; sunt acceptate, dar
nu necesare.
Observaie:
Primele doua ci (Include i Libraries) sunt deja completate odat cu
instalarea mediului, rmnnd de setat doar ultimele dou. Deoarece n sistemul de
operare DOS un nume de director / fiier poate avea maxim 8 caractere, directorul
LABORATOR se va prescurta la LABORA~1 (8 caractere).
La bcw sunt prezente n meniul directories doar primele 3 (include, lib i
output ) i se seteaz la fel.
Mediul poate rula Full Screen (acoper tot ecranul) sau Window (ntr-o fereastr).
Comutarea ntre cele doua moduri se face cu ALT+ENTER. Modul n care se va lansa
mediul (Full Screen sau Window) se poate seta astfel: click dreapta pe icon-ul mediului,
Properties Screen Usage i se alege ntre Full Screen sau Window.
1.4. Prsirea mediului
(a) definitiv: se d comanda File Quit (comanda Quit din meniul File) sau
combinaia de taste Alt-X.. Dac s-au fcut modificri ce nu fuseser salvate, vei fi
ntrebat dac se dorete salvarea.
(b) temporar pentru a lansa comenzi de sub prompt-ul DOS: se d comanda
File Dos Shell. Se revine n mediu prin comanda EXIT (tastat din DOS).
3

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 2

(c) se trece temporar la alt program fr a se iei din mediu; programele respective
sunt incluse n meniul sistem (activat prin combinaia Alt-Spacebar). Programele implicit
incluse n acesta categorie sunt: GREP, Turbo Assembler, Turbo Debugger i Turbo
Profiler (fr s se verifice dac sunt instalate i incluse n cale). GREP face parte din
kit-ul C++ i se afl n directorul \BIN.
Se poate modifica aceast lista de programe prin comanda Options Transfer.
1.5. Linia meniu (menu bar)
Linia meniu (afiat la limita superioar a ecranului) este mijlocul prin care se
ajunge la toate comenzile meniurilor. Dac, comanda dintr-un meniu este urmata la afiare
de semnul ... (ellipsis), dup alegerea ei se va afia o rubric de dialog (dialog box). Dac
este urmat de semnul >, dup alegerea comenzii respective se va afia un submeniu
(pop-up menu) ce conine alte comenzi. Tasta F10 selecteaz linia meniu. Meniul curent
selectat va fi scos n evidena (highlighted). Meniul dat se selecteaz cu ajutorul tastelor
sgeat (Left, Right) i apoi cu Enter se activeaz comanda dorit. Alt variant (shortcut)
este apsarea literei scoase n eviden din titlul meniului dorit (de exemplu F pentru
meniu File). De oriunde din interiorul mediului, combinaia Alt + litera scoas n eviden
afieaz meniul dorit. Dac se dorete prsirea meniului se va tasta ESC. Comenzile pot
fi selectate i cu ajutorul unui mouse. Nu toate comenzile meniurilor sunt disponibile n
orice moment; selectarea uneia nedisponibile (nu va fi scoasa in evidenta) permite
eventual numai obinerea unui help.
2. Fiiere proiect
Un fiier proiect reunete lista fiierelor ce trebuie linkeditate mpreuna (fiecare cu
eventualele opiuni proprii) pentru crearea unei aplicaii. n Borland C++, toate informaiile
necesare pentru construirea unui program se depun intr-un fiier proiect binar, ce poate fi
convertit ntr-un fiier de tip ASCII prin programul de conversie PRJ2MAK.EXE - project to
make. Fiecare fiier proiect are ataat un fiier desktop (prjname.dsk) care conine
informaii despre fiecare fiier din proiect (poziia curent - la editare - n fiier, amplasarea
ferestrei corespunztoare pe ecran), history lists pentru input boxes, aranjamentul
ferestrelor, etc. La crearea unui proiect nou, noul fiier desktop l motenete pe
precedentul. Fiierul proiect este controlat de ctre Project Manager care la fiecare
reconstruire a executabilului actualizeaz informaiile incluse: numele fiierelor, poziiile
ocupate pe HDD, ce fiiere depind de altele care trebuie compilate anterior, ce
translatoare (compilator / asamblor) se folosesc i ce opiuni se trec n linia de comanda a

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 2

fiecrui modul, unde se depune programul rezultat, numrul de linii surs, mrimea
codului i a datelor generate (n octei ) dup ultima compilare.
Meniul Project conine
- Open project
- Close project
- Add item
- Delete item
- Local options
- Include files
2.1. Construirea unui proiect :
se activeaz din meniu comanda Project Open project i se completeaz
numele proiectului n rubrica de dialog deschis; ca urmare se va deschide o fereastr
corespunztoare noului fiier proiect creat;
dac se deschide un proiect deja existent pe disc i fereastra corespunztoare nu
este vizibil pe ecran, ea se activeaz din Window Project;
se adaug pe rnd fiierele surs componente (Project|Add item); numele
acestora vor fi trecute pe linii separate n fereastra corespunztoare proiectului;
se selecteaz comanda Compile|Make EXE (F9) ce va aciona acum asupra
fiierului proiect.
Numele fiierului proiect poate diferi de cel al fiierului surs care conine funcia
main(), dar executabilul are numele fiierului proiect. n Status Line din fereastra proiect
sunt afiate comenzile disponibile :
- F1

Help

- Ins

se adaug un fiier n proiect

- Del

se elimin un fiier din proiect

- Ctrl-O :

se indica opiunile pentru fiierul curent

- Spacebar: se afieaz informaii despre fiierele incluse n proiectul curent


- Enter :
- F10

deschide o fereastr de editare pentru fiierul curent


:

se trece n meniul principal (main menu)

2.2. Opiunile posibile (Ctrl - O):


- ce translator s se foloseasc pentru crearea fiierului destinaie
- opiunile liniei de comanda
- numele fiierului destinaie (poate fi i n alt director)
- dac se includ i informaii pentru depanare
- dac modulul respectiv sa fie inclus la linkeditare
5

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 2

Fiecare fiier proiect are ncorporat propriul fiier de "note" (activat prin
Window|Project notes) opional, unde se trec informaii ca: data / persoana de la
eliminarea unui deficiene). Dac se selecteaz opiunea Options|Make|Check autodependencies ON, se compar la fiecare construcie datele i ora memorate n fiecare
fiier OBJ pentru fiierele incluse cu data i ora curente ale acelorai fiiere. Dac se
gsete vreo diferena se face automat recompilarea.
3. Shortcut-uri (hot keys)
Shortcut-urile sunt combinaii de taste cu efect echivalent selectrii unei comenzi a
unui meniu (au avantajul unui acces mai rapid, fr a mai umbla prin meniuri). Exist mai
multe grupuri de astfel de hot keys, ce vor fi detaliate complet pe parcursul ntregului ciclu
de lucrri.
F1 (Help)

Afieaz un ecran cu informaii ajuttoare

F2 (File:Save)

Se salveaz (pe disc) fiierul din fereastra de editare activ n acelai

loc n care a fost salvat ultima dat; dac nu fusese salvat niciodat trebuie s se indice o
cale de directoare i numele cu care este salvat fiierul respectiv. Dac nu se d nume,
se va pune un nume automat de genul NONAMExx.C sau NONAMExx.CPP, unde xx este
un numr ce ncepe de la 00.
F3 (File:Open)

Se activeaz o rubric de dialog pentru deschiderea unui fiier

existent (care se alege dintr-o list) sau a unuia nou (caz n care acesta este imediat creat
cu numele indicat de utilizator)
F4 (Run: Go to cursor)

Se execut programul pn la linia pe care este poziionat

cursorul
F5 (Window:Zoom)

Se mrete fereastra activ

F6 (Window:Next)

Se trece succesiv prin toate ferestrele deschise (n ordinea n

care s-au deschis)


F7 (Run:Trace into) Se execut programul pas cu pas, intrndu-se n interiorul funciilor
apelate
F8 (Run:Step over)
F9 (Make)

Se execut programul pas cu pas fr a se intra n funcii


Se creeaz un fiier executabil care deriv ori din fiierul din

fereastra curent ori din fiierul proiect .prj anterior definit i deschis
(F10)

Se activeaz linia meniu

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 2

3.1. Combinaii de taste pentru execuie:


Alt+F9:Compile
Compileaz programul surs i scoate un fiier cu extensia .obj.
Afieaz o caset cu liniile compilate i numrul de erori i atenionri. Dac sunt erori sau
atenionri (warnings) acestea vor apare ntr-o fereastr separat numita Message window
Ctl-F9 :Run

Se lanseaz n execuie programul curent (fiierul .exe); dac s-

au fcut modificri de la ultima salvare, fiierul va fi recompilat


F9

Se face compilare i linkeditare (rezult fiierele .obj i .exe)

Alt-F7:Previous error

Se trece la precedenta eroare semnalat de compilator

Alt-F8:Next error

Se trece la urmtoarea eroare din list

4. Utilizarea sistemului HELP


Meniul Help ofer acces la informaii ajuttoare ntr-o fereastr proprie.
4.1. Comanda Help:Contents (sau F1) deschide fereastra Help, fiind afiat o list
cu elementele principale disponibile i explicaii asupra modului de utilizare. Cuvintele
cheie sunt scoase n eviden: dup selectarea unuia (Tab sau sgei i apoi Enter sau
double-click) se afieaz informaiile detaliate corespunztoare. Dac se apas F1, cnd
suntem poziionai pe o operaie din meniu se vor afia informaiile referitoare la acea
operaie.
4.2. Comanda Help:Index (sau Shift-F1) afieaz lista complet a cuvintelor cheie
disponibile. Lista poate fi parcurs cu ajutorul sgeilor sau se poate cuta direct
introducnd prima litera (primele litere) pentru grupul de cuvinte dorit.
4.3. Comanda Help:Topic Search (sau Ctrl-F1) afieaz informaii asupra
elementului pe care este poziionat cursorul n fereastra de editare la un moment dat.
4.4. Prin Help:Previous Topic (sau Alt-F1) se reafieaz textul help anterior (se
poate merge napoi cu maximum 20 ecrane).
Exemplele de programe pot fi copiate n clipboard prin comanda Edit: Copy
Example de unde pot fi aduse n fereastra de editare curent folosind comanda Paste a
aceluiai meniu (vezi meniul Edit) sau combinaia de taste Shift-Insert.
5. Prezentare meniuri
5.1. Meniul File
New
Open(F3)

creare fiier
ncrcare fiier existent sau creare fiier nou (se tasteaz
numele nou)

Save(F2)

salvarea fiierului din fereastra de editare activ

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 2

Save as

salvarea fiierului n lucru sub alt nume, pe alt cale eventual

Save all

salvarea tuturor fiierelor ncrcate (deschise) i modificate

Change dir

schimbarea directorului curent

Print

listarea fiierului curent

Get info

afiarea de informaii despre programul curent

DOS shell

ieirea temporar din mediu sub prompt-ul DOS

Quit(Alt-X)

ieirea definitiv din mediu

5.2. Meniul Edit


Undo

anuleaz ultima editare

Redo

anuleaz efectul ultimei comenzi Undo

Cut(Shift-Del)

elimin textul selectat din document i l depune n Clipboard

Copy(Ctrl-Ins) copie textul selectat din fereastra curent n Clipboard; textul


rmne n document
Paste(Shift-Ins) insereaz textul din Clipboard n document la poziia
cursorului
Clear(Ctrl-Del) elimin textul selectat fr a-l depune n Clipboard (nu mai
poate fi refcut !)
Copy example copie exemplul de program din fereastra Help n Clipboard
Show clipboard deschide fereastra Clipboard (se poate face editare ca n
celelalte ferestre)
Observaie:
Clipboard-ul reprezint o zon de memorie (sau un fiier pe disc temporar)
folosit pentru transferul datelor text ntre diferite programe.
5.3. Meniul Search
Find

cutare text

Replace

cutare i nlocuire text

Search again

repetarea ultimei comenzi de cutare sau de


nlocuire

Go to line number

deplasarea cursorului la o linie specificat prin


numrul de ordine

Previous error(Alt-F7)

deplasarea cursorului la poziia precedentei erori

Next error (Alt-F8)

deplasarea cursorului la poziia urmtoarei erori


8

PROGRAMAREA CALCULATOARELOR

Locate function

LUCRAREA NR. 2

cutarea declaraiei unei funcii n timpul depanrii

5.4. Meniul Run


Run (Ctrl-F9)

se execut programul curent (dac este cazul, se fac


nti compilare i linkeditare).

Program reset (Ctrl F2) se

abandoneaz

depanarea

se

elibereaz

memoria alocat n acest scop.


Go to cursor (F4)

se execut programul (de la run bar) pn la poziia


cursorului.

Trace into (F7)

se execut programul pas cu pas, inclusiv n


interiorul funciilor (scrise de utilizator) apelate.

Step over (F8)

se execut programul pas cu pas dar nu i n


interiorul funciilor.

Arguments

se fixeaz argumentele liniei de comand ce vor fi


transmise programului.

5.5. Meniul Compile


Compile(ALT-F9)

se compileaz fiierul surs (filename.C - fiierul din


fereastra de editare curent i rezult un fiier cu
extensia .obj).

Make(F9)

se creeaz fiierul EXE (dac este cazul, se fac


compilare i linkeditare).

Link EXE file

se linkediteaz fiierele OBJ i LIB, cu condiia s


existe deja (spre deosebire de Make, nu se face
automat compilare).

Build all

se reface recompilarea i linkeditarea pentru toate


fiierele (din proiect).

Remove messages terge toate mesajele din fereastra Message


Information

informaii despre program

5.6. Meniul Window


Size/Move (Ctrl-F5) modificarea dimensiunilor sau deplasarea n alt parte
a ecranului
Zoom F5

extinderea

la

dimensiunile

revenirea la forma iniial


9

ntregului

ecran

sau

PROGRAMAREA CALCULATOARELOR

Tile

LUCRAREA NR. 2

afiarea ferestrelor deschise una lng alta, fiecare


ocupnd acelai spaiu

Cascade

afiarea ferestrelor una peste alta, fiind vizibile toate


barele de titlu

Next (F6)

se trece la urmtoarea fereastr din cele deschise

Close (Alt-F3)

se nchide fereastra activ

Message

se

activeaz

fereastra:

message

(prezint

avertismentele i mesajele de eroare la compilare,


linkeditare)
Output

se deschide o fereastr n care se afieaz textul


existent pe ecranul utilizator ca rezultat al unei comenzi
de sub prompt-ul DOS sau rezultatele programului n
lucru (numai n mod text, nu i grafic). n acest mod se
pot urmri att rularea programului (la depanare ct i
ce se afieaz pe ecran la execuie). Nu se poate face
vreo editare n aceast fereastr; se pot folosi tastele
sgeat numai pentru scroll.

Watch

se deschide fereastra Watch ( se va detalia la


prezentarea posibilitilor de depanare a programelor)

User Screen Alt-F5 se afieaz n ntregime ecranul utilizator (lucreaz i n


modul grafic)
Register

se deschide fereastra Register (se afieaz coninutul


registrelor CPU)

Project

se activeaz fereastra project (se va detalia ulterior)

Project notes

se deschide o fereastr de editare pentru note asupra


proiectului curent

List (Alt-0)

se afieaz toate ferestrele deschise n momentul


respectiv (putndu-se alege una care s devin activ)

6. Gestionarea ferestrelor
Pot fi deschise oricte ferestre la un moment dat (n limitele memoriei disponibile),
dar una singur este activ. Orice comand se aplic numai ferestrei active (excepie:
dac acelai fiier este deschis pentru editare n mai multe ferestre, aciunea comandat
va fi aplicat peste tot fiierului respectiv). Fereastra activ are conturul dintr-o linie dubl
10

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 2

i totdeauna este afiat deasupra celorlalte (dac s-a optat pentru prezentarea ferestrelor
n cascad).
Dac suntem ntr-o fereastr de editare se afieaz n linia de jos numrul liniei i al
coloanei pentru poziia curent; un asterisc indic dac s-au operat modificri de la
deschiderea ferestrei.
n partea din stnga sus se afl un dreptunghi pus ntre [ i ]. Printr-un click pe acest
dreptunghi se nchide fereastra respectiv (din tastatur Window | Close sau Alt-F3). Linia
superioar (title bar) mai conine numele i numrul ferestrei, precum i zoom box. Pentru
o fereastr de editare, numele ferestrei este n mod normal numele fiierului n lucru. Prin
double-click pe title bar se obine aa numitul zoom (extinderea ferestrei la dimensiunile
ntregului ecran), iar prin drag se poate muta fereastra n alta zon a ecranului. Zoom box
poate consta dintr-o bar vertical cu sgeata sus (fereastra poate fi extins) sau o bar
cu sgei att sus ct i jos (cnd este la dimensiunea maxim). Comutarea ntre cele
dou variante se face prin click pe zoom box sau (din tastatur) prin F5 sau Window |
Zoom.
Primele nou ferestre deschise au asociat cte un numr (ntre 1 i 9). Combinaia
Alt-0 (zero) afieaza lista ferestrelor deschise (toate, nu numai primele 9; se poate activa
una din ele cu ajutorul tastelor Up, Down i apoi Enter). Prin Alt-n (cu n de la 0 la 9) se
activeaz fereastra cu numrul de ordine respectiv. Alt posibilitate de activare a unei
ferestre este click n interiorul ei (evident, dac este vizibil, fie i parial, pe ecran). Pentru
mrirea sau micorarea dimensiunilor ferestrei active (n limitele ecranului) se face drag pe
oricare col al ferestrei sau din tastatur se comanda: Window | Size | Move sau Ctrl-F5 i
apoi se folosesc Shift i sgeile.
7. Linia de stare (status line)
Status line apare la limita inferioar a ecranului i afieaz tastele funcionale
aplicabile n momentul respectiv n fereastra activ sau aciunea n curs de execuie (dac
s-a dat o comand ce dureaz un timp semnificativ). Linia de stare tipic (pentru fereastra
Edit) este de forma:
F1 HELP F2 SAVE F3 OPEN

F7 TRACE

F8 STEP

F9 MAKE F10 MENU

La selectarea unui titlu de meniu (din menu bar) sau a unei comenzi dintr-un meniu,
linia de stare indic pe scurt semnificaia elementului respectiv.

11

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 2

8. Rubrici de dialog (dialog boxes)


Rubricile de dialog (a cror apariie este anticipat de afiarea semnului "?" n
dreptul unei comenzi) sunt zone speciale ale ecranului care se activeaz pentru lansarea
amnunit a unei comenzi. Sunt 5 tipuri de elemente componente: radio buttons, check
boxes, action buttons, input boxes, list boxes.
9. Comenzi de editare
(A) comenzi de deplasare a cursorului
cu un caracter la stnga

Left (sgeata stnga)

cu un caracter la dreapta

Right (sgeata dreapta)

cu un cuvnt la stnga

Ctrl-Left

cu un cuvnt la dreapta

Ctrl-Right

cu o linie n sus

Up (sgeata sus)

cu o linie n jos

Down (sgeata jos)

scroll-up o linie

Ctrl-W

scroll-down o linie

Ctrl-Z

scroll-up un ecran

PgUp

scroll-down un ecran

PgDn

salt nceput linie

Home

salt sfrit linie

End

salt nceput fereastr

Ctrl-Home

salt sfrit fereastr

Ctrl-End

salt nceput fiier

Ctrl-PgUp

salt sfrit fiier

Ctrl-PgDn

salt nceput bloc selectat

Ctrl-Q B

salt sfrit bloc selectat

Ctrl-Q K

salt la ultima poziie cursor

Ctrl_Q P

(B) comenzi de inserare i tergere


comutarea

ntre

modurile

inserare

i tasta

Ins

sau

din

supratiprire

Options:Environment:Editor...

tergerea caracterului din stnga cursorului

Backspace

tergerea caracterului din poziia cursorului

Del

tergerea cuvntului din dreapta cursorului

Ctrl-T

inserare linie

Ctrl-N
12

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 2

tergere linie

Ctrl-Y

tergere pn la sfritul liniei

Ctrl-Q Y

(C) comenzi de lucru pe blocuri


marcare bloc

Shift i sgeata sus, jos, stnga, dreapta n


direcia dorit;
Ctrl-K B (pentru nceput) i Ctrl-K K (pentru
sfrit de bloc)

demarcare bloc

Ctrl-K H

marcare cuvnt

Ctrl-K T (dac cursorul nu este poziionat n


interiorul unui cuvnt se va lua cel din stnga)

copiere bloc n Clipboard

Edit:Copy sau Ctrl-Ins

copiere bloc din Clipboard

Edit:Paste sau Shift-Ins

mutare bloc n Clipboard

Edit:Cut sau Shift-Del

tergere bloc

Edit:Clear sau Ctrl-Del sau Ctrl-K Y

copiere bloc selectat

Ctrl-K C

mutare bloc selectat

Ctrl-K V

citire bloc de pe disc

Ctrl-K R

scriere bloc pe disc

Ctrl-K W

tiprire bloc

Ctrl-K P

indent bloc

Ctrl-K I

unindent bloc

Ctrl-K U

(D) alte comenzi


autoindent on/off

Options: Environment:Editor

cutare text

Search:Find sau Ctrl-Q F

cutare text cu nlocuire

Search:Replace sau Ctrl-Q A

repetarea ultimei cutri

Search:Search again sau Ctrl-L

revenirea din meniuri n editare

Esc

tiprire fiier

File: Print

n cazul comenzilor de cutare / nlocuire se deschide o rubric de dialog cu


urmtoarele elemente:
textul de cutat (Text to Find) Implicit estecuvntul pe care era poziionat
cursorul);
opiuni de cutare (de tip ON/OFF):
13

PROGRAMAREA CALCULATOARELOR

case sensitive

LUCRAREA NR. 2

s se diferenieze sau nu literele mari de cele mici (implicit

ON);
whole words only

s se caute apariia textului ca un cuvnt separat

(implicit OFF);
regular expression dac este ON, se accept caractere wildcards
asemenea programului GREP (Get Regular Expression and Print) (implicit
este OFF).
direcia de cutare (dou variante ce se exclud reciproc):
Forward (implicit)
Backward

cutarea se face nainte

cutarea se face napoi

domeniul de cutare:
Global (implicit) ntregul fiier;
Selected text

se lucreaz numai n blocul selectat

poriunea de cutare
From cursor (implicit) se caut de la poziia curent pn la limita nainte /
napoi a fiierului
Entire scope

se caut n ntregul bloc selectat sau n ntregul fiier.

La nlocuire apare n plus o rubric pentru textul de nlocuire (New text).


Butonul [Change All] este pentru nlocuirea tuturor apariiilor textului respectiv n
fiier.
10. Structura unui program C
Un program C se compune din una sau mai multe funcii din care obligatoriu una (i
numai una!) are numele main. Aceasta reprezint punctul din care se va lansa n execuie
programul. Daca nu exist un modul main (sau sunt mai multe cu acest nume) va rezulta o
eroare la linkeditare.
Este obligatoriu sa fie cunoscut de ctre compilator tipul unei funcii nainte de a fi
folosit n program. Pentru aceasta se scriu prototipurile funciilor folosite. Prototipul este
declararea unei funcii: tipul parametrilor i tipul valorii furnizate de funcie. Dac se
folosesc funcii de bibliotec, acestea au prototipurile descrise n fiierele antet (header),
fiiere cu extensia .h (aflate uzual n directorul \borlandc\INCLUDE). Ele vor trebui incluse
n programe prin directive de forma: #include <nume_header.h>

14

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 2

Problema exemplu nr. 1


Se va edita i rula urmtorul program (selectnd File:New ; nume de fiier implicite
sunt NONAMEnn.C, cu 00..nn..88; Se va salva cu numele dorit n directorul de lucru).
1:

#include <stdio.h>

2:

#include <conio.h>

3:

int main(void)

4:

/* Primul program */

5:

char nume[40]; /* tablou memorare nume */

6:

clrscr();

7:

printf("Cum te cheam ?\n");

8:

scanf ("%s", nume);

9:

printf("\nHello, %s !", nume);

10:

printf("\nApsai orice tast ...");

11:

getch();

12:

return 0;

13:

}
Mai nti se includ fiierele header ce conin prototipurile funciilor de bibliotec ce vor

fi folosite n program (liniile 1 i 2). Construcii de tipul #.... se numesc directive, se


plaseaz n afara programului propriu-zis i nu se ncheie cu ;.
Urmeaz programul principal ce este de fapt o funcie: int main(void). Nu se ncheie
cu ;. Se recomand indicarea explicit a parametrilor i a tipului valorii returnate de funcia
main(). n cazul de mai sus: int main(void).
Void se folosete pentru a indica absena parametrilor i respectiv a vreunei valori de
retur. Uzual, programele returneaz numere ntregi: 0 pentru terminarea cu succes i
valori pozitive pentru diversele cazuri de eroare. Aceste coduri de retur sunt necesare n
cazul ncorporrii programului respectiv ntr-un fiier batch (sau fiier de comenzi, care pot
fi vzute din IDE prin File:Get Info dup rularea programului). Comentariile sunt delimitate
de "/*" respectiv "*/" i cuprind explicaii date de programator. Comentariile nu sunt luate
n considerare la compilare.
Programul citete un ir de caractere de la tastatur (terminat cu Enter dar fr s
conin spaii) pe care apoi l afieaz pe ecran alturi de un alt mesaj. Funcia clrscr()
terge ecranul (are prototipul n CONIO.H). Funcia printf(...) (cu prototipul n STDIO.H) se
folosete pentru afiare de mesaje pe monitor; caracterul '\n' nseamn trecere la linie
nou. Funcia scanf(...) (cu prototipul n STDIO.H) se folosete pentru citirea i conversia
datelor de la tastatur. Se observ c fiecare instruciune sau declaraie este ncheiat de
15

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 2

;. n final se afieaz mesajul "Apsai orice tast ...", dup care se ateapt apsarea
unei taste (funcia getch(), cu prototipul tot n CONIO.H care returneaz caracterul
respectiv i revine n mediu). Dac getch() ar lipsi atunci rezultatele programului nu ar mai
fi vizibile, deoarece se face imediat comutarea napoi n mediul BorlandC. n acest caz
pentru a vizualiza rezultatele se apas ALT+F5.
Se vor executa urmtorii pai:
se deschide o noua fereastr de editare: File:New
se editeaz cteva linii
se salveaz programul n directorul de lucru : File:Save sau F2
se continu editarea (nu uitai s dai F2 pentru a salva modificrile)
se compileaz (F9) i se corecteaz fiecare eroare dac este cazul
se lanseaz n execuie (CTRL+F9)
se vizualizeaz rezultatele (ALT+F5)
Exersai comenzile de editare pe fiierul de mai sus (selectare bloc, mutare / copiere
dintr-un punct n altul al sursei etc.)
Problema exemplu nr. 2
#include <stdio.h>
int main( void )
{
int a, b, suma, dif ;
printf ("Introducei cele dou numere:\n");
scanf ("%d%d",&a,&b);
printf("\nSuma este : %d\n", a+b);
printf("\nDiferena este : %d", a-b);
return 0;
}
Cteva explicaii pentru programul de mai sus (fr a intra n detalii):
Fiierul STDIO.H conine prototipurile funciilor i o serie de constante pentru lucrul
cu intrarea / ieirea standard. Directiva preprocesor #include face ca nainte de compilare
coninutul fiierului respectiv s nlocuiasc acesta linie. Funcia printf(...) se folosete
pentru conversia i afiarea datelor; specificatorii de conversie ncep cu % (procent),
celelalte caractere

din irul de format (ncadrat ntre ghilimele) fiind afiate ca atare

(pentru eventualele mesaje). Specificatorul '%d' se folosete pentru numere ntregi.


16

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 2

Funcia scanf(...) se folosete pentru citirea i conversia datelor din intrare (de la
tastatur). De exemplu, numrul 10 este introdus de la tastatur ca un ir de caractere
ASCII, urmnd s fie convertit n reprezentarea intern (binar: 64H). Se folosete de
asemenea %d pentru a se indica faptul c numrul este zecimal. Se observ la scanf(...)
apariia semnului & (operatorul adres, ce va fi detaliat ulterior). Pentru moment este
suficient s se rein faptul c variabilele ce apar ca parametri n scanf(...) trebuie
transmise prin adres (pentru a le putea fi modificat coninutul n interiorul funciei), deci
totdeauna vor fi precedate de simbolul &.
Funcia scanf(...) sare peste caracterele albe (spaiul, tab, newline), ncepnd citirea
i conversia dup introducerea datelor i apsarea tastei Enter. Se observ apariia unor
expresii aritmetice n printf(...). Acolo unde poate aprea o variabil de un anumit tip poate
aprea orice expresie de acel tip.
Programele pot fi mprite n funcii. n acest caz, programul de mai sus are
urmtoarea structur:
#include <stdio.h>
/* Declaraiile funciilor fcute nainte de main*/
int suma(int x, int y);
int dif(int x, int y);
int main(void)
{
/*citete a i b */
/*apelul funciilor*/
printf ("\nSuma este :%d",suma(a,b));
printf("\nDiferena este :%d", dif(a,b));
return 0;
}
/* Definiiile funciilor
Fiecare funcie are un nume, nite parametri cu tipurile lor i returneaz ceva
(n cazul de fa un ntreg)
*/
int suma (int u, int v)
{
return(u+v);
}
int dif(int u, int v)
17

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 2

{
return(u-v);
}
Este necesar s se cunoasc de ctre compilator tipul de retur al unei funcii nainte
de a fi apelat; uzual, toate prototipurile funciilor se pun ntr-un fiier header (n care se
declar tipul valorii returnate, numrul i tipul parametrilor dup modelul prezentat la
curs).
n continuare sunt prezentate formele simplificate ale funciilor scanf(...) i printf(...)
pentru citirea, respectiv afiarea tipurilor de date ce vor fi folosite la rezolvarea temelor ce
urmeaz. Funciile scanf(...) i printf(...) vor fi detaliate ulterior.
Pentru citirea unui numr ntreg zecimal de la tastatur i pstrarea lui n variabila n:
int n;
scanf (%d, &n);
Pentru afiarea unui numr ntreg zecimal
printf(Numrul ntreg este: %d , n);
sau mai simplu, fr mesaj explicativ:
printf(%d, n);
Pentru citirea unui numr real de la tastatur i pstrarea lui n variabila n
float n;
scanf (%f, &n);
Pentru afiarea unui numr real
printf(Numrul real este: %f , n);
sau mai simplu, fr mesaj explicativ:
printf(%f, n);

TEMA 1
Problema nr. 1
S se scrie un program care citete de la tastatur trei numere ntregi i afieaz
maximul lor.
Problema nr. 2
S se scrie un program care citete de la tastatur cinci numere ntregi (nu se vor
folosi vectori), dup care determin i afieaz media lor aritmetic (pentru mprire se
18

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 2

folosete operatorul '/'; pentru a lucra cu numere reale - necesar probabil pentru medie
se folosete tipul de data float / double pentru reprezentarea n simpl /dubl precizie, cu
specificatorii de conversie '%f' i respectiv '%lf').
Problema nr. 3
S se scrie un program care citete de la tastatur trei numere ntregi i determin
dac aceste numere pot reprezenta lungimile laturilor unui triunghi. n caz afirmativ,
programul trebuie s determine i tipul triunghiului (isoscel sau dreptunghic sau echilateral
sau oarecare).
Problema nr. 4
S se scrie un program care determin i afieaz vrsta utilizatorului (msurat n
ani i n luni). Luna i anul naterii, luna i anul curent se citesc de la tastatura.
Problema nr. 5
S se scrie un program care determin cel mai mare divizor comun pentru dou
numere ntregi strict pozitive dup algoritmul lui Euclid: se mparte numrul mai mare la cel
mai mic att timp ct mpritorul este nenul; la fiecare pas, pn cnd restul este zero, se
nlocuiete dempritul cu mpritorul i mpritorul cu restul; ultimul mpritor nenul este
c.m.m.d.c. Pentru rest se folosete operatorul modulo: % (exemplu: a%b nseamn restul
mpririi lui a la b)
TEMA 2
Problema 2.1.
O pereche de numere naturale a i b se numesc prietene dac suma divizorilor unuia
din numere este egal cu cellalt numr (i invers). De exemplu, 220 i 284 sunt numere
prietene deoarece:
1, 2, 4, 5, 10, 11, 20, 22, 44, 55, 110 sunt divizori ai numrului 220 i suma lor este
284
1, 2, 4, 71, 142 sunt divizori ai numrului 284 i suma lor este 220.
S se scrie un program care gsete toate numerele prietene dintr-un interval dat de
numere naturale [x, y]. Cele dou numere care reprezint capetele intervalului sunt citite
de la tastatur i programul face i validarea datelor (verific corectitudinea datelor de
intrare). Nu se vor folosi tablouri.

19

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 2

Indicaii:
n afara funciei main se vor mai scrie dou funcii ale cror prototipuri se vor indica
ntr-un fiier header:
1. o funcie care primete ca parametru un numr natural i returneaz suma
divizorilor numrului.
2. o funcie avnd ca parametri dou numere naturale i care returneaz 1 sau 0
dup cum cele numere sunt sau nu prietene.
Problema 2.2.
Numerele naturale pot fi clasificate n: deficiente, perfecte sau abundente dup cum
suma divizorilor este mai mic, egal sau mai mare dect valoarea numrului. Astfel:
n = 12 este abundent deoarece are suma divizorilor sd = 1+2+3+4+6 = 16 > 12,
n = 6 este perfect pentru c sd = 1+2+3 = 6,
n=14 este deficient deoarece sd = 1 + 2 + 7 = 10 < 14.
Scriei un program care citete dou valori naturale x i y i, n funcie de opiunea
utilizatorului, afieaz toate numerele perfecte, abundente sau deficiente din intervalul
[x, y]. Programul trebuie s conin o secven de validare a datelor. Nu se vor folosi
tablouri.
Indicaii:
n afara funciei main se vor mai scrie dou funcii ale cror prototipuri se vor indica
ntr-un fiier header:
1. o funcie care primete ca parametru un numr natural i returneaz suma
divizorilor numrului.
2. o funcie avnd ca parametru un numr natural, funcie care returneaz -1, 1
sau 0 dup cum numrul transmis ca parametru este deficient, perfect sau
abundent.
Problema nr. 2.3.
Se citesc de la tastatur un numr necunoscut de numere ntregi nenule terminate
cu caracterul CTRL/Z. S se stabileasc dac acestea:
-

formeaz un ir strict cresctor (tip ir = 6)

formeaz un ir cresctor

formeaz un ir strict descresctor

(tip ir = 2)

formeaz un ir descresctor

(tip ir = 3)

(tip ir = 5)

20

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 2

sunt identice (irul este constant)

nu sunt ordonate

(tip ir = 4)

(tip ir = 1)

Programul are posibilitatea de a analiza mai multe seturi de date (va exista
posibilitatea de reluare a programului).
Observaii:
1. Numerele citite nu se vor memora ntr-un vector (tablou).
2. Caracterul CTRL/Z se obine prin apsarea simultan a tastelor Ctrl i Z i are
semnificaie de sfrit de fiier asociat tastaturii. Se va consulta Help-ul pentru a
vedea cum se comport funcia scanf n cazul ntlnirii sfritului de fiier.
Indicaii:
Intre doua elemente ale irului se pot stabili urmtoarele relaii de ordine:
-

mai mic

egal

mai mare

Se determina numrul de relaii de ordine de fiecare tip i n funcie de acest numr


se stabilete tipul irului astfel:
a. numai relaii mai mic - sir strict cresctor
b. relaii mai si relaii egal sir cresctor
c. numai relaii egal sir constant
d. relaii egal si relaii mai mare sir descresctor
e. numai relaii mai mare sir strict descresctor
f. toate tipurile de relaii sir oarecare
n afara funciei main se vor mai scrie dou funcii ale cror prototipuri se vor indica
ntr-un fiier header:
1. o funcie care nu are nici un parametru i returneaz o valoare n funcie de tipul
irului analizat. Aceast funcie citete i analizeaz irul.
2. o funcie care primete ca parametru un numr natural reprezentnd tipul irului
i afieaz mesajul corespunztor.

21

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 3

NOIUNI DE BAZ ALE LIMBAJULUI C. ELEMENTE INTRODUCTIVE


1. Structuri de control...........................................................................................................................2
1.1 Instruciunea if ...........................................................................................................................2
1.2 Instruciunea while.....................................................................................................................2
1.3 Instruciunea do while ...............................................................................................................3
1.4 Instruciunea for.........................................................................................................................3
1.5 Instruciunea switch...................................................................................................................4
2. Alte instruciuni................................................................................................................................6
2.1. Instruciunea break...................................................................................................................6
2.2. Instruciunea continue ..............................................................................................................6
3. Comentarii........................................................................................................................................7
4. Tipuri de date ...................................................................................................................................7
5. Constante..........................................................................................................................................8
6. Declaraii i definiii de variabile i tablouri..................................................................................11
7. scanf i printf() n forma simplificat ............................................................................................12
TEMA 1 .............................................................................................................................................13
TEMA 2 .............................................................................................................................................13
TEMA 3 .............................................................................................................................................16

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 3

1. Structuri de control
1.1 Instruciunea if
Forma general:
if (expresie)
bloc_instr_1;
else
bloc_instr_2;
Se evalueaz expresia; dac este adevrat (diferit de 0) se execut blocul de
instruciuni bloc_instr_1; altfel se execut blocul de instruciuni bloc_instr_2; Un bloc de
instruciuni reprezint mai multe instruciuni simple grupate ntre acolade{ }. Dac un bloc
de instruciuni este vid atunci se nlocuiete prin {}.
Ramura else poate lipsi i atunci forma instruciunii devine:
if (expresie)
bloc_instr;
Exemplu:
if (a<=b)
{
min=a;
max=b;
}
else
{
min=b;
max=a;
}
1.2 Instruciunea while
Forma general:
while(expresie)
bloc_instr;
Att timp ct expresia este adevrat (diferit de 0), se va executa blocul de
instruciuni bloc_instr; n momentul n care expresia devine fals se iese din bucla while i
se continu cu instruciunea urmtoare din program.

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 3

Exemplu:
while (a != 0) {
a=a/10;
printf("%d",a);
}
Linia while (a!=0) se poate scrie mai simplu : while(a)
1.3 Instruciunea do while
Forma general:
do {
bloc_instr;
} while (expresie);
Se execut blocul de instruciuni bloc_instr; apoi se evalueaz expresia; dac
rezultatul este 0 (fals), execuia instruciunii se termin i se trece la urmtoarea
instruciune din program; dac expresia este diferit de 0, adic adevrat, atunci se
repet execuia blocului de instruciuni.
Diferena fa de while este c blocul de instruciuni se execut cel puin o dat,
dup care se pune problema dac s se repete sau nu.
Exemplu:
do {
a=a/10;
printf("%d", a);
} while (a!=0);
1.4 Instruciunea for
Forma general:
for(ei; et; em)
bloc_instr;
unde:
ei expresia de iniializare prin care se atribuie valori iniiale variabilei sau
variabilelor de bucl;
et expresia de test; dac este adevrat se va executa bloc_instr i se revine
la evaluarea expresiei de test; dac expresia de test este fals, se iese din ciclul for
i se continu cu instruciunea urmtoare din program;

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 3

em expresia de modificare a variabilei de bucl. Se folosete pentru


modificarea variabilei de bucl n pentru a permite terminarea repetrii secevenei de
instruciuni.
Acelai efect cu ciclul "for" de mai sus se obine cu:
ei;
while(et) {
bloc_instr;
em;
}
Exemplu:
for (int i=0;i<10;i=i+1)
{
printf("%d",i);
}
Instruciunea i=i+1 se poate scrie mai simplu i++ (incrementarea cu 1).
Observaie:
Toate expresiile pot fi vide deci instruciunea for devine:
for (;;)
n acest caz se va executa un ciclu infinit. Pentru a opri un program ce a intrat ntr-o
bucl infinit (sau alt situaie de blocaj) se vor ncerca urmtoarele combinaii de taste:
CTRL+C
CTRL+Break (apoi Enter)
CTRL+ALT+DEL, Task Manager, apoi se d End Task la aplicaia respectiv
(n mediul Windows 2000)
1.5 Instruciunea switch
Forma general:
switch(expresie) {
case exp1:
bloc_i1;
break;
case exp2:
bloc_i2;
break;

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 3

....
case expn:
bloc_in;
break;
default:
bloc_in+1;
}
Observaie:
expresie este de tip ntreg; expi sunt expresii constante de tip ntreg; bloc_ii sunt
blocuri de instruciuni; Partea cu "default" poate lipsi ;
Mod de execuie:
Se evalueaz expresia i se compar pe rnd cu expresiile constante:
exp1...exp_n; Dac ea produce o valoare egal cu expi se execut blocul de instruciuni
aferent, adic bloc_ii i se iese din switch (break foreaz acest lucru). Dac expresie nu
are nici una din valorile exp1...exp_n, atunci se execut blocul de instruciuni din "default",
adic bloc_in+1 (desigur dac "default" este prezent ).
Dac pe una din ramuri, s zicem pe cea de ordin i, nu ar exista break, atunci s-ar
trece i s-ar compara expresie cu expi+1, adic ramura imediat urmtoare.
Exemplu:
switch(i) {
case 1:
printf("este 1");
break;
case 2:
printf("este 2");
break;
case 3:
printf("este 3");
break;
default:
printf("este altceva");
}

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 3

2. Alte instruciuni
2.1. Instruciunea break
Se ntlnete n corpul unui ciclu (for, while, do while) i are ca efect terminarea
execuiei buclei i continuarea cu instruciunea urmtoare ciclului respectiv.
Exemplu:
...
i=0;
while (i<10)
{
if (i==5)
break;
printf("%d,",i);
i++;
}
....
Rezultatul este afiarea irului 0,1,2,3,4, deoarece n momentul n care i devine 5 se
iese din bucl i nu se mai face afiarea.
Instruciunea break se poate ntlni i n corpul instruciunii switch avnd rolul
prezentat mai sus.
2.2. Instruciunea continue
Se ntlnete tot n corpul unui ciclu cu rolul de a abandona iteraia curent. Dac
este n "for" va fora execuia expresiei de reiniializare. Dac este n while sau do while va
produce reevaluarea condiiei.
Exemplu:
...
for(i=0;i<10;i++)
{
if(a[i]==0)
continue;
aux=a[i]/i;
printf("%d",aux);
}
...

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 3

3. Comentarii
Un comentariu este o secven care nu se ia n considerare la compilare, deci nu are
nici un efect; are doar rol explicativ. Comentariile pe mai multe linii ncep cu /* i se
termina cu */. Pentru a comenta o linie sau o poriune din ea (sfritul) se folosete //
(numai n C++)
Exemplu:
/* acesta e un comentariu
pe mai multe linii
*/
.....
// acesta este un comentariu pe o linie (numai n C++)
.....

4. Tipuri de date
n tabelul de mai jos sunt prezentate tipurile de date cu domeniile lor de
reprezentare (pentru BorlandC 3.1)
Tip

Dim_biti

Semnificaie

Domeniu de valori

Int

16

ntreg

[-32768..32767]

Short

16

ntreg

[-32768..32767]

Long

32

ntreg

[-2147483648..2147483647]

Unsigned

16

ntreg fr semn

[0..65535]

Unsigned

32

ntreg fr semn

[0..4294967295]

Cod ascii caracter

[0..255]

Signed char

Cod ascii caracter

[-128,127]

Float

32

Flotant

long
Unsigned
char
simpl [3.4x10^(-38)..3.4x10^38]

precizie
Double

64

Flotant dubl precizie

[1.7x10^(-308)..1.7x10^308]

Long double

80

Flotant dubl precizie

[3.4x10^(4932)..3.4x10^4932]

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 3

Observaii:
Pentru tipul char, implicit se consider "signed char". Variabilele de tip ntreg
folosesc pentru memorarea datelor codul complementar fa de 2 (dac se rein date cu
semn) sau baza 2 (pentru date fr semn). Caracterele se memoreaz prin codul ASCII,
care este tot un numr ntreg. Pentru tipurile flotante (reale) se folosete reprezentarea n
virgul mobil.
Tem :
Explicai pentru tipurile int i unsigned char cum se calculeaz domeniile de valori.

5. Constante
Orice constant are un tip i o valoare; valoarea unei date constante nu poate fi
schimbat pe parcursul execuiei programului. Tipul constantei decurge din valoarea ei.
Tipuri de constante
Constante ntregi: numere ntregi zecimale, octale sau hexazecimale

zecimale: ncep cu o cifr diferit de 0; pot fi pe 16 bii (int) sau 32 (long). Dac vrem
ca o constant ce ncape pe 16 bii s fie reprezentat pe 32 bii, trebuie terminat cu
"L" sau "l" (exemplu: 4000l).Dac este "unsigned" se termin cu "u" (ex: 4000u); Pot
apare i formele ul, lu, Lu, uL (reprezentare pe 32 biti fr semn; exemplu: 4000lu);

octale: succesiune de cifre octale (0..7), precedate de un 0 nesemnificativ (exemplu:


0123). Pot fi pe 16 sau 32 bii; dac se termin cu l sau L se reprezint pe 32 biti
(long); dac se termin cu u sunt pe 16 bii (unsigned); dac se termin uL, Lu, ul, lu
sunt pe 32 bii (unsigned long)

hexazecimale: succesiune de cifre hexazecimale (0...F sau 0...f) precedate de 0x


(pentru litere mici a...f) sau OX (pentru litere mari A...F). Exemplu: 0x123; 0X1A; 0x1c

Constante reale: numr real simpl precizie (float-32 bii) sau dubl precizie (double-64
bii, long double-80 bii). Pot avea semn: + sau - . Au o parte ntreag (ce poate fi vid); n
acest caz devine o constant zecimal. Au o parte fracionar (ce poate fi vid numai dac
partea ntreag este prezent); aceasta este format din: caracterul "." (punct) urmat de o
succesiune de cifre zecimale. Au un exponent (poate lipsi); ncepe cu E sau e, apoi + sau (opional) urmat de un ir de cifre zecimale; E sau e exprim o putere a lui 10. Pentru
reprezentare (explicit) simpl precizie (32 bii) constanta se termin cu f sau F. Dac se

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 3

termin cu l sau L se reprezint pe 80 bii (long double) chiar dac ar ncape pe mai puin.
n rest n funcie de valoarea pe care o are (domeniu) se reprezint pe 32, 64 sau 80 bii.
Exemple:
Constant real

Valoare

123.

123

123.7

123.7

.25

0.25

78e4

78x10^4

.1E-3

0.1x10^(-3)

123.456e2

123.456x10^2=12345.6

1234.567e-4

1234.567x10^(-4)=0.1234567

Constante caracter: conin codul ASCII al caracterului ce l reprezint. Au tipul int.


De reinut :
O CONSTANT caracter (un caracter inclus ntre

' ' ) are tipul int, deci se

pstreaz pe 16 bii.
Exemplu:
Caracter

Valoare

97

65

48

32

Observaie:
Este diferen ntre cifra 0 (ce are valoarea 0) i caracterul '0' (ce are valoarea 48).
Pentru

reprezentarea caracterelor speciale se folosesc secvenele ESCAPE ce sunt

precedate de caracterul \ (backslash).


Exemplu:
Caracter

Cod ASCII

Semnificaie

\n

10

Rnd nou

\t

Tab orizontal (deplasare cu un nr.


de spaii la dreapta)

\a

Bell (semnal sonor)

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 3

\b

Back space

\v

11

Tab vertical

\r

13

Deplasare

la

nceputul

liniei

curente
\\

92

Semnul \ nsui

34

" (ghilimelele)

39

' (apostroful)

\r

13

Retur

de

car-

poziioneaz

cursorul n coloana 1 din rndul


curent
O construcie '\ddd', d este cifr octal, reprezint o constant caracter al crui cod
ASCII este egal cu valoarea ntregului octal ddd ; fiindc ddd sunt cifre octale nu mai este
necesar includerea cifrei 0, n faa (cum se pune la orice constanta octal)
Exemplu:
'\a' este totuna cu '\7' ; deci '\a' are codul ASCII 7;
'\b' este totuna cu '\10' (10 n baza 8 este :1*8+0=8 n baza 10); deci '\b' are codul
ASCII 8
Constante ir de caractere
Succesiune de 0 sau mai multe caractere incluse ntre ghilimele; pot include i
secvene ESCAPE.
Exemple:
"acesta este un ir"
"alt ir \n"
O constant ir poate fi continuat pe rndul urmtor folosind caracterul \.
Caracterele ce alctuiesc irul se memoreaz ntr-o zon contigu de memorie, prin
codurile lor ASCII; dup ultimul caracter se pune NULL (valoarea 0), adic marcajul de
sfrit de ir; deci pentru a memora o constant ir e nevoie de (nr_car+1) octei.
Observaie:
Este diferen ntre caracterul 'A' i irul "A" (ce conine un singur caracter); primul va
fi reprezentat pe un octet (ce conine valoarea 65 -codul ascii) iar al doilea are nevoie de 2
octei (unul pentru a pstra 65 i altul pentru marcajul de sfrit de ir.

10

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 3

6. Declaraii i definiii de variabile i tablouri


Declaraia de variabil simpl
Orice variabila nainte de a fi utilizata trebuie declarat i/sau definit. n felul acesta i
se rezerv in memorie un numr de octei n care se va pstra valoarea variabilei
respective.
Declaraia are forma:
tip lista_var;
unde tip este unul din tipurile predefinite, iar lista_var este lista de variabile ce au tipul
respectiv; ele se separa prin virgule.
Exemplu:
int i,j;

// 2 octei pentru i; 2 octei pentru j

char c;

// 1 octet

long double x;

// 10 octei

Declaraia de tablou
Tabloul este o mulime ordonat de elemente la care ne putem referi cu ajutorul unor
indici. Orice tablou are un

nume, iar tipul comun al elementelor este tipul tabloului;

elementele pot fi ele nsele tablouri (caz n care avem de-a face cu un tablou
multidimensional, un tablou bidimensional se numete matrice). Evident pentru un tablou
simplu e nevoie de un singur indice pentru a-l parcurge; pentru o matrice e nevoie de 2
indici. Declaraia de tablou are forma :
tip nume[lim1][lim2]...[limn];
unde :
tip

este unul din tipurile predefinite

nume

este numele tabloului

lim1, ..., limn

sunt valori constante care reprezint numrul de elemente de pe

fiecare dimensiune.
La fiecare declaraie de tablou se aloc o zon de memorie necesar pentru a
memora elementele tabloului. La primul element ne vom referi prin nume[0], la al doilea
prin nume[1]...la ultimul prin nume[lim-1], deci indicele de parcurgere poate varia intre
0..(limita-1);
Exemple:
int a[10];
// se rezerv 10*sizeof(int) octei (sizeof(int) are ca rezultat numrul de octei folosii
pentru memorarea unei valori de tip int ntreg).

11

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 3

char tab[100];
// se aloc 100 octei ; ultimul element este tab[99] primul este tab[0];
double mat[2][3];
// o matrice de 2 linii i 3 coloane; se aloc 2*3*8 octei;
// primul element este mat[0][0], al doilea mat[0][1]...ultimul mat[1][2];

7. scanf i printf() n forma simplificat


Se prezint n continuare formele simplificate ale funciilor scanf() i printf() pentru
citirea, respectiv afiarea valorilor ce vor fi folosite la rezolvarea temelor ce urmeaz.
Funciile scanf() i printf() vor fi detaliate n lucrarea viitoare.

Pentru citirea unui numr ntreg zecimal de la tastatur


int n;
scanf (%d ,&n);

Pentru afiarea unui numr ntreg zecimal


printf(Numrul ntreg este: %d , n);

Pentru citirea unui numr real (simpl precizie) de la tastatur


float n;
scanf (%f ,&n);

Pentru afiarea unui numr real simpl precizie


printf(Numrul real este: %f , n);

Pentru citirea unui numr real (dubl precizie)


double n;
scanf (%lf ,&n);

Pentru afiarea unui numr real dubl precizie


printf(Numrul real este: %lf , n);

12

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 3

Pentru rezolvarea corect a problemelor ce urmeaz v rog s citii cu


atenie fiecare enun de la nceput pn la sfrit.
Rezolvrile se fac folosind proiecte i fr variabile globale.
TEMA 1
Problema 1.1.
S se scrie un program care citete de la tastatur un tablou de maximum 20 de
numere ntregi, determin maximul, minimul, media aritmetic i media geometric i
afieaz rezultatele. Pentru media geometric se va folosi funcia (cu prototipul n
MATH.H):
double pow(double x, double y); /* returneaz x la puterea y */
Problema 1.2.
S se scrie un program care citete un tablou de maximum 30 de numere ntregi de
la tastatur, le sorteaz (ordoneaz) cresctor prin metoda bulelor i afieaz rezultatul.
Metoda const n compararea tuturor perechilor a(i) a(i+1), cu i de la 0 la (N-2) (N:
numrul elementelor), i interschimbarea lor dac este cazul. Operaia se reia att timp ct
s-a fcut vreo interschimbare. S se fac apoi o variant a programului n care se va
indica prin dialog dac ordonarea s se fac crescator sau descrescator.
Interschimbarea a 2 elemente a[i] i a[i+1] se face astfel:
{
aux=a[i];
a[i]=a[i+1];
a[i+1]=aux;
}
deoarece se schimb, de fapt, coninutul a dou locaii de memorie a[i] i a[i+1] i nu se
poate face asta n mod direct de genul: a[i]=a[i+1] cci s-ar pierde ce era n a[i]; ori este
nevoie de aceasta valoare pentru a o depune apoi n locaia a[i+1].

TEMA 2
Problema 2.1.
n urma unor msurtori fcute n cadrul unui experiment rezult un ir de n date
experimentale (de tip real) care se memorez ntr-un vector (tablou unidimensional) x.
Prelucrarea acestor date experimentale nseamn:
a. calcularea valorii medii cu formula
1 n 1
xm = xi
n i =0
13

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 3

b. calcularea abaterii medii ptratice cu formula:


n 1

xp =

(x
i =0

xm )

n (n 1)

c. afiarea numrului de componente care nu depesc valoarea medie


d. crearea unui alt vector y cu elementele din x mai mari dect valoarea medie i s
se afieze cte 5 elemente pe o linie.
S se scrie un program pentru a putea prelucra datele experimentale obinute.
Pentru rezolvarea problemei se vor folosi funcii pentru:
1. citirea unui ir de numere cu prototipul:
int citire(int a[]);
// funcia returneaz numrul de elemente efectiv citite
2. afiarea unui ir de numere cu prototipul:
void afisare(int a[], int n);
3. fiecare din cele 4 tipuri de prelucrri se va scrie cte o funcie.
Pentru punctul d se vor scrie dou funcii: una pentru crearea vectorului y avnd ca
date de intrare vectorul x, numrul de elemente din x i vectorul y i ca date de ieire
numrul de elemente din y i cea de a doua pentru afiarea unui vector cu cte 5
elemente pe o linie.
Prototipurile funciilor se vor gsi ntr-un fiier header dup modelul dat la curs.
Problema 2.2.

Se citete de la tastatur un ir de cel mult 100 numere ntregi, pn la ntlnirea


combinaiei de taste CTRL/Z (vezi i problema 2.3. din laboratorul precedent). irul de
numere se memoreaz ntr-un tablou.
S se afieze elementele distincte.
Exemplu: n irul 2 2 5 4 5 1 2 elementele distincte sunt 2 5 4 1.
Se vor scrie funcii pentru:
1. citirea unui ir de numere cu prototipul (de la problema anterioar):
int citire(int a[]);
// funcia returneaz numrul de elemente efectiv citite
2. afiarea unui ir de numere cu prototipul (de la problema anterioar):
void afisare(int a[], int n);
14

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 3

3. determinarea irului cu elemente distincte cu prototipul:


int distinct(int a[], int b[], int n);
// funcia are ca parametri de intrare irul iniial (a), irul final (cu elemente
distincte b) i numrul de elemente din irul iniial n i returneaz numrul de
elemente din irul final.
Prototipurile funciilor se vor gsi ntr-un fiier header dup modelul dat la curs.
Problema 2.3.

n cadrul unui laborator de analize medicale se fac msurtori care privesc modul n
care evolueaz n timp concentraia unei anumite componente n proba de laborator
analizat. Pentru aceasta se noteaz pe o fi concentraia i momentul de timp
corespunztor (considernd momentul de nceput al analizei ca moment zero). Se obin
astfel dou iruri de valori: (i) irul cu valorile momentelor de timp i (ii) irul cu valorile
concentraiilor la aceste momente de timp.
Se cere s se scrie un program care citete cele dou iruri de valori (care sunt
numere reale) i afieaz coeficienii dreptei de regresie sau afieaz un mesaj
corespunztor dac acetia nu pot fi calculai.
Dreapta de regresie

x = a*t + b

are proprietatea c pentru punctele din plan

valoarea expresiei
E =

n 1

(x

a t i b)

i =0

este minim, unde n este numrul de msurtori fcute.


Coeficienii a i b se determin prin rezolvarea sistemului:
n 1
n 1

(t i ) = (x i )
n a + b

i =0
i =0
n 1
n 1
a
(t ) + b (t i t i ) =
i =0 i
i =0

n 1

(t

xi )

i =0

Pentru rezolvarea problemei se vor scrie urmtoarele funcii:


a. funcie pentru citirea unui vector
b. funcie pentru afiarea unui vector
(Aceste dou funcii sunt cele scrise pentru rezolvarea problemei 1)
c. funcie pentru rezolvarea unui sistem de dou ecuaii cu dou necunoscute.
Aceast funcie are doi parametri:
un tablou cu 6 elemente coninnd coeficienii celor dou ecuaii;
un tablou cu dou elemente coninnd soluiile sistemului
15

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 3

i returneaz rezultatul:
1 dac sistemul este compatibil determinat
2 dac sistemul este compatibil nedeterminat
3 dac sistemul este incompatibil
d. funcie care calculeaz produsul scalar a doi vectori a i b. Funcia are ca
pearametri cei doi vectori i numrul de elemente al unui vector i returneaz valoarea
produsului scalar. Pentru calculul sumei valorilor elementelor unui vector folosind funcia
produs scalar unul din vectori va fi un vector iniializat cu uniti.
Observaie:
Toate sumele se vor calcula folosind funcia produs scalar.
Prototipurile funciilor se vor gsi ntr-un fiier header dup modelul dat la curs.

TEMA 3
Problema 3.1.

S se scrie un program care determin i afieaz toate numerele prime inferioare


unui numr dat (prestabilit), folosind ciurul lui Eratostene. Metoda const din eliminarea
succesiv a numerelor neprime prin parcurgerea urmtorilor pai:
1. Se elimina numrul 1 (prin definiie nu este prim).
2. Apoi se caut (pornind de la ultimul numr prim considerat - iniial 1) primul numr
neeliminat (acesta este prim) i se elimina toi multiplii si (din intervalul 1-n).
3. Se repet pasul 2 pn cnd numrul prim considerat este mai mare dect sqrt(n)
adic radical din n. Funcia sqrt are prototipul n math.h
Problema 3.2.

Rezolvai problema lui Josephus: sunt N oameni aezai n cerc (avnd numerele de
ordine 1..N) i la fiecare pas se elimin al K-lea, pn cnd rmne unul singur. La primul
tur se ncepe numrtoarea de la primul om, apoi de la cel care urmeaz celui eliminat. Se
cere numrul de ordine pentru "supravieuitor".

16

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 4

FUNCII DE INTRARE - IEIRE


1. Funciile scanf(...) i printf(...) .........................................................................................................1
1.1. Funcia printf(...) .......................................................................................................................1
1.2. Funcia scanf(...)........................................................................................................................6
2. Funcii de intrare-ieire pentru caractere i iruri de caractere ......................................................10
2.1. Funcii de intrare (citire) .........................................................................................................10
2.2. Funcii de ieire (scriere).........................................................................................................12
2.3. Clasificarea caracterelor..........................................................................................................13
TEMA 1 .............................................................................................................................................14
TEMA 2 .............................................................................................................................................15

1. Funciile scanf(...) i printf(...)


Introducerea datelor se face n mod normal de la tastatura (stdin) iar afiarea
rezultatelor se face pe monitor (stdout). Aceste simboluri sunt definite n STDIO.H.
stdin

dispozitivul periferic de intrare standard;

stdout dispozitivul de ieire standard;


stderr dispozitivul de afiare a mesajelor de eroare (numai monitorul);
stdaux

dispozitivul de comunicaii seriale (implicit COM1);

stdprn

dispozitivul de imprimare standard (implicit LPT1);

stdin i stdout pot fi redirectate (din linia de comanda) conform conveniilor de


redirectare DOS:
<

redirectarea intrrii (datele se vor citi dintr-un fiier n locul tastaturii);

>

redirectarea ieirii - crearea unui fiier n care sa se scrie datele ce s-ar afia in

mod normal pe monitor;


>> redirectarea ieirii cu adugare la sfritul unui fiier (dac nu exista, va fi
creat).
Dispozitivele de I/E standard sunt tratate intr-un mod asemntor fiierelor (ca fluxuri
de date) fiindu-le asignate numerele logice (handle) de la 0 la 4 (n ordinea indicat).
1.1. Funcia printf(...)
Funcia printf(...) scrie ieirea formatat la stdout (ecran). Are prototipul n STDIO.H.
int printf(const char * format [, argument, ...] );

Termenul const nseamn c irul de format nu poate fi modificat n interiorul


funciei. Funcia accept un numr variabil de argumente, i aplic fiecruia specificatorul
de format coninut n irul de caractere "format" i afieaz datele formatate la stdout.
Trebuie ca numrul argumentelor sa coincid cu numrul specificatorilor de conversie
(formatare). irul de format controleaz cum se face conversia, formatarea i tiprirea
1

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 4

fiecrui argument. Dac numrul argumentelor este mai mic dect cel al specificatorilor de
format rezultatul este imprevizibil. Argumentele n exces sunt ignorate. irul de format
conine doua tipuri de elemente:
caractere simple (sunt scrise identic n fluxul de ieire)
specificatorii de conversie (aduce argumentele din lista i le formateaz).
Specificatorii au urmtoarea form general:
%[flags][lime][.prec] tip_car
Fiecare specificator de conversie ncepe cu semnul procent (%) dup care urmeaz
n ordine:
- flags: o secven opional de caractere de control (cadrarea ieirii la dreapta /
stnga, afiarea zerourilor nesemnificative, prefixe octale sau hexazecimale, punctul
zecimal, semn). Poate avea valorile:
-

aliniere la stnga, completeaz la dreapta cu blank-uri; dac nu se specific, se

aliniaz rezultatul la dreapta i completeaz la stnga cu zero-uri sau blank-uri;


+

pune semn + sau - ; are prioritate fa de blank dac sunt ambele valori sunt

prezente;
blank dac numrul este pozitiv se pune blank n fa, dac e negativ se pstreaz
minusul
- lime: un specificator opional pentru numrul minim de caractere ce se vor afia,
completnd la nevoie cu spaii sau zero-uri. Poate avea una din valorile:
n

numr ntreg (vor fi afiate cel puin n caractere, completndu-se dup caz cu

spaii);
0n vor fi afiate cel puin n caractere, dar se completeaz cu zerouri.
- prec: un modificator opional pentru afiare numr maxim de caractere sau de
poziii zecimale. Pentru ntregi reprezint numrul minim de digii ce trebuie afiai. Poate
fi:
neprecizat:

La afiare, precizia este cea implicit, adic

1 pentru tipurile d, i, o, u, x, X;
6 pentru e, E, f (6 poziii zecimale implicit);
toate cifrele semnificative pentru G i g;
afieaz toate caracterele pn la primul caracter diferit de NULL pentru tipul
s; nu are efect la tipul c
0

pentru d, i, o, u, x precizia este cea implicit


pentru e, E, f nu e afiat simbolul de punct zecimal
2

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 4

sunt afiate n caractere sau n poziii zecimale

Dac este cazul ieirea poate fi trunchiat sau rotunjit.


Deci cnd se specific o precizie n, efectul este:
- pentru d, i:

sunt afiai cel puin n digii;

- pentru o, u, x, X: dac argumentul de intrare are un numr de digii < n, ieirea se va


completa cu zerouri (la stnga) pn la atingerea preciziei; dac
argumentul de intrare are numr de digii > n, ieirea nu va fi
trunchiat
- pentru f, e, E:

vor fi afiai n digii dup punctul zecimal, iar ultimul digit va fi rotunjit
(lips sau adaos dup cum este <5 sau >5).

- pentru g, G:

sunt afiai primii n digii semnificativi.

Observaie: nu se va afia nimic n cazul urmtor (toate condiiile ndeplinite):

precizia este pus explicit zero

tipul este unul dintre d, i, o, u, x

valoarea de afiat este nul

- tip_car (caracterul care indic tipul conversiei)


Valoare de

Caracter

intrare ateptat

Ieire formatat

ntreg

ntreg zecimal cu semn

ntreg

ntreg zecimal cu semn

ntreg

ntreg octal fr semn

ntreg

ntreg zecimal fr semn

ntreg

ntreg hexazecimal fr semn (cu litere mici)

ntreg

ntreg hexazecimal fr semn (cu litere mari)

Real

Valoare cu semn de forma [-]dddd.dddd

Real

Valoare cu semn de forma [-]d.dddd e[+/-]ddd

Real

Idem; se folosete E pentru exponent

Real

Real

Valoare cu semn n forma e sau f (se alege


forma ce ocupa numr minim de poziii)
Idem cu g; cu E pentru exponent

Caracter

Un singur caracter

ir

Afieaz irul pn la caracterul NULL sau


pn este atins precizia indicat
Tiprete simbolul %

Pointer

Tiprete argumentul ca xxxx:yyyy (segment


:offset) sau numai n forma yyyy
3

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 4

S detaliem :
- litera c

- litera s

afieaz un caracter
printf("%c", 'A');

//afieaz: caracterul A

printf("*%4c*,'A');

//afieaz: * A* (cadrare la dreapta)

printf("*%-4c*,'A');

//afieaz: *A * (cadrare la stnga)

i=97;printf("%c", i);

//afieaz: a (deoarece 97 este codul ASCII al lui 'a')

afieaz un ir
printf("acesta e un exemplu");

//afieaz: acesta e un exemplu

printf("%s", "abc");

//afieaz: abc

printf("*%10s*","abc");

// afieaz:*

abc* (completare

// la stnga cu 7 spaii)
printf("*%-10s*","abc");

// afieaz:*abc

* (completare la

// dreapta 7 spaii)
Dac se dau i zecimale de exemplu "%10.3s" nu se iau n considerare
- litera d

afieaz valori de tip ntreg


printf("*%10d*",123);

- litera o

//afieaz: *

123*

printf("*%-10d*",123);

//afieaz: *123

printf("*%010d*",123);

//afieaz: *0000000123*

afieaz n octal date de tip int sau unsigned (ntreg i ntreg fr semn)
printf("*%10o*",123);

//afieaz: *

173*

//(deoarece 173 n baza 8 este 123


//zecimal)
- literele x, X afieaz n hexazecimal date de tip int sau unsigned (ntreg i ntreg fr
semn)
x se folosete pentru litere mici a ... f
X se folosete pentru litere mari A ... F
printf("*%10x*,123);

//afieaz: *

7b"

- litera u

la fel cu d; se folosete pentru conversia din unsigned n zecimal

- litera l

poate nsoi una din literele d, o, x, X, u


ld

conversia din long int (ntreg lung) n zecimal

lu

conversia din long unsigned (ntreg lung fr semn) n zecimal

lo

conversia din long sau long unsigned n octal

lx

conversia din long sau long unsigned n hexazecimal

lX

la fel u lx, dar se folosesc litere mari

PROGRAMAREA CALCULATOARELOR

- litera f

LUCRAREA NR. 4

afieaz numere reale, de tip float sau double. Aceste numere pot avea o parte

ntreag i o parte fracionar sau numai parte ntreag. Numrul de zecimale e definit de
precizia indicat n specificatorul de format. Dac nu e precizat numrul de zecimale,
implicit se afieaz 6. Ultima cifr e rotunjit prin adaos sau lips dup cum cifra este >=5
sau <5
Exemple:
Valoare

Specificator

Rezultat afiat

3.14159265

%5f

3.14153(rotunjire adaos la 6 zecimale)

123.672

%7f

3.14159265

%7.2f

123.672000 (completare cu 0 pn la 6
zecimale)
3.14 (rotunjire lips pn la 2 zecimale)

123.672

%10.1f

123.7 (rotunjire adaos pn la o zecimal)

-123.672

%10.1f

-123.7 (idem)

3.14159265

%10.0f

(rotunjire lips, nici o zecimal)

123.672

%10.0f

124

(rotunjire adaos, nici o zecimal)

- literele e, E afieaz un numr real (de tip float sau double) sub forma: p_int.p_fract exp
sau p_int exp;
Exemple:
Numr

Specificator

Rezultat afiat

3.14159265

%e

3.141593e+00

123.672

%e

1.236720e+02

123.672

%.1E

1.2e+02

0.673

%E

6.730000E-01

- literele g, G funcioneaz la fel ca f sau ca e, E. Se alege forma convenabil pentru a


afia un numr minim de caractere; afieaz 6 zecimale numai dac acestea sunt
semnificative; afieaz punctul zecimal numai dac este prezent partea fracionar. Se
folosete g pentru e, G pentru E (desigur dac s-a preferat forma e, E formei f). Tipul float
are 6,7 zecimale; nu se recomand afiarea unui numr mai mare de zecimale. Tipul
double are 15 zecimale; alegerea afirii cu un numr mai mare de zecimale nu are sens;
- litera L

poate nsoi literele f, e, E, g, G. Data care se afieaz este de tip long double

(real lng dublu). Lf este forma fr exponent, Le, LE forma cu exponent, iar Lg, LG forma
mai convenabil dintre f i e(E)
Observaii:
1). + i sunt afiate ca +INF i -INF
5

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 4

2). Dac rezultatul nu este numr (not_a_number) se afieaz +NAN sau -NAN
3). La formatul %e sau %E se convertete argumentul n forma [-]d.ddd...e[+/-]ddd
cu o cifr naintea punctului zecimal, un numr de cifre dup punct egal cu precizia i
exponentul avnd cel puin doua cifre.
4). La formatul %f se convertete argumentul n forma [-]ddd.ddd..., cu numr de
cifre de dup punctul zecimal egal cu precizia indicat (poate fi zero).
5). La %g sau %G se elimin zerourile nesemnificative i punctul zecimal apare
numai dac este nevoie. Argumentul este afiat n forma e sau f (pentru g), respectiv E
(pentru G), depinde care form e mai avantajoas (mai scurt)
6). Caracterele speciale (escape sequences) se reprezint prin secvene avnd
primul caracter backslash (\).
Exemple:
`\n' newline trecere la nceputul urmtoarei linii (LF)
`\r' carriage return revenire la nceputul liniei curente (CR)
`\t'

horizontal tab (HT)

`\v' vertical tab (VT)


`\b' backspace
`\f'

form feed (FF)

`\a' alarm sonor


`\\'

backslash nsui;

'\''

apostrof

`\"' ghilimele
`\?' semnul ntrebrii;
`\ooo' numr octal;
`\xhh' numr hexazecimal.
printf(...) returneaz numrul de octei scrii sau EOF (-1) n caz de eroare.
1.2. Funcia scanf(...)
Funcia (cu prototipul tot n STDIO.H) citete i formateaz datele de intrare (citite de
la stdin). Are formatul:
int scanf(const char *format [,address,...] );

scanf(...) citete elementele de intrare (caracter cu caracter) de la stdin, dup care le


formateaz n conformitate cu specificatorul din format i depune rezultatul la adresa
transmis ca argument (dup format). Trebuie sa fie acelai numr de specificatori de
format i de adrese ale elementelor de intrare. Dac sunt mai puine adrese, efectul este
6

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 4

imprevizibil. Argumentele adres n exces sunt ignorate. Funcia ncepe scanarea dup
apsarea tastei Enter (cu condiia s se fi introdus minimum attea elemente cte adrese
apar. Elementele introduse n plus rmn pentru citirile ulterioare).
irul de caractere format poate conine:
a) caractere albe - whitespaces (spaiul, tab - `\t', newline - `\n', carriage return \r)
Dac scanf(...) ntlnete un astfel de caracter n format, va citi (fr s le
memoreze) toate spaiile albe consecutive pn la urmtorul caracter diferit din intrare.
b) caractere non whitespace ( toate celelalte caractere ASCII fr "%")
Dac scanf(...) ntlnete un caracter ce nu este caracter alb n format, va citi (fr
memorare) caracterul corespunztor (dac n intrare este un caracter diferit, se ncheie
scanarea).
c) specificatori de format : %[*][lime] tip_car
Forma minim a specificatorului de format: ncepe cu % i se termin cu 1-2 litere
ce definesc tipul conversiei)
lime - reprezint numr maxim de caractere (n- ntreg zecimal) ce urmeaz a fi
citite. Sunt citite, convertite i stocate la adrese, pn la n caractere
tip_car - aceeai semnificaie ca la printf(...). Prezentm in tabelul de mai jos valorile
posibile
Tip_car

Intrare

Tip argument

ntreg zecimal

pointer la int (int *arg)

ntreg zecimal

pointer la long (long *arg)

e, E

Real

pointer la float (float *arg)

Real

pointer la float (float *arg)

g, G

Real

pointer la float (float *arg)

ntreg octal

pointer la int (int *arg)

ntreg octal

pointer la long (long *arg)

ntreg zecimal, octal sau hexazecimal

pointer la int (int *arg)

ntreg zecimal, octal sau hexazecimal

pointer la long (long *arg)

ntreg zecimal fr semn

ntreg zecimal fr semn

ntreg hexazecimal

pointer la int fr semn (unsigned


int *arg)
pointer la long fr semn
(unsigned long *arg)
pointer la int (int *arg)

ntreg hexa

pointer la int (int *arg)

ir de caractere

pointer la tablou de caractere


(char arg[])
7

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 4

pointer la caracter (char *arg) sau


pointer la un tablou de width
caractere (char arg[Width])
Toate argumentele trebuie s fie adrese ale unor variabile de tipul indicat (adresa
Caracter

este indicat prin prezena operatorului &).


Elementele din intrare se separ astfel:
- toate caracterele pn la urmtorul spaiu alb (exclusiv);
- toate caracterele pn la primul care nu poate fi convertit conform formatului
specificat;
- pn la n caractere (specificat prin cmpul lime).
La folosirea formatului "%c" se citete urmtorul caracter, chiar dac este spaiul alb.
Pentru a se sri la urmtorul caracter ce nu este alb i a-l citi se recomand s se
foloseasc " %c" ( spaiul de dinainte de %c va face s se sar peste toate spaiile albe
intermediare). Dac asteriscul (assignment suppression character) urmeaz semnului %,
urmtorul element din intrare va fi scanat (conform tip_car din continuare), dar nu va fi
asignat urmtorului argument adres (nu se poate determina dac operaia s-a fcut cu
succes sau nu). Putei ntlni pentru a sri peste spaiile albe din intrare forma
scanf("%*c").
Funcia scanf(...) se termin la:
- tastarea combinaiei de taste CTRL-Z;
- la terminarea scanrii elementului curent din intrare;
- dac urmtorul element din intrare nu poate fi convertit conform formatului;
- dac s-a atins limita indicat prin lime
Elementul la care se termin scanf(...) se va considera ca necitit i va fi primul pentru
urmtoarea operaie de citire de la stdin. Funcia returneaz numrul elementelor din
intrare ce au fost scanate, convertite i memorate. Dac se detecteaz EOF (s-a apsat
CTRL-Z), funcia returneaza -1. Datele se citesc efectiv dup acionarea tastei ENTER .
Pentru o golire total a tuturor datelor rmase necitite n intrare se poate folosi funcia:
fflush(stdin); //(cu prototipul n STDIO.H)
Cnd se citesc iruri de caractere (tablouri) nu se mai folosete operatorul & n fa
ca la variabile simple, deoarece numele unui tablou este el nsui o adres de memorie i
anume adresa primului element din tablou.
S detaliem literele ce pot apare dup %:
- litera c: se citete caracterul curent chiar dac este alb. Exemplu:
scanf("%c", &var_c);

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 4

- litera s: ncepe cu caracterul care nu e alb i se continu pn la alt caracter alb sau
pn se atinge lungimea maxim. La sfritul unui ir citit astfel se pstreaz automat '\0'
marcajul de sfrit de ir
Exemplu1:
....
char ir[2];
scanf("%1s",ir);

//citete un singur caracter, primul ce nu este alb


//memoreaz i '\0' la sfrit

....
Exemplu 2:
char tab1[10];
char tab2[10];
scanf("%2s%9s", tab1, tab2);
....
S presupunem c se tasteaz la intrare irul necunoscut. Atunci n tab1 se va
pstra "ne", iar n tab2 "cunoscut", desigur terminate cu '\0'
- litera d: citete ntregi zecimali (date de tip ntreg zecimal cu semn int), deci domeniul
de valori este [- 32768, 32767].
Exemplu 1:
int i1,i2,i3;
scanf("%2d%3d%2d",&i1,&i2,&i3);
La intrare avem:1234567, atunci: i1=12; i2=345; i3=67
Exemplu 2:
int n;
scanf("%d",&n);
La intrare: i23 atunci se returneaza 0, cci i nu corespunde formatului. Dac era la
intrare:23i atunci se citea 23.
- litera o:

la fel ca d, dar se citete un ntreg octal

- literele x, X:
- litera u:

la fel cu d, dar se citete un ntreg n forma hexazecimal


pentru citire ntregi zecimali, tip unsigned (fr semn, deci numere

naturale)
- litera f:

citire numr real simpl precizie (tip float)

- literele e, E:

citire numr flotante simpl precizie n forma cu exponent

- literele g, G:

citire numr flotante n forma f sau e(E)

- litera l:

poate nsoi d, o, x, X, u, f.
ld, lo, lx, lX: data citit e convertit spre long
9

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 4

lu: data citit e convertit spre unsigned long


lf: data citit este convertit spre flotant dubl precizie (tipul double)
-literele D, O, U, I: pentru numere ntregi de tipul long.

2. Funcii de intrare-ieire pentru caractere i iruri de caractere


2.1. Funcii de intrare (citire)
(a) int getc(FILE *stream);
- citete un caracter dintr-un fiier deschis pentru citire sau de la dispozitivul standard
de intrare (stdin de obicei asociat tastaturii) i incrementeaz indicatorul de poziie al
fiierului pentru a adresa urmtorul caracter
- are prototipul n STDIO.H;
- returneaz n caz de succes, caracterul citit (convertit n int fr extensie de semn)
sau EOF pentru end-of-file sau eroare.
(b) int getchar(void);
- citete un caracter de la stdin (dispozitiv standard de intrare);
- are prototipul n STDIO.H;
- este o macrodefiniie (definit ca getc(stdin)) care returneaz urmtorul caracter de
la stdin;
- n caz de succes, getchar() returneaz caracterul citit, dup ce l-a convertit ntr-un
int fr extensie de semn. Pentru end-of-file (sfrit de fiier) sau eroare, returneaz EOF
(definit n STDIO.H ca -1). Caracterul CTRL-Z (0x1A) este interpretat ca EOF i convertit
n -1 ;
- funcia lucreaz bufferat (line buffered), adic nu putem prelucra caracterele citite
pn cnd nu s-a tastat Enter; caracterele introduse sunt memorate intr-un buffer i abia
dup ce se tasteaz Enter, funcia le citete de acolo.
(c) char *fgets(char *s, int n, FILE *stream);
- citete un ir de caractere dintr-un fiier deschis pentru citire sau de la tastatur n
cazul n care stream este stdin;
- are prototipul in STDIO.H;
- funcia un ir de caractere terminat cu Enter de la tastatur sau o linie dintr-un fiier.
Citirea se oprete la sfritul liniei sau la citirea a n-1 caractere (se ia n considerare prima
condiie ndeplinit). Funcia pstreaz n ir caracterul \n, dup care adaug \0.
- irul citit se stocheaz n s

10

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 4

- funcia returneaz adresa irului de caractere citit n caz de citire corect, valoarea
0 (zero) la citirea sfritului de fiier i n caz de eroare.
- spre deosebire de funcia gets (a crei descriere urmeaz), funcia fgets
controleaz i lungimea irului de caractere, nepermind depirea lungimii specificate de
programator. Din acest motiv se recomand folosirea acestei funcii i nu a funciei gets.
(d) char *gets(char *s);
- citete un ir de caractere de la stdin
- are prototipul n STDIO.H
- funcia citete un ir de caractere terminat cu '\n' de la tastatur i-l depune n
tabloul s (nlocuind newline cu caracterul NULL '\0')
- spre deosebire de scanf(...) care ncheie citirea la ntlnirea primului caracter alb,
gets(...) citete iruri care pot conine spatii sau tab-uri. Este rspunderea programatorului
s aloce spaiu suficient pentru a ncpea toate caracterele pn la '\n';
- irul poate fi (voluntar sau involuntar) i vid (de exemplu cnd se face o citire cu
gets(...) dup scanf(...))
- returneaz pointer la irul citit pentru succes i NULL (definit n STDIO.H ca 0) n
caz de end-of-file (Ctrl-Z) sau eroare.
(e) int getw(FILE *stream);
- citete urmtorul ntreg din fluxul de intrare indicat
- pentru citire de la tastatura se indica stdin
- are prototipul n STDIO.H;
- returneaz urmtorul ntreg din fluxul de intrare, EOF pentru end-of-file sau eroare.
Deoarece codul pentru EOF este posibil i corect sa apar n interiorul unui fiier binar, nu
se testeaz valoarea returnat de getw(), ci funciile feof(...) sau ferror(...) (se vor detalia
ulterior).
(f) int getch(void);
- citete un caracter (direct) de la tastatur, fr ecou pe ecran;
- are prototipul n CONIO.H
- returneaz caracterul citit
- funcia ateapt apsarea unei taste (se sare peste caracterele anterior introduse i
necitite nc - prin getchar() sau scanf(...));
- tasta Enter are codul '\r' (carriage return) la citirea cu getch(); este convertit n '\n'
(newline sau line feed) la citirea cu getchar();
11

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 4

- tastele sgei, cele funcionale (Fn) precum i combinaiile Ctrl-Fn sau Alt-tasta
genereaz o pereche de coduri, primul fiind 0x00. Pentru prelucrarea lor este nevoie de
doua citiri la nivel de caracter sau s se foloseasc funcia bioskey(...). Prin dou getch()
succesive, dac s-a apsat o astfel de tasta, se fac ambele citiri (la al doilea apel nu se
ateapt o noua tastare).
(g) int getche(void);
- citete un caracter (direct) de la tastatur i l afieaz n ecou pe ecran
- are prototipul n CONIO.H;
- returneaz caracterul citit.
2.2. Funcii de ieire (scriere)
(a) int putc(int c, FILE *stream);
- scrie un caracter intr-un flux (stdout sau un fiier deschis n scriere);
- are prototipul n STDIO.H;
- returneaz caracterul c pentru succes, altfel EOF.
(b) int putchar(int c);
- trimite un caracter la stdout (dispozitiv standard de iesire);
- are prototipul n STDIO.H; este definit ca: putc(c, stdout);
- returneaz caracterul c pentru succes, EOF pentru eroare.
(c) int fputs(const char *s, FILE *stream)
- scrie un ir de caractere terminat cu \0 ntr-un fiier (sau pe monitor cnd fiierul
indicat (stream) este stdout). Se presupune c irul are deja n componen \n;
- are prototipul n STDIO.H;
- returneaz ultimul caracter scris, iar n caz de eroare returneaz EOF.
(d) int puts(const char *s);
- trimite un ir de caractere la stdout;
- are prototipul n STDIO.H;
- funcia copie irul s (terminat cu NULL) la stdout, adugnd un newline (linie nou);
- returneaz o valoare pozitiva pentru succes, altfel EOF.
(e) int putw(int w, FILE *stream);
- scrie un ntreg intr-un flux
12

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 4

- are prototipul n STDIO.H


- returneaz ntregul scris pentru succes, altfel EOF. Deoarece EOF poate aprea ca
un ntreg normal intr-un fiier binar, se va folosi ferror(...) pentru detectarea erorilor. Se va
detalia ulterior.
(f) int ungetc(int c, FILE *stream);
- trimite napoi un caracter n fluxul de intrare;
- are prototipul n STDIO.H;
- funcia trimite napoi caracterul c n fluxul de intrare (stream care trebuie deschis
pentru citire); acest caracter va fi returnat la urmtoarea citire cu getc(...) sau fread(...) din
respectivul flux de intrare;
- un al doilea apel al ungetc(...) fr vreun getc(...) va duce la ignorarea caracterului
precedent;
- apelarea fflush(...), fseek(...), fsetpos(...) sau rewind(...) sterge din memorie toate
caracterele trimise napoi;
- returneaz caracterul c pentru succes, EOF pentru eroare
(g) int putch(int c);
- trimite un caracter pe ecran;
- are prototipul n CONIO.H;
- afieaz caracterul c n fereastra text curenta; nu convertete (spre deosebire de
printf(...) sau putchar(...)) caracterul '\n' n perechea '\n'-'\r' ('\n' va avea ca efect trecerea
pe linia urmtoare n aceeai coloana, iar '\r' trecerea la nceputul liniei curente);
- returneaz caracterul c pentru succes, EOF pentru eroare.
(h) int ungetch(int ch);
- trimite un caracter napoi n buffer-ul tastaturii;
- are prototipul n CONIO.H;
- caracterul ch va fi urmtorul caracter citit de la tastatura;
- funcia eueaz dac este apelata de mai multe ori nainte de a se face o citire;
- returneaz caracterul ch pentru succes, EOF pentru eroare.
2.3. Clasificarea caracterelor
Prezentam n continuare cteva macrodefiniii din CTYPE.H, care ne ajut sa
difereniem ntre ele caracterele.

13

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 4

(a) int isalpha(int c);


returneaz un ntreg diferit de zero, dac c este liter (a ... z sau A ... Z).
(b) int isascii(int c);
returneaz un ntreg diferit de zero dac octetul inferior al lui c este n intervalul
0 ... 127 (0x00 ... 0x7F)
(c) int iscntrl(int c);
returneaz un ntreg diferit de zero dac c este caracterul Del (0x7F) sau un
caracter de control obinuit ce are codul ASCII n gama 0x00 ... 0x1F
(d) int isdigit(int c);
returneaz un ntreg diferit de zero dac c este o cifr zecimal (0 ... 9)
(e) int islower(int c);
returneaz un ntreg diferit de zero dac c este liter mic (a ... z).
(f) int isspace(int c);
returneaz un ntreg diferit de zero dac c este spaiu( ), tab(\t), carriage
return(\r), new line(\n), vertical tab(\v) sau form feed(\f).
(g) int isupper(int c);
returneaz un ntreg diferit de zero dac c este liter mare (A ... Z).
(h) int isxdigit(int c);
returneaz un ntreg diferit de zero dac c este cifr hexazecimal (0 ... 9, a ... f, A
... F).

TEMA 1
Problema 1.1
Scriei un program care numra apariiile unui anumit caracter ntr-o secvena de
caractere citit de la tastatur.

14

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 4

Problema 1.2
S se scrie un program care contorizeaz toate apariiile vocalelor (fiecare n parte)
dintr-o secven citit de la tastatura. Se va include posibilitatea relurii programului la
cerere.
Problema 1.3
Scriei un program care folosete dou funcii proprii care convertesc textul din
intrare n majuscule / litere mici dup cum se indic prin dialog de la tastatur.
Problema 1.4
S se scrie un program care afieaz lungimile cuvintelor dintr-o secvena citita de
la tastatura, secvena ncheiata cu Enter. Se consider c orice cuvnt se termin la
primul caracter alb. Nu se vor folosi funciile de bibliotec pentru lungimea unui ir.
Problema 1.5
Comparai efectul funciilor proprii scrise la Problema 5 cu cel al funciilor de
bibliotec echivalente (int toupper(int ch) i respectiv int tolower(int ch)). Aplicai una din
aceste funcii textului din intrare i afiai rezultatul.

TEMA 2
Problema 2.1
S se scrie o funcie care are un parametru de tip unsigned long care reprezint un
numr dat n baza 10 i care calculeaz reprezentarea valorii parametrului funciei n baza
16 i depune rezultatul ntr-un ir de caractere dat ca al doilea parametru al funciei (irul
de caractere va ncepe cu 0x sau 0X).
S se testeze funcia scris ntr-un program care citete un numr ntreg de la
tastatur i afieaz irul de caractere corespunztor reprezentrii n baza 16.
(Nu se vor folosi eventualele funcii de conversie existente n bibliotecule mediului).
Problema 2.2
Se citete de la tastatur un text format din mai multe linii pn la ntlnirea
combinaiei de taste CTRL/Z (Windows) sau CTRL/D (Linux).
Stabilii numrul de litere, cifre, numrul de separatori, numrul de cuvinte, numrul
de propoziii i numrul de aliniate.

15

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 4

De asemenea, se vor afia numrul total de caractere i procentele de litere i cifre


din numrul total de caractere.
Cuvintele sunt separate prin caractere albe, punct, virgul, dou puncte, punct
virgul i cratim. La sfritul fiecrei propoziii avem un punct utmat de un spaiu, iar un
aliniat este terminat cu punct urmat de sfrit de linie.
Indicaie:
Textul se citete caracter cu caracter. Caractere albe sunt spaiu, TAB, Enter.
Nu se vor folosi alte funcii de bibliotec dect cele pentru citire i scriere.

16

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 5

DEPANAREA PROGRAMELOR. ERORI IMPORTANTE


TABLOURI BIDIMENSIONALE

1. Depanarea programelor.....................................................................................................2
1.1. Opiuni generale ..........................................................................................................2
1.2. Comenzi disponibile ....................................................................................................2
1.3. Urmrirea programelor................................................................................................3
1.4. Folosirea punctelor de intrerupere (breakpoints)........................................................3
1.5. Folosirea ferestrelor Inspector ....................................................................................4
1.6. Evaluarea ....................................................................................................................5
1.7. Supravegheri (watches) ..............................................................................................6
1.8. Alte comenzi folosite la depanare ...............................................................................7
2. Erori importante .................................................................................................................7
2.1. Out of memory.............................................................................................................7
2.2. Erori la execuie...........................................................................................................7
(a) Abnormal program termination..................................................................................7
(b) Divide error................................................................................................................8
(c) Floating point error : divide by 0................................................................................8
(d) Floating point error : Partial loss of precison ............................................................8
(e) Floating point error : Stack fault ................................................................................8
(f) Null pointer assignment..............................................................................................8
(g) Stack overflow ...........................................................................................................9
TEMA 1 Problema 1.1............................................................................................................9
Problema 1.2 ......................................................................................................................9
Problema 1.3 ......................................................................................................................9
Problema 1.4 ....................................................................................................................10
TEMA 2 Problema 2.1..........................................................................................................10
Problema 2.2 ....................................................................................................................12
Problema 2.3 ....................................................................................................................12
Problema 2.4 ....................................................................................................................12

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 5

1. Depanarea programelor
Depanarea este operaiunea de detectare i eliminare a erorilor logice ale
programului. Absena erorilor de compilare i linkeditare nu este deloc relevant pentru
buna funcionare a unui program).
1.1. Opiuni generale
Pentru depanare se poate folosi depanatorul integrat n IDE sau depanatorul (de uz
general) TD (Turbo Debugger). Prin comanda Options->Debugger se stabilete modul de
lucru pentru depanare.
Grupul Source Debugging indic dac se lucreaz cu depanatorul inclus (On), cu
TD (Standalone) sau dac nu se dorete includerea informaiilor pentru depanare (None).
n cazul includerii depanrii, se vor aduga la linkeditare informaii speciale n fiierul EXE,
rezultnd un cod mai mare cu circa 30%. Dup testarea completa a programelor, se poate
renuna la opiune i s se creeze varianta finala mai compact. Selectarea On permite i
folosirea TD, dar selectarea Standalone exclude folosirea depanatorului integrat. Pentru a
avea acces la module sursa, trebuie ca acestea sa fie compilate cu opiunea Debug Info
ON (se gasete n Options Compiler Advanced Code generation).
Grupul Display Swapping stabilete cnd se comut de la fereastra de editare la
User Screen :
- None (niciodat)
- Smart (cnd programul trimite date spre afiare pe ecran sau se apeleaz o
funcie)
- Always (la fiecare instruciune).
Grupul Inspectors indic varianta de afiare n fereastra Inspectors (in zecimal, n
hexa sau ambele).
Program Heap Size, stabilete ct memorie s fie acordat

unui program la

depanare (implicit 64KO; valoarea depinde de alocrile dinamice fcute).


1.2. Comenzi disponibile
La depanare se lucreaz cu urmtoarele operaii din meniul principal:
Meniul Run
Program Reset

Ctrl-F2

Go to cursor

F4

Trace into

F7

Step over

F8
2

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 5

Meniul Debug
Inspect

Alt-F4

Evaluate/modify

Ctrl-F4

Call stack.

Ctrl-F3

Watches

>
Add watch. Ctrl-F7
Delete watch
Edit watch
Remove all watches

Toggle breakpoint

Ctrl-F8

Breakpoints...
1.3. Urmrirea programelor
Este un proces prin care se face rularea programului pas cu pas n vederea detectrii
erorilor logice, a cazurilor n care programul se blocheaz sau nu creeaz efectul ateptat.
Operaia Run Trace into (F7) face (dac este cazul) compilarea i linkeditarea, dup
care depanatorul se deplaseaz pe nceputul funciei main() n fereastra de editare,
scond linia respectiv n eviden. Prin F7, n continuare, se execut programul pas cu
pas, intrnd i n corpul funciilor apelate.
La folosirea Run Step over (F8), se face acelai lucru, dar nu se intr n corpul
funciilor apelate.
Depanatorul lucreaz numai pentru funciile ce au codul sursa ntr-un fiier care a fost
compilat cu informaii de depanare, nu i cu funciile de bibliotec. Dac ecranul plpie
nseamn ca se executa o instruciune care afieaz date ecran sau se face un apel de
funcie (in varianta F8) i se comut temporar pe User Screen.
1.4. Folosirea punctelor de intrerupere (breakpoints)
Un Breakpoint este un punct (din surs) unde vrem sa se opreasc execuia
programului (poate nu ne intereseaz la rulm toat sursa, ci doar o poriune din ea).
Linia surs respectiv (cea pe care este fixat un punct de ntrerupere) este scoas n
eviden. De fiecare dat cnd desfurarea programului ajunge la o linie pe care s-a
fixat un breakpoint, programul se ntrerupe i se revine n debugger (nu numai la rularea
pas cu pas ci i la rularea cu CTRL-F9). Punctele de ntrerupere stabilite se menin pn
la:
- ieire din mediu
- comutarea lor (ON/OFF) cu Ctrl-F8
3

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 5

- tergerea cu Debug Breakpoints Delete


- tergerea liniei respective
- abandonarea fiierului fr a-l salva
Dup orice modificare n fiierul curent, reluarea comenzilor de depanare produce
ntrebarea "Source modified, rebuild?"(se tasteaz Y pentru ca programul sa fie refcut
astfel nct sa conin modificrile).
Comanda Debug Breakpoints duce la deschiderea ferestrei Breakpoint List
(unde sunt afiate punctele de ntrerupere cu urmtoarele informaii:
- numrul liniei sursa corespunztoare - Line#
- condiia de ntrerupere - dac exist
- Pass - de cate ori sa se sar peste punctul de ntrerupere respectiv nainte de a
opri execuia.
Cu ajutorul tastelor Up, Dn se poate alege un breakpoint pentru care s se dea una
din comenzile:
- Edit

modificarea lui sau crearea unuia nou

- Delete

tergerea lui

- View

se face defilarea n fereastra de editare pn la poziia lui

- At

se indica un nume de funcie pe care sa se stabileasc un punct de

ntrerupere (chiar pe prima linie din definirea ei)


Condiia de ntrerupere pentru un breakpoint poate fi orice expresie C corecta, care
sa nu conin un apel de funcie, simboluri sau macrouri definite de #define sau typedef,
variabile locale sau statice n afara domeniului funciei curente.
La tastarea Ctrl-Break, depanatorul ateapt pn la terminarea execuiei liniei surs
i oprete programul la instruciunea urmtoare. Dac se tasteaz Ctrl-Break de dou ori,
se face un instant break - depanatorul termina programul imediat, fr sa se curee (flush)
ieirile i fr se apeleze funciile de ieire (exit); coninutul fiierelor de date poate deveni
imprevizibil i depanatorul nu mai poate stabili care linie sursa ar urma (se recomanda a
se folosi numai la bucle infinite de genul while(1))
1.5. Folosirea ferestrelor Inspector
Pentru deschidere se da comanda Debug Inspect sau Alt-F4. Se aduce implicit
n Input Box a ferestrei "Data Inspect" cuvntul pe care se afla cursorul n fereastra de
editare (nimic dac se afla pe un spaiu). Dac elementul din fereastra Edit era de tipul
tab[x], se aduce tab i cu ajutorul tastei sgeata dreapta se poate aduce continuarea,
ncheind cu Enter. Coninutul Input Box poate fi i editat.
4

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 5

Dup aceasta, se deschide fereastra Inspector (ncepe cu numele elementului


selectat). Pentru o variabil, prima linie conine adresa ei (segment:offset). Urmtoarea
linie indica tipul de data al elementului (dac nu este un tablou sau o funcie) i n dreapta,
valoarea curent. Se selecteaz automat formatul adecvat pentru afiare (de exemplu '\' i
valoarea n hexa pentru caracterele netipribile; ntregii vor fi afiai n zecimal, hexa sau
n ambele variante). Pentru tablouri sau iruri de caractere (tablou de caractere avnd un
null final) se afieaz cate o linie pentru fiecare element (cu indicele corespunztor-[0]
pentru variabile simple) i n partea de jos- mrimea tabloului respectiv, dac linia scoasa
n eviden este cea corespunztoare adresei) sau tipul fiecrui element component (dup
deplasarea cu ajutorul sgeilor). Se poate indica i un singur element din tablou (prin
nume i indice tab[x]). La structuri i uniuni se afieaz tipul i valoarea pentru fiecare
membru. Pentru pointeri se afieaz adresa pointerului, adresa la care pointeaz
(separate prin '>>') i datele aflate la acea adresa. La funcii (nu se introduc i parantezele
n Input Box din Data Inspect) se indic adresa, tipul valorii de retur, tipurile parametrilor;
dac se tasteaz Enter se face defilarea n fereastra de editare pn la definiia funciei
respective. Fereastra Inspector este implicit temporar, nchizndu-se la tastarea ESC (nu
este trecuta n lista ferestrelor deschise).
1.6. Evaluarea
Prin comanda Debug Evaluate (Ctrl-F4) se deschide o rubrica de dialog cu trei
elemente:
Expression (expresia ce se dorete sa se evalueze), Result i New value (se
poate introduce valoarea dorit). Implicit este adus n cmpul Evaluate, cuvntul de la
poziia cursorului n fereastra de editare; cu ajutorul tastei sgeata dreapta se poate aduce
continuarea, dac se dorete, pentru un element de tablou precis; se poate face editarea
ca la orice Input Box. Dac expresia este numele unui tablou, se afieaz rezultatele intre
acolade, separate prin virgule. Expresiile trebuie sa nu includ apelarea vreunei funcii i
sa nu foloseasc o valoare data prin #define.
Pentru a indica un format de afiare altul dect cel implicit, se scrie dup expresie o
virgul i apoi un specificator de format:
c

: caracter

: ntreg zecimal

f :n : real
h, x: : hexazecimal

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 5

: memory dump - afieaz un vidaj de memorie ncepnd

de la

adresa respectiv; numrul de elemente afiate depinde de mrimea tabloului


p
despre

: pointer - afieaz variabila selectata ca un pointer, oferind informaii

memoria la care pointeaz (se poate folosi pentru tabela vectorilor de

ntrerupere, zona de date BIOS etc)


r

: structuri /uniuni

: ir (implicit)

Pentru tablouri se poate indic numrul de valori care sa se afieze: tab, 5 (5


valori); se admit i combinaii ca: tab[2],4h (4 elemente ncepnd cu al 3-lea, afiate n
hexazecimal). La structuri sau uniuni se afieaz ntre acolade valorilor membrilor,
separate prin virgule. Dac s-a specificat r' rezultatul va fi de forma: {nume_membru:
valoarea}. Se poate cere evaluarea variabilelor statice ale altor funcii dect cea n curs de
execuie sau a variabilelor funciei care a apelat-o pe cea curenta (se indic sub forma
nume_funcie.nume_variabil sau, dac variabila este dintr-un modul compilat separat,
nume_modul.nume_funcie_variabil). Variabilele automate, evident, nu pot fi examinate
deoarece la ieire din funcii nu mai au vreo valoare.
Rubrica New value permite mascarea temporar a unei deficiene i continuarea
depanrii sau faciliteaz proiectarea top_down a aplicaiilor (se fixeaz valoarea de retur
pentru funcii deocamdat fictive, ce urmeaz sa fie concretizate ulterior).
1.7. Supravegheri (watches)
Prin comanda Debug Watches: Add Watch sau Ctrl-F7 se deschide rubrica de
dialog Add watch, n care se indic o nou variabil creia se dorete s i se urmreasc
valoarea pe parcursul execuiei programului. Implicit se aduce n Input box cuvntul pe
care se afla poziionat cursorul n fereastra de editare. Se deschide fereastra Watch i se
adaug noul element. Dac sunt mai multe, pentru defilare, se folosesc tastele sgei.
Formatul de afiare se indic la fel ca la evaluare. Pentru adugarea / eliminarea
supravegherilor se da comanda Debug Watches Add Watch sau Ins (din fereastra
Watch) respectiv Debug Watches Delete Watch sau Del.
Prin Debug Watch Edit watch se poate indica alt variabil de urmrit
editnd numele uneia din supravegherile deja stabilite (sau direct Enter dup poziionarea
dorit n fereastra Watch).
Se elimin toate supravegherile prin Debug Watches Remove All Watches.

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 5

1.8. Alte comenzi folosite la depanare


(a) Debug Call Stack
se afieaz toate funciile care i ateapt terminarea execuiei n punctul
respectiv din program (inclusiv valorile parametrilor cu care au fost apelate);
cea mai recent apelat funcie apare prima;
dup selectarea unei funcii cu tastele Up, Dn (este scoasa n eviden), prin Enter
se defileaz n fereastra Edit pn la ultima linie executata din funcia respectiv;
comanda lucreaz i cu funcii din module compilate separat
(b) Search Locate Function
se indica funcia (numai numele, fr paranteze) a crei definiie s se caute (la
depanare) n fereastra de editare;
comanda Search->Find ar cuta i apelurile funciei, nu direct definiia
(c) Run:Program reset (Ctrl-F2)
se oprete depanarea, se elibereaz memoria alocata programului i se nchid
fiierele eventual deschise de ctre acesta;
se elibereaz i o parte din memorie folosit pentru informaiile de depanare
Erorile tipice sunt: depirea limitelor pentru tablouri sau bucle (out-of-bounds
errors), ncurcarea adreselor cu valorile de la acele adrese, plasarea incorecta a
operatorilor de incrementare/decrementare.

2. Erori importante
2.1. Out of memory
Borland C++ scrie pe disc numai fiierele OBJ rezultate, nu i structurile
intermediare. Toate lucrrile fcndu-se n RAM poate aprea un asemenea mesaj la
compilare dac nu este suficient memorie disponibil. Soluia n acest caz este: fie
micorarea funciilor componente, fie divizarea fiierului iniial n mai multe fiiere ce vor fi
compilate separat i apoi reunite intr-un fiier proiect, fie eliminarea eventualelor programe
rezidente.
2.2. Erori la execuie
(a) Abnormal program termination
Aceasta eroare apare cnd nu este suficient memorie pentru execuia programelor
sau dup apelarea funciei abort(). Eroarea mai poate proveni i datorit suprascrierii
memoriei (alterarea ei prin folosirea incorect a pointerilor). Ignorarea avertismentelor
despre folosirea pointerilor nainte de a fi iniializai sau greelile n alocarea memoriei ori
depirea limitelor tablourilor pot avea efecte dezastruoase mai ales dac nu se face o
testare serioasa a programelor i se trage pripit concluzia ca "merge i aa ... ".
7

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 5

(b) Divide error


Mesajul apare la mprirea unui numr ntreg prin 0 (dac nu se captureaz
tratarea erorii prin funcia signal()). Borland C++ apeleaz funcia abort() i se termin
programul.
(c) Floating point error : divide by 0
: Domain
: Overflow
Aceste erori apar atunci cnd rezultatul unei operaii n virgul mobila nu este finit.
divide by 0
Domain

- mprirea unui numr real la 0 (-INF sau +INF)

- operaie 0.0/0.0 (NAN - not a number)

Overflow - depirea (+INF sau -INF - pierderea total a preciziei)


(d) Floating point error : Partial loss of precison
: Underflow
Erorile de acest tip sunt implicit mascate (pot fi activate prin funcia _control87()),
depirile inferioare fiind convertite n 0.
(e) Floating point error : Stack fault
n acest caz nseamn c stiva pentru operaiile n virgul mobil a fost depit.
(f) Null pointer assignment
La terminarea unui program n modelele de memorie SMALL sau MEDIUM, se
verific dac primii octei din segmentul de date al programului au fost modificai (ceea ce
ar fi normal). Dac se gsete vreo modificare, se afieaz acest mesaj pentru a semnala
c (cel mai probabil) o valoare a fost memorata la un pointer neiniializat. Chiar dac
programul n cauza pare s funcioneze corect, este obligatoriu s se detecteze i s se
corecteze eroarea, altfel putndu-se ajunge la un comportament imprevizibil al
programului (fiind posibil chiar blocarea calculatorului n modelele de memorie
COMPACT, LARGE sau HUGE).

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 5

(g) Stack overflow


Mrimea implicit a stivei este de 4096 de octei. Programele cu funcii recursive
sau cu date locale de mari dimensiuni pot depi acest prag (activarea verificrii stivei se
face prin selectarea opiunii Options | Compile | Code generation | Test stack overflow).
Pentru depirea acestei situaii exist trei posibiliti :
se trece la un model de memorie mai mare
se mrete dimensiunea stivei, dat de variabila global _stklen (definita n
DOS.H) nainte de apelarea funciei main() astfel:
extern unsigned _stklen = 20000; //pentru 20000 de octei
se micoreaz solicitrile asupra stivei prin folosirea de variabile statice.
Dezavantajul acestei variante este faptul ca funcia n cauza nu mai poate fi reentrant.
Dac funcia este apelat recursiv i trebuie ca fiecare apel al funciei sa aib copia sa
unic a variabilei, variabila nu poate fi fcut static (s-ar folosi la fiecare apel aceeai
zon de memorie n loc s se aloce spaiu nou de fiecare dat).

TEMA 1

Problema 1.1
S se scrie un program care calculeaz suma i produsul a dou matrice A i B.
Elementele matricelor sunt numere ntregi. Se vor scrie funcii pentru: citirea unei matrice
de la tastatur, afiarea unei matrice pe monitor (n formatul cunoscut de la matematic
pe linii), calculul sumei a dou matrice i calculul produsului a doua matrice. Matricele nu
sunt neaprat ptratice. Alegerea operaiei (suma sau produs de matrice) se va face de
ctre utilizator la rularea programului. Pentru fiecare din cele dou operaii trebuie fcut
validarea dimensiunilor matricelor astfel nct operaia s poat fi fcut.
Problema 1.2
S se scrie o funcie care calculeaz transpusa unei matrice ptratice. Se vor afia
matricea iniial i cea transpus.
S se verifice relaia:
(A B)T = BT AT
unde A, B sunt matrice ptratice, iar AT este transpusa matricei A. Se vor afia cele dou
matrice, transpusele lor, precum i cei doi membri ai egalitii.
Problema 1.3
Pentru o matrice ptratic cu elemente numere reale se definesc urmtoarele norme:

PROGRAMAREA CALCULATOARELOR

= max aij

(maximul sumelor de pe fiecare coloan)

(maximul sumelor de pe fiecare linie)

A 1 = max aij
A

LUCRAREA NR. 5

i , j =1

2
ij

unde x definete modulul numrului real x.


S se calculeze normele definite mai sus. Se va realiza un dialog prin care s se
aleag opiunea de prelucrare. Programul va fi realizat astfel nct s permit prelucrarea
mai multor seturi de date.
Problema 1.4
Se citete o matrice A de dimensiune n n, cu n 20 (se va face validarea
dimensiunii n).
Matricea poate fi prelucrat (alegerea este a utilizatorului) astfel nct:
a) elementele de pe prima linie s fie n ordine cresctoare
b) elementele de pe prima coloan s fie n ordine cresctoare
c) elementele de pe diagonala principal s fie n ordine cresctoare
Se va lua n considerare posibilitatea relurii programului cu alte date de test.
Trebuie scrise funcii pentru: citire matrice, afiare matrice, interschimbare a dou linii
din matrice, interschimbare a dou coloane dintr-o matrice, cte o funcie pentru fiecare
opiune de sortare. Cele dou funcii de interschimbare vor primi ca parametri matricea,
dimensiunea matricei, i cei doi indeci ai liniilor, respectiv coloanelor care se
interschimb.

TEMA 2

Problema 2.1
P2.1.a. S se deduc relaii de recuren pentru calcularea urmtoarelor matrice:

Ti =
Bn =

Ai
, cu T0 = I n (unde A este o matrice ptratic de ordin n).
i!
n

T
i =0

, cu B0 = I n

(1)

I n este matricea unitate de dimensiune n.


P2.1.b. S se scrie un program care
1). citete de la tastatur o matrice A de numere reale i de dimensiune n (cu n linii
i n coloane), cu n 20 i afieaz matricea citit.

10

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 5

2). Calculeaz matricea B cu expresia dat de relaia (1)


3). Afieaz matricea B calculat la punctul 2).
Programul va fi astfel construit nct s poate fi introduse mai multe seturi de date, iar
valoarea dimensiunii n citite de la tastatur va trebui validat (dac n 0 sau n 20 se va
afia un mesaj de eroare i se va cere o nou valoare (corect)).
Date de test:
1 2 3
A = 4 5 6
7 8 9

95 116 138
B = 214 264 312
334 410 487

A=

B=

0
7
0

11 - 3 24 - 15
1.2965e + 004 2.6409e + 004
1.9550e + 004 3.9034e + 004
1 5 9
0 3 14
21 43 17

4.3914e + 004 9.6555e + 004


2.5745e + 004 4.9372e + 004

2.2184e + 004 2.4646e + 003


3.7497e + 004 4.2440e + 003
7.9225e + 004 1.3801e + 004

3.4299e + 004 5.1896e + 002

Barem de notare:
1. Citire i validare dimensiune matrice

0,5

2. Citire matrice

1,0

3. Afiare matrice

1,0

4. Calcul matrice B

1,0

4a). Adunarea a dou matrice

1,0

4b). nmulirea a dou matrice

1,5

4c). nmulirea unei matrice cu un scalar

1.0

5. posibilitatea de reluare a programului

1,0

6. Folosire proiect

0,5

7. Folosire fiier header

0,5

8. Funcia main

1,0

TOTAL

10 p

11

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 5

Problema 2.2
Un teren de form dreptunghiular este mprit n parcele, dispuse pe n rnduri, pe
fiecare rnd fiind m parcele. Se msoar altitudinea fiecrei parcele (se consider c o
parcel are altitudine constant). Altitudinile tuturor parcelelor se memoreaz ntr-un
tablou cu n linii i m coloane. Valoarea elementului de pe linia i i coloana j a tabloului
este altitudinea celei de a j-a parcele de pe linia i.
S se afieze coordonatele parcelelor vrf. O parcel vrf are altitudinea strict mai
mare dect a tuturor vecinilor si.
Se va lua n considerare posibilitatea prelucrrii mai multor seturi de date, la aceeai
rulare a programului.

Problema 2.3
Se d o matrice ptratic de ordin n. Se consider c diagonalele mpart matricea n
patru zone: nord, sud, est, vest (elementele de pe diagonale nu fac parte din nici o zon).
S se afieze matricea citit.
S se calculeze suma elementelor din nord, produsul elementelor din sud, media
aritmetic a elementelor din est i media geometric a elementelor din vest.
S se determine imaginea n oglind a matricii iniiale i s se afieze.
Se va lua n considerare posibilitatea prelucrrii mai multor seturi de date, la aceeai
rulare a programului.

Problema 2.4
S se scrie un program care creeaz un ptrat magic de dimensiune prestabilit. Un
ptrat magic (de latur n) are proprietatea c include n locaiile sale toate numerele ntregi
din intervalul 1 ... n2, iar sumele numerelor de pe fiecare linie, fiecare coloana sau fiecare
diagonala sunt egale.
De exemplu, pentru n = 3, ptratul magic este:
6 1 8
7 5 3
2 9 4
Pentru crearea unui ptrat magic (de dimensiune impar!) se va folosi regula lui H.
Coxeter: se pornete cu 1 n mijlocul primei linii, apoi se merge la fiecare pas cu o linie n
sus i cu o coloana la stnga, scriind numerele n ordine cresctoare n locaiile libere. De
pe prima linie se va trece pe ultima, din prima coloan n ultima. Dac locaia ce ar urma
n acest mod este deja ocupat, se trece la cea situat cu o linie n jos (pe aceeai
12

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 5

coloan, sub elementul curent). Se vor afia att ptratul rezultat ct i toate sumele ce ar
trebui sa coincid.

13

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 6

OPERATORI PENTRU LUCRU LA NIVEL DE BIT

Operatorii de deplasare << i >> ...........................................................................................2


Operatorul & (I)....................................................................................................................3
Operatorul | (SAU) .................................................................................................................4
Operatorul ^ (SAU EXCLUSIV XOR)..................................................................................5
Operatorul unar ~...................................................................................................................5
TEMA .....................................................................................................................................5
Problema 1 .........................................................................................................................5
Problema 2 .........................................................................................................................6
Problema 3 .........................................................................................................................6
Problema 4 .........................................................................................................................6
Problema 5 .........................................................................................................................7
Problema 6 .........................................................................................................................7
Problema 7 .........................................................................................................................8

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 6

OPERATORI PENTRU LUCRU LA NIVEL DE BIT


Limbajul C ofer un numr de operatori pentru lucrul la nivel de bit. Aceti operatori
se aplic numai variabilelor de tip int i char i conduc la expresii ale cror rezultate
depind de reprezentarea intern a ntregilor i au caracteristici care depind de
implementarea tipurilor cu semn.
Operatorii binari de lucru la nivel de bit sunt:
<<

deplasare stnga cu un anumit numr de bii

>>

deplasare dreapta cu un anumit numr de bii

&

I (AND) la nivel de bit;

SAU EXCLUSIV (XOR) la nivel de bit;

SAU (OR) la nivel de bit.

n afar de aceti operatori binari, limbajul ne mai pune la dispoziie un operator unar
care permite determinarea complemetului fa de 1 al operandului. Acest operator este ~
i are aceeai prioritate ca i ceilali operatori unari existeni n limbaj.
Operatorii &, ^ i | sunt folosii, de obicei, pentru a realiza operaiile dorite asupra
primului operand n conformitate cu o configuraie de bii indicat de cel de-al doilea
operand. Din acest motiv, de foarte multe ori, cel de al doilea operand mai este numit i
masc pentru c nu face dect s mascheze anumii bii din primul operand. Aceti
operatori se aplic fiecrui bit din reprezentarea intern (binar, n virgul fix) a
numrului.
Operatorii de deplasare << i >>
<< Deplaseaz la stnga numrul din stnga operatorului cu un numr de poziii egal
cu numrul existent n dreapta operatorului.
Exemplu: rezultatul expresiei
n << 3
este valoarea numrului n deplasat cu 3 (trei) poziii la stnga.
Deplasarea la stnga completeaz poziiile rmase libere cu zerouri. Deplasarea cu
o poziie a numrului n este echivalent cu o nmulire cu 2 a valorii iniiale a numrului n
i n exemplu dat (n<<3) expresia este echivalent cu n * 2 * 2 * 2.
>> Deplaseaz la dreapta numrul din stnga operatorului cu un numr de poziii
egal cu numrul existent n dreapta operatorului.
2

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 6

Exemplu: rezultatul expresiei


n >> 3
este valoarea numrului n deplasat cu 3 (trei) poziii la dreapta.
Deplasarea spre dreapta completeaz poziiile rmase libere cu o extensie a
semnului (dac numrul este pozitiv, completarea se face cu zero; dac numrul este
negativ completarea se face cu 1). Deplasarea la dreapta cu un bit (o poziie) este
echivalent cu o mprire la 2 a numrului iniial. Astfel n exemplul considerat expresia
n>>3 este echivalent cu expresia n/(2*2*2).
n cazul n care considerm n fiind un ntreg reprezentat pe 2 octei (de tip short int)
i a crui valoare este 38, reprezentarea sa intern este urmtoarea:
15 14 13 12 11 10 9
0 0 0 0 0 0 0

8
0

7
0

6
0

5
1

4
0

3
0

2
1

1
1

0
0

Dup deplasarea cu trei poziii la stnga, coninutul celor doi octei asociai variabilei
n are urmtoarea reprezentare binar:
15 14 13 12 11 10 9
0 0 0 0 0 0 0

8
1

7
0

6
0

5
1

4
1

3
0

2
0

1
0

0
0

Rezultatul deplasrii spre dreapta cu trei poziii a valorii iniiale a variabilei n are
urmtoarea reprezentare binar:
15 14 13 12 11 10 9
0 0 0 0 0 0 0

8
0

7
0

6
0

5
0

4
0

3
0

2
1

1
0

0
0

Operatorul & (I)


Lucreaz dup urmtorul tabel de adevr:
&

i este folosit pentru a pune pe zero (a reseta) anumii bii din variabila luat n considerare
(biii respectivi se terg). Datorit acestui mod de lucru, folosirea operatorului & permite
scoaterea n eviden a biilor care ne intereseaz.
Exemple:
a). c = n & 0100;
pune pe zero toi biii lui n mai puin bitul 6 (numerotarea ncepe de la 0 (zero) i din
dreapta) care rmne la valoarea iniial.

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 6

n = 6710 = 26 + 21 + 20 = 010000112 = 01038


c = n & 01008 = 01038 & 01008 = 01008
b). c = n & 01774008 = n & 11111111
1424
3 00000000
1424
3 2;
octet superior

octet inferior

face octetul inferior egal cu zero, cel superior rmne neschimbat;


c). c = n & 03778 = n & 00000000
1424
3 2;
1424
3 11111111
octet superior octet inferior

face octetul superior egal cu zero, cel inferior rmnnd la fel ca n n.

Operatorul | (SAU)
Lucreaz dup urmtorul tabel de adevr:
|

i este folosit pentru a pune pe 1 (unu) (a seta) toi biii care au valoarea 1 n "masc".
Exemplu:
z = x | MASK;
x = 6610; MASK = 0118;
z = 6610 | 0118 = 01028 | 0118 = 01138 = 7510
x = 6610; MASK = 0778;
z = 6610 | 0778 = 01028 | 0778 = 01778 = 12710
x = 6610; MASK = 6810;
z = 6610 | 6810 = 01028 | 01048 = 010000102 | 010001002 = 010001102 =
01068 = 7010
Operatorii pe bii & i | sunt diferii de operatorii logici && i ||. Operatorii logici
implic o evaluare de la stnga la dreapta a valorii de adevr a expresiilor implicate, pe
cnd operatorii care lucreaz pe bit execut operaiile ca n algebra Boolean.
Exemplu: x = 1; y = 2 x&y = 0, pe cnd x&&y = 1.

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 6

Operatorul ^ (SAU EXCLUSIV XOR)


Lucreaz n conformitate cu tabelul de adevr urmtor:
^

Operatorul unar ~
Aplicarea acestui operator are ca rezultat complementul fa de 1 al operandului (biii
egali cu zero devin unu i cei egali cu unu devin zero).
Exemplu, n instruciunea:
x = x & ~077;
este folosit pentru complementarea valorii octale 077 i astfel putem realiza resetarea
(punerea pe zero) a ultimilor 6 bii ai lui x.
Exemple:
a).

x = 6610

i ~077 = 1111111111000000 = 1777008, deci

x = 6610 & ~077 = 01028 & 1777008 = 01008


b)

~1234 = ~00000100110100102 = 11111011001011012 = 01754558


~-1234 = ~ 11111011001011102 = 00000100110100012 = 023218
-~1234 = -11111011001011012 = 0000010011010011 = 023238

TEMA
n cele ce urmeaz se vor folosi numai operatori de lucru pe bit pentru toate
operaiile cerute.
Se consider c bitul cel mai semnificativ al unui numr este bitul din stnga,
iar cel mai puin semnificativ este cel din dreapta.
Problema 1
S se scrie o funcie care are ca parametri un numr ntreg i un numr real i
returneaz un numr real i care realizeaz ridicarea unui numr oarecare la o putere
ntreag, folosind urmtorul algoritm cu aplicarea operatorilor de lucru pe bit:
Observaie: orice numr ntreg se poate exprima n baza 2.
De exemplu 2310 = 101112 = 24 + 22 + 21 + 20.
Pentru ridicarea unui numr a la puterea 23 se poate face urmtorul calcul:
a23 = a(16 + 4 + 2 + 1) = a16 a4 a2 a1
5

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 6

Ca urmare, pentru ridicarea unui numr la o putere ntreag trebuie s se genereze


un ir care va include valorile a avnd ca exponeni puteri ale lui 2, adic trebuie s se
genereze urmtorul ir:
a, a2, a4, a8, a16, a32, ..
Termenii acestui ir se genereaz printr-un numr relativ mic de operaii, astfel:
f = a;
f = f * f;
innd cont de observaia de mai sus, an se poate calcula fcnd apel la termenii
acestui ir, alegndu-i numai pe aceea ai cror exponeni nsumai dau puterea n. Pentru
aceasta se face operaia n&1, i dac rezultatul este 1, primul termen este a. Se
deplaseaz n spre dreapta cu o poziie. Dac n&1=1, se selecteaz a2, s.a.m.d.
S se scrie un program care citete un numr real i un numr ntreg i afieaz
rezultatul ridicrii numrului real la numrul ntreg.
Problema 2
S se scrie un program care realizeaz rotirea la dreapta sau la stnga (n funcie de
opiunea utilizatorului) cu un anumit numr de bii a unui numr ntreg lung.
Se vor scrie funcii de rotire dreapta, rotire stnga, i afiare bit cu bit.
Problema 3
S se scrie un program care determin paritatea unui numr ntreg lung citit de la
tastatur i nscrie n bitul cel mai semnificativ 1 sau 0 dup cum numrul biilor de 1 din
ceilali 31 de bii este impar sau par. De asemenea, operatorii de lucru pe bit se vor folosi
pentru a determina dac un numr este par sau nu (cum?). Se va afia numrul iniial i
reprezentarea binar a numrului cu paritatea setat.
Problema 4
S se scrie o funcie care folosind numai operatori de lucru pe bit calculeaz
valoarea n octal a unui numr ntreg primit ca parametru i o depune ntr-un ir de
caractere primit ca al doilea parametru. Numrul octal este reprezentat ntr-un ir de
caractere (care este al doilea parametru al funciei) i este precedat de caracterul 0. Se va
ine seama de faptul c o cifr octal poate fi reprezentat pe 3 bii.
S se scrie o funcie care folosind numai operatori de lucru pe bit calculeaz
valoarea n hexazecimal a unui numr ntreg primit ca parametru i o depune ntr-un ir de
caractere primit ca al doilea parametru. Numrul hexazecimal este reprezentat ntr-un ir

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 6

de caractere (care este al doilea parametru al funciei) i este precedat de caracterele 0x.
Se va ine seama de faptul c o cifr hexazecimal poate fi reprezentat pe 4 bii.
S se scrie un program care citete de la tastatur un ntreg fr semn i folosind
cele dou funcii de mai sus, afieaz reprezentarea hexazecimal sau octal a numrului.
Opiunea de afiare este dat de utilizator.
Problema 5
P5.1. S se scrie un program care folosete numai operatorii de lucru la nivel de bit
pentru a realiza mpachetarea unei date calendaristice ntr-un ntreg de doi octei (astfel
biii 0-4 reprezint ziua, biii 5-8 reprezint luna, biii 9-15 reprezint anul numrat de la
1900) i afiarea reprezentrii binare a rezultatului.
ATENIE: NU se folosesc vectori.
Se va defini tipul de dat WORD ca sinonim pentru ntreg scurt fr semn.
Data se citete sub forma: zz/ll/aaaa i se memoreaz ntr-o structur de forma:
struct DATA {
WORD zi, luna, an;
};
Se vor scrie obligatoriu funcii pentru: mpachetare dat, afiare binar.
P5.2. S se scrie o funcie care primete ca parametru o dat mpachetat (ca mai
sus) i returneaz o structur de tip DATA. Funcia extrage informaiile din data
mpachetat i le nscrie n structura considerat
Problema 6
S se scrie un program care determin i afieaz toate numerele prime inferioare
unui numr dat (prestabilit), folosind ciurul lui Eratostene. Metoda const din eliminarea
succesiv a numerelor neprime prin parcurgerea urmtorilor pai:
1. Se elimina numrul 1 (prin definiie nu este prim).
2. Apoi se caut (pornind de la ultimul numr prim considerat - iniial 1) primul numr
neeliminat (acesta este prim) i se elimina toi multiplii si (din intervalul 1-n).
3. Se repet pasul 2 pn cnd numrul prim considerat este mai mare dect sqrt(n)
adic radical din n. Funcia sqrt are prototipul n math.h.
Pentru rezolvare nu se vor folosi vectori, fiecrui numr natural fiindu-i asociat un bit
a crei valoare este 1 dac numrul este prim i 0 dac numrul nu este prim.

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 6

Problema 7
S se scrie o funcie care, folosind numai operatori de lucru pe bit, verific dac un
numr natural este o putere a lui 2 (un numr natural este o putere a lui 2 dac, n
reprezentare binar, numrul are exact un bit egal cu 1). Funcia primete ca parametru
numrul de analizat i returneaz 1 sau 0 dup cum numrul este sau nu putere a lui 2.
(NU se vor folosi operatorii aritmetici "/" sau "%").
S se scrie o funcie care, folosind numai operatori de lucru pe bit, inverseaz cei doi
octei ai unui numr ntreg reprezentat pe doi octei. Funcia primete ca parametru un
numr ntreg i returneaz numrul cu octeii inversai. (NU se vor folosi operatorii
aritmetici "/" sau "%").
S se scrie o funcie care primete ca parametri un vector de ntregi i dimensiunea
acestui vector. Funcia asociaz fiecrui element din vector un bit dintr-un ntreg i pune
bitul respectiv pe 1 dac elementul are o valoare par i pe 0 dac elementul respectiv are
o valoare impar i returneaz numrul astfel construit. (NU se vor folosi operatorii
aritmetici "+", "-", "*", "/" sau "%").
S se scrie un program care face una din prelucrrile de mai sus, n funcie de
alegerea utilizatorului.

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 7

DIRECTIVELE PREPROCESORULUI ..................................................................................2


1. Directive preprocesor.........................................................................................................2
1.1. #define i #undef .........................................................................................................2
1.2. #include .......................................................................................................................5
1.3. Compilarea condiionat..............................................................................................5
1.4. #error mesaj_de_eroare ..............................................................................................7
1.5. #pragma.......................................................................................................................7
TEMA .....................................................................................................................................7
Problema 1 ........................................................................................................................7
TIPURI COMPLEXE DE DATE STRUCTURI ....................................................................8
1. Declaraia i definiia unei structuri ....................................................................................8
1.1. Declaraia unei structuri...............................................................................................8
1.2. Definiia unei structuri ..................................................................................................9
2. Operaii cu structuri............................................................................................................9
2.1. Iniializarea...................................................................................................................9
2.2. Accesarea membrilor.................................................................................................10
2.3. Copierea unei structuri ..............................................................................................10
2.4. Structuri i funcii .......................................................................................................11
TEMA ...................................................................................................................................13
Problema nr. 1 ..................................................................................................................13
Problema nr. 2 ..................................................................................................................15
Problema nr. 3 ..................................................................................................................16

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 7

DIRECTIVELE PREPROCESORULUI
DIRECTIVELE PREPROCESORULUI ..................................................................................2
1. Directive preprocesor.........................................................................................................2
1.1. #define i #undef .........................................................................................................2
1.2. #include .......................................................................................................................5
1.3. Compilarea condiionat..............................................................................................5
1.4. #error mesaj_de_eroare ..............................................................................................7
1.5. #pragma.......................................................................................................................7
TEMA .....................................................................................................................................7
Problema 1 ........................................................................................................................7
Compilatoarele C clasice erau de tip multi-pass: la prima parcurgere a textului surs
se includ fiierele necesare, se testeaz directivele de compilare condiionata, se
expandeaz macrourile producndu-se un fiier intermediar ce va fi folosit n paii
urmtori. Mediile de programare folosite n prezent folosesc un compilator single-pass, dar
se ofer un preprocesor (CPP.EXE) independent, cu rolul descris mai sus, ce poate fi
folosit pentru depanarea programelor (va crea un fiier cu acelai nume cu fiierul surs,
dar cu extensia ".i"). Orice linie sursa care ncepe cu caracterul `#' este considerat o
directiv

preprocesor (cu condiia s nu fac parte dintr-un comentariu sau ir de

caractere). Caracterul # poate fi precedat sau urmat de spaii (nu i de new line).

1. Directive preprocesor
1.1. #define i #undef
Aceasta directiv asociaz unui identificator o constant, un cuvnt cheie, o
expresie sau o instruciune uzual. Identificatorii care reprezint constante se numesc
constante simbolice. Identificatorii care reprezint expresii sau instruciuni se numesc
macrodefiniii (sau macro-uri). Un nume de identificator odat definit, poate fi folosit n
tot programul cu valoarea dat iniial sau poate fi redefinit ori de cte ori este necesar.
Definirea se termin la apariia directivei #undef sau la sfritul fiierului surs.
Directiva #define poate fi utilizat cu sau fr parametri.
(a) Fr parametri folosit n special pentru definirea constantelor simbolice
#define nume_id <text>
Modul de lucru: fiecare apariie a identificatorului nume_id n codul surs ulterior
directivei, va fi nlocuit cu <text> (care poate fi i un ir vid). Este aa numita expandare
a macrodefiniiei. Expandarea nu se face n interiorul irurilor de caractere, al constantelor

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 7

caracter sau al comentariilor. Dup fiecare expandare individual, se face o parcurgere


suplimentar a textului rezultat (care la rndul sau poate s conin macrodefiniii - nested
macros - ce vor fi expandate corespunztor). Nu se aplic i n cazul unor rezultate care
arat ca o directiv preprocesor:
#define G #include <stdio.h.>
...
G
linia #include <stdio.h>, care nlocuiete pe G la prima expandare, nu va mai fi expandat,
ci transmis direct compilatorului, rezultnd o eroare;
Observaie: macrodefiniia nu poate fi expandata n cursul propriei expandri (altfel
#define A A continu la infinit).
Perechea directivei #define este
#undef nume_id
La ntlnirea acestei directive, nume_id va fi ters din tabelul de simboluri
nemaificurnd ca fiind definit. Dup aceast directiv nume_id poate fi redefinit.
Caracterul ';' nu apare la sfritul directivelor preprocesor (ar fi inclus ca atare la
expandare).
Exemplu:
#define MAX 20
int main(void)
{
.....
#define MAX 40
.....
#define MAX 80
.....
#undef MAX //constanta MAX nu mai este definit
.....
#define MAX 1000
.....
}
(b) Cu parametri. Forma general este:
#define nume_macro(<lista_de_parametri>) <text>

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 7

Observaie: nu apare spaiu ntre nume_macro i parantezele ce ncadreaz lista de


parametri;
Aceast macrodefiniie se apeleaz astfel:
nume_macro(<lista_de_parametri_efectivi>)
Dac numrul parametrilor n cele dou liste (definire i apel) difer, se va produce o
eroare de compilare.
Apelul unei de macrodefiniii este asemtor cu cel al unei funcii i la apel se
realizeaz urmtoarele operaii:
1. nume_macro i lista_de_parametri sunt nlocuite cu text (secvena de
simboluri).
2. parametrii formali din text sunt nlocuii cu parametrii reali corespunztori din
lista_de_parametri_efectivi.
Macrodefiniiile se folosesc pentru:
a) nlocuirea funciilor foarte scurte (ca timp de execuie i volum de cod
generat).
Exemplu:
#define CUB(X) ((x)*(x)*(x))
...
n = CUB(y); /* va fi expandat n n = ((y)*(y)*(y)); */
Dac parantezele din definiie lipsesc se produc efecte nedorite la expandare.
Exemplu:
#define CUB(X) (x*x*x)
...
n = CUB(y+1); /* va fi expandata n n = (y+1*y+1*y+1); */
b) concatenarea a dou simboluri prin folosirea caracterelor ##.
Exemplu:
#define VAR(i,j) (i##j)
...
VAR(x,6); /* va fi expandat n (x6) */
Caracterul # plasat naintea unui parametru formal va converti parametrul efectiv ntrun ir de caractere dup nlocuire. Exemplu:
#define TRACE(f) printf(#f"=%d\n",f)
...

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 7

TRACE(x); /*printf("x""=%d\n",x); echivalent cu printf("x=%d\n",x);*/


O secvena foarte lung poate depi o linie dac se ncheie

cu '\'. Apelurile

macrodefiniiilor NU permit verificarea tipurilor parametrilor. Efectul secundar (side effect)


cel mai periculos poate apare atunci cnd argumentul real se evalueaz de mai multe ori
i n apel se folosesc operatorii de incrementare /decrementare.
d = CUB(a++); /* se expandeaz ca ((a++)*(a++)*(a++)) */
Spre exemplu pentru x=5, CUB(x++) va fi calculat 5*6*7=210, iar CUB(++x) va fi
calculat 6*7*8=336
1.2. #include
Pentru includerea fiierelor antet (header) n codul surs se poate folosi una din
formele:
#include <header_name>
#include "header_name"
#include nume_macro cu condiia ca dup expandare s se obina una din
primele forme
Preprocesorul elimina linia #include, nlocuind-o (din punctul de vedere al
compilatorului) cu ntregul coninut al fiierului antet, n punctul respectiv din codul surs.
Dac se folosete forma cu semnele < >, se va cuta fiierul n directoarele INCLUDE
(stabilite ca opiune n Options Directories sau indicate prin -I la folosirea compilatorului
linie de comand bcc), n ordinea n care sunt definite. Dac se folosete forma cu
ghilimele " ", se caut nti n directorul curent i apoi (daca nu este gsit) n directoarele
INCLUDE. Aceast ultim variant se folosete pentru includerea fiierele antet proprii
(scrise de programator).
Atenie: ntre ghilimele este bine s se treac toata calea pn la fiierul respectiv, n
cazul n care acesta nu se afla n directorul curent, sau calea spre directoarele n care se
gsesc fiierele header s se treac n Options Directories Include Directories
1.3. Compilarea condiionat
Directivele pentru compilare condiionat controleaz compilarea diferitelor poriuni
de program. Pot avea formele:
a).
#if test1
secventa_1;

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 7

[#elif test2
secventa_2;]
[#elif test3
secventa_3;]
....
[#else
secventa_n;]
#endif
Fiecare test trebuie sa fie o expresie constant. Se testeaz mai nti test1. Dac
este adevrat se selecteaz secvena_1. Dac nu, se selecteaz testul adevrat i se
executa secvena care i corespunde . Dac nici un test nu este adevrat se selecteaz
secvena din #else. Dac nu exist se trece la prima directiv sau instruciune dup
#endif.
Exemplu:
#if 0
...
#endif
Se sare peste partea de program scris ntre aceste doua directive, deci are rol de
comentariu.
b)
#ifdef identificator
#ifndef identificator
Se testeaz dac un identificator a fost definit anterior sau nu (fie i NULL) i se
execut secvena pn la primul #endif
Exemplu de folosire:
#ifdef MAX
...
#endif
sau
#ifndef MAX
...
#endif

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 7

c)
#if defined(m)
#endif
Este identic cu #ifdef m, dar are avantajul ca se poate folosi de mai multe ori intr-o
expresie.
Exemplu:
#if defined(m) && !defined(y)
#endif
1.4. #error mesaj_de_eroare
Directiva duce la terminarea compilrii cu mesajul:
Error: filename line#: :Error directive: mesaj_de_eroare
1.5. #pragma
Aceste directive au forme diferite de la compilator la compilator astfel nct trebuie
consultat documenatia fiecruia din ele pentru a afla opiunile specifice.
n cazul compilatorului BorlandC 3.1 poate avea una din urmtoarele opiuni:
(a) argused
Este permis ntre definiiile funciilor, afectnd-o numai pe urmtoarea creia i
inhib eventualul avertisment:
parameter name is never used in function func_name
(b) startup/exit
Se pot specifica funcii care sa fie apelate (la execuie) nainte de apelarea funciei
int main(void), respectiv dup terminare prin apelarea funciei exit().
#pragma startup nume_functie <prioritate>
#pragma exit nume_functie <prioritate>
Funciile trebuie s fie anterior definite, s fie fr argumente i s nu furnizeze
rezultat, adic s fie de tip void, (prototipul lor trebuie s fie: void nume_fct(void);).
Prioritatea este un numr ntre 64 i 255 (64 - maxim; implicit 100).
TEMA
Problema 1
S se scrie trei macrodefiniii pentru determinarea maximului, minimului, respectiv
testarea egalitii dintre dou numere ntregi.

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 7

TIPURI COMPLEXE DE DATE STRUCTURI


TIPURI COMPLEXE DE DATE STRUCTURI ....................................................................8
1. Declaraia i definiia unei structuri ....................................................................................8
1.1. Declaraia unei structuri...............................................................................................8
1.2. Definiia unei structuri ..................................................................................................9
2. Operaii cu structuri............................................................................................................9
2.1. Iniializarea...................................................................................................................9
2.2. Accesarea membrilor.................................................................................................10
2.3. Copierea unei structuri ..............................................................................................10
2.4. Structuri i funcii .......................................................................................................11
TEMA ...................................................................................................................................13
Problema nr. 1 ..................................................................................................................13
Problema nr. 2 ..................................................................................................................15
Problema nr. 3 ..................................................................................................................16
O structur este o colecie de una sau mai multe variabile (de acelai tip sau de tipuri
diferite) grupate sub un singur nume. Variabilele care fac parte din structur se numesc
membrii structurii respective. Membrii unei structuri pot fi tipuri de date simple (int, float,
etc), tipuri de date agregate (tablouri, alte tipuri de structuri) sau pointeri (la diverse tipuri
de date, inclusiv pointer la acelai tip de structur structuri autoreferite).

1. Declaraia i definiia unei structuri


1.1. Declaraia unei structuri
Forma general a declaraiei unei structuri este:
struct NUME_STRUCTUR {
declaraii de date;
};
i cuprinde:
Cuvntul cheie struct
Numele modelului (prototipului) structurii NUME_STRUCTUR
Descrierea membrilor structurii respective. Forma general a membrilor unei
structuri este

tip nume;

tip nume[dim1][dim2][dimn];

sau

Prin aceast descriere se indic "prototipul" (modelul) structurii respective, nu se


rezerv zon de memorie i aceast declaraie poate apare ntr-un fiier header.

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 7

O structur se poate declara i fr indicarea componenei sale, adic putem scrie:


struct NUME_STRUCTUR;
urmnd ca descrierea s se fac ulterior, nainte de prima definire a unei variabile al crui
tip este structura respectiv.
Declaraia unei structuri va apare n fiierul header nainte oricror referiri la tipul de
structur respectiv (de exemplu, naintea specificrii prototipurilor funciilor care folosesc
ca parametru sau ca valoare de retur o structur de tipul specificat).
1.2. Definiia unei structuri
Are rolul de a rezerva zon de memorie pentru variabilele de tip structur forma
general este:
struct [NUME_STRUCTUR] {
declaraii de date;
} v1, v2[10], , vn;
unde v1, v2, , vn sunt variabile de tipul NUME_STRUCTUR. Aici [] indic faptul c
partea respectiv din definiie poate s lipseasc.
n cazul n care structura a fost declarat anterior, definirea unor variabile de tip
structur se face n forma:
struct NUME_STRUCTUR v1, v2[10], , vn;
Definiia unei structuri nu poate apare ntr-un fiier header.
2. Operaii cu structuri
2.1. Iniializarea
Forma general pentru iniializarea unei structuri este:
struct NUME_STRUCTUR variabila_structura = {val1, , valn};
dac structura a fost declarat anterior sau
struct NUME_STRUCTUR {
declaraii de date;
} variabila_structura = {val1, , valn};
dac se face i definirea variabilei de tip structur o dat cu declararea ei. val1, , valn
reprezint valorile de iniializare ale membrilor structurii respective i trebuie s coincid
cu tipul membrului structurii la care se refer.
Exemplu:
Fiind dat o declaraie de structur care descrie o dat calendaristic de forma:
struct DATA {

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 7

int zi;
char luna[15];
int an;
};
Definirea cu iniializare a unei variabile ziDeNastere de tip DATA se face prin:
struct DATA ziDeNastere = {11, "iunie", 1970};
2.2. Accesarea membrilor
Un membru al unei structuri se acceseaz folosind operatorul de selecie . (punct).
Forma general este:
variabila_structura.membru_structura
Lund exemplul de mai sus, afiarea coninutului variabilei de tip structur
ziDeNatere se face astfel:
printf("%d %s %d\n", ziDeNastere.zi, ziDeNastere.luna, ziDeNastere.an);
Observaie:
Atunci cnd un membru al unei structuri este de un tip real (float, double
sau long double) iniializarea prin citire de la tastatur a valorii membrului
respectiv se face folosind o variabil auxiliar, ca n exemplul urmtor:
PUNCT a;
double aux;
scanf("%lf", &aux);
a.x = aux;
2.3. Copierea unei structuri
Este permis copierea unei structuri n alt structur fie membru cu membru (prin
atribuiri aplicate unor variabile simple), fie lund structura ca un ntreg.
Exemplu:
struct DATA zi1 = {25, "martie", 2004};
struct DATA zi2, zi3;
zi2 = zi1;
zi3.zi = zi1.zi;

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 7

dup secvena de cod de mai sus, membrii structurii zi2 vor avea aceleai valori ca i
membrii structurii zi1, iar membrul zi al structurii zi3 va avea aceeai valoare cu membrul
zi al structurii zi1, ceilali doi membri rmnnd cu valori nedeterminate.
2.4. Structuri i funcii
O structur poate fi folosit ca parametru de intrare pentru o funcie i o funcie poate
returna o structur. Modificrile fcute asupra valorii membrilor unei structuri ntr-o funcie
nu se pstreaz i dup ieirea din funcie. O structur se transmite ctre o funcie prin
valoare, prin intermediul stivei.
Exemplu:
Fiind declarat structura urmtoare asociat unui punct din plan
struct _PUNCT {
double x, y;
};
typedef struct _PUNCT PUNCT;
a) s se scrie o funcie care returneaz distana dintre dou puncte;
b) s se scrie o funcie care returneaz punctul simetric fa de origine al unui punct
dat.
a)

double distanta(PUNCT a, PUNCT b)


{
double d;
d = sqrt((a.x b.x) * (a.x b.x) + (a.y b.y) * (a.y b.y));
return d;
}

b)

PUNCT simetric(PUNCT a)
{
PUNCT b;
b.x = -a.x;
b.y = -a.y;
return b;
}

Considernd urmtoarele definiii:


double d;
PUNCT A, B, X, Y;
i c variabilele structur de tip PUNCT A, B, Y sunt iniializate pe parcursul programului,
apelul celor dou funcii se face astfel:

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 7

d = distanta(A, B);
/*
*
*

Calculeaz distana dintre punctele ale cror coordonate


sunt n structurile A i B de tip PUNCT

*/
X = simetric(Y);
/*
*

Membrii variabilei structur X, de tip PUNCT, va conine valorile simetrice

fa de originea axelor de coordonate ale membrilor variabilei structur Y,

de asemenea de tip PUNCT.

*/

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 7

TEMA
Pentru fiecare problem se va construi un proiect cu fiierul header
corespunztor.
Problema nr. 1
Se consider urmtoarea structur asociat unui punct din spaiul bidimensional:
struct _PUNCT {
double x;

// abscisa

double y;

// ordonata

};
i declaraia de tip
typedef struct _PUNCT PUNCT;
Folosind aceste dou declaraii s se rezolve urmtoarea problem:
Se citete de la tastatur un numr ntreg n i apoi coordonatele a n puncte din
spaiul bidimensional.
S se calculeze aria i perimetrul poligonului determinat de cele n puncte,
presupunnd c poligonul este convex. Valorile pentru arie i perimetru se vor afia dup
afiarea coordonatelor vrfurilor poligonului cu 3 zecimale.
Se vor scrie i folosi funcii pentru:
Calculul distanei dintre dou puncte;
Calculul ariei unui triunghi folosind formula lui Heron;
Calculul semiperimetrului unui triunghi;
Calculul ariei totale;
Calculul perimetrului poligonului
Citirea unui vector de structuri.
Afiarea coordonatelor vrfurilor poligonului tiind c primul vrf este notat cu
A, iar coordonatele unui vrf se indic ntre paranteze dup "numele" vrfului.
Exemplu:
A(1, 1)

B(2.75, 3.14)

Pentru coordonate de tip real se vor indica dou zecimale i se vor afia cte 5
puncte pe o linie, puncte separate printr-un TAB.

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 7

Exemplu:

F
Perimetrul = lungimilor laturilor AB, BC, CD, DE, EF, FA

B
C

Aria

= ariilor triunghiurilor ABC, ACD, ADE, AEF

Date de test:
a). pentru poligonul A(1,1), B(-2,4), C(-4,-3)
Aria = 13,500
Perimetrul = 17,926
b) pentru poligonul A(2,98; 8,88), B(9,02; 5,98), C(13,16; 10,12), D(11,02; 14,00),
E(6,04; 18,08)
Aria = 68,732
Perimetrul = 33,129

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 7

Problema nr. 2
Se consider polinomul cu coeficieni compleci:

P (x ) = a0 x n + a1 x n 1 + K + an 1 x + an
S se calculeze, folosind schema lui Horner, valoarea polinomului n punctul z din
planul complex, z fiind definit cu expresia
z = x + j y

unde j =

-1

Relaia de recuren pentru calculul valorii unui polinom ntr-un punct z este:

Pn (z ) = Pn 1 (z ) z + an cu P1 (z ) = 0
(nu se vor folosi funcii recursive).
Se asociaz unui numr complex structura:
struct COMPLEX {
double re;

// partea real

double im;

// partea imaginar

};
i unui polinom structura:
struct POLINOM {
int n;

// gradul polinomului

struct COMPLEX c[20];

// coeficienii polinomului

};
Se vor scrie i folosi funcii pentru:
Citirea unui vector de numere complexe;
Adunarea a dou numere complexe;
nmulirea a dou numere complexe;
Calculul valorii unui polinom de variabil complex cu coeficieni compleci
(varianta iterativ i nu recursiv).

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 7

Problema nr. 3
Fie tipul de dat PUNCT declarat astfel:
typedef struct _PUNCT {
double x;

//

abscisa

double y;

//

ordonata

} PUNCT;
asociat unui punct din plan i un tip de dat declarat:
typedef struct _LINIE {
double m;

// panta

double n;

// tietura

} LINIE;
asociat unei drepte a crei ecuaie este:

y = mx +n
Se citete, de la tastatur, un numr ntreg n i apoi coordonatele a n puncte din
plan.
a) S se verifice dac toate punctele se gsesc pe dreapta determinat de primele
dou puncte introduse. Pentru aceasta se determin ecuaia unei drepte lund n
considerare coordonatele primelor dou puncte din cele introduse i apoi se verific dac
celelalte puncte aparin dreptei.
b) S se afieze ecuaia dreptei.
c) S se afieze coordonatele punctelor care nu sunt pe dreapta care trece prin
primele dou puncte din plan ale cror coordonate au fost introduse. Fiecrui punct i se
asociaz un bit. Bitul respectiv va avea valoarea 1 dac punctul se gsete pe dreapt i
va avea valoarea 0 dac punctul nu se gsete pe dreapt. Dup setarea valorii fiecrui
bit, se afieaz coordonatele punctelor care nu sunt pe dreapt sub forma (x, y).
Se vor scrie i folosi funcii pentru:
Citirea unui vector de structuri
Determinarea ecuaiei unei dreptei (determinarea pantei i tieturii dreptei
respective)
Verificarea coliniaritii punctelor introduse
Afiare ecuaie dreapt
Determinare puncte care nu sunt pe dreapt
Afiare puncte care nu sunt pe dreapt

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 7

Observaie:
Trei puncte sunt coliniare dac

x1
x2

y1 1
y2 1 = 0

x3

y3 1

unde (xi, yi) cu i = 1, 2, 3 sunt coordonatele celor trei puncte. Relaia de mai sus
poate fi folosit (cu adaptrile necesare) i pentru determinarea ecuaiei unei
drepte care trece prin dou puncte.

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 8

1. Pointeri

1.1. Definiia noiunii de pointer..........................................................................................1


1.2. Declaraia / definiia unui pointer.................................................................................2
1.3. Legtura dintre pointeri i tablouri...............................................................................4
1.4. Operaii cu pointeri ......................................................................................................4
2. Alocarea dinamic a memoriei
6
TEMA

Problema nr. 1....................................................................................................................8


Problema nr. 2....................................................................................................................8
Problema nr. 3....................................................................................................................9
Problema nr. 4....................................................................................................................9

POINTERI. ALOCAREA DINAMIC A MEMORIEI

1. Pointeri
1.1. Definiia noiunii de pointer
Un pointer este o variabil care conine adresa altei variabile dac este iniializat cu
aceast adres.
Fie definiia:
int x;
Efectul acestei definiii este c variabilei x i se rezerv o zon de memorie capabil
s stocheze o variabil de tip int (16 bii la BorlandC 3.1). n aceasta zon se va depune
ulterior valoarea lui x. La aceasta zon ne putem referi direct sau indirect, utiliznd o
variabil p iniializat cu adresa variabilei x.
p=&x;

// p conine adresa lui x

La ntlnirea instruciunii de atribuire


x=10;
valoarea 10 se va depune n memorie la adresa indicat de variabila p. n acest caz
variabila p este o variabil pointer (deoarece conine adresa altei variabile), prin urmare i
pentru acest p este nevoie de o zon de memorie pentru a-i pstra valoarea (dimensiunea
zonei de memorie necesar pentru a pstra valoarea variabilei p depinde de modul n care
sunt reprezentate adresele n sistemul respectiv).
n condiiile de mai sus putem scrie:
*p=x ;

// valoarea de la adresa indicat de p este chiar x

Deci exist 2 operatori unari folosii n cazul pointerilor:


1

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 8

operatorul & care indic adresa unei zone de memorie i se numete operator de

refereniere;
operatorul * care indic valoarea pstrat n acea zon de memorie i se numete
operator de derefereniere.
Exemplu:
p=&x ;
*p=x;
atunci x=10 este echivalent cu *p=10 (ceea ce se afl la adresa indicat de p este
valoarea 10).
Dac scriem n continuare *p=13, atunci x=13.
Pointerii se utilizeaz pentru a face referire la date cunoscute prin adresele lor.
Avantajele utilizrii lor sunt:
nlocuirea expresiilor cu indici prin expresii cu pointeri;
posibilitatea alocrii dinamice a memoriei (de ctre utilizator);
folosirea ca parametri n listele de parametri ai funciilor. n felul acesta se rezolv
restriciile legate de transmiterea prin valoare a argumentelor dintre funcia apelant n cea
apelat, specifice limbajului C standard (ANSI).
1.2. Declaraia / definiia unui pointer
Un pointer se declar ca orice variabil obinuit cu deosebirea c numele este
precedat de simbolul * astfel:
T *nume;
unde nume este un identificator asociat cu adresa sau adresa de nceput a unei zone de
memorie care conine date de tipul T (T este un tip de entitate recunoscut de limbajul C,
predefinit sau definit de programator) . Spunem c nume este un pointer la tipul de dat T.
*nume reprezint coninutul zonei de memorie n care s pstreaz date de tipul T.
Exemplu:
int x;
int *p;

//p pointeaz spre date de tipul int

float y;
O atribuire de forma: p=&x este corect n timp ce atribuirea p=&y este eronat
deoarece y este de tip real (float), iar p este pointer spre ntreg (int).
Dac avem : float *q atunci o instruciune de forma q=&y este corect.
Exemple:
2

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 8

int x,y;
int *p;
1) y=x+100 este echivalent cu: {p=&x; y=*p+100;}
2) x=y

este echivalent cu: {p=&x; *p=y;}

3) x++

este echivalent cu: {p=&x; (*p)++;}

Exist situaii cnd dorim ca un pointer s fie utilizat cu mai multe tipuri de date. n
acest caz nu se specific un tip anume, ci se folosete pointerul generic definit astfel:
void *nume;
Exemplu:
int x;
float y;
char c;
void *p;
Se pot scrie urmtoarele instruciuni
p=&x;
p=&y;
p=&c;
deoarece lui p i se pot atribui adrese de memorie ce pot conine date de tipuri diferite
Observaie:
Cnd se folosete tipul de dat pointer generic este necesar s se fac conversii
explicite prin expresii de tip cast, pentru a se preciza tipul datei spre care pointeaz un
astfel de pointer. Deci o instruciune *p=10 nu e corect, pentru c nu e definit tipul datei
spre care pointeaz p (am definit void *p). Pentru a realiza o astfel de atribuire va trebui s
convertim valoarea lui p spre "pointer de tipul int", adic
(int *)
Atribuirea de mai sus devine corect astfel:
*(int*)p=10.
Folosirea pointerilor de tip void da o flexibilitate mai mare, dar nu se recomand
folosirea lor abuziv. Trebuie s se tie n orice moment ce fel de tip de pointer este
valoarea atribuit variabilei de tip (void*).

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 8

1.3. Legtura dintre pointeri i tablouri


Numele unui tablou este un pointer, deoarece el are ca valoare adresa primului su
element. Exist totui o diferen: unei variabile de tip pointer i se atribuie valori la
execuie, n timp ce pentru numele unui tablou acest lucru nu este posibil. Acesta are ca
valoare, pe tot parcursul programulu, adresa primului su element. De aceea se
obinuiete s se spun c numele unui tablou este un pointer constant.
Exemplu:
int t[10];
int *p;
int x;
Dac scriem
p = t;
atunci p are adresa lui t[0], adic p = &t[0].
x = t[0] este echivalent cu x = *p (se atribuie lui x valoarea lui t[0]).
Elementul t[i] este al (i+1)lea element al tabloului t (n C valoarea indexului unui
tablou ncepe de la 0). n momentul n care tablourile apar ca parametri formali n antetul
unei funcii se pot folosi 2 forme pentru prototip, ca n exemplul de mai jos:
f(int t[]);
sau
f(int *t);
Deci t este un parametru formal; el este un pointer cruia i se va atribui o valoare
prin apelul funciei. Dac avem o declaraie:
int tab[10];
atunci funcia de mai sus se apeleaz prin f(tab);
n acest moment lui t i se atribuie la apel valoarea lui tab, adic adresa primului su
element tab[0].
1.4. Operaii cu pointeri
1) operatorii de incrementare i de decrementare se pot aplica la variabile de tip
pointer, dar n acest caz operatorul crete sau scade adresa pstrat de variabil cu un
numr de octei corespunztor tipului de dat spre care pointeaz pointerul.
Fie:
int *p;
p++ i ++p mresc valoarea lui p cu 2 (2 octei pentru tipul int), adic cu lungimea n
octei a obiectului pointat)
4

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 8

Fie:
double tab[10];
double *p;
p=&tab[i];

/* cu 0<i<9 */

p++ sau ++p mresc valoarea lui p cu 8 (p va avea ca valoare adresa urmtorului
element tab[i+1]), adic pointeaz urmtorul obiect de tip double.
2) adunarea / scderea unui numr ntreg nseamn modificarea valorii lui p cu
n*t, unde t este numrul de octei necesari pentru a pstra o dat de tipul celei spre care
pointeaz p, iar n este numrul ntreg care se adaug /scade din p.
Fie:
tip tab[n];
O expresie de forma (tab+i) este corect i conine chiar adresa lui tab[i].
tab nseamn adresa primului element (care poate fi indicat i prin &tab[0])
tab+1

nseamn adresa lui tab[1] (adic &tab[1])

...
tab+i

nseamn adresa lui tab[i] (adic (&tab[i])

Deci *(tab+n) = tab[n], iar o construcie de forma x = tab[n] este echivalent cu


x = *(tab+n).
Variabilele cu indici pot fi nlocuite prin expresii cu pointeri (obinndu-se o optimizare
a codului).
3) compararea a doi pointeri. Doi pointeri ce pointeaz spre elementele aceluiai
tablou pot fi comparai folosind operatorii relaionali:
Fie:
p = &t[i];
q = &t[j];
atunci (p<q) este echivalent cu (i<j).
Compararea a doi pointeri este utilizat mai ales pentru a determina dac un pointer
are sau nu o valoare diferit de NULL (constanta simbolic care ne permite s determinm
dac de exemplu o operaie de alocare de memorie a avut loc cu succes sau nu - mai
concret dac un pointer are sau nu o valoare) .
Deci se pot folosi:
5

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 8

p == NULL sau p != NULL


sau:
p == 0 sau p != 0
sau:
!p sau p
Valoarea 0 (zero) pentru un pointer nu definete o adres, ci este o indicaie de pointer
invalid, astfel de teste fiind folosite pentru a pune n eviden anumite erori.
4) diferena a doi pointeri. Este folosit ntre pointeri care indic spre elementele
aceleiai entiti pentru a determina cte elemente exist ntre elementele indicate.
Fie:
p=&t[i];
q=&t[i+n];
atunci (q-p)=n

2. Alocarea dinamic a memoriei


Fie declaraia de forma (unde T este un tip oarecare de entitate):
T nume;
Dac se utilizeaz n corpul unei funcii, atunci pentru variabila nume se rezerv
memorie pe stiv la fiecare apel al funciei respective. La revenire din funcie, stiva se
elibereaz i astfel variabila nume devine nedefinit, nu mai are memorie rezervat. O
rezervare de memorie de acest fel este automat pentru c se face automat, fr
intervenia utilizatorului. Pentru datele globale sau statice memoria este rezervat n fazele
premergtoare execuiei (deci la compilare) i definiia lor rmne valabil pn la sfritul
execuiei programului. Pentru acest tip de date nu se rezerv memorie pe stiv, ci ntr-o
zon de memorie rezervat special pentru ele. O astfel de rezervare de memorie se
numete alocare static. Exist i alt modalitate de alocare a memoriei, n funcie de
necesiti, utiliznd pointeri, realizat prin apelul de ctre utilizator al unor funcii speciale.
Exist o zon de memorie, distinct de stiv, zon numit heap, care este rezervat
pentru astfel de alocri (dinamice). Funciile folosite pentru alocarea dinamic a memoriei
au prototipurile n stdlib.h. n descrierea funciilor se folosete tipul de dat size_t care
este definit n fiierul header stdio.h ca sinonim pentru tipul de date unsigned int.
void *malloc(size_t n);
aloc un bloc de memorie de n octei n heap;
6

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 8

n caz de succes, returneaz un pointer la blocul de memorie alocat (cruia nu-i

schimb coninutul)
returneaz valoarea 0 (zero) dac nu s-a putut face alocarea de memorie (pentru
c nu exist spaiu liber cu mrimea solicitat sau dac se apeleaz cu n = 0).
Funcia returneaz un pointer generic de tip void, a crui valoare poate fi asignat
unui pointer de orice tip folosind o conversie exdplicit. Se recomand s se testeze
totdeauna dac valoarea returnat este sau nu 0 (zero).
Exemplu:
char *x;
x = (char *) malloc(100);
if(0 == x) {
fprintf(stderr, Memorie insuficienta\n);
exit(EXIT_FAILURE):
}
void *calloc(size_t nrElemente, size_t dimElement);
aloc un bloc de memorie de mrime nrElemente * dimElement (care nu trebuie
s depeasc 64 Ko octei din heap), coninutul blocului fiind resetat (se scrie 0);
n caz de succes, returneaz un pointer la blocul de memorie alocat;
returneaz 0 dac nu exist spaiu liber de mrimea solicitat (sau dac se
apeleaz cu valorea 0).
void *realloc(void* block, size_t marime);
funcia redimensioneaz (prim mrire sau micorare) un bloc de memorie (alocat
dinamic anterior) la numrul de octei specificai de parametrul marime;
block trebuie s indice un bloc de memorie obinut prin apelarea funciilor malloc()
/ calloc() / realloc() (altfel rezultatul este imprevizibil);
dac block este 0 (zero), lucreaz exact ca malloc();
funcia ajusteaz mrimea blocului alocat la marime, copiind (dac este cazul)
coninutul su la o nou adres;
returneaz adresa blocului realocat (poate diferi de block) sau 0 (zero), dac nu se
poate face realocarea sau marime = 0 (n acest ultim caz funcia lucreaz ca i funcia
free()).

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 8

void free(void *block);


elibereaz un bloc de memorie alocat anterior de ctre malloc() / calloc() /
realloc();
rezultatul este dezastruos dac parametrul nu este rezultatul unei alocri dinamice
anterioare sau dac se apeleaz de doua ori la rnd cu acelai parametru.

TEMA
Problema nr. 1
S se citeasc de la tastatur elementele a dou tablouri unidimensionale (vectori)
de n numere ntregi a i b alocate dinamic. S se calculeze vectorul sum i s se afieze.
Rezolvarea problemei presupune construirea unui proiect (cu fiierul header
corespunztor) i scrierea urmtoarelor funcii:
9 funcie pentru: alocarea cu verificarea alocrii (funcia xmalloc din curs);
9 funcie pentru citirea unui vector de ntregi cu n elemente. Funcia trebuie s aib
urmtorul prototip:
int *citireVector(size_t n);
9 funcie pentru afiarea elementelor unui vector de ntregi, cu prototipul:
void afisareVector(int *a, size_t n);
9 funcie pentru calculul vectorului sum a doi vectori, cu prototipul:
int *sumaVectori(int *x, int *y, size_t n);
Problema nr. 2
Se citete de la tastatur un numr ntreg (poate fi pozitiv sau negativ). Citirea se
face cu scanf. Se determin numrul de cifre ale numrului (prin logaritmare n baza 10).
Se face alocare dinamic de memorie pentru un ir de caractere capabil s
memoreze cifrele numrului i eventualul semn. Numrul citit se transform n ir de
caractere, fr a folosi funcii de bibliotec. Transformarea se face astfel nct fiecare cifr
s se plaseze direct pe locul ei.
Se afieaz irul de caractere rezultat.
Rezolvarea problemei presupune realizarea unui proiect care, pe lng funcia main,
s cuprind i funcii pentru:
9 alocare dinamic cu verificare (funcia xmalloc din curs)
9 transformarea numrului n ir de caractere. n acest caz funcia are prototipul:
char *transformareToAscii(long int);

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 8

Problema nr. 3
Se citete de la tastatur un numr natural n i un vector de numere naturale v
pentru care se face alocare dinamic de memorie.
Se formeaz un nou vector w cu n elemente, de asemenea alocat dinamic, n care
valoarea fiecrui element este suma cifrelor elementului corespunztor din vectorul v.
S se afieze elementul din vectorul v care are cea mai mare sum a cifrelor sale.
Se vor scrie urmtoarele funcii:
9 Funcie pentru citirea unui vector de numere naturale care are ca parametru
numrul de elemente i returneaz un pointer.
9 Funcie pentru afiarea vectorului de numere naturale sub forma
A = (23, 543, 912)
Funcia are ca parametri vectorul de afiat (exprimat ca un pointer) i numrul de
elemente.
9 Funcie pentru calculul sumei cifrelor unui numr natural. Funcia are ca
parametru un numr natural (numrul pentru care se calculeaz suma cifrelor) i
returneaz un numr natural (suma calculat).
9 Funcie pentru determinarea elementelor vectorului w. Funcia are ca parametri
un pointer i un numr natural i returneaz un pointer la un numr natural. Aceast
funcie face apel, pentru calculul sumei cifrelor unui numr natural, la funcia definit
la punctul anterior.
9 Funcie pentru determinarea maximului dintr-un ir de numere. Funcia
primete ca parametri un pointer la un numr natural i un ntreg i returneaz
indexul elementului cu valoarea maxim.
Problema nr. 4
S se defineasc tipul de dat MULTIME ca o structur care cuprinde:
cardinalul mulimii (numrul de elemente din mulime) care este un numr
ntreg fr semn;
elementele mulimii (de tip real), stocate prin intermediul unui pointer
S se scrie un program care pentru dou mulimi
1. citete de la tastatur cardinalul i elementele mulimii i le stocheaz ntr-o
structur de tip MULTIME.
2. afieaz cele dou mulimi sub forma
A = {3.14, 5.12, 3.00, 4.39}
B = {34.29, 15.14, 3.14}
9

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 8

(se presupune c numele celor dou mulimi sunt A i B, iar numerele reale se vor afia
cu dou zecimale i vor fi separate de o virgul i un spaiu).
Observaie (referitoare la punctele 1 i 2):
Se scriu funcii pentru o singur mulime. Funciile se apeleaz de mai multe ori.
3. afieaz un meniu care d posibilitatea utilizatorului s aleag una din
urmtoarele prelucrri:
a) determinarea mulimii intersecie a celor dou mulimi (A&B) i cardinalul acestei
mulimi.
b) determinarea mulimii diferen simetric a celor dou mulimi (A-B) (mulimea
diferen simetric include elementele mulimii A care nu sunt n mulimea B i elementele
mulimii B care nu sunt n mulimea A) i cardinalul acestei mulimi.
c) determinarea mulimii reuniune a celor dou mulimi (A+B) i cardinalul acestei
mulimi.
4. Realizeaz prelucrarea dorit i afieaz mulimea care rezult n urma
prelucrrii.
Programul poate face o singur prelucrare n funcie de opiunea utilizatorului i va
trebui scris astfel nct s permit prelucrarea mai multor seturi de date.
Observaii:
1) Se va citi cu atenie tabelul urmtor care descrie n detaliu modul de rezolvare a
problemei i descrierea prototipurilor funciilor care trebuie scrise.
2) Dac nu se folosesc funciile indicate codul nu se puncteaz.
3) Punctajul maxim se acord pentru rezolvarea CORECT a fiecrei subprobleme.
1. Construirea structurii MULTIME (funcia primete ca parametru numele
mulimii i returneaz o structur de tip MULTIME)
2. Alocarea corect (cu verificare) de spaiu de memorie pentru pointeri
3. Citirea valorilor elementelor mulimii (ntr-o funcie care primete ca parametru
un numr natural i returneaz un pointer la real)
4. Afiarea valorilor vectorului din structur conform modelului dat n problem
(funcia are un parametru o structur de tip MULTIME i nu returneaz nimic)
5. Scrierea meniului de prelucrare (funcia nu are nici un parametru i returneaz
un numr care reprezint numrul opiunii de prelucrare)
6. posibilitatea de reluare a programului (prelucrarea mai multor seturi de date)
10

1,0
0,5
1,0
1,0
0,75
0,5

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 8

7. Folosire proiect (corect)

0,5

8. Fiier header (corect i complet)

0,5

9. Funcia main (complet inclusiv eliberarea corect a zonelor de memorie


folosite)

0,75

10. Funcie care stabilete dac o valoare aparine unei mulimi. Funcia are 2
parametri: valoarea i mulimea (reprezentat prin structur) i returneaz 1/0

0,5

dup cum valoarea se gsete sau nu n mulime.


11. Calculul mulimii intersecie (funcia primete ca parametri dou structuri de
tip MULTIME i returneaz o structur de tip MULTIME) inclusiv alocarea

1,0

corect de memorie.
12. Calculul mulimii diferen (funcia primete ca parametri dou structuri de tip
MULTIME i returneaz o structur de tip MULTIME) inclusiv alocarea corect

1,0

de memorie.
13. Calculul mulimii reuniune (funcia primete ca parametri doi pointeri la date
de tip MULTIME i returneaz o structur de tip MULTIME) inclusiv alocarea

1,0

corect de memorie.
TOTAL

10 p

11

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 9

1. Tablouri de pointeri ............................................................................................................2


2. iruri de caractere. Funcii specifice..................................................................................3
2.1. Lungimea unui ir de caractere...................................................................................4
2.2. Copierea dintr-o zon de memorie n alt zon de memorie .....................................4
2.3. Concatenarea a dou iruri.........................................................................................5
2.4. Compararea a dou iruri ...........................................................................................6
2.4. Alte funcii utile: ...........................................................................................................7
3. Funcii de conversie .........................................................................................................10
4. Terminarea Programelor..................................................................................................12
TEMA ...................................................................................................................................13
Problema nr. 1..................................................................................................................13
Problema nr. 2..................................................................................................................13
Problema nr. 3..................................................................................................................13
Problema nr. 4..................................................................................................................14
Problema nr. 5..................................................................................................................14
Problema nr. 6..................................................................................................................14
Problema nr. 7..................................................................................................................14

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 9

TABLOURI DE POINTERI.
IRURI DE CARACTERE. FUNCII SPECIFICE

1. Tablouri de pointeri
Dac se consider c T este un tip de entitate, predefinit n limbaj sau definit de
utilizator, un tablou unidimensional (vector) tab cu elemente de tipul T se declar astfel:
T tab[100];
n cazul n care T este un tip de entitate definit cu typedef astfel:
typedef T1* T;
atunci avem de fapt declaraia:
T1* tab[100];
care definete un tablou de pointeri n care fiecare element este un pointer la tipul T.
Pentru vectorul de pointeri tab avem urmtoarea reprezentare schematic:
tab
tab[0]
tab[1]

tab[99]

11

21

34

Figura 1. Reprezentarea schematic a unui tablou de pointeri cu 100 de elemente


Fiecare element al tabloului fiind un pointer trebuie alocat spaiu de memorie pentru
el (nu mai mult dect este necesar), iar la terminarea lucrului n zona de memorie alocat,
memoria trebuie eliberat..
Tablourile de pointeri sunt folosite cnd se lucreaz cu mai multe zone de memorie,
de dimensiuni diferite, care trebuie s stocheze elemente de acelai tip (aa cum se
lucreaz cu vectori de ntregi, de exemplu, cnd trebuie prelucrate mai multe date de tip
ntreg).
Exemplu cel mai sugestiv este stocarea unui text cu un anumit numr de linii. n
acest caz, fiecare linie poate avea o lungime diferit de a celorlalte linii. Deoarece
stocarea unui ir de caractere se face prin intermediul unui vector de caractere (sau
2

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 9

pointer la caracter), stocarea unui text (n care fiecare linie este privit ca un ir de
caractere) se poate face prin intermediul unui tablou de pointeri la char. Dac textul care
trebuie prelucrat are cel mult 50 de linii i primele trei linii sunt:
Exemplu
de
text
atunci el are urmtoarea reprezentare schematic de memorie:
text
text[0]
text[1]
text[2]

e m p

e \0

u \0

t \0

text[49]

Figura 2. Reprezentarea schematic a unui tablou de pointeri


care poate conine cel mult 50 de linii de text.

2. iruri de caractere. Funcii specifice


Un ir de caractere se pstreaz ntr-o zon de memorie organizat sub forma unui
tablou unidimensional de tip char. Fiecare caracter se pstreaz pe un octet prin codul sau
numeric (codul ASCII). Dup ultimul caracter al irului se pstreaz caracterul '\0'.
Exemplu:
char tab[]="Acesta este un sir";
n exemplul de mai sus:
tab este un pointer care conine adresa locaiei de memorie care conine codul
ASCII al caracterului A
tab+1 conine adresa caracterului c (este un pointer care conine adresa locaiei de
memorie n care se gsete codul ASCII al caracterului c).
...
tab[0] sau *tab conine codul ASCII al caracterului A
tab[1] sau *(tab+1) conine codul ASCII al caracterului c
....
Declaraia de mai sus pentru tab poate fi fcuta i astfel:
3

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 9

const char *p="Acesta este un ir";


p pointeaz pe adresa lui 'A'
p+1 pointeaz pe adresa lui 'c'
...
p[0] sau *p este caracterul 'A'
p[1] sau *(p+1) este caracterul 'c'
Principalele operaii cu iruri de caractere se refer la :
lungime
copiere
concatenare
comparare
conversie
cutare caractere /subiruri n iruri
Prototipurile funciilor ce lucreaz cu iruri de caractere se gsesc n fiierul header
string.h.
2.1. Lungimea unui ir de caractere
Lungimea unui ir de caractere este numrul de caractere ce intr n componena
irului respectiv (fr '\0' final). Prototipul funciei care returneaz lungimea unui ir de
caractere este:
unsigned strlen(const char *s);
Parametrul formal al funciei este un pointer spre o dat constant deoarece funcia
nu are voie sa modifice irul cruia i calculeaz lungimea.
Exemplu:
char *tab="acesta este un sir";
int n;
n=strlen(tab);
Se poate folosi i : n=strlen("acesta este un sir");
2.2. Copierea dintr-o zon de memorie n alt zon de memorie
Prototipul funciei care realizeaz copierea este:
char *strcpy(char *dest, const char *sursa);
Aceast funcie realizeaz copierea irului de caractere a crui adres de nceput
este coninut n pointerul sursa n zona de memorie care ncepe de la adresa dat de
4

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 9

valoarea pointerului dest. Se copie i caracterul final '\0'. Se presupune c pentru zona de
memorie indicat de dest (n care se copie) s-a fcut deja alocarea de memorie necesar
pentru stocarea ntregului ir de caractere (inclusiv terminatorul de ir) de la adresa
indicat de sursa. dest nu e declarat cu const deoarece funcia modific zona de
memorie corespunztoare; n schimb sursa este declarat cu const. Funcia returneaz
un pointer a crui valoare este adresa zonei n care s-a fcut copierea, adic dest.
Exemple:
char *tab="acest sir se copie";
int n = strlen(tab)+1;
/ * numrul minim de octei pentru destinaie este n, include i un octet
pentru terminatorul final \0, pe care strlen() nu l contorizeaz */
char *t;
char *q;
t = (char *)malloc(n*sizeof(char));
if(t == 0) {
fprintf(stderr, "Memorie insuficenta\n");
exit(EXIT_FAILURE);
}
strcpy(t,tab); /* copierea lui tab n t */
/* Sau putem scrie */
q=strcpy(t,tab);
puts(q);

/* afiare ir */

Dac se dorete copierea a cel mult n caractere din irul surs atunci se folosete
funcia cu prototipul:
char * strncpy(char *dest, const char *sursa, unsigned n) ;
Dac n > lungimea sursei se copie toate caracterele, altfel numai primele n. irul
rezultat nu are \0 la final.
2.3. Concatenarea a dou iruri
Funcia care realizeaz acest lucru are prototipul:
char * strcat(char *dest, const char *sursa)
Copie irul de caractere din zona de memorie a crei adres de nceput este dat
de valoarea pointerului sursa n zona de memorie care urmeaz dup ultimul caracter din
irul de caractere care are primul caracter memorat la adresa indicat de pointerul dest.
5

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 9

Se presupune c pentru zona de memorie indicat de pointerul sursa s-a alocat suficient
memorie (prin alocare dinamic sau prin rezervare static printr-un tablou de caractere)
pentru a memora caracterele din cele 2 siruri i caracterul '\0' de la final. Funcia
returneaz un pointer a crui valoare este adresa de nceput a zonei de memorie unde se
face copierea, adic dest.
Exemplu:
char tab1[100]="primul sir";
char tab2[]="al doilea sir";
strcat(tab1," ");
strcat(tab1,tab2);
n acest moment tab1 va deveni: "primul sir al doilea sir".
Dac se dorete s se ia doar primele n caractere de la surs se folosete funcia:
char * strncat(char *dest, const char *sursa, unsigned n)
irul rezultat nu are \0 la final.
2.4. Compararea a dou iruri
irurile de caractere se pot compara pe baza codurilor ASCII ale caracterelor ce intr
n componena lor (comparaia alfabetic sau lexicografic).
Fie :
char *s1,*s2;
s1=s2 dac au lungimi egale i s1[i]==s2[i] oricare ar fi i=0 ... strlen(s1)
s1<s2 dac exista un i pentru care s1[i]<s2[i] si s1[j]==s2[j] oricare ar fi j=0 ... (i-1)
s1>s2 dac exista un i pentru care s1[i]>s2[i] si s1[j]==s2[j] oricare ar fi j=0 ... (i-1)
Funcii de comparare:
int strcmp(const char *s1, const char *s2)
Returneaz o valoare <0 dac s1<s2 (s1 este naintea lui s2 la o ordonare
alfabetic), valoarea 0 dac s1=s2 (cele dou iruri coincid i o valoarea >0 dac s1>s2
(s1 este dup s2 la o ordonare alfabetic).
Exemplu:
strcmp("ab","ab") returneaz 0
strcmp("aab","abb") returneaz un numr negativ
strcmp("za","z") returneaz un numr pozitiv
strcmp("a","A") returneaz un numr pozitiv
deoarece codul ASCII al lui a > codul ASCII al lui A
6

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 9

int stricmp(const char *s1, const char *s2)


Are acelai efect ca la funcia strcmp, dar nu se face diferena ntre litere mari i
mici.
Exemplu:
stricmp("a","A") returneaz 0
int strncmp(const char *s1, const char *s2, unsigned n)
Folosete doar n caractere pentru comparaie; n cazul n care n este mai mare
dect minimul dintre cele dou lungimi funcioneaz la fel cu strcmp.
2.4. Alte funcii utile:
char *strrev(char *s)
Inverseaz caracterele din ir cu excepia '\0' de la final. Returneaz un pointer la
irul inversat.
char *strlwr(char *s)
Convertete literele mari n litere mici, celelalte caractere rmn neschimbate.
Returneaz pointer la irul modificat.
char *strupr(char *s)
Convertete literele mici n litere mari, celelalte caractere rmn neschimbate.
Returneaz pointer la irul modificat.
char *strdup(const char *s)
Copie un ir de caractere ntr-un spaiu obinut prin apel de genul malloc. n cazul n
care funcia nu poate face alocare, ea returneaz, ca i malloc, un pointer nul.
Spaiul alocat are dimensiunea (strlen(s)+1) (unde s este irul care trebuie copiat) i
este responsabilitatea utilizatorului s elibereze spaiul alocat de funcia strdup.
De exemplu, secvena urmtoare:
char *s="Sir exemplu";
char *x;
x = strdup(s);
if(x == 0) {
7

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 9

fprintf(stderr, "Memorie insuficienta\n");


exit(EXIT_FAILURE):
}
are acelai efect cu:
char *s="Sir exemplu";
char *x;
x=(char*)malloc((strlen(s)+1)*sizeof(char));
if(x == 0) {
fprintf(stderr, "Memorie insuficienta\n");
exit(EXIT_FAILURE):
}
strcpy(x,s);
char *strchr(const char *s, int c)
parcurge un ir de caractere (s) n cutarea primei apariii a unui caracter (c);
'\0' se consider ca fcnd parte din ir, deci strchr(s, 0) returneaz un pointer la
caracterul terminator de ir al lui s;
returneaza un pointer la prima apariie a caracterului c n s, NULL dac caracterul
cutat nu exist n ir.
char *strrchr(const char *s, int c)
parcurge un ir de caractere n direcie invers, cutnd ultima apariie a
caracterului c (poate fi 0 sau '\0') n irul s;
returneaz un pointer la ultima apariie a caracterului c n s, NULL dac nu exist.
size_t strcspn(const char *s1, const char *s2)
parcurge un ir de caractere (s1) pentru a separa segmentul de la nceput care nu
conine nici un caracter care face parte din al doilea ir de caractere (s2);
returneaz lungimea segmentului iniial din s1 compus din caractere ce nu fac
parte din s2;
size_t strspn(const char *s1, const char *s2)
parcurge un ir de caractere (s1) att timp ct fiecare caracter face parte i din s2;
8

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 9

returneaz lungimea segmentului iniial din s1 compus din caractere ce fac parte
i din s2;
char *strset(char *s, int ch)
toate caracterele din s vor deveni ch;
returneaza s;
char *strstr(const char *s1, const char *s2)
caut prima apariie a irului s2 n interiorul lui s1;
returneaz un pointer la elementul din s1 unde ncepe s2, NULL dac s2 nu apare
ca subir al s1;
char *strpbrk(const char *s1, const char *s2)
caut n irul s1 prima apariie a unui caracter din s2;
returneaz un pointer la prima apariie a vreunui caracter din s2 n s1, NULL dac
nu exist;
char *strtok(char *s1, const char *s2)
funcia se folosete de regul pentru descompunerea irului s1 n subiruri
delimitate de caractere din irul s2;
funcia interpreteaz irul s1 ca fiind alctuit din subiruri, delimitate de caractere
(indiferent care din ele) coninute n irul s2;
la primul apel al funciei strtok, aceasta ntoarce un pointer pe primul subir care
nu are nici un caracter din s2, subir cruia i adaug '\0' la sfrit. La al doilea apel,
funcia trebuie sa aib primul argument NULL (n locul lui s1). Ea continu separarea a
ceea ce a rmas din s1, ntorcnd pointeri pe subirurile astfel obinute si punnd '\0' la
sfritul lor, pn la epuizarea lui s1. Dac irul s2 este ales convenabil, ca un delimitator
pentru subirurile din s1, descompunerea este bun.
Exemplu:
char *s;
s=strtok("abcxxabxxbcxaaabccde","xx");
printf("\nPrimul subir: %s",s);
do
{
9

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 9

s=strtok(NULL,"xx");
printf("\nUrmatorul subir:%s",s);
} while(s!=NULL);
Vor fi separate subirurile:
abc
ab
bc
aaabccde
void swab(char *sursa, char *dest, int nr);
funcia copie nr octei de la sursa la dest, inversnd octeii de la adresele pare cu
cei de la cele impare;
nr trebuie sa fie par;
este util pentru transferarea datelor ntre dou calculatoare cu memorare diferit
(octetul cel mai semnificativ dintr-un cuvnt la adresa superioar sau la cea inferioar);
Atenie: ordinea octeilor afecteaz organizarea cmpurilor de bii care depesc un
octet !
Exemplu:
...
char sir[]="1234567890";
char s[15];
lung=strlen(sir);
swab(sir,s,lung)
s[lung]='\0';
puts(s);
...
Pe monitor va apare:2143658709

3. Funcii de conversie
Au prototipul n stdlib.h
int atoi (const char* ir)
convertete un ir de caractere ntr-un numr ntreg
irul de caractere trebuie s fie de forma:
10

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 9

[ws][sn][ddd]
unde :
[ws] este un ir opional de spaii sau tab-uri
[sn] este un semn opional + sau [ddd] un ir de cifre zecimale
primul caracter care nu satisface conversia duce la terminarea funciei
dac rezult un numr care iese din gama pentru tipul int rezultatul este nedefinit;
returneaz rezultatul conversiei sau 0 dac irul de caractere nu poate fi convertit
ntr-un numr corespunztor tipului de data int (ATENIE: nu se poate separa cazul
corect al irului de caractere "0" de eroare !)
long atol(const char * ir)
convertete un ir de caractere (de forma prezentat mai sus) ntr-un numr long;
n caz de depire rezultatul este nedefinit
conversia se oprete la primul caracter ilegal
returneaz valoarea n care a fost convertit irul de intrare sau 0 dac numrul nu
poate fi convertit ntr-un numr corespunztor tipului long.
double atof(const char* ir)
convertete irul de caractere ntr-un numr real dubl precizie (tipul double)
irul trebuie s fie de forma :
[whitespaces][sign][ddd][.][ddd][e|E[sign]ddd]
primul caracter necunoscut duce la sfritul conversiei
recunoate +INF , -INF (+/- infinit) i +NAN sau -NAN (not a number)
returneaz valoarea convertit a irului de intrare; dac se produce depire
returneaz +/- HUGE_VAL
char *itoa(int valoare, char* ir, int baza)
convertete un ntreg (valoare) ntr-un ir de caractere
baza specifica baza de numeraie n care se consider a fi acel ntreg ; daca
valoarea este negativa i baza=10, primul caracter din ir va fi semnul '-'
spaiul alocat pentru ir trebuie sa fie suficient de mare pentru a memora irul
rezultat inclusiv '\0' final; itoa poate produce un ir de pn la 17 octei
returneaz un pointer la char (deci un ir)
11

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 9

char *ltoa(long valoare, char *ir, int baza)


convertete un long (valoare) n ir de caractere
lucreaz asemntor cu itoa; irul rezultat poate avea pn la 33 de caractere
char *ultoa(unsigned long valoare, char *ir, int baza)
convertete un unsigned long ntr-un ir de caractere (poate rezulta de maxim 33
octeti)
Alte funcii de conversie sunt:
ecvt, fcvt, gcvt (pentru conversie din numr real n ir de caractere)
strtod, strtol, strtoul (conversie din ir n double, long respectiv unsigned long)

4. Terminarea Programelor
In BorlandC++ exist urmtoarele funcii:
void exit(int status);
terminarea programului curent;
status poate avea valori cuprinse ntre 0 i 255 (dac se indic valori mai mari, se
face mprirea modulo 255);
nainte de terminare, toate fiierele sunt nchise i bufferele golite
aceleai aciuni se petrec i la terminarea normal a programului chiar dac nu se
apeleaz exit, codul de retur fiind ns o valoare aleatoare.
void _exit(int status);
termin execuia fr a se nchide fiierele, fr s goleasca buffer-ele de ieire, i
fr s apeleze eventualele exit functions stabilite prin atexit();
parametrul status are aceeai semnificaie ca la exit().
void abort(int test)
scrie un mesajul de sfrit: Abnormal program termination la dispozitivul
standard de erori (stderr) dup care abandoneaz programul apelnd _exit(3).

12

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 9

TEMA
Problema nr. 1
Scriei un program care citete un text format din cel mult 100 de linii de la
tastatur, depune liniile n zone de memorie alocate dinamic (alocnd spaiul de memorie
strict necesar), ordoneaz textul alfabetic sau dup lungimea liniilor (n funcie de opiunea
utilizatorului) i afieaz textul ordonat. Exemplu (pentru ordonarea alfabetic) textul:
zzz
zabcs
abc
aaaaaaa
ordonat alfabetic este:
aaaaaaa
abc
zabcs
zzz
Problema nr. 2
Scriei un program care citete un text format din cel mult 50 de linii de la tastatur,
depune liniile n zone de memorie alocate dinamic (alocnd spaiul de memorie strict
necesar). Fiecare linie este format din mai multe cuvinte (secvene de caractere separate
prin caractere albe, punct, virgul, semnul ntrebrii, semnul exclamrii).
Se cere s se afieze numrul de cuvinte de pe fiecare linie, iar pentru o linie
(indicat de utilizator) se cere afiarea tuturor cuvintelor din linia respectiv (fiecare pe
cte o linie). Se va folosi funcia strtok.
Problema nr. 3
Scriei doua funcii care s extrag un subir dintr-un ir:
a) una cu prototipul:
char * substr(char *sir, int start, int stop)
Exemplu:
substr("abcdef",0,2) s returneze "abc"
substr("abcdef",1,5) s returneze "bcdef"
b) i cealalt cu prototipul:
13

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 9

char *str(char *sir,int start, int nr_car)


Exemplu:
str("abcdef",0,2) s returneze "ab"
str("abcdef",2,3) s returneze "cde"
Scriei un program care citete un text format din cel mult 50 de linii de la tastatur,
depune liniile n zone de memorie alocate dinamic (alocnd spaiul de memorie strict
necesar). Din fiecare linie din textul astfel citit se extrage un subir folosind una din cele
dou funcii scrise la punctul a sau b (la alegerea utilizatorului) i afieaz subirurile
extrase de pe fiecare linie.
Problema nr. 4
S se citeasc de la tastatur un ir de caractere ce reprezint un numr ntreg i
baza de numeraie a acestuia (ntre 2 i 16). S se converteasc acest ir ntr-un numr,
reprezentat ntr-o alt baz de numeraie cerut tot de la tastatur.
Exemplu:
Se introduc:
-sirul:"1111", baza_1 este 2
-baza_2 sa fie 16
Rezultatul trebuie s fie F. Dac baza_2 este 10 rezultatul va fi 15, dac baza_2 va
fi 8 rezultatul va fi 17.
Sugestie: se poate trece mai nti din baza_1 n baza 10, iar apoi din baza 10 n
baza _2.
Problema nr. 5
Se citete de la tastatur un ir de forma: [ddd][.][ddd]. Se cere s se transforme
acest ir n numrul real corespunztor (baza 10)
Problema nr. 6
Scriei i testai o funcie:
char *elim(char *a, const char *b)
care elimin din irul de caractere a toate subirurile de forma b.
Problema nr. 7
Scriei si testai o funcie :
14

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 9

int last(const char *a, const char *b)


care s returneze indicele ultimei apariii a irului de caractere b ca subir al lui a (funcia
returneaz valoarea -1 cnd irul b nu apare deloc n irul a).

15

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 10

1. Pointer la pointer................................................................................................................1
2. Pointeri i structuri .............................................................................................................2
TEMA .....................................................................................................................................4
Problema nr. 1....................................................................................................................4
Problema nr. 2....................................................................................................................5
Problema nr. 3....................................................................................................................6
Problema nr. 4....................................................................................................................6
Problema nr. 5....................................................................................................................7

POINTER LA POINTER.
POINTERI I STRUCTURI

1. Pointer la pointer
n lucrarea de laborator anterioar am luat n consideraie tipul de dat tablou de
pointeri. Avnd n vedere legtura care exist ntre pointeri i tablouri, tabloul poate fi privit
ca un pointer i, aa, cum un tablou de ntregi poate fi privit ca o zon de memorie alocat
pentru un pointer la ntreg, tot aa un tablou de pointeri poate fi privit ca un pointer la
pointer.
Exemplu (T1 este un tip oarecare de entitate) n loc de:
T1 tab[100];
putem folosi n program
T1* tab;
cu alocarea de memorie corespunztoare:
tab=(T1*)xmalloc(100*sizeof(T1));
Dac, aa cum am considerat i n lucrarea anterioar, T1 este definit prin typedef
ca un pointer la T, adic prin definiia de tip:
typedef T* T1;
atunci vom avea, de fapt, declaraia:
T** tab;
Adic, un pointer la pointer la T.
n acest caz, trebuie s facem alocare dinamic att pentru tabloul de pointeri (pe
care l-am nlocuit cu un pointer), ct i pentru fiecare element al tabloului (care este un
pointer).

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 10

La eliberarea zonei de memorie, vom avea grij s eliberm zoma de memorie


alocat pentru fiecare pointer i pentru tabloul de pointeri n ansamblul su.
Un pointer la pointer poate fi echivalat cu un tablou bidimensional (o matrice). Atunci
cnd ne referim la matrice alocate dinamic, ne referim de fapt la tipul de dat pointer la
pointer la tipul elementelor matricei.
Reprezentarea schematic a unei matrice alocate dinamic este cea din Figura 1.
tab
tab[0]
tab[1]

tab[99]

11

21

34

Figura 1. Reprezentarea schematic a unui pointer la pointer


Diferena fa de un tablou de pointer este aceea c numrul elementelor de tip
pointer la T nu mai este impus la scrierea programului, ci este stabilit dinamic la lansarea
n execuie a programului.

2. Pointeri i structuri
O structur poate conine pointeri, putem defini pointeri la structuri pentru rezolvarea
diverselor probleme. ntotdeauna trebuie s facem alocare dinamic pentru pointerul
definit (indiferent dac este membru ntr-o structura sau un pointer la o structur).
La ieirea dintr-o funcie, modificrile fcute n membrii unei structuri nu se pstreaz.
Din acest motiv, pentru structurile care au membri ale cror valori se modific n nteriorul
unor funcii trebuie s folosim transmiterea informaiilor cu ajutorul pointerilor la structuri.
De exemplu, pentru structura declarat astfel:
struct DATA {
int zi;
char *nume_luna;
int an;
};
i variabila de tip structur data definit:
struct DATA d;
2

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 10

dac se apeleaz funcia f, al crei parametru este adresa de nceput a unei zone de
memorie rezervat pentru structura d de tip DATA astfel:
f(&d)
Funcia f va fi declarat astfel:
void f(struct DATA *pd)
unde pd este un pointer la o structur de tip DATA. La apelul funciei, pointerul pd se va
iniializa cu adresa variabilei de tip structur DATA (&d).
Pentru a accesa un membru al ei, utilizm operatorul de selecie indirect "->" (care
are prioritate maxim, ca i operatorul .(punct)).
Exemplu
pd->an
Acest acces este echivalent cu (*pd).an, dar se prefer utilizarea operatorului ->
Deci, pentru a putea modifica valorile membrilor unei structuri n corpul unei funcii
-se declar funcia avnd parametru pointer spre acea structur
funcie( struct nume_structura *nume_parametru_formal)
-apelul se face astfel : functie(&nume_parametru_efectiv)
-iar n corpul funciei se folosesc construcii de tipul:
nume_parametru_formal->nume_membru
Se recomand, pentru lizibilitatea programelor, ca noile nume date de utilizator s fie
scrise cu majuscule.
Exemplu
typedef struct{
double real, imaginar;
} COMPLEX;
Se poate calcula modulul unui numr complex, utiliznd urmtoarea funcie:
double modul (COMPLEX *a)
{
double val;
val = sqrt(a->real * a->real + a->imaginar *a->imaginar);
return val;
}
Funcia modul a utilizat funcia sqrt din biblioteca math.h i n cazul n care avem
secvena de cod:
COMPLEX c;
double m;
3

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 10

.....................
c={1.2, 3.4};
Secvena de apel trebuie s fie:
m = modul(&c);
Se pot defini tablouri de structuri.
Exemplu
Dac se consider structura (declarat n header):
struct PERSONAL{
char *nume;
char initialaTatalui;
char *prenume;
struct DATA dataNasterii, dataAngajarii;
};
Atunci,
struct PERSONAL tab_pers[20];
definete un tablou de structuri, cu 20 de elemente i fiecare element, accesat cu
tab_pers[i], i = 0, ..., 19 este o structur de tip PERSONAL.
Echivalent, n program se poate folosi un pointer la structura PERSONAL
struct PERSONAL *tab_pers;
pentru care se face alocare dinamic pentru numrul de elemente necesar. n continuare
(dup alocare) se folosete pointerul ca i cum ar fi un tablou de structuri i a crui
dimensiune coincide cu numrul de elemente stabilit de utilizator.
Dac se face definiia::
struct PERSONAL *tab_pers[20];
atunci tab_pers este un tablou de pointeri la structuri i tab_pers[i] este un pointer la o
structura de tip PERSONAL. Aceast construcie nu este echivalent cu
struct PERSONAL tab_pers[20];

TEMA
Problema nr. 1
Se d o matrice real, ptratic, de dimensiune n x n, care se citete de la tastatur
i pentru care se face alocare dinamic. S se ordoneze cresctor liniile matricei lund n
considerare elementul maxim al liniei.
Date de test:
4

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 10

Matricea ordonat:

Matricea care trebuie ordonat:


2

-3

1 3

Programul se va rezolva prin intermediul unui proiect i se vor scrie funcii pentru:
alocare cu verificarea alocrii (funcia xmalloc din curs), alocare dinamic pentru o
matrice (privit ca pointer la pointer), dealocare memorie pentru matrice, citire matrice,
afiare matrice, ordonare matrice, determinare element maxim de pe o linie,
interschimbare a dou linii. Toate funciile vor folosi operaii de lucru cu pointeri.
Funcia de interschimbare linii are prototipul:
void swap(TIP **l1, TIP **l2);
unde TIP este tipul elementelor matricei (stabilit de utilizator).
Apelul funciei swap se face prin instruciunea:
swap(&a[i], &a[i+1])
dac matricea considerat este a.
Problema nr. 2
S se scrie un program care testeaz doua funcii proprii de conversie a datei:
- dac se d ziua, luna i anul s se calculeze ziua din an (a cta zi din an este) cu
prototipul:
void f1(struct DATA *d);
- dac se d ziua din an i anul, s se determine ziua i luna care i corespund cu
prototipul:
void f2(struct DATA *d);
Indicaie:
Se va folosi o structur cu declaraia
struct DATA {
int zi, luna, an, zian;
};
iar variabila de tip structur va fi:
struct DATA d;
Se va folosi, de asemenea, un tablou pentru numrul de zile din cele 12 luni ale
anului. Se va ine cont i dac anul este bisect (se pot declara 2 tablouri, pentru an bisect
/nebisect). Funciile vor folosi ca argument un pointer la o structur de tip DATA. Apelarea
se va face utiliznd f1(&d) sau f2(&d);
5

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 10

Problema nr. 3
S se determine frecvena de apariie a unor cuvinte cheie dintr-un text (n particular
dintr-un program C). Textul se memoreaz pe linii ntr-un tablou de iruri de caractere (ca
n laboratorul anterior). Textul va conine cel puin 3 cuvinte cheie. Se va folosi un tablou
de structuri cu prototipul:
struct CHEI {
char *cuv;
int contor; /*nr.de apariii a cuvntului*/
};
Tabloul de structuri va fi inializat astfel:
struct CHEI tab_chei[]= {
"break", 0,
"case", 0,
/*alte cuvinte cheie */
"while", 0,
};
Problema nr. 4
Se consider un tablou de structuri de tip PERSONAL:
struct PERSONAL{
char *nume;
char *prenume;
int virsta;
};
struct PERSONAL tab_pers[20];
S se scrie un program care realizeaz urmtoarele:
- citete datele pentru n persoane; n fiind citit de la tastatur
- afieaz datele pentru aceste n persoane intr-un tabel (cu cap de tabel)
- afieaz toate persoanele care au vrsta sub 30 ani
- afieaz toate persoanele ordonate alfabetic dup nume, prenume i chiar dup
vrsta, n cazul n care se gsesc persoane cu acelai nume i prenume (nu se face
distincie ntre litere mari i mici).

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 10

Problema nr. 5
S se defineasc tipul de dat MATRICE (asociat unei matrice cu elemente reale) ca
o structur care cuprinde:
numele matricei memorat prin intermediul unui pointer (numele este format din
mai multe caractere);
numrul de linii i numrul de coloane care sunt numere ntregi fr semn;
elementele matricei (de tip real) stocate ntr-o zon de memorie alocat dinamic
(printr-un pointer la pointer)
S se scrie un program care pentru o matrice
1. citete de la tastatur numele matricei (unul sau mai multe caractere);
2. stocheaz toate informaiile referitoare la matrice ntr-o structur de tip MATRICE,
citind de la tastatur numrul de linii i de coloane i elementele matricei;
3. afieaz pe linii matricea citit (fiecare element cu cte 3 zecimale);
4. afieaz un meniu care d posibilitatea utilizatorului s aleag una din
urmtoarele prelucrri:
a) ordonarea matricei astfel nct elementele de pe diagonala principal s fie n

secven cresctoare
b) ordonarea matricei astfel nct elementele de pe diagonala secundar s fie n

secven descresctoare
c) ordonarea matricei astfel nct elementele de pe linia median vertical s fie n

secven cresctoare (n cazul n care matricea are un numr impar de coloane).


Programul poate face o singur prelucrare n funcie de opiunea utilizatorului i va
trebui scris astfel nct s permit prelucrarea mai multor seturi de date.
Observaii:
1) Punctajul maxim se acord pentru rezolvarea CORECT a fiecrei subprobleme.
Barem de notare
1.ncrcarea informaiilor ntr-o structur de tip MATRICE (funcia primete ca
parametru numele matricei un pointer i returneaz o structur de tip

1,0

MATRICE)
2. Alocarea corect de spaiu de memorie pentru pointeri (nume i matrice)
7

1,0

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 10

3. Citirea elementelor matricei (ntr-o funcie care primete ca parametri dou


numere naturale i returneaz un pointer la pointer la real)
4. Afiarea pe monitor a matricei citite (funcia are un parametru un pointer la o
structur de tip MATRICE i nu returneaz nimic)
5. Scrierea meniului de prelucrare (funcia nu are nici un parametru i returneaz
un numr care reprezint numrul opiunii de prelucrare)

1,0

0,5

0,5

6. posibilitatea de reluare a programului (prelucrarea mai multor seturi de date)

0,5

7. Folosire proiect (corect)

0,5

8. Fiier header (corect i complet)

0,4

8a. Definirea corect a structurii de tip MATRICE


9. Funcia main (complet inclusiv eliberarea corect a zonelor de memorie
folosite)

0,1
1,0

10. Interschimbarea valorilor a doi vectori de reali (funcia primete ca parametri


doi pointeri la pointer la real i nu returneaz nimic) funcie folosit n funciile

0,5

de ordonare
11. Ordonarea (prin metoda bulelor) dup diagonala principal (funcia primete
ca parametru un pointer la o structur de tip MATRICE i nu returneaz nimic)
12. Ordonarea (prin metoda bulelor) dup diagonala secundar (funcia primete
ca parametru un pointer la o structur de tip MATRICE i nu returneaz nimic)

1,0
1,0

13. Ordonarea (prin metoda bulelor) dup linia median vertical (funcia
primete ca parametru un pointer la o structur de tip MATRICE i nu returneaz

1,0

nimic)
TOTAL TABEL

10 p

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 11

POINTERI LA FUNCII
1. Declararea unui pointer la funcii .......................................................................................1
2. Pointeri la funcii ca argumente n alte funcii ....................................................................5
2.1. Exemplu ......................................................................................................................5
2.1.1. Calculul ariei domeniului mrginit de graficul unei funcii ....................................5
3. Tablouri de pointeri la funcii..............................................................................................7
4. Pointeri la funcii ca membri n structuri.............................................................................8
TEMA .....................................................................................................................................9
Problema nr. 1 ....................................................................................................................9
Problema nr. 2 ....................................................................................................................9
Problema nr. 3 ....................................................................................................................9
Problema nr. 4 ..................................................................................................................10
Problema nr. 5 ..................................................................................................................10

1. Declararea unui pointer la funcii


Pointerii folosii pn acum au fost pointeri la diferite tipuri de date, dar este posibil
s avem i pointeri la funcii. Pointerii la funcii sunt folosii din aceleai motive ca i
pointerii la date: atunci cnd se dorete un alt nivel de indirectare, cnd dorim ca aceeai
secven de cod s apeleze funcii diferite depinznd de condiiile concrete ale
programului.
Ca i n cazul pointerilor la date, pentru utilizarea pointerilor la funcii trebuie s
declarm o variabil care s conin un pointer la funcie. Un pointer la o funcie se
declar astfel:
tip (*pf)(tip1 p1, tip2 p2, ..., tipn pn);
unde
tip este tipul funciei (tipul valorii returnate de funcie)
tip1 p1, tip2 p2, ..., tipn pn este lista parametrilor funciei care va fi accesat prin
intermediul pointerului. Numele parametrilor, adic p1, p2, ..., pn pot lipsi.
Exemplu, dac scriem
int (*pfi)(float a, int b);
se declar pfi ca fiind un pointer la o funcie care va returna un ntreg. Ca i n alte
declaraii * indic faptul c avem un pointer, iar ( ) arat c avem de a face cu o funcie.
1

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 11

Parantezele din (*pfi) sunt necesare deoarece i n declaraii exist o anumit preceden
a operatorilor (o anumit ordine de evaluare interpretare) ca i n expresii i cnd
ordinea implicit nu este cea dorit, trebuie s o schimbm folosind parantezele de
explicitare. n declaraii, ( ) - operatori de funcie i [ ] - operatorii de indexare sunt mai
prioritari dect * indicnd pointerii. Fr parantezele menionate, declaraia de mai sus
arat astfel:
int *pfi(float a, int b);
i declar o funcie pfi care va returna un pointer la ntreg. Cu parantezele explicite, int
(*pfi)() ne spune c pfi este mai nti un pointer, c acest pointer indic o funcie i mai
apoi c funcia respectiv returneaz un ntreg.
Pointerii la funcii se pot defini i ca noi tipuri de date prin utilizarea declaraiei de tip
typedef. De exemplu, putem scrie
typedef int (*FPTR)(float a, int b);
i identificatorul FPTR este un sinonim pentru tipul de dat pointer la o funcie care
returneaz un ntreg, astfel nct declaraia
FPTR pfi;
este echivalent cu
int (*pfi)(float a, int b);
O dat declarat, unui pointer la funcie i se poate atribui valoarea adresei de nceput
a funciei dorite. Dac avem prototipurile urmtoarelor funcii
int f1(float a, int b);
int f2(float a, int b);
int f3(float a, int b);
atunci putem scrie:
pfi = &f1;
sau
if (conditie)
pfi = &f2;
else
pfi = &f3;
Bineneles, nu vom fi restrni la aceste dou forme, putem asigna pointeri la funcii
n orice condiii dorim. Al doilea exemplu poate fi scris mai compact:
pfi = conditie ? &f2 : &f3;
n aceste exemple am folosit operatorul &, aa cum am fcut pn acum pentru a
genera un pointer. Totui cnd generm pointeri la funcii, operatorul & este opional,
2

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 11

deoarece atunci cnd menionm numele unei funcii fr s o apelm menionm de fapt
adresa funciei respective, numele unei funcii fiind de fapt un pointer la funcia dat. Astfel
se poate scrie:
pfi = f1;
sau
if (conditie)
pfi = f2;
else
pfi = f3;
sau
pfi = conditie ? f2 : f3;
Faptul c un pointer la o funcie este generat automat cnd o funcie apare ntr-o
expresie, dar nu este apelat este asemntor, i de fapt este de legat de faptul c un
pointer la primul element al unui vector este generat automat atunci cnd un vector apare
ntr-o expresie.
Avnd o variabil pointer la o funcie care conine adresa unei funcii, putem apela
(folosi) funcia respectiv astfel:
1. scriem numele variabilei pointer la funcie
pfi
2. se folosete operatorul * n fa pentru "a accesa coninutul acelui pointer"
*pfi
Aceast expresie reprezint tocmai funcia pe care dorim s o folosim.
3. adugm lista de parametri n paranteze mpreun cu un set de paranteze
pentru a avea precedena dorit a operaiilor:
(*pfi)(arg1, arg2)
Formm astfel apelul la funcie.
Parantezele din expresia (*pfi) au aceeai explicaie ca la declararea pointerului la o
funcie. Dac scriem
*pfi(arg1, arg2)
interpretarea este: apeleaz funcia pfi (care va returna un pointer), transfer-i
argumentele arg1 i arg2 i ia coninutul de la adresa indicat de variabila pointer la
ntoarcere. Totui ceea ce dorim s facem este urmtorul lucru: ia coninutul lui pfi (care
este un pointer la o funcie), apeleaz funcia spre care pointeaz, transmindu-i

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 11

argumentele arg1 i arg2. Din nou, parantezele explicite schimb precedena implicit,
astfel nct se aplic mai nti operatorul * i apoi se apeleaz funcia.
Expresia
pfi(arg1, arg2)
este echivalent cu
(*pfi)(arg1, arg2).
Atunci cnd apelm o funcie pointat de un pointer la funcie, operatorul * este
opional. Este recomandabil folosirea lui pentru a scoate n evidena faptul c folosim un
pointer la funcie i nu o funcie propriu-zis.
Pentru fiecare funcie folosit trebuie s avem un prototip pentru a permite
compilatorului s genereze corect codul pentru apelul funciilor i s verifice dac funcia
este apelat cu numrul i tipul adecvat pentru argumente.
n general nu se va ti dect n momentul rulrii programului care este funcia
pointat de pfi, astfel nct compilatorul nu poate verifica dac apelul s-a fcut corect. Pe
de alt parte, atunci cnd am declarat un pointer la funcie a trebuit s declarm tipul
valorii returnate de funcia respectiv. De asemenea, putem declara prototipul
argumentelor folosite de funcie, adic putem scrie:
int (*pfi)(float a, int b);
Acum tim c pfi este un pointer la o funcie care accept dou argumente i care
returneaz un ntreg. Avnd toate acestea specificate, compilatorul va putea s verifice
corectitudinea anumitor apeluri pentru funcia respectiv. De exemplu, dac scriem:
(*pfi)(1, 2, 3)
compilatorul va semnaliza eroare, pentru c el tie c funcia nu poate accepta dect dou
argumente. De asemenea, compilatorul va verifica dac funciile spre care pointeaz
variabila pointer la funcie au lista de argumente i valoarea de retur n concordan cu
declaraia pentru pointer.
Deci pentru o variabil pointer la funcie trebuie s declar att tipul valorii returnate,
ct i tipul argumentelor din lista de argumente.
Alte exemple de construire a pointerilor la funcii:
double (*a)(int);
float (*b)(char *);
int * (*f1)(double, int);
double *(*f2)(char *, int , double *);

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 11

2. Pointeri la funcii ca argumente n alte funcii


n continuare s presupunem c o funcie f are ca parametru o funcie g. Dac se
scrie:
f(g);
nseamn c lui f i se transmite un pointer la funcia g.
Dac prototipul funciei g este
tip_g g(lista_g);
atunci prototipul funciei f n care g este parametru va fi
tip_f f(tip_g (*g)(lista_g));
sau
tip_f f(tip_g (*)(lista_g));
iar definiia funciei f va fi
tip_f f(tip_g (*p)(lista_g)) { .}
unde (*p) poate fi i (*g).
Exemple:
int g(double);
double f(int (*)(double));
2.1. Exemplu
2.1.1. Calculul ariei domeniului mrginit de graficul unei funcii
Valoarea ariei domeniului mrginit de graficul unei funcii este valoarea integralei
acelei funcii, valoare calculat lund ca limite capetele intervalului de reprezentare.
Fie funcia, considerat fr bucle:

f : [a, b] R

(1)

Pentru calculul integralei se va folosi metoda trapezelor. Intervalul [a,b] va fi mprit


n n diviziuni, astfel c mrimea unei diviziuni va fi:
dx =

ba
n

(2)

Punctele xi se vor calcula cu expresia:


x i = a + i dx = x i 1 + dx cu

i = 1,K, n 1

(3)

iar aria corespunztoare unei diviziuni (aria parial) este:


Ai =

f (x i ) + f (x i +1 )
(x i +1 x i )
2

Integrala se obine ca sum a ariilor pariale:


5

(4)

PROGRAMAREA CALCULATOARELOR
n 1

I n = Ai =
i =0

Lucrarea nr. 11

b a f (a) + f (b ) n1

+ f (x i )
2
n
i =1

(5)

Aceast modalitate de calcul a ariei este acelai, indiferent de expresia funciei f.


Dac vom lua n considerare de fiecare dat forma funciei f va trebui s scriem o funcie
care calculeaz integrala pentru fiecare funcie pe care trebuie s o utilizm. Pointerii la
funcii ne permit s transmitem ca parametru funcia pentru care vrem s calculm
integrala astfel nct vom lua n considerare urmtorul prototip:

double integralaTrapez(double a, double b, int n, double (*f)(double));


n care:

a, b reprezint capetele intervalului de integrare


n numrul de diviziuni ale intervalului
f pointer la o funcie care primete un parametru de tip double i returneaz o
valoare de tip double. Aceast funcie calculeaz valorile funciei pentru care vrem s
calculm integrala ntr-un punct specificat ca parametru. Funcia poate fi o funcie proprie
sau o funcie din biblioteca matematic (de exemplu sin, sqrt, etc).
Funcia integralaTrapez implementeaz formula (5) i are forma:

double integralaTrapez(double a, double b, int n, double (*f)(double))


{
double val;

// Valoarea integralei

double dx = (b-a)/n;
double x;
val = ((*f)(a) + (*f)(b))/2;
for(x=a+dx; x<b; x = x+dx)
val = val + (*f)(x);
val = val * dx;
return val;
}
Ce semnific urmtoarele declaraii?

int f1(int a, double (*f)(float *b));


int f2(int a, double f(char c), int (*g)(int d, int *e));
float *f3(double *a, int * (*f)(double));
double (*fc)(int a, float ff(void));
int *(*fd)(float *a, double *f(int *d));
6

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 11

3. Tablouri de pointeri la funcii


Ca orice tip de date pointerii la funcii se pot grupa n tablouri.
Exemplu:avem un tablou de pointeri la funcii care primesc ca parametru un double i
returneaz un double:
double (*fm[10])(double);
Pentru citirea acestor declaraii folosim aa-numite regul de citire dreapta-stnga:
se pornete de la numele variabilei fm, n dreapta avem [10] (deci este un;tablou, aici de
10 elemente); mergem n stnga: avem * (tablou de 10 elemente pointeri); din nou n
dreapta ( (tablou de 10 elemente pointeri la funcii); din nou stnga double (tablou de 10
pointeri la funcii care returneaz un double); la dreapta double lista de argumente a
funciilor. n concluzie avem un tablou de 10 elemente, fiecare din ele este un pointer la o
funcie care returneaz un double i primete ca parametru o dat de tip double.
Exemplu: s se scrie un program care tabeloeaz funciile trigonometrice sin, asin,
cos, acos, tan, atan ntre 0 i 1 rad cu pasul de 0.05.

#include <stdio.h>
#include <math.h>
int main(void)
{
double (*fm[])(double x) = {
sin, asin, cos, acos, tan, atan};
int i;
double x;
double dx = 0.05;
int nf = sizeof(fm)/sizeof(fm[0]);
puts("Tabelul");
for(x=0; x<=1; x+= dx)
{
printf("x = %5.3lf f= ", x);
for(i=0; i<nf; i++)
printf("%5.3lf ", (*fm[i])(x));
7

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 11

printf("\n");
}
return 0;
}

4. Pointeri la funcii ca membri n structuri


Pointerii la funcii pot apare i ca membri n structuri de date.
Aceast construcie poate fi utilizat pentru construirea unor meniuri, de exemplu.
Fie tipul de dat FM sinonim pentru un pointer la funcie care primete un double i
returneaz un double:

typedef double (*FM)(double x);


O structur care are n componen acest pointer se declar astfel:

struct S1 {
................ /* declaraii pentru ali membri */
FM f;

/* echivalent cu double (*f) (double x); */

................ /* declaraii pentru ali membri */


};
Putem construi astfel o structur care s conin numele unei funcii i un pointer la
funcia respectiv. Exemplu:

struct functii {
char *nume;
double (*f) (double x);
};
n programul principal putem iniializa un tablou de astfel de structuri pentru a-l folosi
la construirea unui meniu. Exemplu:

struct functii tab_f[] = {


"sinus", sinus,
"cosinus", cos,
"tangenta", tan };
Definiia funciei pentru construirea meniului este:
8

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 11

void meniu(struct functii tab[], int nf, char *msg)


{
int i;
clrscr();
puts(msg);
for(i=0; i<nf; i++)
printf("\t%d - %s\n",i+1, tab[i].nume);
printf("\t0 - exit\n");
printf("\t >> ");
}
n aceast funcie tab[i].nume este numele prelucrrii (funciei) dorite, iar apelul
acestei funcii este (*tab_f[i].fm)(x) (tab_f este tabloul de structuri definit mai sus).

TEMA
Problema nr. 1
Folosind tablouri de pointeri la funcii, s se scrie un program care tabeleaz funciile
de bibliotec sinus, cosinus i tangent pentru valori cuprinse ntre 0 i cu un pas egal
cu /20.

Problema nr. 2
S se calculeze urmtoarele integrale:
1

sin( x + 3x)dx
2

1
2

(x + 4 x + e )dx
2

Indicaie:
Se va folosi pentru calculul integralei funcia integralaTrapez prezentat la curs.

Problema nr. 3
S se declare o structur norme care conine ca membri un pointer la caracter i un
pointer la o funcie care returneaz un double i primete ca parametri un pointer la double
i un ntreg (dup modelul structurii functii dat mai sus).
S se scrie un program care calculeaz, pentru un tablou unidimensional (vector)
urmtoarele norme:
9

PROGRAMAREA CALCULATOARELOR

Lucrarea nr. 11

= max x i

- norma infinit

x 1 = x1 + x 2 + ... + x n

x1 + x 2 + ... + x n

- norma 1
2

- norma 2

Programul definete i iniializeaz (dup modelul dat mai sus) un tablou de structuri
norme cu numele i funciile care calculeaz cele trei norme, afieaz un meniu care

folosete acest tablou de structuri, iar prelucrarea dorit se va face prin intermediul
pointerilor la funcii.
Se poate folosi, ca exemplu, funcia meniu dat mai sus.
Problema nr. 4

S se defineasc o funcie generic de ordonare a unui ir de date (metoda folosit


este metoda bulelor). Funcia primete ca parametri adresa zonei de memorie unde se
gsete irul de date (un pointer generic), numrul de date care se ordoneaz,
dimensiunea unui element din ir, precum i un pointer la o funcie care realizeaz
compararea a dou elemente din ir.
S se defineasc o funcie generic de interschimbare a dou elemente dintr-un ir
de date (funcie ce poate fi folosit pe orice tip de date).
Folosind aceste funcii s se scrie un program care face ordonarea unor date citite
de la tastatur i afieaz irul ordonat pe monitor. Aceste date pot fi: un ir de numere
reale n dubl precizie sau un text.
Atenie! Trebuie scris o singur funcie de ordonare (sortare) care va fi folosit

att pentru sortarea textului ct i a irului de date numerice i o singur funcie de


interschimbare.
Problema nr. 5

Se reia Problema nr. 4 folosind funcia de bibliotec qsort.

10

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 12

ARGUMENTELE LINIEI DE COMAND.


LUCRUL CU FIIERE LA NIVEL INFERIOR
1. Argumentele liniei de comand i parametrii funciei main().............................................2
2. Lucrul cu fiiere la nivel inferior .........................................................................................4
2.1. Prezentare general....................................................................................................4
2.2. Operai cu fiiere la nivel inferior.................................................................................6
2.2.1. Deschiderea i crearea unui fiier ........................................................................6
2.2.2. Detectarea sfritului de fiier ............................................................................10
2.2.3. Duplicarea descriptorului unui fiier ...................................................................10
2.2.4. Schimbarea descriptorului unui fiier .................................................................10
2.2.5. Citirea dintr-un fiier ...........................................................................................10
2.2.6. Scrierea ntr-un fiier ..........................................................................................11
2.2.7. Poziionarea ntr-un fiier....................................................................................12
2.2.8. nchiderea unui fiier ..........................................................................................13
2.2.9. Citirea / modificarea drepturilor de acces la un fiier .........................................14
TEME ...................................................................................................................................15
Problema nr. 1..................................................................................................................15
Problema nr. 2..................................................................................................................15
Problema nr. 3..................................................................................................................15
Problema nr. 4..................................................................................................................16
Problema nr. 5..................................................................................................................16

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 12

1. Argumentele liniei de comand i parametrii funciei main()


Orice program C trebuie s aib o funcie main.. Rutina de startup transmite funciei
main trei parametrii (argumente): argc, argv i env.
argc este de tip int i reprezint numrul argumentelor din linia de comanda
transmise funciei main (in linia de comanda sau direct din compilator Run | Arguments)
argv este un tablou de pointeri la caracter (char *[ ]). Fiecare element din acest
tablou conine adresa de nceput a unui ir de caractere i au urmtoarele semnificaii:
argv[0] conine adresa de nceput a irului de caractere care reprezint numele complet al
programului n curs de execuie (include calea ctre directorul care conine programul
executabil); argv[1] conine adresa de nceput a priimului ir de caractere tastat n linia de
comand dup numele programului (de care este separat printr-un spaiu); argv[argc-1]
conine adresa de nceput a ultimului argument al liniei de comand transmis funciei
main; argv[argc] este NULL.
Aceste argumente (ce sunt iruri de caractere separate prin spaii) se specific n
linia de comand sub forma:
nume_program arg1 arg2 ...argn
n cazul folosirii mediului BorlandC 3.1, aceste argumente se pot specifica i n linia
corespunztoare meniului Run-Arguments (cnd nu se indic numele programului).
- env este tot un tablou de pointeri la caracter i fiecare element din tablou conine
un ir de forma ENVVAR = value, unde ENVVAR este numele unei variabile de mediul
(PATH, PROMPT, etc.), iar value este irul de caractere asociat. Nu se poate ti n avans
(ca la argv) numrul de elemente din tablou, dar se tie c ultimul element din tablou are
valoarea 0 (NULL). Astfel explorarea tabloului env se continu pn cnd se ntlnete un
element al tabloului egal cu 0 (zero).
Observaie:
Cu ajutorul comenzii DOS, SET se pot declara un set de variabile de mediu
environment, variable accesibile pentru citire din orice program care ruleaz n respectivul
mediu (sistem de operare). Sistemul de operare adaug automat parametrii PROMPT i
PATH (dup lansarea acestor comenzi) i COMSPEC (la ncrcarea sistemului - indic
unitatea i calea utilizat pentru rencrcarea interpretorului de comenzi).
Cei trei parametri ai funciei main trebuie declarai exact n ordinea menionat (chiar
dac se pot folosi i alte nume); sunt deci posibile 4 forme ale acestei funciei:
Int main(void);
Int main(int argc);
Int main(int argc, char *argv[ ]);
2

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 12

Int main(int argc, char *argv[ ], char *env[ ]);


n urmtorul exemplu, programul afieaz pe monitor argumentele liniei de comand
i variabilele de mediu specifice calculatorului de pe care este lansat n execuie:
#include <stdio.h>
#include <conio.h>
int main(int argc, char *argv[ ], char *env[ ])
{
int i;
clrscr();
for (i=0; i<argc; i++)
{
printf("argv[%d] : %s\n", i, argv[i]);
}
getch();
clrscr();
for (i=0; env[i]!=NULL; i++)
{
printf("env[%d] : %s\n", i, env[i]);
}
getch();
return 0;
}
Observaie:
Argumentele liniei de comand pot conine blanc-uri dac sunt ncadrate ntre
ghilimele (acestea vor dispare la prelucrarea argumentelor). Lungimea maxim a
argumentelor liniei de comand transmise funciei main (inclusiv numele programului i
spaiile dintre argumente) este de 128 de caractere (limitarea este dat de sistemul de
operare DOS).
Argumentele liniei de comand pot conine caracterele wildcard (*, ?). Aceste
argumente se comport ca nite "modele" ale numelor fiierelor care trebuie transmise
ctre program. Caracterul * nlocuiete un ir de caractere din nume, iar caracterul ?
nlocuiete un singur caracter. Pentru aceasta trebuie s se includ n proiect fiierul
3

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 12

WILDARGS.OBJ care se gsete n directorul (folderul) borlandc\lib. n acest caz tabloul


argv va fi completat cu adresele de nceput ale unor iruri de caractere care conin numele
tuturor fiierelor care corespund modelului dat n linia de comand. Acest proces se
numete expandarea liniei de comand (pentru c, n general, exist mai multe nume de
fiiere care corespund aceluiai "model"). Dimensiunea tabloului argv depinde de mrimea
memoriei disponibile. Dac nu se gsete nici un fiier al crui nume s se potriveasc
modelului din linia de comand, argumentul este transmis neschimbat (nu se
expandeaz). Argumentele ncadrate ntre ghilimele nu sunt expandate. Deci dac se vrea
ca tabloul argv s conin anumite fiiere, s spunem toate fiierele cu extensia .c din
directorul de lucru, linia de comand este (p1 este numele programului):
p1 *.c
Dac p1 este programul din exemplul de mai sus, pe monitor se vor afia toate
fiierele cu extensia .c din directorul de lucru.

2. Lucrul cu fiiere la nivel inferior


2.1. Prezentare general
Un fiier este o colecie de date sau informaii care are un nume. Toate informaiile
existente ntr-un calculator trebuie s fie cuprinse ntr-un fiier. Sunt diferite tipuri de
fiiere: fiiere de date, fiiere text, fiiere program, fiiere director (i directoarele sunt de
fapt nite fiiere), etc. Exist tipuri diferite de fiiere pentru c exist tipuri diferite de
informaie care trebuie stocat. De exemplu, n fiierele executabile gsim programe care
pot fi lansate n execuie, n timp ce fiierele text conin pur i simplu texte. Fiierele sunt
necesare pentru pstrarea informaiilor n vederea utilizrii lor ulterioare, ca atare sau
prelucrate conform unor algoritmi utilizator. Informaiile stocate n fiiere pot fi introduse de
pe un suport extern sau pot fi rezultate din aplicarea algoritmului de calcul. Exist dou
mari categorii de fiiere: fiiere text i fiiere binare. Fiierele text sunt fiiere n care
caracterele sunt reprezentate prin codul lor (ASCII sau UNICODE), deci conin numai
codurile tipribile; ele pot fi citite cu uurin de operatorul uman. Fiierele binare sunt
accesibile pentru prelucrare numai calculatorului, nu i operatorului uman; aceste fiiere
pot conine att coduri ale caracterelor tipribile, ct i codificarea binar a operaiilor pe
care un program trebuie s le execute.
Diversele tipuri de date stocate n fiiere sunt grupate n nregistrri. Fiecare
nregistrare dintr-un fiier conine aceleai tipuri de date (i n aceeai ordine), ca urmare
putem spune c fiierul este o colecie de nregistrri i se caracterizeaz prin
urmtoarele:
4

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 12

- nregistrrile (ce conin date) sunt omogene din punctul de vedere al coninutului;
- nregistrrile sunt stocate intr-o ordine cunoscuta, specifica fiierului;
- este definit cel puin un criteriu de regsire a unei nregistrri din fiier
Fiierele sunt pstrate pe suporturi de memorie extern definite de utilizator (diskete,
discuri dure (hard discuri), benzi magnetice, CD, DVD, stick-uri de memorie).
Prelucrarea fiierelor implic un numr de operaii specifice acestora. Pentru ca un
fiier s poat fi prelucrat el trebuie mai nti deschis (dac exist) i apoi nchis (dup
prelucrare). Dac fiierul nu exist, el va fi mai nti creat. ntre aceste dou operaii
(deschis/inchis) pot fi programate diverse alte aciuni:
- adugare nregistrri, constnd n construirea unor noi nregistrri i scrierea lor n fiier
cu respectarea ordinii i a criteriului de regsire;
- tergerea unei nregistrri, constnd n eliminarea acesteia din fiier cu respectarea
ordinii nregistrrilor rmase i a criteriului lor de regsire;
- consultarea (citirea unei nregistrri sau a mai multora) n scopul utilizrii unor date, fr
a modifica coninutul fiierului;
- actualizarea constnd n citirea unei nregistrri, modificarea unei date (sau mai multor
date) din cuprinsul nregistrrii urmat obligatoriu de o rescriere (salvare) a nregistrrii
astfel actualizate.
Toate aceste prelucrri se realizeaz utiliznd funcii din bibliotecile standard ale
limbajului C, funcii ale cror prototipuri se gsesc n fiierele header: stdio.h, io.h, fcntl.h,
sys\stat.h.
Prelucrarea fiierelor se poate face pe doua nivele:
- nivel inferior, care face apel direct la sistemul de operare. Pe acest nivel fiecrui fiier i
se asociaz un descriptor de fiier (o variabil de tip ntreg);
- nivel superior, cnd se face apel la proceduri specializate n prelucrarea fiierelor (de
exemplu rezervarea unor zone tampon speciale pentru operaii de intrare / ieire) i cnd
fiecrui fiier cu care se lucreaz i se asociaz un pointer la o structur de tip FILE (se va
detalia n Lucrarea nr. 13).
Observaie: n cele ce urmeaz expresia pointer de fiier va fi folosit pentru a denumi
indicatorul de poziie curent n fiier (poziia n fiier de unde putem citi sau unde putem
scrie). Nu confundai "pointer de fiier", n sensul de poziia curent n fiier, cu un pointer
pe o structur de tip FILE !!!
Pentru lucrul cu fiiere pe nivel inferior este necesar includerea urmtoarelor fiiere
header: io.h, fcntl.h, sys\stat.h. Dup folosirea oricrei funcii se recomand testarea
valorii returnate pentru a verifica dac operaia s-a executat corect sau nu.
5

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 12

2.2. Operai cu fiiere la nivel inferior


2.2.1. Deschiderea i crearea unui fiier
Deschiderea unui fiier se face cu funcia open. Aceast funcie returneaz un
numr ntreg, numit descriptor de fiier (df) sau numr logic. El este utilizat apoi de
sistemul de operare pentru a identifica fiierul n toate operaiile realizate asupra lui.
Pentru fiierul standard de intrare, adic pentru intrarea de la tastatur, descriptorul de
fiier, df = 0, pentru fiierul standard de ieire, care este ecranul monitorului, df = 1, pentru
fiierul standard de afiare a erorilor, df = 2. nchiderea i deschiderea acestor trei fiiere
se face automat de ctre sistem (deci ele nu se deschid i nu se nchid de ctre
programator).
Prototipul funciei open, aflat n fiierul header io.h este:
int open(const char *numefiier, int acces [,unsigned mod]);
unde:
- numefiier este un pointer la caracter care definete numele fiierului care se deschide
(inclusiv calea lui, dac este cazul);
- acces este o variabil de tip ntreg care poate lua una din valori:
O_RDONLY

- fiier deschis numai pentru citire;

O_WRONLY

- fiier deschis numai pentru scriere;

O_RDWR

- fiier deschis pentru citire / scriere;

O_APPEND

- fiierul se deschide pentru adugare de nregistrri (indicatorul de poziie


din fiier se poziioneaz dup ultima nregistrare);

O_BINARY

- fiierul care se deschide este binar;

O_TEXT

- fiierul care se deschide este de tip text.

O_CREAT

- nu are efect daca fiierul exist; dac nu exist fiierul este creat i
biii din mod stabilesc atributele fiierului ca la funcia chmod(...);

O_TRUNC

- dac fiierul exist, lungimea sa este trunchiat la zero, atributele


rmnnd neschimbate;

O_EXCL

- se folosete numai cu O_CREAT; se returneaz eroare dac fiierul


exista deja;

Fiecreia din aceste valori i corespunde un bit din variabila de tip ntreg access i
aceste valori se pot combina cu ajutorul operatorului de lucru pe bii SAU (|), de exemplu
pentru a deschide un fiier pentru numai pentru citire binar pentru access se va folosi
combinaia
O_RDONLY | O_BINARY.
6

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 12

Dac acces include O_CREAT, atunci trebuie precizat i valorile pentru parametrul
mod folosind una urmtoarele constante simbolice (definite n sys\stat.h):
S_IWRITE

se permite scrierea;

S_IREAD

se permite citirea;

S_IREAD | S_IWRITE

se permit scrierea i citirea;

n caz de succes, funcia open returneaz un ntreg nenegativ care reprezint


descriptorul de fiier i poziioneaz indicatorul de poziie curent la nceputul fiierului. n
caz de eroare, funcia returneaz valoarea -1.
Calea unui fiier respect conveniile din MS_DOS. Dac fiierul se afl n directorul
implicit (de lucru), calea se reduce doar la numele fiierului. Dac fiierul nu se afl n
directorul implicit, calea cuprinde unitatea, directorul i subdirectoarele n care se afl
fiierul i bineneles numele lui.
Funciile de deschidere a unui fiier (open) i de creare a unui fiier(creat) sunt
singurele funcii n care se indic explicit numele fiierului cu care dorim s lucrm n
program. Toate celelalte funcii se refer la acest fiier prin descriptorul de fiier asociat.
Exemple:
char nume[] = "test.dat";
int df;
...
df = open (nume, O_RDONLY);
if(df == -1)
{
fprintf(stderr, "Fisierul %s nu s-a putut deschide.\n", nume);
exit(EXIT_FAILURE);
}
...
Fragmentul de program de mai sus are urmtorul efect: se deschide n numai pentru
citire fiierul "test.dat" care se afl n directorul implicit. Descriptorul de fiier se atribuie
variabilei de tip ntreg "df".
char nume[] = "A:\\USER\\CB\\sport.c";
int df;
...
df = open (nume, O_RDWR);
if(df == -1)
7

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 12

{
fprintf(stderr, "Fisierul %s nu s-a putut deschide.\n", nume);
exit(EXIT_FAILURE);
}
...
Fragmentul de program de mai sus are urmtorul efect: se deschide pentru citire /
scriere fiierul sport.c aflat pe discul flexibil din unitatea A, n directorul USER i
subdirectorul CB.
Fiierele binare pot fi deschise i cu funcia _open, cu prototipul:.
int _open(const char *numefiier, int acces);
- deschide fiierul specificat prin numefiier pentru citire sau scriere;
- are prototipul n io.h;
- fiierul este deschis ntotdeauna n mod binar;
- acces se poate compune folosind urmtoarele constante simbolice definite n FCNTL.H
i operatorul de lucru pe bii SAU (|):
O_RDONLY

- fiierul se deschide numai pentru citit;

O_WRONLY

- fiierul se deschide numai pentru scriere;

O_RDWR

- fiierul se deschide pentru citire/scriere;

O_NOINHERIT

- fiierul nu este transmis programelor fiu;

O_DENYALL

- numai descriptorul de fiier curent va putea accesa fiierul;

O_DENYWRITE

- alt deschidere a fiierului va putea face numai citiri;

O_DENYREAD

- alt deschidere a fiierului va putea face numai scrieri;

O_DENYNONE

- permite alte deschideri partajate ale fiierului;

- se poate folosi o singur valoare dintre O_DENYxxx;


- returneaz descriptorul de fiier asociat n caz de succes sau -1 la eroare;
- indicatorul de poziie curent este poziionat pe nceputul fiierului;
- numrul fiierelor ce pot fi deschise simultan este definit n fiierul io.h i este 200.
Pentru a crea un fiier nou, se folosete funcia creat care returneaz descriptorul de
fiier sau -1 n caz de eroare. Utilizarea funciei creat presupune includerea fiierelor
header io.h i sys\stat.h.
Prototipul funciei creat este:
int creat(const char *numefiier, int acces);
unde:
numefiier

- are aceeai semnificaie ca la funcia open

PROGRAMAREA CALCULATOARELOR

acces

LUCRAREA NR. 12

- un ntreg care indic modul de acces i care poate lua una din valorile
(vezi sys\stat.h) date date de constantele simbolice:
S_IREAD

- fiierul poate fi citit;

S_IWRITE

- se poate scrie n fiier;

S_IEXEC

- fiierul conine un program care se poate executa.

Se pot realiza combinaii ntre aceste opiuni folosind caracterul "|".


Exemplu:
S_IREAD | S_IWRITE
Dac funcia creat este folosit pentru un fiier care exist deja, lungimea lui va fi
resetat (fcut egal cu zero, operaie care este echivalent cu tergerea fiierului) i,
apoi, se va crea un alt fiier cu acelai nume. Pentru crearea unui fiier binar, se utilizeaz
funcia _creat.
int _creat(const char *numefiier, int atribut);
- creeaz un fiier nou sau suprascrie unul existent;
- are prototipul n io.h;
- fiierul este deschis totdeauna n modul binar, att pentru scriere ct i pentru citire;
- daca fiierul exist, mrimea sa este modificata la zero (se pastreaza practic numai
numele);
- argumentul atribut se poate compune din constantele (definite n dos.h);
FA_RDONLY

fiier deschis numai pentru citire

FA_HIDDEN

- fiier ascuns

FA_SYSTEM

- fiier sistem

- returneaz descriptorul pentru noul fiier n caz de succes, altfel returneaz valoarea -1;
Tot pentru crearea unui fiier, putem utiliza funciile:
int creatnew(const char *numefiier, int mod);
- creeaz un fiier nou;
- are prototipul n io.h;
- este identic cu _creat(...) numai ca, dac fiierul exist, se returneaz codul de eroare (1) i se las fiierul nemodificat;
int creattemp(char *cale, int atribut);
- se creeaz un fiier temporar n directorul indicat prin cale;
- are prototipul n io.h;
- cale trebuie s se incheie cu "\" (evident dublat !) i s fie suficient de mare pentru a
pstra i numele de fiier obinut (de forma AHBKCIDC., AHBLCFCD. etc.);
- fiierul creat nu este ters automat la terminarea programului;
9

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 12

- atribut este acelai ca la _creat(...);


- returneaz descriptorul pentru fiier n caz de succes, altfel -1;
2.2.2. Detectarea sfritului de fiier
Detectarea sfritului de fiier (markerul EOF) se face apelnd funcia:
int eof (int df);
Funcia are prototipul n io.h i returneaz 1 dac n fiierul asociat cu descriptorul df
s-a detectat End-Of-File (EOF), altfel returneaz valoarea 0;
Dac valoarea returnat este -1 atunci s-a detectat o eroare (Bad file number).
2.2.3. Duplicarea descriptorului unui fiier
Descriptorul unui fiier se poate duplica folosind funcia:
int dup(int df);
Noul descriptor, returnat de dup, se refer la acelai fiier ca i descriptorul df. Avem
n acest caz pentru un acelai fiier doi descriptori de fiier.
2.2.4. Schimbarea descriptorului unui fiier
Descriptorul de fiier se poate schimba cu funcia (are prototipul n io.h):
int dup2(int vechiul_descriptor, int noul_descriptor);
Aceast funcie creeaz un nou descriptor de fiier avnd urmtoarele elemente n
comun cu originalul:
- acelai fiier deschis sau dispozitiv de I/E;
- aceeai poziie curent n fiier
- acelai mod de acces
Dac fiierul asociat cu noul descriptor este deschis, la apelarea funciei dup2, va fi
nchis. Noul descriptor i vechiul descriptor sunt obinute prin una din funciile creat(...),
open(...), dup(...) sau dup2(...) (dup(...) lucreaz i cu descriptori obinuti prin _creat(...)
sau _open(...)).
Funcia returneaz 0 pentru succes, altfel -1;
2.2.5. Citirea dintr-un fiier
Dup deschiderea fiierului, informaia din fiier se citesc pe blocuri de octei. De
fiecare dat se returneaza numrul octeilor citii. n io.h exist prototipurile a dou funcii
pentru citire:
int read(int df, void *buf, unsigned lung);
10

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 12

unde:
df

- descriptorul de fiier, returnat de una din funciile open(), creat(), dup() sau

dup2()
buf - pointer spre o zona de memorie n care se stocheaz octeii citii;
lung - lungimea maxim n octei a blocurilor care se citesc.
Dup orice citire, indicatorul de poziie curent din fiier, se incrementeaz cu
numrul de octei citii. Dac citirea se face de la tastatur (deci din fiierul standard de
intrare), operaia se termin la apsarea tastei <Enter>. n acest caz funcia se apeleaz
astfel:
read(0, buf, lung);
Dac citirea s-a fcut corect, funcia returneaz numrul de octei efectiv citii; dac
citirea nu se poate face corect, funcia read returneaza -1. Numrul maxim de octei care
pot fi citii este dat de tipul variabilei (lung) care indic acest lucru i anume ntreg fr
semn pe 2 octei (unsigned). Astfel valoarea posibil de a fi stocat este ntre 0 i 65 535,
dar 65 535 are aceeai reprezentare (0xFF) ca i valoarea 1 (care este codul pentru
operaie terminat cu eroare). Ca urmare se pot citi maximum 65534 octei n caz de
succes, funcia returnnd valoarea 1 n caz de citire eronat.
Dac fiierul este accesat n mod text, se elimin Carriage Return (CR) i se
consider (pentru fiierul standard de intrare) Ctrl-Z ca End-Of-File (EOF). Dac se
acceseaz fiierul n mod text, valoarea returnat nu numar i `\r' (Carriage Return - CR)
sau Ctrl-Z;
Tot pentru citire se poate utiliza funcia:
int _read(int df, void *buf, unsigned lung);
Parametrii au aceeai semnificaie ca i la funcia read, singura diferen fa de
read(...) este ca nu se elimina `\r' la fiierele accesate n mod text;
2.2.6. Scrierea ntr-un fiier
Pentru scrierea ntr-un fiier, deschis cu o funcie open(...), creat(...), dup(...) sau
dup2(...), se utilizeaz funcia write(...) al crui prototip este n io.h i are forma:
int write (int df, void *buf, unsigned lung);
Parametrii acestei funcii sunt aceiai ca la funcia read(). Deosebirea este aceea
c, n cazul acestei funcii, transferul pe blocuri de octei se face din zona de memorie
indicat de pointerul buf n fiierul al crui descriptor este df. Funcia returneaza numrul
de octei nscrii n fiierul cu descriptorul df, la fiecare apel, sau valoarea -1 dac la
11

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 12

scriere a aprut o eroare. Dac valoarea returnat este mai mic dect valoarea
parametrului lung este, de asemenea, vorba de o eroare (Disk full);
Valoarea maxim a parametrului lung poate fi tot 65534 (din motivele expuse la
prezentarea funciei read(...)).
La fiierele text, caracterul linefeed (`\n') este convertit n perechea CR/LF (carriage
return / line feed );
Pentru fiierele de pe disc (avnd discul ca dispozitiv de I/E), scrierea se face
totdeauna ncepnd de la poziia curent (dat de indicatorul de poziie curent). Excepie
fac fiierele deschise cu opiunea O_APPEND, pentru care indicatorul de poziie curent
este poziionat la sfritul fiierului - de ctre write(...) - naintea fiecrei scrieri.
Pentru scrierea n fiiere binare, putem foloi funcia:
int _write (int df, void *buf, unsigned lung);
Aceast funcie difer de write(...) prin aceea c lucreaz numai cu fiiere binare,
nefcnd conversia LF CR/LF i nu pozitioneaz indicatorul de poziie curent la
sfritul fiierului naintea scrierii pentru fiierele deschise cu opiunea O_APPEND;
Dac valoarea descriptorului de fiier este 1 (df = 1), scrierea se va face pe ecran (n
fiierul standard de ieire), iar dac df = 2, scrierea se face n fiierul standard pentru erori.
2.2.7. Poziionarea ntr-un fiier
Dac datele dint-un fiier nu trebuie prelucrate secvenial (adic ncepnd cu prima i
terminnd cu ultima), se folosete funcia lseek() pentru a poziiona indicatorul de poziie
curent acolo n locul dorit. Dup poziionare, urmeaz prelucrarea (citirea sau scrierea n
fiier).
Poziionarea ntr-un fiier se face cu funcia lseek, al crui prototip este:
long lseek (int df, long depl, int or);
Parametrii acestei funcii au urmtoarele semnificaii:
df

- descriptorul de fiier

depl - numrul de octei cu care se va deplasa indicatorul de poziie curent;


or

- poziia de unde se deplaseaz indicatorul de poziie curent, care poate fi:


SEEK_SET sau 0 dac deplasarea se consider de la nceputul fiierului;
SEEK_CUR sau 1 dac deplasarea se consider din poziia curent din fiier;
SEEK_END sau 2 dac deplasarea se consider de la sfritul fiierului.
Funcia returneaz poziia indicatorul de poziie curent fa de nceputul fiierului

exprimat n octei i -1, n caz de eroare. n cazul dispozitivelor de I/E de tip imprimant
sau terminal, valoarea returnat este nedefinit.
12

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 12

Exemplu:
lseek(df, 0, 0)

- poziionarea se face la nceputul fiierului

lseek(df, 0, 2)

- poziionarea se face la sfritul fiierului.

Utilizarea funciei lseek cere includerea fiierului header io.h.


Funcia:
long tell (int df);
returneaz poziia n care se gsete indicatorul de poziie curent n fiierul al crui
descriptor de fiier este df exprimat ca distan n octei fa de nceputul fiierului.
Funcia are prototipul n io.h i returneaz -1L pentru eroare (Bad file number).
2.2.8. nchiderea unui fiier
Dup ce se termin prelucrarea (citirea i/sau scrierea) unui fiier, el trebuie nchis.
nchiderea se face cu una din funciile close(...) sau _close(...) ale caror prototipuri sunt:
int close (int df);
i
int _close (int df);
Cele dou funcii au un singur parametru de intrare care este descriptorul pentru
fiierul care trebuie nchis. La nchiderea unui fiier se pune i markerul de sfrit de fiier
(este singura modalitate de marcare a sfritului de fiier).
Aceste funcii returneaz valoarea 0 daca nchiderea s-a realizat corect i valoarea -1
dac apare eroare la nchiderea fiierului.
Fiierele standard se nchid automat. Utilizarea funciilor de nchidere fiiere cere
includerea fiierului header io.h..
Funciile close(...)/open(...) exist i n UNIX, n timp ce _close(...)/_open(...) sunt
numai n DOS.
n exemplul urmtor se folosete prelucrarea la nivelul inferior a fiierelor pentru
copierea fiierului standard de intrare (tastatura) n fiierul standard de ieire (monitorul):
#include <stdio.h>
#include <conio.h>
#include <io.h>
#define BUF 70
int main (void )
{
char bf [BUF];
13

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 12

int lung;
clrscr ( );
printf ("\n Introduceti text de la tastatura (pana la CTRL/Z): \n");
while ( (lung = read(0,bf, BUF) ) > 0)
write(1, bf, lung);
getch();
}

2.2.9. Citirea / modificarea drepturilor de acces la un fiier


n cazul n care se dorete verificarea existenei unui fiier i a drepturilor de acces la
fiierul respectiv se folosete funcia (al crui prototip este in io.h):
int acces (const char *numefiier, int amod);
Funcia are doi parametri de intrare:
(a) numele fiierului care respect toate specificaiile indicate la funcia open;
(b) parametrul amod indic drepturile care se verific i poate lua una din valorile:
06 verific dac se permite citirea i scrierea (modificarea);
04 verific dac se permite citirea;
02 verific dac se permite scrierea;
01 executat (ignorat);
00 verific daca un fiier exist.
n MS DOS toate fiierele existente pot fi accesate n citire, aa ca 00 i 04 produc
acelai rezultat. De asemenea, 06 i 02 sunt echivalente (n DOS, permisiunea de scriere
implica permisiunea de citire).
Dac numefiier este numele unui director, funcia determin numai dac acesta
exist.
Funcia returneaz valoarea 0 dac este permis accesul indicat sau valoareal -1 n
caz contrar. Indicatorul de eroare errno se poziioneaz pe:
ENDENT Path or file name not found
EACCES Permission denied.
Dac se dorete modificarea drepturilor de acces la un fiier se folosete funcia (cu
prototipul tot n io.h):
int chmod (const char *numefiier, int amod);

14

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 12

Funcia modific drepturile de acces la fiierul indicat prin numefiier n conformitate


cu valorile date de cel de-al doilea parametru (amod). Constantele simbolice (definite n
sys\stat.h) care pot fi folosite pentru cel de-al doilea parametru al funciei sunt aceleai ca
pentru cel de-al doilea parametru de intrare al funciei creat i anume:
S_IWRITE
S_IREAD
S_IREAD | S_IWRITE;
Funcia returneaz valoarea 0 pentru modificarea cu succes a drepturilor de acces
dorite sau valoarea -1 n caz de eroare. La eroare se seteaz indicatorul de eroare errno
pe una din valorile:
ENDENT Path or file name not found
EACCES Permission denied.

TEME
N TOATE PROBLEMELE CARE URMEAZ SE VA FOLOSI NIVELUL INFERIOR DE
PRELUCRARE A FIIERELOR.
Problema nr. 1
S se citeasc de la tastatur un text ncheiat cu un caracter '.' sau cu CTRL/Z i s
se scrie acest text ntr-un fiier al crui nume este dat ca argument n linia de comand.
Dup ncheierea citirii, textul nscris n fiier trebuie afiat pe ecran (tot prin program).
Problema nr. 2
S se scrie un program care concateneaz toate fiierele de tip C din directorul
curent ntr-un fiier numit final.c. Linia de comand este de forma:
p1 *.c
n care p1 este numele programului.
Problema nr. 3
Scriei un program numit tail care tiprete un set de linii specificate ntr-o gam dat
ca argument n linia de comanda. Liniile se citesc de la tastatur (sau prin indirectare dintrun fiier text) i se depun ntr-un tablou de iruri
Exemplu:
tail 5- /* tiprete toate liniile, ncepnd cu linia 5 */
tail -10 /* tiprete primele 10 linii */
15

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 12

tail 2-8 /* tiprete 7 linii (inclusiv liniile 2 i 8) */


tail

/* tiprete toate liniile */

Problema nr. 4
S se scrie un program care citete de la tastatur un ir de numere ncheiat cu
CTRL/Z. Numerele pare vor fi scrise ntr-un fiier, iar cele impare n altul. Numele celor
dou fiiere vor fi date ca argumente n linia de comand. Numerele citite pot fi formate din
una sau mai multe cifre.

Problema nr. 5
S se scrie un program care face analiza urmtoarei linii de comand:
matrice [-p][-s][-m][-h] [fisier_intrare] [fisier_iesire]
unde opiunile liniei de comand au urmtoarele semnificaii (parantezele ptrate indic
faptul c parametrii respectivi sunt opionali):
-p

prelucrarea 1

-s

prelucrarea 2

-m

prelucrarea 3

-h

afiarea unui mesaj de help (care descrie ce trebuie s fac programul i

forma liniei de comand)


Opiunea implicit de prelucrare este prelucrarea 3, iar n linia de comand nu poate
apare dect o singur opiune.
n cazul n care n linia de comand nu exist numele nici unui fiier, citirea datelor se
face de la tastatur, iar afiarea se face pe monitor. n cazul n care avem numele unui
singur fiier, acesta se consider a fi fiierul de intrare din care se citete matricea, iar
rezultatele se afieaz pe monitor.
Programul va scrie n fiierul de ieire doar un mesaj care s indice numele fiierului
de intrare i prelucrarea care urmeaz a fi fcut.

16

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 13

PRELUCRAREA LA NIVEL SUPERIOR A FIIERELOR


1. Deschiderea unui fiier ......................................................................................................2
2. Inchiderea fiierelor............................................................................................................4
3. Prelucrarea caracter cu caracter a unui fiier....................................................................4
3.1. Citirea unui caracter dintr-un fiier ..............................................................................4
3.2. Scrierea unui caracter ntr-un fiier.............................................................................4
4. Prelucrarea pe iruri de caractere a unui fiier..................................................................5
5. Poziionarea ntr-un fiier...................................................................................................5
6. Prelucrarea cu format a fiierelor.......................................................................................6
7. Prelucrarea fiierelor binare...............................................................................................6
8. Alte funcii de lucru cu fiiere la nivel nalt.........................................................................8
1) int fflush(FILE *pf); .........................................................................................................8
2) int flushall(void); .............................................................................................................9
3) void setbuf(FILE *pf, char *buffer); ................................................................................9
4) int setvbuf(FILE *pf, char *buf, int tip, int dim); ............................................................10
5) void clearerr(FILE *pf);.................................................................................................11
6) FILE *fdopen(int df, char *tip acces); ...........................................................................11
7) FILE *freopen(char *nume, char *tip, FILE *pf); ..........................................................12
8) int feof(FILE *pf); ..........................................................................................................13
9) int ferror(FILE *pf); .......................................................................................................13
10) char *tmpnam(char *s); si char *tempnam(char *dir, char *prefix); ........................13
11) FILE * tmpfile(void);....................................................................................................14
12) int rmtmp(void); ..........................................................................................................15
13) int fileno(FILE *pf); .....................................................................................................15
9. Funcii de lucru cu toate fiierele .....................................................................................15
1) int rename(const char *nume_vechi, const char *nume_nou);....................................15
2) int unlink(const char *nume_fiier);..............................................................................15
3) int remove(const char *nume_fiier); ...........................................................................15
TEME ...................................................................................................................................16
Problema nr. 1..................................................................................................................16
Problema nr. 2..................................................................................................................16
Problema nr. 3..................................................................................................................16
Problema nr. 4..................................................................................................................16
Problema nr. 5..................................................................................................................17
1

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 13

Pentru acest tip de prelucrare a fiierelor, se definete (n fiierul header stdio.h) o


structur de tip FILE astfel:
typedef struct {
int

level;

/* Indicator de umplere a zonei tampon

*/

unsigned

flags;

/* Indicatorii strii fiierului

*/

char

df;

/* Descriptor de fiier

*/

unsigned char hold;


int

bsize;

/* Zon pentru reprimirea unui caracter dac


nu exist zon tampon

*/

/* Mrimea zonei tampon asociate

*/

unsigned char _FAR *buffer; /* Adresa zonei tampon

*/

unsigned char _FAR *curp;

/* Indicatorul adresei curente din fiier

*/

unsigned

istemp;

/* Indicator de fiier temporar

*/

short

token;

/* Folosit pentru testarea validitii

*/

} FILE;
Fiierele standard (predefinite) acceptate de limbajul C sunt urmtoarele:
stdin

- fiierul standard de intrare (tastatura);

stdout

- fiierul standard de ieire (monitorul);

stderr

- fiierul standard de afiare a erorii (n general monitorul);

stdaux

- fiierul standard pentru comunicaia serial;

stdprn

- fiierul standard de tiprire (ieirea paralel la imprimant).

Aceste fiiere nu trebuie deschise sau nchise de programator.


n cele ce urmeaz cu pf va fi notat un pointer la o structur de tip FILE asociat
fiierului care se prelucreaz. Acest pointer este asociat numelui fiierului de prelucrat de
una din funciile (descrise mai jos) fopen(), fdopen(), freopen(), tmpfile().
Not: indicatorul de poziie definete unde anume n fiier vom scrie sau de unde
vom citi (adresa curent din fiier, relativ la nceputul fiierului) i difer de pf.
Toate funciile care lucreaz cu fiiere la acest nivel au prototipurile n fiierul header
stdio.h.

1. Deschiderea unui fiier


Deschiderea unui fiier se face cu funcia fopen, care returneaz un pointer la o
structur de tip FILE. Prototipul funciei este urmtorul:
2

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 13

FILE *fopen(const char *nume.fiier, const char *mod);


unde: nume_fiier

- la fel ca n funcia open (lucrarea anterioar);

mod

- pointer la caracter care prin intermediul cruia se indic modul n

care se va deschide fiierul; valorile posibile pentru irul de caractere sunt::


"r

- fiier deschis numai pentru citire;

"w"

- fiier deschis numai pentru scriere;

"a"

- fiier deschis pentru adugare;

"r+"

- fiier deschis pentru actualizare (citire + scriere);

"w+"

- se creeaz un nou fiier n care se vor face att citire ct i scrieri;

"a+"

- se deschide pentru actualizare la sfritul fiierului;

"t"

- modul de acces text;

"b"

- modul de acces binar.

Combinaiile se pot face n forma "rt", "wt", "r+t" sau "rt+" i respectiv "rb", "wb", "r+b"
sau "rb+". Dac un fiier inexistent se deschide cu "w" sau "a", el va fi deschis pentru
creare. Dac un fiier existent se deschide cu "w", atunci el va fi mai nti ters iar apoi
deschis pentru scriere.
Deschiderea unui fiier pentru adugare / actualizare face ca indicatorul de poziie
curent s fie plasat la sfritul fiierului. n toate celelalte cazuri indicatorul de poziie
curent se gsete la nceputul fiierului.
Funcia returneaz un pointer la o structur de tip FILE; dac fiierul indicat nu poate
fi deschis funcia returneaz pointerul NULL. De aceea, testarea valorii returnate de
funcia fopen() este important pentru execuia corect a programului.
Exemplu:
FILE *fp;

fp = fopen("input.dat", "r");

/* se ncearc deschiderea fiierului cu numele


input.dat numai pentru citire */

if (fp == NULL)
{
fprintf(stderr, "Nu se poate deschide fiierul input.dat \n", );
exit(EXIT_FAILURE);
}

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 13

2. Inchiderea fiierelor
Dup ce s-a terminat lucrul cu un fiier, el trebuie nchis. nchiderea unui fiier se
face cu funcia fclose, al crui prototip este:
int fclose(FILE *pf);
Funcia returneaza 0 la nchidere normal i -1 n caz de eroare. Toate buferele
asociate fiierului indicat sunt golite nainte de nchidere.
Pentru a nchide toate fiierele deschise, cu excepia fiierelor standard (stdin,
stdout, stderr, etc.) se utilizeaz funcia fcloseall cu prototipul.
int fcloseall(void);
Funcia returneaz numrul fiierelor nchise, iar n caz de eroare returneaz EOF.

3. Prelucrarea caracter cu caracter a unui fiier


3.1. Citirea unui caracter dintr-un fiier
Operaia de citire se poate realiza cu una din funciile:
(a) fgetc cu prototipul
int fgetc(FILE *pf);
(b) fgetchar pentru citirea de la tastatur cu prototipul:
int fgetchar(void);
(c) getc cu prototipul:
int getc(FILE *pf);
(d) getchar pentru citirea de la tastatur cu prototipul:
int getchar(void);
Funciile returneaz codul ASCII al caracterului citit convertit ntr-un ntreg fr semn
sau EOF la sfrit de fiier sau eroare.
3.2. Scrierea unui caracter ntr-un fiier
Scrierea unui caracter ntr-un fiier se poate realiza cu una din funciile:
(a) fputc al crui prototip este
int fputc(int c, FILE *pf);
(b) putc cu prototipul:
int putc(int c, FILE *pf);
(c) fputchar pentru scrierea pe monitor cu prototipul
int fputchar(int c);
care este echivalent cu fputc(c, stdout);
4

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 13

(d) putchar pentru scrierea pe monitor cu prototipul


int putchar(int c);
care este echivalent cu putc(c,stdout);
Pentru toate funciile c este un ntreg care conine codul ASCII al caracterului care va
fin nscris i returneaz codul ASCII al caracterului scris sau -1 n caz de eroare.

4. Prelucrarea pe iruri de caractere a unui fiier


Pentru acest tip de prelucrare se folosesc dou funcii: fgets (citire ir de caractere
dintr-un fiier) i fputs (scriere ir de caractere ntr-un fiier).
Funcia fgets are prototipul:
char *fgets(char *s, int n, FILE *pf);
unde:
s

- pointer care indic o zon de memorie n care se va citi irul de caractere

(n -1)

- numrul maxim de caractere care se pot citi

Citirea se face pn se citesc n-1 caractere sau pn cnd se ntlnete caracterul


LF (linie nou sau \n) (depinde ce condiie este ndeplinit mai nti), pstreaz caracterul
\n i adaug \0 pentru a marca sfritul de ir. Funcia returneaz valoarea pointerului s
sau NULL la ntlnirea sfritului de fiier (EOF) sau n caz de eroare.
Funcia fputs are prototipul:
int fputs(const char *s, FILE *pf);
unde:
s

- pointer care indic o zon de memorie care conine irul de caractere

(terminat cu caracterul \0) care trebuie scris n fiierul indicat. Funcia nu adaug la irul
scris caracterul \n i nici nu copie terminatorul de ir (\0).
Funcia fputs returneaz codul ASCII al ultimului caracter scris i -1 n caz de eroare.

5. Poziionarea ntr-un fiier


Pentru acces aleator n interiorul unui fiier, se utilizeaz funcia fseek, cu ajutorul
creia se poate muta indicatorul de poziie curent n locul dorit. Prototipul funciei este:
int fseek(FILE *pf, long depl, int or);
unde depl i or - au aceeai semnificaie ca la funcia lseek (vezi lucrarea 12).
Funcia returneaz 0 n caz de poziionare corect i o valoare diferit de 0 n caz
contrar.
Locul unde se gsete indicatorul de poziie curent la un moment dat se poate afla
folosind funcia ftell, cu prototipul:
5

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 13

long ftell(FILE *pf);


Funcia returneaz distana n octei, fa de nceputul fiierului, la care se gsete
indicatorul de poziie pentru fiierul cruia i este asociat pointerul pf.
Mutarea indicatorului de poziie a unui fiier se face cu funcia:
int fsetpos(FILE *pf, const fpos_t *pos);
unde: pos un pointer la o dat de tip fpos_t (care este de fapt un ntreg lung o dat de tip
long) i conine adresa unde gsim o valoare a indicatorului de poziie determinat cu
funcia fgetpos al crei prototip este:
int fgetpos(FILE *pf, fpos_t *pos);
Dup apelul lui fsetpos urmtoarea operaie n fiier poate fi o citire sau o scriere.
Funcia terge i indicatorul de sfrit de fiier, anulnd i rezultatele unei funcii ungetc.
n caz de succes funciile returneaz valoarea 0, altfel o valoare diferit de 0.
Poziionarea indicatorului de poziie curent la nceputul fiierului se face cu funcia
void rewind(FILE *pf);
este echivalent cu fseek(pf, 0L, SEEK_SET), cu deosebirea c terge indicatorii de
sfrit de fiier i de eroare, pe cnd fseek terge numai indicatorul de sfrit de fiier.

6. Prelucrarea cu format a fiierelor


n aceast categorie de prelucrare intr funciile fscanf i fprintf. Funcia fscanf
realizeaz citirea dintr-un fiier, conform argumentului de control:
int fscanf(pf, "control", &arg1, &arg2, ...);
unde: "control", &arg1, &arg2, ...

- au aceeai semnificaie ca la funcia scanf;

Funcia returneaza numrul de date corect citite i EOF la sfritul fiierului.


Funcia fprintf scrie intr-un fiier date cu un anumit format (conform argumentului
control) i are prototipul:
int fprintf(pf, "control", arg1, arg2, ...);
unde: "control", arg1, arg2, ...

- au aceeai semnificaie ca la funcia printf;

7. Prelucrarea fiierelor binare


Fiierele care conin informaii numerice (binare) sunt prelucrate cu ajutorul funciilor
fread i fwrite. nregistrarea ntr-un astfel de fiier se numete articol. Un articol este o
colecie de date structurate, de lungime fix. La citire se transfer ntr-o zon de memorie
numit tampon, un numr de articole. La scriere aceste articole, se iau din tampon i se
transfer ntr-un fiier.
6

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 13

Prototipul funciei fread este:


unsigned fread(void *tampon,

/* pointer spre o zona de memorie unde se


depun articolele citite */

unsigned dim,

/* lungimea unui articol */

unsigned nr_art,

/* numrul maxim de articole transferate*/

FILE *pf);
Funcia returneaz numrul de articole citite efectiv, cel mult egal cu nr_art.
Prototipul funciei fwrite este:
unsigned fwrite(const void *tampon,
unsigned dim,
unsigned nr_art,
FILE *pf);
Semnificaia parametrilor este aceeai ca la funcia fread, cu specificaia c
transferul se face din zona "tampon" n fiierul cu pointerul asociat pf. Funcia returneaz
numrul de articole scrise.
Exemplu de program pentru prelucrarea la nivel nalt al fiierelor.
S se copie coninutul fiierului input.dat n fiierul output.dat:
#include <stdio.h>
int main(void)
{
int c;
FILE *fin, *fout;
char *fi = "input.dat";
char *fo = "output.dat";
/*
* Deschide fisierul de intrare numai pentru citire
*/
fin = fopen(fi,"rt");
if(0 == fin)
{
fprintf(stderr, "Fisierul %s nu se poate deschide.\n", fi);
exit(EXIT_FAILURE);
}
7

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 13

/*
* Deschide fisierul de iesire pentru scriere
*/
fout = fopen(fo,"wt");
if(0 == fout)
{
fprintf(stderr, "Fisierul %s nu se poate deschide.\n", fo);
exit(EXIT_FAILURE);
}
while((c = getc(fin)) ! = EOF)
putc(c, fout);
/*
* Inchide fisierele deschise
*/
fclose(fin);
fclose(fout);
return 0;
}

8. Alte funcii de lucru cu fiiere la nivel nalt


Toate aceste funcii au prototipurile n fiierul stdio.h i lucreaz cu pointeri la o
structur de tip FILE asociat fiierului considerat.
1) int fflush(FILE *pf);
Dac fiierul asociat pointerului pf este deschis pentru operaii de ieire (scriere),
fflush scrie n fiier coninutul tamponului asociat fiierului. Dac fiierul este deschis
pentru operaii de intrare, fflush golete tamponul (buffer-ul) asociat fiierului cu pointerul
pf i nu are nici un efect dac fiierul nu are zon tampon.
Funcia ntoarce 0 dac tamponul s-a golit sau dac fiierul cu pointerul asociat pf nu
are zon tampon sau dac este "read-only". In caz de eroare, funcia ntoarce -1.
Fiierul rmne deschis dup execuia funciei. Mrimea implicita a tamponului creat
pentru un fiier cu zon tampon este de 512 octei.
8

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 13

Exemplu:
Dac ncheiem introducerea unor date de la tastatura cu <Ctrl+Z>, pentru a mai
putea citi ulterior alte date cu getchar(...) sau scanf(...) va trebui sa scoatem caracterul
<Ctrl+Z> = EOF din tamponul asociat intrrii standard cu fflush(stdin);
2) int flushall(void);
Se folosete pentru a goli zonele tampon asociate tuturor fiierelor deschise pentru
intrare sau ieire. Dac fiierul este deschis pentru citire, i se golete bufferul asociat.
Dac este deschis pentru scriere, coninutul bufferului asociat se "vars" n fiier, dup
care bufferul este ters. Toate fiierele rmn deschise.
Funcia returneaz numrul acestor fiiere.
3) void setbuf(FILE *pf, char *buffer);
Funcia permite utilizatorului s controleze bufferul unui fiier. Argumentul pf trebuie
sa se refere la un fiier deschis, nainte de a fi citit sau scris. Argumentul buffer este
pointer pe o zona de memorie BUFSIZ = 512 octei. Dac acest pointer = NULL, nseamn
ca fiierul nu are buffer. Buffer-ul setat de programator este folosit n operaii de I/E n locul
buffer-ului alocat implicit de sistem. Implicit stderr i stdaux nu au buffere, dar li se pot
ataa cu funcia setbuf.
Exemplu
#include <stdio.h>
char buf[BUFSIZ]; // trebuie sa fie variabila globala !
FILE *pf1, *pf2;
int main(void)
{
pf1 = fopen("fis1", "r");

/* va utiliz buf[] */

pf2 = fopen("fis2", "w");

/* fara buffer */

setbuf(pf1, buf);
setbuf(pf2, NULL);
puts ("S-au setat bufferele !!");
return 0;
}

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 13

4) int setvbuf(FILE *pf, char *buf, int tip, int dim);


Funcia d posibilitatea utilizatorului s controleze mrimea i tipul buffer-ului unui
fiier, deschis i asupra cruia s-au fcut deja operaii de I/E. Bufferul ataat fiierului
(indicat de parametrul buf) are dimensiunea dim, cu 0 dim 32767, iar tip poate avea
valorile:
- _IOFBF bufferare complet. Zona tampon pentru fiier este buf i are dimensiunea
dim. Dac buffer = NULL, este folosit un buffer implicit, de dimensiunea dim.
- _IOLBF bufferarea este de tip linie.
- _IONBF nu se utilizeaz nici un buffer, indiferent de argumentele buf i dim.
Funcia ntoarce 0 n caz de succes i o valoare diferit de 0 n caz de eroare.
Exemplu:
#include <stdio.h>
char buf[1024]; // definit de mrimea predefinit
FILE *pf1, *pf2;
int main(void)
{
int val_ret;
pf1 = fopen("fis 1", "r");
pf2 = fopen("fis 2", "w");
if((val_ret = setvbuf(pf1, buf, _IOFBF, size(buf))) != 0)
{
printf("Tipul sau dimensiunea bufferului sunt eronate!\n");
}
else
{
printf("Fiierul fis 1 are un tampon de 1024 octeti !\n");
}
if((val_ret = setvbuf(f2, NULL, _IONBF, 0)) != 0)
{
printf ("Eroare argumente \n");
}
else
{
printf("Fis 2 nu este bufferat !\n");
}
10

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 13

return 0;
}
5) void clearerr(FILE *pf);
Reseteaz (pune pe zero) indicatorul de eroare i indicatorul de sfrit de fiier
pentru fiierul al crui pointer asociat este pf. Se tie c indicatorii de eroare i de EOF nu
sunt teri automat. Odat setai, ei se pstreaz pn la apelul funciei clearerr sau
rewind.
6) FILE *fdopen(int df, char *tip acces);
Asociaz unui fiier cu descriptorul de fiier df (deschis la nivel inferior), un pointer la
o structur de tip FILE, pentru a putea fi prelucrat la nivel ridicat (bufferizare, formatare).
tip_acces, poate fi:
"r"

- deschis pentru citire (fiierul trebuie s existe);

"w"

- deschis pentru scriere. Dac n fiier exista ceva, el va fi mai nti ters.

"a"

- deschis pentru adugare. Dac nu exist, va fi creat;

"rt"

- deschide pentru citire /scriere un fiier existent.

"w+" - deschide un fiier gol pentru scriere i citire. Dac fiierul exist, coninutul lui
va fi mai nti ters.
"a+" - deschide fiierul pentru adugare i citire. Dac fiierul nu exista, va fi creat.
Observaie: La utilizarea tipului "w" i "w+" trebuie mult atenie, cci acest mod de lucru
are ca efect mai nti tergerea fiierului, iar apoi scrierea n el. Dac un fiier este deschis
cu "a" sau "a+", toate operaiile de scriere au loc la sfritul lui. Cnd un fiier este deschis
cu "r+" sau "w+" sau "a+", sunt permise operaiile de citire i scriere. Totui cnd trecem
de la citire la scriere sau invers, trebuie sa utilizam fsetpos(...), fseek(...) sau rewind(...).
Cu fsetpos(...) sau fseek se poate stabili poziia curent. De asemenea irul pointat de
argumentul tip_acces poate avea n compoziia sa caracterul `b' sau `t' (cu semnificaia
binar sau text): "w+t" sau "wt+". Opiunea `t' nu face parte din standardul ANSI, ci este o
extensie MICROSOFT. Deschiderea n modul text transform <CR+LF> n <LF> la intrare,
iar la ieire are loc transformarea invers. De asemenea <CTRL+Z> este interpretat la
intrare ca EOF. Funcia asociaz un pointer la o structur de tip FILE fiierului deschis sau
NULL n caz de eroare.
Exemplu
#include <stdio.h>
#include <fcntl.h>
11

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 13

FILE *pf;
int main(void)
{
int df;
FILE *pf;
df = open ("fiier", O_RDONLY);
pf = fdopen (df, "r");
if(pf == NULL)
{
printf ("Eroare la deschidere cu fdopen(...)");
}
else
{
printf ("\"fiier\" are asociat un pointer pe o structura FILE \n);
}
return 0;
}
7) FILE *freopen(char *nume, char *tip, FILE *pf);
Funcia nchide mai nti fiierul cu pointerul asociat pf, apoi asociaz acestui pointer
fiierul nume. Funcia se utilizeaz pentru redirectarea fiierelor standard stdin, stdout,
stderr, stdaux i stdprn. Noul fiier nume, asociat cu pf este deschis dup argumentul tip,
care este la fel ca la fopen(...) i fdopen(...). Funcia freopen(...) asociaz pointerul pf cu
noul fiier deschis sau returneaz NULL n caz de eroare.
Exemplu
S redirectam ieirea standard stdout ntr-un fiier "fis":
...
FILE *pf;
...
pf = freopen("fis", "w", stdout);
if(pf == NULL)
{
printf("eroare de redirectare ! \n");
}
else
12

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 13

{
fprintf(pf, "Acest text se scrie n \"fis\" \n");
fprintf(pf, "pentru ca stdout este redirectat \n");
}
...
8) int feof(FILE *pf);
Macrodefiniia feof(...) testeaz dac n fiierul al crui pointer asociat pe o structur
de tip FILE este pf s-a ajuns la sfrit (adic la EOF). ntoarce 0 dac nu s-a atins EOF i
o valoare diferit de 0 dac s-a detectat EOF n timpul ultimei operaii de citire.
9) int ferror(FILE *pf);
Macrodefiniia ferror(...) testeaz dac exista o eroare de scriere sau citire la fiierul
pf. Dac o astfel de eroare a aprut, indicatorul de eroare rmne setat pana se nchide
fiierul sau pn se executa funciile rewind(...) sau clearerr(...).
Macro-ul ntoarce 0 dac nu este eroare i o valoare 0 n cazul apariiei unei erori.
Exemplu
...
char *s = "Test de eroare";
FILE *pf;
...
pf = fopen("fiier", "r"); /*deschis pentru citire*/
fprintf(pf, "%s\n", s);/*scriere n fiier deschis pentru citire*/
if(ferror(pf))
{
fprintf(stderr, "Eroare la scriere \n");
clearerr(pf);
}
...
10) char *tmpnam(char *s); si char *tempnam(char *dir, char *prefix);
Funcia tmpnam(...) creeaz un nume de fiier care poate fi folosit temporar. Numele
fiierului este unic i este memorat n irul s. Dac nu se poate genera un astfel de nume
funcia furnizeaz valoarea NULL, altfel furnizeaz un pointer la un ir care este numele
de fiier generat.
13

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 13

La fiecare apel, funcia genereaz un nume definit, de forma:


TMP1.$$$, TMP2.$$$,... TMP65535.$$$
tergerea acestor fiiere trebuie fcut de utilizator. Funcia tempnam(...) permite crearea
unui nume de fiier temporar ntr-un director dat de utilizator. Numele fiierului poate fi
precizat de utilizator. In rest, funcioneaz la fel ca funcia tmpnam(...).
Exemplu
#include <stdio.h>
int main (void)
{
char *fis1, *fis2;
if((fis1 = tmpnam(NULL))! =NULL)
{
printf("fiierul %s este temporar !\n", fis1);
}
else
{
printf("Nu se poate crea nume unic !\n");
}
if((fis2 = tempnam("f:\\users\\temp", "test"))! =NULL);
{
printf("fiierul %s este temporar !\n", fis2);
}
else
{
printf("Nu se poate crea nume unic !\n");
}
return 0;
}
11) FILE * tmpfile(void);
Funcia genereaz un fiier temporar i i asociaz un pointer la o structur de tip
FILE. Dac acest fiier nu se poate crea, funcia furnizeaz valoarea NULL. Fiierul
temporar, este ters automat la nchiderea lui sau la terminarea programului, dar poate fi
ters i cu funcia rmtmp(...).

14

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 13

12) int rmtmp(void);


Funcia terge toate fiierele temporare din directorul curent, fiiere create cu funcia
tmpfile(...). Execuia acestei funcii are ca rezultat un numr de tip ntreg (int) care
reprezint numrul de fiiere terse.
13) int fileno(FILE *pf);
Funcia furnizeaz descriptorul de fiier pentru fiierul al crui pointer la o structura
FILE este pf. Acest fiier trebuie s fie deschis, altfel nu i se poate stabili descriptorul de
fiier.
Exemplu
df = fileno(stderr);

/* Face ca df = 2 */

9. Funcii de lucru cu toate fiierele


1) int rename(const char *nume_vechi, const char *nume_nou);
Funcia redenumete un fiier. Dac nume_nou conine n calea sa o unitate de disc,
aceeai unitate trebuie s existe i n nume_vechi. Deci fiierul redenumit nu poate fi
mutat pe alt unitate de disc, dar poate fi mutat pe alt director. n numele de fiier nu sunt
permise caracterele `*' i `?'. Dac exist deja un fiier cu nume_nou, operaia de
redenumire nu are loc. Funcia returneaza 0 n caz de succes i -1 n caz de eroare.
2) int unlink(const char *nume_fiier);
terge un fiier. Are prototipul n io.h i stdio.h. Nu se pot terge fiiere cu atributul
Read-Only. n nume_fiier poate fi indicat i calea (cu unitatea de disc i cu secvena de
directoare), dar nu pot figura caracterele `*' i `?'.
3) int remove(const char *nume_fiier);
terge un fiier. Este o macrodefiniie din stdio.h:
#define remove(cale) unlink(cale)

15

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 13

TEME
Pentru urmtoarele probleme, numele fiierelor sunt date ca argumente n linia de
comand i va fi folosit nivelul superior de prelucrare a fiierelor.
Problema nr. 1
S se scrie un program care afieaz coninutul unui fiier pe ecran
Problema nr. 2
S se scrie un program care citete de la tastatur un ir de numere reale i scrie
numerele citite ntr-un fiier, cte dou numere pe linie. Dimensiunea irului de numere
reale este dat ca prim argument n linia de comand, iar numele fiierului n care se
nscriu numerele este al doilea argument al liniei de comand. Dup ce s-a terminat citirea
datelor, coninutul fiierului se afieaz pe ecran, cte un numr pe linie.
Problema nr. 3
S se scrie un program pentru concatenarea ntr-un fiier a dou sau mai multe
fiiere ale cror nume sunt date ca argumente n linia de comand. Numele fiierului care
rezult n urma concatenrii este ultimul argument din linia de comand. Dac n linia de
comanda nu este nici un argument, se copie intrarea standard n ieirea standard. Dac
n linia de comand este un singur fiier, acesta este fiierul n care se nscrie ceea ce se
tasteaz. Dac sunt dou fiiere n linia de comand se copie primul fiier n cel de al
doilea. Se va scrie o funcie pentru a copia un fiier n alt fiier care are ca parametri doi
pointeri la structuri de tip FILE.
Problema nr. 4
S se scrie un program care are urmtoarea linie de comand:
matrice [-p][-s][-m][-h] [fisier_intrare] [fisier_iesire]
unde opiunile liniei de comand au urmtoarele semnificaii (parantezele ptrate indic
faptul c parametrii respectivi sunt opionali):
-p

prelucrarea 1

-s

prelucrarea 2

-m

prelucrarea 3

-h

afiarea unui mesaj de help (care descrie ce trebuie s fac programul)

fisier_intrare

fiierul de unde se citesc datele cu urmtorul format:


16

PROGRAMAREA CALCULATOARELOR

LUCRAREA NR. 13

1. prima linie

numele matricei

2. a doua linie

- numrul de linii i de coloane, separate de un

spaiu
3. urmtoarele linii

matricea (pe linii, elementele unei linii fiind

separate printr-un spaiu)


fisier_iesire

fiierul unde se nscriu rezultatele cu urmtorul format:

1. prima linie

prelucrarea dorit

2. a doua linie

- numele matricei

3. a treia i urmtoarele linii - matricea (pe linii, elementele unei linii fiind
separate printr-un spaiu)
Opiunea implicit de prelucrare este prelucrarea 3.
n cazul n care n linia de comand nu exist numele nici unui fiier, citirea datelor se
face de la tastatur, iar afiarea se face pe monitor. n cazul n care avem numele unui
singur fiier, acesta se consider a fi fiierul de intrare din care se citete matricea, iar
rezultatele se afieaz pe monitor.
Programul trebuie s identifice prelucrarea dorit, s citeasc din fiierul
corespunztor matricea, iar n fiierul de ieire s afieze prelucrarea dorit i matricea
citit.
Problema nr. 5
S se creeze un fiier binar care conine date cu urmtorul format:
Denumire

Cod

conductor

1012345

Unit_mas
ml

Pret

Cantitate

60.0

1000.50

...............................
Tabelul de mai sus trebuie s aib cel puin 5 linii.
Structura unui articol va fi:
typedef struct{
char den[50];
long cod;
char um[5];
float pret,cant;
} ARTICOL;

17

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