Documente Academic
Documente Profesional
Documente Cultură
Programare Structurata in Limbajul C Standard Editia 2008
Programare Structurata in Limbajul C Standard Editia 2008
CLAUDIA BOTEZ
PROGRAMARE
STRUCTURAT N
LIMBAJUL C STANDARD
Ediia 2008
http://www.ace.tuiasi.ro/~eserban
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
va
rezolva
problema
dat;
pentru
aceasta
utilizatorul
transmite
de
programare
trebuie
pun
la
dispoziia
utilizatorului
faciliti
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
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
D. I.
MEMORIE
D.E.
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
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.
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.
F =
9
C + 32
5
(Bn Bn 1 K B2 B1B0 )2
= 2 n Bn + 2 n 1 Bn 1 + K + 22 B2 + 21 B1 + 20 B0
schemei
logice
permite
ca
programatorul
neleag
logica
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
Scrie
list de variabile
list de expresii
De exemplu,
Citete
a, b, c
Scrie
"n nu poate fi 0"
Scrie "x=", x
Scrie x
Funcie
STOP
Retur
(a)
A
(b) Conectori pentru scheme
reprezentate pe mai multe pagini
logice
Funcie
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=
c =
(x A
x B ) + (y A y B )
2
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
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
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
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
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
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
NU
2 tarif (nrOre 60 )
S 40 tarif +
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
19
START
Citeste
a, b, c
T esteTriung hi ( a, b , c)
NU
DA
T=1
Scrie
"Nu este triunghi"
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
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
esteEchilateral(a,b,c,)
NU
DA
(a=b)
SI (b=c)
r 0
DA
r 1
Retur r
21
esteIsoscel(a,b,c,)
NU
(a=b) SAU
(b=c) SAU
(c=a)
r 0
DA
r 1
Retur r
esteDreptunghic(a,b,c,)
NU
r 0
DA
r 1
Retur r
22
START
Citeste a, b
Calculeaza catul c
Scrie c
STOP
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
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
24
are
numeroase
variante,
deosebindu-se
de
la
proiectant
la
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
p (a + b + c ) 2
A
p (p a) (p b ) (p c )
Funcie calculLungime(x1,y1,x2,y2)
(x
x 2 ) + (y 1 y 2 )
2
transmite d
sfrit funcie
26
27
Actiune 1
Actiune 2
Aici sche ma se
continua cat
este nevoie
Actiune n
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
Adevarat
conditie
Secventa
29
verific
<condiie
1>;
dac
valoarea
este
adevrat
se
execut
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
31
Expresie ?
Val1
Secventa 1
Val2
Secventa 2
Val3
Secventa 3
Valn
Secventa n
Rest
Secventa
n+1
<Secvena n+1>;
sf. alege
32
Fals
conditie
Adevarat
Secventa
33
Secventa
Fals
Adevarat
conditie
34
va r vi
Fals
var vf
Adevarat
Secventa
v ar v ar + pas
Ei
Fals
Et
Adevarat
Secventa
Em
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
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 2
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
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
- Del
- Ctrl-O :
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)
F2 (File:Save)
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)
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)
cursorul
F5 (Window:Zoom)
F6 (Window:Next)
fereastra curent ori din fiierul proiect .prj anterior definit i deschis
(F10)
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 2
Alt-F7:Previous error
Alt-F8:Next error
creare fiier
ncrcare fiier existent sau creare fiier nou (se tasteaz
numele nou)
Save(F2)
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 2
Save as
Save all
Change dir
Get info
DOS shell
Quit(Alt-X)
Redo
Cut(Shift-Del)
cutare text
Replace
Search again
Go to line number
Previous error(Alt-F7)
PROGRAMAREA CALCULATOARELOR
Locate function
LUCRAREA NR. 2
abandoneaz
depanarea
se
elibereaz
Arguments
Make(F9)
Build all
extinderea
la
dimensiunile
ntregului
ecran
sau
PROGRAMAREA CALCULATOARELOR
Tile
LUCRAREA NR. 2
Cascade
Next (F6)
Close (Alt-F3)
Message
se
activeaz
fereastra:
message
(prezint
Watch
Project
Project notes
List (Alt-0)
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
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
cu un caracter la 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
scroll-up o linie
Ctrl-W
scroll-down o linie
Ctrl-Z
scroll-up un ecran
PgUp
scroll-down un ecran
PgDn
Home
End
Ctrl-Home
Ctrl-End
Ctrl-PgUp
Ctrl-PgDn
Ctrl-Q B
Ctrl-Q K
Ctrl_Q P
ntre
modurile
inserare
i tasta
Ins
sau
din
supratiprire
Options:Environment:Editor...
Backspace
Del
Ctrl-T
inserare linie
Ctrl-N
12
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 2
tergere linie
Ctrl-Y
Ctrl-Q Y
demarcare bloc
Ctrl-K H
marcare cuvnt
tergere bloc
Ctrl-K C
Ctrl-K V
Ctrl-K R
Ctrl-K W
tiprire bloc
Ctrl-K P
indent bloc
Ctrl-K I
unindent bloc
Ctrl-K U
Options: Environment:Editor
cutare text
Esc
tiprire fiier
File: Print
PROGRAMAREA CALCULATOARELOR
case sensitive
LUCRAREA NR. 2
ON);
whole words only
(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
domeniul de cutare:
Global (implicit) ntregul fiier;
Selected text
poriunea de cutare
From cursor (implicit) se caut de la poziia curent pn la limita nainte /
napoi a fiierului
Entire scope
14
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 2
#include <stdio.h>
2:
#include <conio.h>
3:
int main(void)
4:
/* Primul program */
5:
6:
clrscr();
7:
8:
9:
10:
11:
getch();
12:
return 0;
13:
}
Mai nti se includ fiierele header ce conin prototipurile funciilor de bibliotec ce vor
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
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 cresctor
(tip ir = 2)
formeaz un ir descresctor
(tip ir = 3)
(tip ir = 5)
20
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 2
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
21
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 3
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
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]
[0..255]
Signed char
[-128,127]
Float
32
Flotant
long
Unsigned
char
simpl [3.4x10^(-38)..3.4x10^38]
precizie
Double
64
[1.7x10^(-308)..1.7x10^308]
Long double
80
[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);
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
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
Cod ASCII
Semnificaie
\n
10
Rnd nou
\t
\a
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
10
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 3
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
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
nume
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];
12
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 3
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
xp =
(x
i =0
xm )
n (n 1)
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 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
valoarea expresiei
E =
n 1
(x
a t i b)
i =0
(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
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.
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
stdprn
>
redirectarea ieirii - crearea unui fiier n care sa se scrie datele ce s-ar afia in
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:
-
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:
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
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 4
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:
Caracter
intrare ateptat
Ieire formatat
ntreg
ntreg
ntreg
ntreg
ntreg
ntreg
Real
Real
Real
Real
Real
Caracter
Un singur caracter
ir
Pointer
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 4
S detaliem :
- litera c
- litera s
afieaz un caracter
printf("%c", 'A');
//afieaz: caracterul A
printf("*%4c*,'A');
printf("*%-4c*,'A');
i=97;printf("%c", i);
afieaz un ir
printf("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
- 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*
//afieaz: *
7b"
- litera u
- litera l
lu
lo
lx
lX
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
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.672
%10.1f
-123.7 (idem)
3.14159265
%10.0f
123.672
%10.0f
124
- 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
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'
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,...] );
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
ntreg zecimal
e, E
Real
Real
g, G
Real
ntreg octal
ntreg octal
ntreg hexazecimal
ntreg hexa
ir de caractere
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 4
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);
....
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:
- literele x, X:
- litera u:
naturale)
- litera f:
- literele e, E:
- literele g, G:
- 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
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
13
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 4
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
16
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 5
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
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
- Delete
tergerea lui
- View
- At
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 5
: caracter
: ntreg zecimal
f :n : real
h, x: : hexazecimal
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 5
de la
: structuri /uniuni
: ir (implicit)
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 5
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
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 5
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
A 1 = max aij
A
LUCRAREA NR. 5
i , j =1
2
ij
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)
10
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 5
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
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
1,0
1,5
1.0
1,0
6. Folosire proiect
0,5
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
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 6
>>
&
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
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
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
octet inferior
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 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
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
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
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
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
PROGRAMAREA CALCULATOARELOR
Lucrarea nr. 7
PROGRAMAREA CALCULATOARELOR
Lucrarea nr. 7
cu '\'. Apelurile
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
tip nume;
tip nume[dim1][dim2][dimn];
sau
PROGRAMAREA CALCULATOARELOR
Lucrarea nr. 7
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)
b)
PUNCT simetric(PUNCT a)
{
PUNCT b;
b.x = -a.x;
b.y = -a.y;
return b;
}
PROGRAMAREA CALCULATOARELOR
Lucrarea nr. 7
d = distanta(A, B);
/*
*
*
*/
X = simetric(Y);
/*
*
*/
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
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
// 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. 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;
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;
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
3) x++
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
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
...
tab+i
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 8
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 8
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
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
0,5
0,5
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
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
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
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]
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 9
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
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 9
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
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
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 9
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
tab[99]
11
21
34
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:
-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
1,0
MATRICE)
2. Alocarea corect de spaiu de memorie pentru pointeri (nume i matrice)
7
1,0
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 10
1,0
0,5
0,5
0,5
0,5
0,4
0,1
1,0
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
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
f : [a, b] R
(1)
ba
n
(2)
i = 1,K, n 1
(3)
f (x i ) + f (x i +1 )
(x i +1 x i )
2
(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)
// 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?
PROGRAMAREA CALCULATOARELOR
Lucrarea nr. 11
#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;
}
struct S1 {
................ /* declaraii pentru ali membri */
FM f;
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:
PROGRAMAREA CALCULATOARELOR
Lucrarea nr. 11
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
10
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 12
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 12
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 12
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 12
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
O_WRONLY
O_RDWR
O_APPEND
O_BINARY
O_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
O_EXCL
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
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
O_WRONLY
O_RDWR
O_NOINHERIT
O_DENYALL
O_DENYWRITE
O_DENYREAD
O_DENYNONE
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
S_IWRITE
S_IEXEC
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
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
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)
lseek(df, 0, 2)
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();
}
14
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 12
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
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
16
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 13
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 13
level;
*/
unsigned
flags;
*/
char
df;
/* Descriptor de fiier
*/
bsize;
*/
*/
*/
*/
unsigned
istemp;
*/
short
token;
*/
} FILE;
Fiierele standard (predefinite) acceptate de limbajul C sunt urmtoarele:
stdin
stdout
stderr
stdaux
stdprn
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 13
mod
"w"
"a"
"r+"
"w+"
"a+"
"t"
"b"
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");
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.
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 13
(n -1)
(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.
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 13
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 13
unsigned dim,
unsigned nr_art,
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;
}
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[] */
/* fara buffer */
setbuf(pf1, buf);
setbuf(pf2, NULL);
puts ("S-au setat bufferele !!");
return 0;
}
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 13
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"
"w"
- deschis pentru scriere. Dac n fiier exista ceva, el va fi mai nti ters.
"a"
"rt"
"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
14
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 13
/* Face ca df = 2 */
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
fisier_intrare
PROGRAMAREA CALCULATOARELOR
LUCRAREA NR. 13
1. prima linie
numele matricei
2. a doua linie
spaiu
3. urmtoarele linii
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